diff --git a/beacon-chain/blockchain/forkchoice/process_block.go b/beacon-chain/blockchain/forkchoice/process_block.go index 2854d241984e..ca3b758d97f8 100644 --- a/beacon-chain/blockchain/forkchoice/process_block.go +++ b/beacon-chain/blockchain/forkchoice/process_block.go @@ -93,6 +93,16 @@ func (s *Store) OnBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock) er return errors.Wrap(err, "could not save state") } + if featureconfig.Get().EnableBlockTreeCache { + tree, err := s.getFilterBlockTree(ctx) + if err != nil { + return errors.Wrap(err, "could not calculate filtered block tree") + } + s.filteredBlockTreeLock.Lock() + s.filteredBlockTree = tree + s.filteredBlockTreeLock.Unlock() + } + // Update justified check point. if postState.CurrentJustifiedCheckpoint.Epoch > s.justifiedCheckpt.Epoch { if err := s.updateJustified(ctx, postState); err != nil { diff --git a/beacon-chain/blockchain/forkchoice/service.go b/beacon-chain/blockchain/forkchoice/service.go index f4ee672f444f..2c7ea8494651 100644 --- a/beacon-chain/blockchain/forkchoice/service.go +++ b/beacon-chain/blockchain/forkchoice/service.go @@ -52,6 +52,8 @@ type Store struct { initSyncState map[[32]byte]*pb.BeaconState initSyncStateLock sync.RWMutex nextEpochBoundarySlot uint64 + filteredBlockTree map[[32]byte]*ethpb.BeaconBlock + filteredBlockTreeLock sync.RWMutex } // NewForkChoiceService instantiates a new service instance that will @@ -262,9 +264,17 @@ func (s *Store) Head(ctx context.Context) ([]byte, error) { defer span.End() head := s.JustifiedCheckpt().Root - filteredBlocks, err := s.getFilterBlockTree(ctx) - if err != nil { - return nil, err + filteredBlocks := make(map[[32]byte]*ethpb.BeaconBlock) + var err error + if featureconfig.Get().EnableBlockTreeCache { + s.filteredBlockTreeLock.RLock() + filteredBlocks = s.filteredBlockTree + s.filteredBlockTreeLock.RUnlock() + } else { + filteredBlocks, err = s.getFilterBlockTree(ctx) + if err != nil { + return nil, err + } } justifiedSlot := helpers.StartSlot(s.justifiedCheckpt.Epoch) diff --git a/shared/featureconfig/config.go b/shared/featureconfig/config.go index 32a0997cfdec..784826f5097e 100644 --- a/shared/featureconfig/config.go +++ b/shared/featureconfig/config.go @@ -38,10 +38,11 @@ type Flags struct { EnableSavingOfDepositData bool // EnableSavingOfDepositData allows the saving of eth1 related data such as deposits,chain data to be saved. // Cache toggles. - EnableAttestationCache bool // EnableAttestationCache; see https://github.com/prysmaticlabs/prysm/issues/3106. - EnableEth1DataVoteCache bool // EnableEth1DataVoteCache; see https://github.com/prysmaticlabs/prysm/issues/3106. - EnableSkipSlotsCache bool // EnableSkipSlotsCache caches the state in skipped slots. - EnableSlasherConnection bool // EnableSlasher enable retrieval of slashing events from a slasher instance. + EnableAttestationCache bool // EnableAttestationCache; see https://github.com/prysmaticlabs/prysm/issues/3106. + EnableEth1DataVoteCache bool // EnableEth1DataVoteCache; see https://github.com/prysmaticlabs/prysm/issues/3106. + EnableSkipSlotsCache bool // EnableSkipSlotsCache caches the state in skipped slots. + EnableSlasherConnection bool // EnableSlasher enable retrieval of slashing events from a slasher instance. + EnableBlockTreeCache bool // EnableBlockTreeCache enable fork choice service to maintain latest filtered block tree. } var featureConfig *Flags @@ -118,6 +119,10 @@ func ConfigureBeaconChain(ctx *cli.Context) { log.Warn("Enable slasher connection.") cfg.EnableSlasherConnection = true } + if ctx.GlobalBool(cacheFilteredBlockTree.Name) { + log.Warn("Enabled filtered block tree cache for fork choice.") + cfg.EnableBlockTreeCache = true + } Init(cfg) } diff --git a/shared/featureconfig/flags.go b/shared/featureconfig/flags.go index 2f507005c93a..2112c8da9f6f 100644 --- a/shared/featureconfig/flags.go +++ b/shared/featureconfig/flags.go @@ -69,6 +69,11 @@ var ( "triggered the genesis as the genesis time. This flag should be used for local " + "development and testing only.", } + cacheFilteredBlockTree = cli.BoolFlag{ + Name: "cache-filtered-block-tree", + Usage: "Cache filtered block tree by maintaining it rather than continually recalculating on the fly, " + + "this is used for fork choice.", + } ) // Deprecated flags list. @@ -192,4 +197,5 @@ var BeaconChainFlags = append(deprecatedFlags, []cli.Flag{ enableSkipSlotsCache, saveDepositData, enableSlasherFlag, + cacheFilteredBlockTree, }...)