From 4edba5df8bd70b88010a79afcccef399a04015c4 Mon Sep 17 00:00:00 2001 From: msutton Date: Sat, 9 Jul 2022 22:18:58 +0300 Subject: [PATCH 1/3] check err --- domain/consensus/consensus.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/domain/consensus/consensus.go b/domain/consensus/consensus.go index f1591a551..93f72fb69 100644 --- a/domain/consensus/consensus.go +++ b/domain/consensus/consensus.go @@ -215,6 +215,9 @@ func (s *consensus) ValidateAndInsertBlock(block *externalapi.DomainBlock, updat for !isCompletelyResolved { isCompletelyResolved, err = s.resolveVirtualChunkWithLock(100) + if err != nil { + return err + } } } From c93f310d207b1e66ab7b4bfb3cde1e0373488ee8 Mon Sep 17 00:00:00 2001 From: msutton Date: Sun, 10 Jul 2022 01:29:37 +0300 Subject: [PATCH 2/3] Parents must be picked first before set as virtual parents --- .../processes/consensusstatemanager/resolve.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/domain/consensus/processes/consensusstatemanager/resolve.go b/domain/consensus/processes/consensusstatemanager/resolve.go index dd527087b..3c94a9482 100644 --- a/domain/consensus/processes/consensusstatemanager/resolve.go +++ b/domain/consensus/processes/consensusstatemanager/resolve.go @@ -168,10 +168,17 @@ func (csm *consensusStateManager) ResolveVirtual(maxBlocksToResolve uint64) (*ex // If `isCompletelyResolved`, set virtual correctly with all tips which have less blue work than pending virtualTipCandidates := []*externalapi.DomainHash{intermediateTip} if isCompletelyResolved { - virtualTipCandidates, err = csm.getLowerTips(readStagingArea, pendingTip) + lowerTips, err := csm.getLowerTips(readStagingArea, pendingTip) if err != nil { return nil, false, err } + + log.Debugf("Picking virtual parents from relevant tips len: %d", len(lowerTips)) + virtualTipCandidates, err = csm.pickVirtualParents(readStagingArea, lowerTips) + if err != nil { + return nil, false, err + } + log.Debugf("Picked virtual parents: %s", virtualTipCandidates) } virtualUTXODiff, err := csm.updateVirtualWithParents(updateVirtualStagingArea, virtualTipCandidates) if err != nil { @@ -183,7 +190,6 @@ func (csm *consensusStateManager) ResolveVirtual(maxBlocksToResolve uint64) (*ex return nil, false, err } - // TODO: why was `readStagingArea` used here ? selectedParentChainChanges, err := csm.dagTraversalManager. CalculateChainPath(updateVirtualStagingArea, prevVirtualSelectedParent, pendingTip) if err != nil { From b1bf8ff2594c1b160c155c0e9191a814462cbbe5 Mon Sep 17 00:00:00 2001 From: msutton Date: Sun, 10 Jul 2022 02:56:24 +0300 Subject: [PATCH 3/3] Keep the flag for tracking virtual state, since tip sorting perf is high with many tips --- domain/consensus/consensus.go | 38 +++++++++++++++++------------------ domain/consensus/factory.go | 1 + 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/domain/consensus/consensus.go b/domain/consensus/consensus.go index 93f72fb69..7483eed29 100644 --- a/domain/consensus/consensus.go +++ b/domain/consensus/consensus.go @@ -61,6 +61,7 @@ type consensus struct { blocksWithTrustedDataDAAWindowStore model.BlocksWithTrustedDataDAAWindowStore consensusEventsChan chan externalapi.ConsensusEvent + virtualNotUpdated bool } func (s *consensus) ValidateAndInsertBlockWithTrustedData(block *externalapi.BlockWithTrustedData, validateUTXO bool) error { @@ -194,31 +195,22 @@ func (s *consensus) BuildBlockTemplate(coinbaseData *externalapi.DomainCoinbaseD // ValidateAndInsertBlock validates the given block and, if valid, applies it // to the current state func (s *consensus) ValidateAndInsertBlock(block *externalapi.DomainBlock, updateVirtual bool) error { - if updateVirtual { s.lock.Lock() - // Make sure virtual is resolved correctly before adding the new block - isCompletelyResolved, err := s.resolveVirtualNoLock(100) - if err != nil { + if s.virtualNotUpdated { s.lock.Unlock() + err := s.ResolveVirtual(nil) + if err != nil { + return err + } + return s.validateAndInsertBlockWithLock(block, updateVirtual) + } + defer s.lock.Unlock() + _, err := s.validateAndInsertBlockNoLock(block, updateVirtual) + if err != nil { return err } - if isCompletelyResolved { - defer s.lock.Unlock() - _, err := s.validateAndInsertBlockNoLock(block, updateVirtual) - if err != nil { - return err - } - return nil - } - s.lock.Unlock() - - for !isCompletelyResolved { - isCompletelyResolved, err = s.resolveVirtualChunkWithLock(100) - if err != nil { - return err - } - } + return nil } return s.validateAndInsertBlockWithLock(block, updateVirtual) @@ -241,6 +233,11 @@ func (s *consensus) validateAndInsertBlockNoLock(block *externalapi.DomainBlock, return nil, err } + // If block has a body, and yet virtual was not updated -- signify that virtual is in non-updated state + if !updateVirtual && blockStatus != externalapi.StatusHeaderOnly { + s.virtualNotUpdated = true + } + err = s.sendBlockAddedEvent(block, blockStatus) if err != nil { return nil, err @@ -943,6 +940,7 @@ func (s *consensus) resolveVirtualNoLock(maxBlocksToResolve uint64) (bool, error if err != nil { return false, err } + s.virtualNotUpdated = !isCompletelyResolved stagingArea := model.NewStagingArea() err = s.pruningManager.UpdatePruningPointByVirtual(stagingArea) diff --git a/domain/consensus/factory.go b/domain/consensus/factory.go index f5167fc7e..3b92ecb93 100644 --- a/domain/consensus/factory.go +++ b/domain/consensus/factory.go @@ -515,6 +515,7 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas blocksWithTrustedDataDAAWindowStore: daaWindowStore, consensusEventsChan: consensusEventsChan, + virtualNotUpdated: true, } if isOldReachabilityInitialized {