From cc1fdb033b1bb499e8c4f87d1dc6126d1fd193c3 Mon Sep 17 00:00:00 2001 From: Petar Dambovaliev Date: Wed, 3 Jan 2024 22:23:29 +0100 Subject: [PATCH 01/10] try --- tm2/pkg/bft/consensus/reactor.go | 8 ++++---- tm2/pkg/bft/consensus/state.go | 21 +++++++++++++++------ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/tm2/pkg/bft/consensus/reactor.go b/tm2/pkg/bft/consensus/reactor.go index ab7f3b55e92..9ddf026543f 100644 --- a/tm2/pkg/bft/consensus/reactor.go +++ b/tm2/pkg/bft/consensus/reactor.go @@ -242,9 +242,9 @@ func (conR *ConsensusReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) ps.ApplyHasVoteMessage(msg) case *VoteSetMaj23Message: cs := conR.conS - cs.mtx.Lock() + cs.mtx.RLock() height, votes := cs.Height, cs.Votes - cs.mtx.Unlock() + cs.mtx.RUnlock() if height != msg.Height { return } @@ -324,9 +324,9 @@ func (conR *ConsensusReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) switch msg := msg.(type) { case *VoteSetBitsMessage: cs := conR.conS - cs.mtx.Lock() + cs.mtx.RLock() height, votes := cs.Height, cs.Votes - cs.mtx.Unlock() + cs.mtx.RUnlock() if height == msg.Height { var ourVotes *bitarray.BitArray diff --git a/tm2/pkg/bft/consensus/state.go b/tm2/pkg/bft/consensus/state.go index 988a455f117..28845e6968f 100644 --- a/tm2/pkg/bft/consensus/state.go +++ b/tm2/pkg/bft/consensus/state.go @@ -226,8 +226,9 @@ func (cs *ConsensusState) GetLastHeight() int64 { // GetRoundState returns a shallow copy of the internal consensus state. func (cs *ConsensusState) GetRoundState() *cstypes.RoundState { cs.mtx.RLock() + defer cs.mtx.RUnlock() + rs := cs.RoundState // copy - cs.mtx.RUnlock() return &rs } @@ -661,9 +662,6 @@ func (cs *ConsensusState) receiveRoutine(maxSteps int) { // state transitions on complete-proposal, 2/3-any, 2/3-one func (cs *ConsensusState) handleMsg(mi msgInfo) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - var ( added bool err error @@ -686,13 +684,14 @@ func (cs *ConsensusState) handleMsg(mi msgInfo) { err = nil } case *VoteMessage: + cs.mtx.Lock() // attempt to add the vote and dupeout the validator if its a duplicate signature // if the vote gives us a 2/3-any or 2/3-one, we transition added, err = cs.tryAddVote(msg.Vote, peerID) if added { cs.statsMsgQueue <- mi } - + cs.mtx.Unlock() // if err == ErrAddingVote { // TODO: punish peer // We probably don't want to stop the peer here. The vote does not @@ -1374,6 +1373,7 @@ func (cs *ConsensusState) finalizeCommit(height int64) { // ----------------------------------------------------------------------------- func (cs *ConsensusState) defaultSetProposal(proposal *types.Proposal) error { + cs.mtx.RLock() // Already have one // TODO: possibly catch double proposals if cs.Proposal != nil { @@ -1382,28 +1382,37 @@ func (cs *ConsensusState) defaultSetProposal(proposal *types.Proposal) error { // Does not apply if proposal.Height != cs.Height || proposal.Round != cs.Round { + cs.mtx.RUnlock() return nil } // Verify POLRound, which must be -1 or in range [0, proposal.Round). if proposal.POLRound < -1 || (proposal.POLRound >= 0 && proposal.POLRound >= proposal.Round) { + cs.mtx.RUnlock() return ErrInvalidProposalPOLRound } // Verify signature if !cs.Validators.GetProposer().PubKey.VerifyBytes(proposal.SignBytes(cs.state.ChainID), proposal.Signature) { + cs.mtx.RUnlock() return ErrInvalidProposalSignature } + cs.Logger.Info("Received proposal", "proposal", proposal) + cs.Proposal = proposal // We don't update cs.ProposalBlockParts if it is already set. // This happens if we're already in cstypes.RoundStepCommit or if there is a valid block in the current round. // TODO: We can check if Proposal is for a different block as this is a sign of misbehavior! if cs.ProposalBlockParts == nil { + cs.mtx.RUnlock() + cs.mtx.Lock() cs.ProposalBlockParts = types.NewPartSetFromHeader(proposal.BlockID.PartsHeader) + cs.mtx.Unlock() + return nil } - cs.Logger.Info("Received proposal", "proposal", proposal) + return nil } From 37bd55ac01b5150ab2e43d83090aa13d3df1cd21 Mon Sep 17 00:00:00 2001 From: Petar Dambovaliev Date: Thu, 4 Jan 2024 15:15:02 +0100 Subject: [PATCH 02/10] save --- tm2/pkg/bft/consensus/state.go | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/tm2/pkg/bft/consensus/state.go b/tm2/pkg/bft/consensus/state.go index 28845e6968f..988a455f117 100644 --- a/tm2/pkg/bft/consensus/state.go +++ b/tm2/pkg/bft/consensus/state.go @@ -226,9 +226,8 @@ func (cs *ConsensusState) GetLastHeight() int64 { // GetRoundState returns a shallow copy of the internal consensus state. func (cs *ConsensusState) GetRoundState() *cstypes.RoundState { cs.mtx.RLock() - defer cs.mtx.RUnlock() - rs := cs.RoundState // copy + cs.mtx.RUnlock() return &rs } @@ -662,6 +661,9 @@ func (cs *ConsensusState) receiveRoutine(maxSteps int) { // state transitions on complete-proposal, 2/3-any, 2/3-one func (cs *ConsensusState) handleMsg(mi msgInfo) { + cs.mtx.Lock() + defer cs.mtx.Unlock() + var ( added bool err error @@ -684,14 +686,13 @@ func (cs *ConsensusState) handleMsg(mi msgInfo) { err = nil } case *VoteMessage: - cs.mtx.Lock() // attempt to add the vote and dupeout the validator if its a duplicate signature // if the vote gives us a 2/3-any or 2/3-one, we transition added, err = cs.tryAddVote(msg.Vote, peerID) if added { cs.statsMsgQueue <- mi } - cs.mtx.Unlock() + // if err == ErrAddingVote { // TODO: punish peer // We probably don't want to stop the peer here. The vote does not @@ -1373,7 +1374,6 @@ func (cs *ConsensusState) finalizeCommit(height int64) { // ----------------------------------------------------------------------------- func (cs *ConsensusState) defaultSetProposal(proposal *types.Proposal) error { - cs.mtx.RLock() // Already have one // TODO: possibly catch double proposals if cs.Proposal != nil { @@ -1382,37 +1382,28 @@ func (cs *ConsensusState) defaultSetProposal(proposal *types.Proposal) error { // Does not apply if proposal.Height != cs.Height || proposal.Round != cs.Round { - cs.mtx.RUnlock() return nil } // Verify POLRound, which must be -1 or in range [0, proposal.Round). if proposal.POLRound < -1 || (proposal.POLRound >= 0 && proposal.POLRound >= proposal.Round) { - cs.mtx.RUnlock() return ErrInvalidProposalPOLRound } // Verify signature if !cs.Validators.GetProposer().PubKey.VerifyBytes(proposal.SignBytes(cs.state.ChainID), proposal.Signature) { - cs.mtx.RUnlock() return ErrInvalidProposalSignature } - cs.Logger.Info("Received proposal", "proposal", proposal) - cs.Proposal = proposal // We don't update cs.ProposalBlockParts if it is already set. // This happens if we're already in cstypes.RoundStepCommit or if there is a valid block in the current round. // TODO: We can check if Proposal is for a different block as this is a sign of misbehavior! if cs.ProposalBlockParts == nil { - cs.mtx.RUnlock() - cs.mtx.Lock() cs.ProposalBlockParts = types.NewPartSetFromHeader(proposal.BlockID.PartsHeader) - cs.mtx.Unlock() - return nil } - + cs.Logger.Info("Received proposal", "proposal", proposal) return nil } From 854b8cf943c48493e2f67f87a82f846c42038ead Mon Sep 17 00:00:00 2001 From: Petar Dambovaliev Date: Fri, 12 Jan 2024 03:47:21 +0100 Subject: [PATCH 03/10] save --- tm2/pkg/bft/consensus/state.go | 3 +-- tm2/pkg/bft/consensus/wal_generator.go | 36 +++++++++++++++++--------- tm2/pkg/bft/wal/wal.go | 10 ++++++- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/tm2/pkg/bft/consensus/state.go b/tm2/pkg/bft/consensus/state.go index 988a455f117..6e419b5db31 100644 --- a/tm2/pkg/bft/consensus/state.go +++ b/tm2/pkg/bft/consensus/state.go @@ -69,9 +69,8 @@ func (ti *timeoutInfo) String() string { func (ti *timeoutInfo) GetHRS() cstypes.HRS { if ti == nil { return cstypes.HRS{} - } else { - return cstypes.HRS{ti.Height, ti.Round, ti.Step} } + return cstypes.HRS{ti.Height, ti.Round, ti.Step} } // interface to the mempool diff --git a/tm2/pkg/bft/consensus/wal_generator.go b/tm2/pkg/bft/consensus/wal_generator.go index 7893c544c7f..12e34fd14cd 100644 --- a/tm2/pkg/bft/consensus/wal_generator.go +++ b/tm2/pkg/bft/consensus/wal_generator.go @@ -35,7 +35,9 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { config := getConfig(t) app := kvstore.NewPersistentKVStoreApplication(filepath.Join(config.DBDir(), "wal_generator")) - defer app.Close() + defer func() { + err = app.Close() + }() logger := log.TestingLogger().With("wal_generator", "wal_generator") logger.Info("generating WAL (last height msg excluded)", "numBlocks", numBlocks) @@ -66,14 +68,18 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { if err := proxyApp.Start(); err != nil { return errors.Wrap(err, "failed to start proxy app connections") } - defer proxyApp.Stop() + defer func() { + err = proxyApp.Stop() + }() evsw := events.NewEventSwitch() evsw.SetLogger(logger.With("module", "events")) if err := evsw.Start(); err != nil { return errors.Wrap(err, "failed to start event bus") } - defer evsw.Stop() + defer func() { + err = evsw.Stop() + }() mempool := mock.Mempool{} blockExec := sm.NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(), mempool) consensusState := NewConsensusState(config.Consensus, state.Copy(), blockExec, blockStore, mempool) @@ -91,7 +97,12 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { // See wal.go OnStart(). // Since we separate the WALWriter from the WAL, we need to // initialize ourself. - wal.WriteMetaSync(walm.MetaMessage{Height: 1}) + err = wal.WriteMetaSync(walm.MetaMessage{Height: 1}) + + if err != nil { + return errors.Wrap(err, "WALGenerateNBlocks: failed to write meta message") + } + consensusState.wal = wal if err := consensusState.Start(); err != nil { @@ -100,11 +111,13 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { select { case <-numBlocksWritten: - consensusState.Stop() - return nil + return consensusState.Stop() case <-time.After(2 * time.Minute): - consensusState.Stop() - return fmt.Errorf("waited too long for tendermint to produce %d blocks (grep logs for `wal_generator`)", numBlocks) + tErr := fmt.Errorf("waited too long for tendermint to produce %d blocks (grep logs for `wal_generator`)", numBlocks) + if err := consensusState.Stop(); err != nil { + return errors.Wrap(tErr, err.Error()) + } + return tErr } } @@ -119,8 +132,8 @@ func WALWithNBlocks(t *testing.T, numBlocks int) (data []byte, err error) { return []byte{}, err } - wr.Flush() - return b.Bytes(), nil + err = wr.Flush() + return b.Bytes(), err } func randPort() int { @@ -216,8 +229,7 @@ func (w *heightStopWAL) WriteMetaSync(m walm.MetaMessage) error { // After processing is successful, commit to underlying store. This must // come last. - w.enc.WriteMeta(m) - return nil + return w.enc.WriteMeta(m) } func (w *heightStopWAL) FlushAndSync() error { return nil } diff --git a/tm2/pkg/bft/wal/wal.go b/tm2/pkg/bft/wal/wal.go index a4a14d638dd..3e5164fa596 100644 --- a/tm2/pkg/bft/wal/wal.go +++ b/tm2/pkg/bft/wal/wal.go @@ -499,7 +499,15 @@ func (enc *WALWriter) Write(v TimedWALMessage) error { line64 := base64stdnp.EncodeToString(line) line64 += "\n" - _, err := enc.wr.Write([]byte(line64)) + + input := []byte(line64) + + n, err := enc.wr.Write(input) + + if len(input) != n { + return fmt.Errorf("could not write msg: %+v bytes", input) + } + return err } From 1beea628366dc39a0038190d9f94b284572bdda9 Mon Sep 17 00:00:00 2001 From: Petar Dambovaliev Date: Mon, 15 Jan 2024 17:48:34 +0100 Subject: [PATCH 04/10] save --- gnovm/pkg/gnomod/fetch.go | 1 + tm2/ordering/ordering.go | 35 ++++++++++++++ tm2/pkg/bft/consensus/common_test.go | 2 +- tm2/pkg/bft/consensus/types/round_state.go | 39 ++++++++++------ .../bft/consensus/types/round_state_test.go | 46 +++++++++++++++++++ tm2/pkg/bft/types/priv_validator.go | 2 +- tm2/pkg/bft/types/validator.go | 8 ++-- tm2/pkg/bft/types/validator_set.go | 10 ++-- tm2/pkg/bft/types/validator_set_test.go | 2 +- tm2/pkg/crypto/crypto.go | 9 ++-- tm2/pkg/crypto/keys/client/add.go | 2 +- tm2/pkg/store/cache/mergeiterator.go | 37 +++++++-------- 12 files changed, 145 insertions(+), 48 deletions(-) create mode 100644 tm2/ordering/ordering.go diff --git a/gnovm/pkg/gnomod/fetch.go b/gnovm/pkg/gnomod/fetch.go index 6c2b1a63121..aedc831d2e3 100644 --- a/gnovm/pkg/gnomod/fetch.go +++ b/gnovm/pkg/gnomod/fetch.go @@ -12,6 +12,7 @@ func queryChain(remote string, qpath string, data []byte) (res *abci.ResponseQue // Height: height, XXX // Prove: false, XXX } + cli := client.NewHTTP(remote, "/websocket") qres, err := cli.ABCIQueryWithOptions(qpath, data, opts2) if err != nil { diff --git a/tm2/ordering/ordering.go b/tm2/ordering/ordering.go new file mode 100644 index 00000000000..d82a1981b85 --- /dev/null +++ b/tm2/ordering/ordering.go @@ -0,0 +1,35 @@ +package ordering + +type Order int + +const ( + less Order = -1 + equal Order = 0 + greater Order = 1 +) + +var ( + Less = Ordering{less} + Equal = Ordering{equal} + Greater = Ordering{greater} +) + +type Ordering struct { + value Order +} + +func NewOrdering(order Order) Ordering { + return Ordering{value: order} +} + +func (o Ordering) IsEqual() bool { + return o == Equal +} + +func (o Ordering) IsLess() bool { + return o == Less +} + +func (o Ordering) IsGreater() bool { + return o == Greater +} diff --git a/tm2/pkg/bft/consensus/common_test.go b/tm2/pkg/bft/consensus/common_test.go index ba19881aace..4cbe81189b8 100644 --- a/tm2/pkg/bft/consensus/common_test.go +++ b/tm2/pkg/bft/consensus/common_test.go @@ -126,7 +126,7 @@ func (vss ValidatorStubsByAddress) Len() int { } func (vss ValidatorStubsByAddress) Less(i, j int) bool { - return vss[i].GetPubKey().Address().Compare(vss[j].GetPubKey().Address()) == -1 + return vss[i].GetPubKey().Address().Compare(vss[j].GetPubKey().Address()).IsLess() } func (vss ValidatorStubsByAddress) Swap(i, j int) { diff --git a/tm2/pkg/bft/consensus/types/round_state.go b/tm2/pkg/bft/consensus/types/round_state.go index a1b92a99d31..0ad8d5c4f34 100644 --- a/tm2/pkg/bft/consensus/types/round_state.go +++ b/tm2/pkg/bft/consensus/types/round_state.go @@ -4,6 +4,8 @@ import ( "fmt" "time" + "github.com/gnolang/gno/tm2/ordering" + "github.com/gnolang/gno/tm2/pkg/bft/types" ) @@ -95,21 +97,32 @@ type HRS struct { Step RoundStepType `json:"step"` } -func (hrs HRS) Compare(other HRS) int { +func (hrs HRS) Compare(other HRS) ordering.Ordering { if hrs.Height < other.Height { - return -1 - } else if hrs.Height == other.Height { - if hrs.Round < other.Round { - return -1 - } else if hrs.Round == other.Round { - if hrs.Step < other.Step { - return -1 - } else if hrs.Step == other.Step { - return 0 - } - } + return ordering.Less + } + + if hrs.Height > other.Height { + return ordering.Greater + } + + if hrs.Round < other.Round { + return ordering.Less + } + + if hrs.Round > other.Round { + return ordering.Greater + } + + if hrs.Step < other.Step { + return ordering.Less } - return 1 + + if hrs.Step > other.Step { + return ordering.Greater + } + + return ordering.Equal } func (hrs HRS) IsHRSZero() bool { diff --git a/tm2/pkg/bft/consensus/types/round_state_test.go b/tm2/pkg/bft/consensus/types/round_state_test.go index 49fe57c4c05..a93cb5d7d9d 100644 --- a/tm2/pkg/bft/consensus/types/round_state_test.go +++ b/tm2/pkg/bft/consensus/types/round_state_test.go @@ -3,6 +3,8 @@ package cstypes import ( "testing" + "github.com/gnolang/gno/tm2/ordering" + amino "github.com/gnolang/gno/tm2/pkg/amino" "github.com/gnolang/gno/tm2/pkg/bft/types" tmtime "github.com/gnolang/gno/tm2/pkg/bft/types/time" @@ -86,3 +88,47 @@ func BenchmarkRoundStateDeepCopy(b *testing.B) { amino.DeepCopy(rs) } } + +func TestCompare(t *testing.T) { + tests := []struct { + name string + hrs1 HRS + hrs2 HRS + result ordering.Ordering + }{ + {"Equal HRS", HRS{Height: 1, Round: 2, Step: RoundStepNewHeight}, HRS{Height: 1, Round: 2, Step: RoundStepNewHeight}, ordering.Equal}, + {"HRS1 Lesser Height", HRS{Height: 1, Round: 2, Step: RoundStepNewHeight}, HRS{Height: 2, Round: 2, Step: RoundStepNewHeight}, ordering.Less}, + {"HRS1 Greater Height", HRS{Height: 2, Round: 2, Step: RoundStepNewHeight}, HRS{Height: 1, Round: 2, Step: RoundStepNewHeight}, ordering.Greater}, + {"Equal Height, HRS1 Lesser Round", HRS{Height: 1, Round: 2, Step: RoundStepNewHeight}, HRS{Height: 1, Round: 3, Step: RoundStepNewHeight}, ordering.Less}, + {"Equal Height, HRS1 Greater Round", HRS{Height: 1, Round: 3, Step: RoundStepNewHeight}, HRS{Height: 1, Round: 2, Step: RoundStepNewHeight}, ordering.Greater}, + {"Equal Height, Equal Round, HRS1 Lesser Step", HRS{Height: 1, Round: 2, Step: RoundStepNewHeight}, HRS{Height: 1, Round: 2, Step: RoundStepPropose}, ordering.Less}, + {"Equal Height, Equal Round, HRS1 Greater Step", HRS{Height: 1, Round: 2, Step: RoundStepPropose}, HRS{Height: 1, Round: 2, Step: RoundStepNewHeight}, ordering.Greater}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := tt.hrs1.Compare(tt.hrs2) + if result != tt.result { + t.Errorf("Expected %d, got %d", tt.result, result) + } + }) + } + + // Test cases for all RoundStepType values + t.Run("All RoundStepType Values", func(t *testing.T) { + for step1 := RoundStepInvalid; step1 <= RoundStepCommit; step1++ { + for step2 := RoundStepInvalid; step2 <= RoundStepCommit; step2++ { + hrs1 := HRS{Height: 1, Round: 2, Step: step1} + hrs2 := HRS{Height: 1, Round: 2, Step: step2} + result := hrs1.Compare(hrs2) + if step1 < step2 && result != ordering.Less { + t.Errorf("Expected -1, got %d for %s < %s", result, step1, step2) + } else if step1 > step2 && result != ordering.Greater { + t.Errorf("Expected 1, got %d for %s > %s", result, step1, step2) + } else if step1 == step2 && result != ordering.Equal { + t.Errorf("Expected 0, got %d for %s == %s", result, step1, step2) + } + } + } + }) +} diff --git a/tm2/pkg/bft/types/priv_validator.go b/tm2/pkg/bft/types/priv_validator.go index 46da2aa83df..8421d8c653f 100644 --- a/tm2/pkg/bft/types/priv_validator.go +++ b/tm2/pkg/bft/types/priv_validator.go @@ -29,7 +29,7 @@ func (pvs PrivValidatorsByAddress) Len() int { func (pvs PrivValidatorsByAddress) Less(i, j int) bool { return pvs[i].GetPubKey().Address().Compare( - pvs[j].GetPubKey().Address()) == -1 + pvs[j].GetPubKey().Address()).IsLess() } func (pvs PrivValidatorsByAddress) Swap(i, j int) { diff --git a/tm2/pkg/bft/types/validator.go b/tm2/pkg/bft/types/validator.go index 34d11223b4a..f3cec9f675d 100644 --- a/tm2/pkg/bft/types/validator.go +++ b/tm2/pkg/bft/types/validator.go @@ -3,6 +3,8 @@ package types import ( "fmt" + "github.com/gnolang/gno/tm2/ordering" + abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types" "github.com/gnolang/gno/tm2/pkg/crypto" "github.com/gnolang/gno/tm2/pkg/random" @@ -59,10 +61,10 @@ func (v *Validator) CompareProposerPriority(other *Validator) *Validator { return other default: result := v.Address.Compare(other.Address) - switch { - case result < 0: + switch result { + case ordering.Less: return v - case result > 0: + case ordering.Greater: return other default: panic("Cannot compare identical validators") diff --git a/tm2/pkg/bft/types/validator_set.go b/tm2/pkg/bft/types/validator_set.go index 80ed994ca39..4c084152f7a 100644 --- a/tm2/pkg/bft/types/validator_set.go +++ b/tm2/pkg/bft/types/validator_set.go @@ -223,7 +223,8 @@ func (vals *ValidatorSet) Copy() *ValidatorSet { // otherwise. func (vals *ValidatorSet) HasAddress(address crypto.Address) bool { idx := sort.Search(len(vals.Validators), func(i int) bool { - return address.Compare(vals.Validators[i].Address) <= 0 + cmp := address.Compare(vals.Validators[i].Address) + return cmp.IsLess() || cmp.IsEqual() }) return idx < len(vals.Validators) && vals.Validators[idx].Address == address } @@ -232,7 +233,8 @@ func (vals *ValidatorSet) HasAddress(address crypto.Address) bool { // itself if found. Otherwise, -1 and nil are returned. func (vals *ValidatorSet) GetByAddress(address crypto.Address) (index int, val *Validator) { idx := sort.Search(len(vals.Validators), func(i int) bool { - return address.Compare(vals.Validators[i].Address) <= 0 + cmp := address.Compare(vals.Validators[i].Address) + return cmp.IsLess() || cmp.IsEqual() }) if idx < len(vals.Validators) && vals.Validators[idx].Address == address { return idx, vals.Validators[idx].Copy() @@ -440,7 +442,7 @@ func (vals *ValidatorSet) applyUpdates(updates []*Validator) { i := 0 for len(existing) > 0 && len(updates) > 0 { - if existing[0].Address.Compare(updates[0].Address) < 0 { // unchanged validator + if existing[0].Address.Compare(updates[0].Address).IsLess() { // unchanged validator merged[i] = existing[0] existing = existing[1:] } else { @@ -813,7 +815,7 @@ func (valz ValidatorsByAddress) Len() int { } func (valz ValidatorsByAddress) Less(i, j int) bool { - return valz[i].Address.Compare(valz[j].Address) == -1 + return valz[i].Address.Compare(valz[j].Address).IsLess() } func (valz ValidatorsByAddress) Swap(i, j int) { diff --git a/tm2/pkg/bft/types/validator_set_test.go b/tm2/pkg/bft/types/validator_set_test.go index 0fafb6fca9e..58994f4c3c6 100644 --- a/tm2/pkg/bft/types/validator_set_test.go +++ b/tm2/pkg/bft/types/validator_set_test.go @@ -1320,7 +1320,7 @@ func (valz validatorsByPriority) Less(i, j int) bool { if valz[i].ProposerPriority > valz[j].ProposerPriority { return false } - return valz[i].Address.Compare(valz[j].Address) < 0 + return valz[i].Address.Compare(valz[j].Address).IsLess() } func (valz validatorsByPriority) Swap(i, j int) { diff --git a/tm2/pkg/crypto/crypto.go b/tm2/pkg/crypto/crypto.go index e7089ca579b..9a80bb787d8 100644 --- a/tm2/pkg/crypto/crypto.go +++ b/tm2/pkg/crypto/crypto.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" + "github.com/gnolang/gno/tm2/ordering" "github.com/gnolang/gno/tm2/pkg/bech32" "github.com/gnolang/gno/tm2/pkg/crypto/tmhash" ) @@ -69,12 +70,8 @@ func (addr *Address) UnmarshalAmino(b32str string) (err error) { return nil } -func (addr Address) Compare(other Address) int { - bz1 := make([]byte, len(addr)) - bz2 := make([]byte, len(other)) - copy(bz1, addr[:]) - copy(bz2, other[:]) - return bytes.Compare(bz1, bz2) +func (addr Address) Compare(other Address) ordering.Ordering { + return ordering.NewOrdering(ordering.Order(bytes.Compare(addr[:], other[:]))) } func (addr Address) IsZero() bool { diff --git a/tm2/pkg/crypto/keys/client/add.go b/tm2/pkg/crypto/keys/client/add.go index 71dc6f03090..e53bae91114 100644 --- a/tm2/pkg/crypto/keys/client/add.go +++ b/tm2/pkg/crypto/keys/client/add.go @@ -187,7 +187,7 @@ func execAdd(cfg *addCfg, args []string, io commands.IO) error { // Handle --nosort if !cfg.noSort { sort.Slice(pks, func(i, j int) bool { - return pks[i].Address().Compare(pks[j].Address()) < 0 + return pks[i].Address().Compare(pks[j].Address()).IsLess() }) } diff --git a/tm2/pkg/store/cache/mergeiterator.go b/tm2/pkg/store/cache/mergeiterator.go index 7578d86ee1c..038f863b743 100644 --- a/tm2/pkg/store/cache/mergeiterator.go +++ b/tm2/pkg/store/cache/mergeiterator.go @@ -3,6 +3,7 @@ package cache import ( "bytes" + "github.com/gnolang/gno/tm2/ordering" "github.com/gnolang/gno/tm2/pkg/store/types" ) @@ -35,12 +36,12 @@ func newCacheMergeIterator(parent, cache types.Iterator, ascending bool) *cacheM func (iter *cacheMergeIterator) Domain() (start, end []byte) { startP, endP := iter.parent.Domain() startC, endC := iter.cache.Domain() - if iter.compare(startP, startC) < 0 { + if iter.compare(startP, startC).IsLess() { start = startP } else { start = startC } - if iter.compare(endP, endC) < 0 { + if iter.compare(endP, endC).IsLess() { end = endC } else { end = endP @@ -73,12 +74,12 @@ func (iter *cacheMergeIterator) Next() { // Both are valid. Compare keys. keyP, keyC := iter.parent.Key(), iter.cache.Key() switch iter.compare(keyP, keyC) { - case -1: // parent < cache + case ordering.Less: // parent < cache iter.parent.Next() - case 0: // parent == cache + case ordering.Equal: // parent == cache iter.parent.Next() iter.cache.Next() - case 1: // parent > cache + case ordering.Greater: // parent > cache iter.cache.Next() } } @@ -102,11 +103,11 @@ func (iter *cacheMergeIterator) Key() []byte { keyP, keyC := iter.parent.Key(), iter.cache.Key() cmp := iter.compare(keyP, keyC) switch cmp { - case -1: // parent < cache + case ordering.Less: // parent < cache return keyP - case 0: // parent == cache + case ordering.Equal: // parent == cache return keyP - case 1: // parent > cache + case ordering.Greater: // parent > cache return keyC default: panic("invalid compare result") @@ -132,11 +133,11 @@ func (iter *cacheMergeIterator) Value() []byte { keyP, keyC := iter.parent.Key(), iter.cache.Key() cmp := iter.compare(keyP, keyC) switch cmp { - case -1: // parent < cache + case ordering.Less: // parent < cache return iter.parent.Value() - case 0: // parent == cache + case ordering.Equal: // parent == cache return iter.cache.Value() - case 1: // parent > cache + case ordering.Greater: // parent > cache return iter.cache.Value() default: panic("invalid comparison result") @@ -150,11 +151,11 @@ func (iter *cacheMergeIterator) Close() { } // Like bytes.Compare but opposite if not ascending. -func (iter *cacheMergeIterator) compare(a, b []byte) int { +func (iter *cacheMergeIterator) compare(a, b []byte) ordering.Ordering { if iter.ascending { - return bytes.Compare(a, b) + return ordering.NewOrdering(ordering.Order(bytes.Compare(a, b))) } - return bytes.Compare(a, b) * -1 + return ordering.NewOrdering(ordering.Order(bytes.Compare(a, b) * -1)) } // Skip all delete-items from the cache w/ `key < until`. After this function, @@ -165,7 +166,7 @@ func (iter *cacheMergeIterator) compare(a, b []byte) int { func (iter *cacheMergeIterator) skipCacheDeletes(until []byte) { for iter.cache.Valid() && iter.cache.Value() == nil && - (until == nil || iter.compare(iter.cache.Key(), until) < 0) { + (until == nil || iter.compare(iter.cache.Key(), until).IsLess()) { iter.cache.Next() } } @@ -191,10 +192,10 @@ func (iter *cacheMergeIterator) skipUntilExistsOrInvalid() bool { keyP := iter.parent.Key() keyC := iter.cache.Key() switch iter.compare(keyP, keyC) { - case -1: // parent < cache. + case ordering.Less: // parent < cache. return true - case 0: // parent == cache. + case ordering.Equal: // parent == cache. // Skip over if cache item is a delete. valueC := iter.cache.Value() @@ -207,7 +208,7 @@ func (iter *cacheMergeIterator) skipUntilExistsOrInvalid() bool { return true // cache exists. - case 1: // cache < parent + case ordering.Greater: // cache < parent // Skip over if cache item is a delete. valueC := iter.cache.Value() From d9022471b11f2727cb77e77bb323107c30ca4aa7 Mon Sep 17 00:00:00 2001 From: Petar Dambovaliev Date: Mon, 15 Jan 2024 18:01:59 +0100 Subject: [PATCH 05/10] save --- tm2/pkg/bft/types/priv_validator.go | 4 +--- tm2/pkg/bft/types/validator.go | 18 +++++++++--------- tm2/pkg/bft/types/validator_set.go | 4 +--- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/tm2/pkg/bft/types/priv_validator.go b/tm2/pkg/bft/types/priv_validator.go index 8421d8c653f..e8db33faa13 100644 --- a/tm2/pkg/bft/types/priv_validator.go +++ b/tm2/pkg/bft/types/priv_validator.go @@ -33,9 +33,7 @@ func (pvs PrivValidatorsByAddress) Less(i, j int) bool { } func (pvs PrivValidatorsByAddress) Swap(i, j int) { - it := pvs[i] - pvs[i] = pvs[j] - pvs[j] = it + pvs[i], pvs[j] = pvs[j], pvs[i] } // ---------------------------------------- diff --git a/tm2/pkg/bft/types/validator.go b/tm2/pkg/bft/types/validator.go index f3cec9f675d..e45578f383c 100644 --- a/tm2/pkg/bft/types/validator.go +++ b/tm2/pkg/bft/types/validator.go @@ -59,16 +59,16 @@ func (v *Validator) CompareProposerPriority(other *Validator) *Validator { return v case v.ProposerPriority < other.ProposerPriority: return other + } + + result := v.Address.Compare(other.Address) + switch result { + case ordering.Less: + return v + case ordering.Greater: + return other default: - result := v.Address.Compare(other.Address) - switch result { - case ordering.Less: - return v - case ordering.Greater: - return other - default: - panic("Cannot compare identical validators") - } + panic("Cannot compare identical validators") } } diff --git a/tm2/pkg/bft/types/validator_set.go b/tm2/pkg/bft/types/validator_set.go index 4c084152f7a..976dff31aa9 100644 --- a/tm2/pkg/bft/types/validator_set.go +++ b/tm2/pkg/bft/types/validator_set.go @@ -819,9 +819,7 @@ func (valz ValidatorsByAddress) Less(i, j int) bool { } func (valz ValidatorsByAddress) Swap(i, j int) { - it := valz[i] - valz[i] = valz[j] - valz[j] = it + valz[i], valz[j] = valz[j], valz[i] } // ---------------------------------------- From 8e3ab26d0b158ca4ad2b9b0ebc905cf70df79f58 Mon Sep 17 00:00:00 2001 From: Petar Dambovaliev Date: Thu, 22 Feb 2024 14:27:19 +0100 Subject: [PATCH 06/10] save --- tm2/pkg/bft/consensus/reactor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tm2/pkg/bft/consensus/reactor.go b/tm2/pkg/bft/consensus/reactor.go index 9ddf026543f..fb52e05607b 100644 --- a/tm2/pkg/bft/consensus/reactor.go +++ b/tm2/pkg/bft/consensus/reactor.go @@ -242,7 +242,7 @@ func (conR *ConsensusReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) ps.ApplyHasVoteMessage(msg) case *VoteSetMaj23Message: cs := conR.conS - cs.mtx.RLock() + cs.mtx.RLock() // must not starve height, votes := cs.Height, cs.Votes cs.mtx.RUnlock() if height != msg.Height { From 69fe220a5ccb81e8c0fc579f8e4897709bdf4091 Mon Sep 17 00:00:00 2001 From: Petar Dambovaliev Date: Fri, 23 Feb 2024 00:42:18 +0100 Subject: [PATCH 07/10] save --- tm2/pkg/bft/wal/wal.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tm2/pkg/bft/wal/wal.go b/tm2/pkg/bft/wal/wal.go index 9bf87546563..c501b744d51 100644 --- a/tm2/pkg/bft/wal/wal.go +++ b/tm2/pkg/bft/wal/wal.go @@ -499,14 +499,7 @@ func (enc *WALWriter) Write(v TimedWALMessage) error { line64 := base64stdnp.EncodeToString(line) line64 += "\n" - - input := []byte(line64) - - n, err := enc.wr.Write(input) - - if len(input) != n { - return fmt.Errorf("could not write msg: %+v bytes", input) - } + _, err := enc.wr.Write([]byte(line64)) return err } From 2b50ee673739544c1c551b031fcef659df7033ac Mon Sep 17 00:00:00 2001 From: Petar Dambovaliev Date: Fri, 23 Feb 2024 00:45:13 +0100 Subject: [PATCH 08/10] save --- tm2/pkg/bft/consensus/wal_generator.go | 36 +++++++++----------------- 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/tm2/pkg/bft/consensus/wal_generator.go b/tm2/pkg/bft/consensus/wal_generator.go index 4f63a87de31..fd322f221fe 100644 --- a/tm2/pkg/bft/consensus/wal_generator.go +++ b/tm2/pkg/bft/consensus/wal_generator.go @@ -36,9 +36,7 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { config := getConfig(t) app := kvstore.NewPersistentKVStoreApplication(filepath.Join(config.DBDir(), "wal_generator")) - defer func() { - err = app.Close() - }() + defer app.Close() logger := log.NewNoopLogger().With("wal_generator", "wal_generator") logger.Info("generating WAL (last height msg excluded)", "numBlocks", numBlocks) @@ -69,18 +67,14 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { if err := proxyApp.Start(); err != nil { return errors.Wrap(err, "failed to start proxy app connections") } - defer func() { - err = proxyApp.Stop() - }() + defer proxyApp.Stop() evsw := events.NewEventSwitch() evsw.SetLogger(logger.With("module", "events")) if err := evsw.Start(); err != nil { return errors.Wrap(err, "failed to start event bus") } - defer func() { - err = evsw.Stop() - }() + defer evsw.Stop() mempool := mock.Mempool{} blockExec := sm.NewBlockExecutor(stateDB, log.NewNoopLogger(), proxyApp.Consensus(), mempool) consensusState := NewConsensusState(config.Consensus, state.Copy(), blockExec, blockStore, mempool) @@ -98,12 +92,7 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { // See wal.go OnStart(). // Since we separate the WALWriter from the WAL, we need to // initialize ourself. - err = wal.WriteMetaSync(walm.MetaMessage{Height: 1}) - - if err != nil { - return errors.Wrap(err, "WALGenerateNBlocks: failed to write meta message") - } - + wal.WriteMetaSync(walm.MetaMessage{Height: 1}) consensusState.wal = wal if err := consensusState.Start(); err != nil { @@ -112,13 +101,11 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { select { case <-numBlocksWritten: - return consensusState.Stop() + consensusState.Stop() + return nil case <-time.After(2 * time.Minute): - tErr := fmt.Errorf("waited too long for tendermint to produce %d blocks (grep logs for `wal_generator`)", numBlocks) - if err := consensusState.Stop(); err != nil { - return errors.Wrap(tErr, err.Error()) - } - return tErr + consensusState.Stop() + return fmt.Errorf("waited too long for tendermint to produce %d blocks (grep logs for `wal_generator`)", numBlocks) } } @@ -133,8 +120,8 @@ func WALWithNBlocks(t *testing.T, numBlocks int) (data []byte, err error) { return []byte{}, err } - err = wr.Flush() - return b.Bytes(), err + wr.Flush() + return b.Bytes(), nil } func randPort() int { @@ -230,7 +217,8 @@ func (w *heightStopWAL) WriteMetaSync(m walm.MetaMessage) error { // After processing is successful, commit to underlying store. This must // come last. - return w.enc.WriteMeta(m) + w.enc.WriteMeta(m) + return nil } func (w *heightStopWAL) FlushAndSync() error { return nil } From f0cefcfff381fe5386047d02bafd38ee7fbce377 Mon Sep 17 00:00:00 2001 From: Petar Dambovaliev Date: Tue, 26 Mar 2024 11:56:58 +0900 Subject: [PATCH 09/10] save --- tm2/pkg/bft/consensus/types/round_state.go | 30 ------------ .../bft/consensus/types/round_state_test.go | 46 ------------------- 2 files changed, 76 deletions(-) diff --git a/tm2/pkg/bft/consensus/types/round_state.go b/tm2/pkg/bft/consensus/types/round_state.go index 0ad8d5c4f34..222d260b558 100644 --- a/tm2/pkg/bft/consensus/types/round_state.go +++ b/tm2/pkg/bft/consensus/types/round_state.go @@ -4,8 +4,6 @@ import ( "fmt" "time" - "github.com/gnolang/gno/tm2/ordering" - "github.com/gnolang/gno/tm2/pkg/bft/types" ) @@ -97,34 +95,6 @@ type HRS struct { Step RoundStepType `json:"step"` } -func (hrs HRS) Compare(other HRS) ordering.Ordering { - if hrs.Height < other.Height { - return ordering.Less - } - - if hrs.Height > other.Height { - return ordering.Greater - } - - if hrs.Round < other.Round { - return ordering.Less - } - - if hrs.Round > other.Round { - return ordering.Greater - } - - if hrs.Step < other.Step { - return ordering.Less - } - - if hrs.Step > other.Step { - return ordering.Greater - } - - return ordering.Equal -} - func (hrs HRS) IsHRSZero() bool { return hrs == HRS{} } diff --git a/tm2/pkg/bft/consensus/types/round_state_test.go b/tm2/pkg/bft/consensus/types/round_state_test.go index a93cb5d7d9d..49fe57c4c05 100644 --- a/tm2/pkg/bft/consensus/types/round_state_test.go +++ b/tm2/pkg/bft/consensus/types/round_state_test.go @@ -3,8 +3,6 @@ package cstypes import ( "testing" - "github.com/gnolang/gno/tm2/ordering" - amino "github.com/gnolang/gno/tm2/pkg/amino" "github.com/gnolang/gno/tm2/pkg/bft/types" tmtime "github.com/gnolang/gno/tm2/pkg/bft/types/time" @@ -88,47 +86,3 @@ func BenchmarkRoundStateDeepCopy(b *testing.B) { amino.DeepCopy(rs) } } - -func TestCompare(t *testing.T) { - tests := []struct { - name string - hrs1 HRS - hrs2 HRS - result ordering.Ordering - }{ - {"Equal HRS", HRS{Height: 1, Round: 2, Step: RoundStepNewHeight}, HRS{Height: 1, Round: 2, Step: RoundStepNewHeight}, ordering.Equal}, - {"HRS1 Lesser Height", HRS{Height: 1, Round: 2, Step: RoundStepNewHeight}, HRS{Height: 2, Round: 2, Step: RoundStepNewHeight}, ordering.Less}, - {"HRS1 Greater Height", HRS{Height: 2, Round: 2, Step: RoundStepNewHeight}, HRS{Height: 1, Round: 2, Step: RoundStepNewHeight}, ordering.Greater}, - {"Equal Height, HRS1 Lesser Round", HRS{Height: 1, Round: 2, Step: RoundStepNewHeight}, HRS{Height: 1, Round: 3, Step: RoundStepNewHeight}, ordering.Less}, - {"Equal Height, HRS1 Greater Round", HRS{Height: 1, Round: 3, Step: RoundStepNewHeight}, HRS{Height: 1, Round: 2, Step: RoundStepNewHeight}, ordering.Greater}, - {"Equal Height, Equal Round, HRS1 Lesser Step", HRS{Height: 1, Round: 2, Step: RoundStepNewHeight}, HRS{Height: 1, Round: 2, Step: RoundStepPropose}, ordering.Less}, - {"Equal Height, Equal Round, HRS1 Greater Step", HRS{Height: 1, Round: 2, Step: RoundStepPropose}, HRS{Height: 1, Round: 2, Step: RoundStepNewHeight}, ordering.Greater}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result := tt.hrs1.Compare(tt.hrs2) - if result != tt.result { - t.Errorf("Expected %d, got %d", tt.result, result) - } - }) - } - - // Test cases for all RoundStepType values - t.Run("All RoundStepType Values", func(t *testing.T) { - for step1 := RoundStepInvalid; step1 <= RoundStepCommit; step1++ { - for step2 := RoundStepInvalid; step2 <= RoundStepCommit; step2++ { - hrs1 := HRS{Height: 1, Round: 2, Step: step1} - hrs2 := HRS{Height: 1, Round: 2, Step: step2} - result := hrs1.Compare(hrs2) - if step1 < step2 && result != ordering.Less { - t.Errorf("Expected -1, got %d for %s < %s", result, step1, step2) - } else if step1 > step2 && result != ordering.Greater { - t.Errorf("Expected 1, got %d for %s > %s", result, step1, step2) - } else if step1 == step2 && result != ordering.Equal { - t.Errorf("Expected 0, got %d for %s == %s", result, step1, step2) - } - } - } - }) -} From 92abef4ca6b007b3dc52818a261b7fcf4eda4298 Mon Sep 17 00:00:00 2001 From: Petar Dambovaliev Date: Tue, 26 Mar 2024 11:57:36 +0900 Subject: [PATCH 10/10] save --- gnovm/pkg/gnomod/fetch.go | 1 - 1 file changed, 1 deletion(-) diff --git a/gnovm/pkg/gnomod/fetch.go b/gnovm/pkg/gnomod/fetch.go index aedc831d2e3..6c2b1a63121 100644 --- a/gnovm/pkg/gnomod/fetch.go +++ b/gnovm/pkg/gnomod/fetch.go @@ -12,7 +12,6 @@ func queryChain(remote string, qpath string, data []byte) (res *abci.ResponseQue // Height: height, XXX // Prove: false, XXX } - cli := client.NewHTTP(remote, "/websocket") qres, err := cli.ABCIQueryWithOptions(qpath, data, opts2) if err != nil {