From 56d4619ea6e04da001abbe9b3804c26ee8cef86b Mon Sep 17 00:00:00 2001 From: Cedric Fung Date: Sat, 27 Jan 2024 00:16:18 +0000 Subject: [PATCH] avoid processing already finalized snapshot --- kernel/cosi.go | 7 ++++++- kernel/election.go | 1 + kernel/final.go | 9 +++++---- kernel/graph.go | 1 + kernel/node.go | 2 +- kernel/round.go | 10 ++++++++-- 6 files changed, 22 insertions(+), 8 deletions(-) diff --git a/kernel/cosi.go b/kernel/cosi.go index ce46f8037..9b993717e 100644 --- a/kernel/cosi.go +++ b/kernel/cosi.go @@ -1022,16 +1022,21 @@ func (node *Node) VerifyAndQueueAppendSnapshotFinalization(peerId crypto.Hash, s return nil } - tx, err := node.checkTxInStorage(s.SoleTransaction()) + tx, finalized, err := node.checkTxInStorage(s.SoleTransaction()) if err != nil { logger.Verbosef("VerifyAndQueueAppendSnapshotFinalization(%s, %s) check tx error %s\n", peerId, s.Hash, err) } else if tx == nil { logger.Verbosef("VerifyAndQueueAppendSnapshotFinalization(%s, %s) SendTransactionRequestMessage %s\n", peerId, s.Hash, s.SoleTransaction()) node.Peer.SendTransactionRequestMessage(peerId, s.SoleTransaction()) + } else if finalized == s.Hash.String() { + return nil } chain := node.getOrCreateChain(s.NodeId) + if cs := chain.State; cs != nil && cs.CacheRound.index[s.Hash] { + return nil + } if _, finalized := chain.verifyFinalization(s); !finalized { logger.Verbosef("ERROR VerifyAndQueueAppendSnapshotFinalization %s %v %d %t %v %v\n", peerId, s, node.ConsensusThreshold(s.Timestamp, true), chain.IsPledging(), chain.State, chain.ConsensusInfo) diff --git a/kernel/election.go b/kernel/election.go index 5f1476ce2..94a4b849c 100644 --- a/kernel/election.go +++ b/kernel/election.go @@ -422,6 +422,7 @@ func (node *Node) finalizeNodeAcceptSnapshot(s *common.Snapshot, signers []crypt Self: final.Hash, External: external.Hash, }, + index: make(map[crypto.Hash]bool), } err = node.persistStore.StartNewRound(cache.NodeId, cache.Number, cache.References, final.Start) if err != nil { diff --git a/kernel/final.go b/kernel/final.go index 9f86783e2..3091bf850 100644 --- a/kernel/final.go +++ b/kernel/final.go @@ -5,11 +5,12 @@ import ( "github.com/MixinNetwork/mixin/crypto" ) -func (node *Node) checkTxInStorage(id crypto.Hash) (*common.VersionedTransaction, error) { - tx, _, err := node.persistStore.ReadTransaction(id) +func (node *Node) checkTxInStorage(id crypto.Hash) (*common.VersionedTransaction, string, error) { + tx, snap, err := node.persistStore.ReadTransaction(id) if err != nil || tx != nil { - return tx, err + return tx, snap, err } - return node.persistStore.CacheGetTransaction(id) + tx, err = node.persistStore.CacheGetTransaction(id) + return tx, "", err } diff --git a/kernel/graph.go b/kernel/graph.go index ba8022d92..44e263f94 100644 --- a/kernel/graph.go +++ b/kernel/graph.go @@ -25,6 +25,7 @@ func (chain *Chain) startNewRoundAndPersist(cache *CacheRound, references *commo Number: final.Number + 1, Timestamp: timestamp, References: references.Copy(), + index: make(map[crypto.Hash]bool), } if dummy { cache.References.External = dummyExternal diff --git a/kernel/node.go b/kernel/node.go index 5de4f49df..0dbfe9c7e 100644 --- a/kernel/node.go +++ b/kernel/node.go @@ -435,7 +435,7 @@ func (node *Node) Authenticate(msg []byte) (crypto.Hash, string, error) { } func (node *Node) SendTransactionToPeer(peerId, hash crypto.Hash) error { - tx, err := node.checkTxInStorage(hash) + tx, _, err := node.checkTxInStorage(hash) if err != nil || tx == nil { return err } diff --git a/kernel/round.go b/kernel/round.go index 52816720e..fe1565d83 100644 --- a/kernel/round.go +++ b/kernel/round.go @@ -19,6 +19,7 @@ type CacheRound struct { Timestamp uint64 References *common.RoundLink Snapshots []*common.Snapshot + index map[crypto.Hash]bool } type FinalRound struct { @@ -96,6 +97,7 @@ func loadHeadRoundForNode(store storage.Store, nodeIdWithNetwork crypto.Hash) (* Number: meta.Number, Timestamp: meta.Timestamp, References: meta.References, + index: make(map[crypto.Hash]bool), } topos, err := store.ReadSnapshotsForNodeRound(round.NodeId, round.Number) if err != nil { @@ -105,6 +107,7 @@ func loadHeadRoundForNode(store storage.Store, nodeIdWithNetwork crypto.Hash) (* s := t.Snapshot s.Hash = s.PayloadHash() round.Snapshots = append(round.Snapshots, s) + round.index[s.Hash] = true } return round, nil } @@ -142,6 +145,7 @@ func (c *CacheRound) Copy() *CacheRound { External: c.References.External, }, Snapshots: append([]*common.Snapshot{}, c.Snapshots...), + index: c.index, } } @@ -184,10 +188,12 @@ func (c *CacheRound) Gap() (uint64, uint64) { func (chain *Chain) AddSnapshot(final *FinalRound, cache *CacheRound, s *common.Snapshot, signers []crypto.Hash) error { chain.node.TopoWrite(s, signers) - if err := cache.validateSnapshot(s, true); err != nil { - panic("should never be here") + err := cache.validateSnapshot(s, true) + if err != nil { + panic(err) } chain.assignNewGraphRound(final, cache) + chain.State.CacheRound.index[s.Hash] = true return nil }