From 3df2dedbb2cd424605efc610d27b8fa2208a902b Mon Sep 17 00:00:00 2001 From: terencechain Date: Mon, 23 Jan 2023 14:27:36 +0100 Subject: [PATCH] Exit properly with terminal block hash (#11892) --- beacon-chain/blockchain/pow_block.go | 18 ++++++++----- beacon-chain/blockchain/pow_block_test.go | 31 ++++++++++++++++++++--- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/beacon-chain/blockchain/pow_block.go b/beacon-chain/blockchain/pow_block.go index 1b20babe04..f5dadeeb5c 100644 --- a/beacon-chain/blockchain/pow_block.go +++ b/beacon-chain/blockchain/pow_block.go @@ -49,9 +49,13 @@ func (s *Service) validateMergeBlock(ctx context.Context, b interfaces.SignedBea if payload.IsNil() { return errors.New("nil execution payload") } - if err := validateTerminalBlockHash(b.Block().Slot(), payload); err != nil { + ok, err := canUseValidatedTerminalBlockHash(b.Block().Slot(), payload) + if err != nil { return errors.Wrap(err, "could not validate terminal block hash") } + if ok { + return nil + } mergeBlockParentHash, mergeBlockTD, err := s.getBlkParentHashAndTD(ctx, payload.ParentHash()) if err != nil { return errors.Wrap(err, "could not get merge block parent hash and total difficulty") @@ -105,7 +109,7 @@ func (s *Service) getBlkParentHashAndTD(ctx context.Context, blkHash []byte) ([] return blk.ParentHash[:], blkTDUint256, nil } -// validateTerminalBlockHash validates if the merge block is a valid terminal PoW block. +// canUseValidatedTerminalBlockHash validates if the merge block is a valid terminal PoW block. // spec code: // if TERMINAL_BLOCK_HASH != Hash32(): // @@ -113,17 +117,17 @@ func (s *Service) getBlkParentHashAndTD(ctx context.Context, blkHash []byte) ([] // assert compute_epoch_at_slot(block.slot) >= TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH // assert block.body.execution_payload.parent_hash == TERMINAL_BLOCK_HASH // return -func validateTerminalBlockHash(blkSlot types.Slot, payload interfaces.ExecutionData) error { +func canUseValidatedTerminalBlockHash(blkSlot types.Slot, payload interfaces.ExecutionData) (bool, error) { if bytesutil.ToBytes32(params.BeaconConfig().TerminalBlockHash.Bytes()) == [32]byte{} { - return nil + return false, nil } if params.BeaconConfig().TerminalBlockHashActivationEpoch > slots.ToEpoch(blkSlot) { - return errors.New("terminal block hash activation epoch not reached") + return false, errors.New("terminal block hash activation epoch not reached") } if !bytes.Equal(payload.ParentHash(), params.BeaconConfig().TerminalBlockHash.Bytes()) { - return errors.New("parent hash does not match terminal block hash") + return false, errors.New("parent hash does not match terminal block hash") } - return nil + return true, nil } // validateTerminalBlockDifficulties validates terminal pow block by comparing own total difficulty with parent's total difficulty. diff --git a/beacon-chain/blockchain/pow_block_test.go b/beacon-chain/blockchain/pow_block_test.go index 96a49e268c..e9ee361869 100644 --- a/beacon-chain/blockchain/pow_block_test.go +++ b/beacon-chain/blockchain/pow_block_test.go @@ -18,6 +18,7 @@ import ( enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1" ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v3/testing/require" + "github.com/prysmaticlabs/prysm/v3/testing/util" ) func Test_validTerminalPowBlock(t *testing.T) { @@ -213,20 +214,42 @@ func Test_getBlkParentHashAndTD(t *testing.T) { func Test_validateTerminalBlockHash(t *testing.T) { wrapped, err := blocks.WrappedExecutionPayload(&enginev1.ExecutionPayload{}) require.NoError(t, err) - require.NoError(t, validateTerminalBlockHash(1, wrapped)) + ok, err := canUseValidatedTerminalBlockHash(1, wrapped) + require.NoError(t, err) + require.Equal(t, false, ok) cfg := params.BeaconConfig() cfg.TerminalBlockHash = [32]byte{0x01} params.OverrideBeaconConfig(cfg) - require.ErrorContains(t, "terminal block hash activation epoch not reached", validateTerminalBlockHash(1, wrapped)) + ok, err = canUseValidatedTerminalBlockHash(1, wrapped) + require.ErrorContains(t, "terminal block hash activation epoch not reached", err) + require.Equal(t, false, ok) cfg.TerminalBlockHashActivationEpoch = 0 params.OverrideBeaconConfig(cfg) - require.ErrorContains(t, "parent hash does not match terminal block hash", validateTerminalBlockHash(1, wrapped)) + ok, err = canUseValidatedTerminalBlockHash(1, wrapped) + require.ErrorContains(t, "parent hash does not match terminal block hash", err) + require.Equal(t, false, ok) wrapped, err = blocks.WrappedExecutionPayload(&enginev1.ExecutionPayload{ ParentHash: cfg.TerminalBlockHash.Bytes(), }) require.NoError(t, err) - require.NoError(t, validateTerminalBlockHash(1, wrapped)) + ok, err = canUseValidatedTerminalBlockHash(1, wrapped) + require.NoError(t, err) + require.Equal(t, true, ok) + + ctx := context.Background() + beaconDB := testDB.SetupDB(t) + opts := []Option{ + WithDatabase(beaconDB), + WithStateGen(stategen.New(beaconDB, doublylinkedtree.New())), + } + service, err := NewService(ctx, opts...) + require.NoError(t, err) + blk, err := blocks.NewSignedBeaconBlock(util.HydrateSignedBeaconBlockBellatrix(ðpb.SignedBeaconBlockBellatrix{})) + require.NoError(t, err) + blk.Block().SetSlot(1) + require.NoError(t, blk.Block().Body().SetExecution(wrapped)) + require.NoError(t, service.validateMergeBlock(ctx, blk)) }