From edf7ed614e41ba355c6f85ebad36729dc8be40c7 Mon Sep 17 00:00:00 2001 From: Nishant Das Date: Thu, 5 Nov 2020 09:33:45 +0800 Subject: [PATCH] Reduce Hashing When Filling In Forkchoice Blocks (#7716) * reduce hashing * add in test * Update beacon-chain/blockchain/process_block_test.go Co-authored-by: terence tsao Co-authored-by: Victor Farazdagi Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com> --- .../blockchain/process_block_helpers.go | 9 ++-- beacon-chain/blockchain/process_block_test.go | 41 +++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/beacon-chain/blockchain/process_block_helpers.go b/beacon-chain/blockchain/process_block_helpers.go index f8967fcd53..b8b80c9137 100644 --- a/beacon-chain/blockchain/process_block_helpers.go +++ b/beacon-chain/blockchain/process_block_helpers.go @@ -363,6 +363,7 @@ func (s *Service) finalizedImpliesNewJustified(ctx context.Context, state *state func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb.BeaconBlock, fCheckpoint, jCheckpoint *ethpb.Checkpoint) error { pendingNodes := make([]*ethpb.BeaconBlock, 0) + pendingRoots := make([][32]byte, 0) parentRoot := bytesutil.ToBytes32(blk.ParentRoot) slot := blk.Slot @@ -380,6 +381,8 @@ func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb. } pendingNodes = append(pendingNodes, b.Block) + copiedRoot := parentRoot + pendingRoots = append(pendingRoots, copiedRoot) parentRoot = bytesutil.ToBytes32(b.Block.ParentRoot) slot = b.Block.Slot higherThanFinalized = slot > fSlot @@ -389,11 +392,7 @@ func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb. // Lower slots should be at the end of the list. for i := len(pendingNodes) - 1; i >= 0; i-- { b := pendingNodes[i] - r, err := b.HashTreeRoot() - if err != nil { - return err - } - + r := pendingRoots[i] if err := s.forkChoiceStore.ProcessBlock(ctx, b.Slot, r, bytesutil.ToBytes32(b.ParentRoot), bytesutil.ToBytes32(b.Body.Graffiti), jCheckpoint.Epoch, diff --git a/beacon-chain/blockchain/process_block_test.go b/beacon-chain/blockchain/process_block_test.go index 69e81b2546..eb38c8d1a1 100644 --- a/beacon-chain/blockchain/process_block_test.go +++ b/beacon-chain/blockchain/process_block_test.go @@ -2,6 +2,7 @@ package blockchain import ( "context" + "fmt" "testing" "time" @@ -372,6 +373,46 @@ func TestFillForkChoiceMissingBlocks_CanSave(t *testing.T) { assert.Equal(t, true, service.forkChoiceStore.HasNode(bytesutil.ToBytes32(roots[8])), "Didn't save node") } +func TestFillForkChoiceMissingBlocks_RootsMatch(t *testing.T) { + ctx := context.Background() + db, _ := testDB.SetupDB(t) + + cfg := &Config{BeaconDB: db} + service, err := NewService(ctx, cfg) + require.NoError(t, err) + service.forkChoiceStore = protoarray.New(0, 0, [32]byte{'A'}) + service.finalizedCheckpt = ðpb.Checkpoint{Root: make([]byte, 32)} + + genesisStateRoot := [32]byte{} + genesis := blocks.NewGenesisBlock(genesisStateRoot[:]) + require.NoError(t, db.SaveBlock(ctx, genesis)) + validGenesisRoot, err := genesis.Block.HashTreeRoot() + require.NoError(t, err) + st := testutil.NewBeaconState() + + require.NoError(t, service.beaconDB.SaveState(ctx, st.Copy(), validGenesisRoot)) + roots, err := blockTree1(db, validGenesisRoot[:]) + require.NoError(t, err) + + beaconState, _ := testutil.DeterministicGenesisState(t, 32) + block := testutil.NewBeaconBlock() + block.Block.Slot = 9 + block.Block.ParentRoot = roots[8] + + err = service.fillInForkChoiceMissingBlocks( + context.Background(), block.Block, beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint()) + require.NoError(t, err) + + // 5 nodes from the block tree 1. B0 - B3 - B4 - B6 - B8 + assert.Equal(t, 5, len(service.forkChoiceStore.Nodes()), "Miss match nodes") + // Ensure all roots and their respective blocks exist. + wantedRoots := [][]byte{roots[0], roots[3], roots[4], roots[6], roots[8]} + for i, rt := range wantedRoots { + assert.Equal(t, true, service.forkChoiceStore.HasNode(bytesutil.ToBytes32(rt)), fmt.Sprintf("Didn't save node: %d", i)) + assert.Equal(t, true, service.beaconDB.HasBlock(context.Background(), bytesutil.ToBytes32(rt))) + } +} + func TestFillForkChoiceMissingBlocks_FilterFinalized(t *testing.T) { ctx := context.Background() db, _ := testDB.SetupDB(t)