Skip to content

Commit

Permalink
Respond With Empty Payloads Pre-Merge (#11184)
Browse files Browse the repository at this point in the history
* regression test

* build

* nil check

* fix test

* gazelle

* lint
  • Loading branch information
rauljordan authored Aug 8, 2022
1 parent bd3dfb2 commit c1f2c36
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 11 deletions.
1 change: 1 addition & 0 deletions beacon-chain/execution/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ go_library(
"//beacon-chain/state/stategen:go_default_library",
"//beacon-chain/state/v1:go_default_library",
"//config/features:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",
"//consensus-types/blocks:go_default_library",
"//consensus-types/interfaces:go_default_library",
Expand Down
27 changes: 27 additions & 0 deletions beacon-chain/execution/engine_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/ethereum/go-ethereum/rpc"
"github.com/holiman/uint256"
"github.com/pkg/errors"
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
Expand Down Expand Up @@ -329,6 +330,17 @@ func (s *Service) ReconstructFullBellatrixBlock(
if err != nil {
return nil, err
}
if header.IsNil() {
return nil, errors.New("execution payload header in blinded block was nil")
}

// If the payload header has a block hash of 0x0, it means we are pre-merge and should
// simply return the block with an empty execution payload.
if bytes.Equal(header.BlockHash(), params.BeaconConfig().ZeroHash[:]) {
payload := buildEmptyExecutionPayload()
return blocks.BuildSignedBeaconBlockFromExecutionPayload(blindedBlock, payload)
}

executionBlockHash := common.BytesToHash(header.BlockHash())
executionBlock, err := s.ExecutionBlockByHash(ctx, executionBlockHash, true /* with txs */)
if err != nil {
Expand Down Expand Up @@ -460,3 +472,18 @@ func tDStringToUint256(td string) (*uint256.Int, error) {
}
return i, nil
}

func buildEmptyExecutionPayload() *pb.ExecutionPayload {
return &pb.ExecutionPayload{
ParentHash: make([]byte, fieldparams.RootLength),
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
StateRoot: make([]byte, fieldparams.RootLength),
ReceiptsRoot: make([]byte, fieldparams.RootLength),
LogsBloom: make([]byte, fieldparams.LogsBloomLength),
PrevRandao: make([]byte, fieldparams.RootLength),
BaseFeePerGas: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, fieldparams.RootLength),
Transactions: make([][]byte, 0),
ExtraData: make([]byte, 0),
}
}
16 changes: 16 additions & 0 deletions beacon-chain/execution/engine_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,22 @@ func TestReconstructFullBellatrixBlock(t *testing.T) {
_, err = service.ReconstructFullBellatrixBlock(ctx, wrapped)
require.ErrorContains(t, want, err)
})
t.Run("pre-merge execution payload", func(t *testing.T) {
service := &Service{}
bellatrixBlock := util.NewBlindedBeaconBlockBellatrix()
wanted := util.NewBeaconBlockBellatrix()
wanted.Block.Slot = 1
// Make sure block hash is the zero hash.
bellatrixBlock.Block.Body.ExecutionPayloadHeader.BlockHash = make([]byte, 32)
bellatrixBlock.Block.Slot = 1
wrapped, err := blocks.NewSignedBeaconBlock(bellatrixBlock)
require.NoError(t, err)
wantedWrapped, err := blocks.NewSignedBeaconBlock(wanted)
require.NoError(t, err)
reconstructed, err := service.ReconstructFullBellatrixBlock(ctx, wrapped)
require.NoError(t, err)
require.DeepEqual(t, wantedWrapped, reconstructed)
})
t.Run("properly reconstructs block with correct payload", func(t *testing.T) {
fix := fixtures()
payload, ok := fix["ExecutionPayload"].(*pb.ExecutionPayload)
Expand Down
1 change: 1 addition & 0 deletions consensus-types/blocks/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ go_test(
"//config/fieldparams:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library",
"//encoding/bytesutil:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/validator-client:go_default_library",
Expand Down
30 changes: 20 additions & 10 deletions consensus-types/blocks/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,20 +154,30 @@ func BuildSignedBeaconBlockFromExecutionPayload(
return nil, errors.Wrap(err, "could not get execution payload header")
default:
}
payloadRoot, err := payload.HashTreeRoot()
wrappedPayload, err := WrappedExecutionPayload(payload)
if err != nil {
return nil, errors.Wrap(err, "could not hash tree root execution payload")
return nil, err
}
payloadHeaderRoot, err := payloadHeader.HashTreeRoot()
empty, err := IsEmptyExecutionData(wrappedPayload)
if err != nil {
return nil, errors.Wrap(err, "could not hash tree root payload header")
return nil, err
}
if payloadRoot != payloadHeaderRoot {
return nil, fmt.Errorf(
"payload %#x and header %#x roots do not match",
payloadRoot,
payloadHeaderRoot,
)
if !empty {
payloadRoot, err := payload.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "could not hash tree root execution payload")
}
payloadHeaderRoot, err := payloadHeader.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "could not hash tree root payload header")
}
if payloadRoot != payloadHeaderRoot {
return nil, fmt.Errorf(
"payload %#x and header %#x roots do not match",
payloadRoot,
payloadHeaderRoot,
)
}
}
syncAgg, err := b.Body().SyncAggregate()
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion consensus-types/blocks/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"testing"

fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/runtime/version"
Expand Down Expand Up @@ -241,6 +242,7 @@ func TestBuildSignedBeaconBlockFromExecutionPayload(t *testing.T) {
require.Equal(t, true, errors.Is(err, ErrUnsupportedGetter))
})
t.Run("payload header root and payload root mismatch", func(t *testing.T) {
blockHash := bytesutil.Bytes32(1)
payload := &enginev1.ExecutionPayload{
ParentHash: make([]byte, fieldparams.RootLength),
FeeRecipient: make([]byte, 20),
Expand All @@ -249,7 +251,7 @@ func TestBuildSignedBeaconBlockFromExecutionPayload(t *testing.T) {
LogsBloom: make([]byte, 256),
PrevRandao: make([]byte, fieldparams.RootLength),
BaseFeePerGas: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, fieldparams.RootLength),
BlockHash: blockHash,
Transactions: make([][]byte, 0),
}
wrapped, err := WrappedExecutionPayload(payload)
Expand Down
3 changes: 3 additions & 0 deletions testing/util/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,8 @@ func HydrateBeaconBlockBodyBellatrix(b *ethpb.BeaconBlockBodyBellatrix) *ethpb.B
PrevRandao: make([]byte, fieldparams.RootLength),
BaseFeePerGas: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, fieldparams.RootLength),
Transactions: make([][]byte, 0),
ExtraData: make([]byte, 0),
}
}
return b
Expand Down Expand Up @@ -815,6 +817,7 @@ func HydrateBlindedBeaconBlockBodyBellatrix(b *ethpb.BlindedBeaconBlockBodyBella
BaseFeePerGas: make([]byte, 32),
BlockHash: make([]byte, 32),
TransactionsRoot: make([]byte, fieldparams.RootLength),
ExtraData: make([]byte, 0),
}
}
return b
Expand Down

0 comments on commit c1f2c36

Please sign in to comment.