Execution Payload / Header Interface Wrappers (#11025)

* exec payload iface

* begin using iface

* use iface more

* build beacon

* builds

* txs field

* fix

* merge test

* pass

* test

* refactor

* fix up builder case

* gaz

* comments

* el test

* build

* no mask

* patch up

* exec wrap

* Terence feedback

* builds

* potuz suggestion

* exec data error

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
Raul Jordan
2022-07-13 01:49:38 +00:00
committed by GitHub
parent 7c30533870
commit e01a898264
53 changed files with 845 additions and 378 deletions

View File

@@ -8,15 +8,18 @@ go_library(
"beacon_block_bellatrix.go",
"beacon_block_phase0.go",
"blinded_beacon_block_bellatrix.go",
"execution.go",
"metadata.go",
"mutator.go",
],
importpath = "github.com/prysmaticlabs/prysm/consensus-types/wrapper",
visibility = ["//visibility:public"],
deps = [
"//consensus-types/forks/bellatrix:go_default_library",
"//config/fieldparams:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library",
"//encoding/bytesutil:go_default_library",
"//encoding/ssz:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/metadata:go_default_library",
@@ -37,11 +40,12 @@ go_test(
"beacon_block_phase0_test.go",
"beacon_block_test.go",
"blinded_beacon_block_bellatrix_test.go",
"execution_test.go",
],
deps = [
":go_default_library",
"//config/fieldparams:go_default_library",
"//consensus-types/forks/bellatrix: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",

View File

@@ -4,7 +4,6 @@ import (
"fmt"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/consensus-types/forks/bellatrix"
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
@@ -158,7 +157,7 @@ func BuildSignedBeaconBlockFromExecutionPayload(
return nil, err
}
b := blk.Block()
payloadHeader, err := b.Body().ExecutionPayloadHeader()
payloadHeader, err := b.Body().Execution()
switch {
case errors.Is(err, ErrUnsupportedField):
return nil, errors.Wrap(err, "can only build signed beacon block from blinded format")
@@ -218,7 +217,7 @@ func WrapSignedBlindedBeaconBlock(blk interfaces.SignedBeaconBlock) (interfaces.
return blk, nil
}
b := blk.Block()
payload, err := b.Body().ExecutionPayload()
payload, err := b.Body().Execution()
switch {
case errors.Is(err, ErrUnsupportedField):
return nil, ErrUnsupportedSignedBeaconBlock
@@ -230,7 +229,7 @@ func WrapSignedBlindedBeaconBlock(blk interfaces.SignedBeaconBlock) (interfaces.
if err != nil {
return nil, err
}
header, err := bellatrix.PayloadToHeader(payload)
header, err := PayloadToHeader(payload)
if err != nil {
return nil, err
}

View File

@@ -5,7 +5,6 @@ import (
ssz "github.com/prysmaticlabs/fastssz"
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/runtime/version"
@@ -313,12 +312,7 @@ func (w altairBeaconBlockBody) Proto() proto.Message {
return w.b
}
// ExecutionPayload is a stub.
func (w altairBeaconBlockBody) ExecutionPayload() (*enginev1.ExecutionPayload, error) {
// Execution is a stub.
func (w altairBeaconBlockBody) Execution() (interfaces.ExecutionData, error) {
return nil, errors.Wrapf(ErrUnsupportedField, "ExecutionPayload for %T", w)
}
// ExecutionPayloadHeader is a stub.
func (w altairBeaconBlockBody) ExecutionPayloadHeader() (*enginev1.ExecutionPayloadHeader, error) {
return nil, errors.Wrapf(ErrUnsupportedField, "ExecutionPayloadHeader for %T", w)
}

View File

@@ -351,6 +351,6 @@ func TestAltairBeaconBlock_ExecutionPayloadHeader(t *testing.T) {
}
wsb, err := wrapper.WrappedSignedBeaconBlock(sb)
require.NoError(t, err)
_, err = wsb.Block().Body().ExecutionPayloadHeader()
_, err = wsb.Block().Body().Execution()
require.ErrorContains(t, "unsupported field for block type", err)
}

View File

@@ -5,7 +5,6 @@ import (
ssz "github.com/prysmaticlabs/fastssz"
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/runtime/version"
@@ -308,12 +307,7 @@ func (w bellatrixBeaconBlockBody) Proto() proto.Message {
return w.b
}
// ExecutionPayload returns the Execution payload of the block body.
func (w bellatrixBeaconBlockBody) ExecutionPayload() (*enginev1.ExecutionPayload, error) {
return w.b.ExecutionPayload, nil
}
// ExecutionPayloadHeader is a stub.
func (w bellatrixBeaconBlockBody) ExecutionPayloadHeader() (*enginev1.ExecutionPayloadHeader, error) {
return nil, errors.Wrapf(ErrUnsupportedField, "ExecutionPayloadHeader for %T", w)
// Execution returns the Execution payload of the block body.
func (w bellatrixBeaconBlockBody) Execution() (interfaces.ExecutionData, error) {
return WrappedExecutionPayload(w.b.ExecutionPayload)
}

View File

@@ -352,9 +352,9 @@ func TestBellatrixBeaconBlockBody_ExecutionPayload(t *testing.T) {
wbb, err := wrapper.WrappedBeaconBlockBody(body)
require.NoError(t, err)
got, err := wbb.ExecutionPayload()
got, err := wbb.Execution()
require.NoError(t, err)
assert.DeepEqual(t, payloads, got)
assert.DeepEqual(t, payloads, got.Proto())
}
func TestBellatrixBeaconBlock_PbGenericBlock(t *testing.T) {
@@ -392,10 +392,14 @@ func TestBellatrixBeaconBlock_PbBlindedBellatrixBlock(t *testing.T) {
func TestBellatrixBeaconBlock_ExecutionPayloadHeader(t *testing.T) {
sb := &ethpb.SignedBeaconBlockBellatrix{
Block: &ethpb.BeaconBlockBellatrix{Slot: 66},
Block: &ethpb.BeaconBlockBellatrix{Slot: 66, Body: &ethpb.BeaconBlockBodyBellatrix{
ExecutionPayload: &enginev1.ExecutionPayload{},
}},
}
wsb, err := wrapper.WrappedSignedBeaconBlock(sb)
require.NoError(t, err)
_, err = wsb.Block().Body().ExecutionPayloadHeader()
exec, err := wsb.Block().Body().Execution()
require.NoError(t, err)
_, err = exec.TransactionsRoot()
require.ErrorContains(t, "unsupported field for block type", err)
}

View File

@@ -5,7 +5,6 @@ import (
ssz "github.com/prysmaticlabs/fastssz"
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/runtime/version"
@@ -301,12 +300,7 @@ func (w Phase0BeaconBlockBody) Proto() proto.Message {
return w.b
}
// ExecutionPayload is a stub.
func (w Phase0BeaconBlockBody) ExecutionPayload() (*enginev1.ExecutionPayload, error) {
// Execution is a stub.
func (w Phase0BeaconBlockBody) Execution() (interfaces.ExecutionData, error) {
return nil, errors.Wrapf(ErrUnsupportedField, "ExecutionPayload for %T", w)
}
// ExecutionPayloadHeader is a stub.
func (w Phase0BeaconBlockBody) ExecutionPayloadHeader() (*enginev1.ExecutionPayloadHeader, error) {
return nil, errors.Wrapf(ErrUnsupportedField, "ExecutionPayloadHeader for %T", w)
}

View File

@@ -82,6 +82,6 @@ func TestPhase0BeaconBlock_ExecutionPayloadHeader(t *testing.T) {
}
wsb, err := wrapper.WrappedSignedBeaconBlock(sb)
require.NoError(t, err)
_, err = wsb.Block().Body().ExecutionPayloadHeader()
_, err = wsb.Block().Body().Execution()
require.ErrorContains(t, "unsupported field for block type", err)
}

View File

@@ -5,7 +5,6 @@ import (
"github.com/pkg/errors"
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
"github.com/prysmaticlabs/prysm/consensus-types/forks/bellatrix"
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
"github.com/prysmaticlabs/prysm/testing/require"
@@ -36,7 +35,9 @@ func TestBuildSignedBeaconBlockFromExecutionPayload(t *testing.T) {
BlockHash: make([]byte, fieldparams.RootLength),
Transactions: make([][]byte, 0),
}
header, err := bellatrix.PayloadToHeader(payload)
wrapped, err := wrapper.WrappedExecutionPayload(payload)
require.NoError(t, err)
header, err := wrapper.PayloadToHeader(wrapped)
require.NoError(t, err)
blindedBlock := util.NewBlindedBeaconBlockBellatrix()
@@ -61,7 +62,9 @@ func TestBuildSignedBeaconBlockFromExecutionPayload(t *testing.T) {
BlockHash: make([]byte, fieldparams.RootLength),
Transactions: make([][]byte, 0),
}
header, err := bellatrix.PayloadToHeader(payload)
wrapped, err := wrapper.WrappedExecutionPayload(payload)
require.NoError(t, err)
header, err := wrapper.PayloadToHeader(wrapped)
require.NoError(t, err)
blindedBlock := util.NewBlindedBeaconBlockBellatrix()
blindedBlock.Block.Body.ExecutionPayloadHeader = header
@@ -71,9 +74,9 @@ func TestBuildSignedBeaconBlockFromExecutionPayload(t *testing.T) {
builtBlock, err := wrapper.BuildSignedBeaconBlockFromExecutionPayload(blk, payload)
require.NoError(t, err)
got, err := builtBlock.Block().Body().ExecutionPayload()
got, err := builtBlock.Block().Body().Execution()
require.NoError(t, err)
require.DeepEqual(t, payload, got)
require.DeepEqual(t, payload, got.Proto())
})
}
@@ -104,7 +107,9 @@ func TestWrapSignedBlindedBeaconBlock(t *testing.T) {
bellatrixBlk := util.NewBeaconBlockBellatrix()
bellatrixBlk.Block.Body.ExecutionPayload = payload
want, err := bellatrix.PayloadToHeader(payload)
wrapped, err := wrapper.WrappedExecutionPayload(payload)
require.NoError(t, err)
want, err := wrapper.PayloadToHeader(wrapped)
require.NoError(t, err)
blk, err := wrapper.WrappedSignedBeaconBlock(bellatrixBlk)
@@ -112,9 +117,9 @@ func TestWrapSignedBlindedBeaconBlock(t *testing.T) {
builtBlock, err := wrapper.WrapSignedBlindedBeaconBlock(blk)
require.NoError(t, err)
got, err := builtBlock.Block().Body().ExecutionPayloadHeader()
got, err := builtBlock.Block().Body().Execution()
require.NoError(t, err)
require.DeepEqual(t, want, got)
require.DeepEqual(t, want, got.Proto())
})
}

View File

@@ -5,7 +5,6 @@ import (
ssz "github.com/prysmaticlabs/fastssz"
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/runtime/version"
@@ -309,12 +308,6 @@ func (w blindedBeaconBlockBodyBellatrix) Proto() proto.Message {
return w.b
}
// ExecutionPayload returns the execution payload of the block body.
func (w blindedBeaconBlockBodyBellatrix) ExecutionPayload() (*enginev1.ExecutionPayload, error) {
return nil, errors.Wrapf(ErrUnsupportedField, "ExecutionPayload for %T", w)
}
// ExecutionPayloadHeader returns the execution payload header of the block body.
func (w blindedBeaconBlockBodyBellatrix) ExecutionPayloadHeader() (*enginev1.ExecutionPayloadHeader, error) {
return w.b.ExecutionPayloadHeader, nil
func (w blindedBeaconBlockBodyBellatrix) Execution() (interfaces.ExecutionData, error) {
return WrappedExecutionPayloadHeader(w.b.ExecutionPayloadHeader)
}

View File

@@ -365,7 +365,9 @@ func TestBellatrixBlindedBeaconBlockBody_ExecutionPayloadHeader(t *testing.T) {
wbb, err := wrapper.WrappedBeaconBlockBody(body)
require.NoError(t, err)
_, err = wbb.ExecutionPayload()
exec, err := wbb.Execution()
require.NoError(t, err)
_, err = exec.Transactions()
require.ErrorContains(t, wrapper.ErrUnsupportedField.Error(), err)
}

View File

@@ -0,0 +1,371 @@
package wrapper
import (
"bytes"
"github.com/pkg/errors"
fastssz "github.com/prysmaticlabs/fastssz"
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/encoding/ssz"
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
"google.golang.org/protobuf/proto"
)
// executionPayload is a convenience wrapper around a beacon block body's execution payload data structure
// This wrapper allows us to conform to a common interface so that beacon
// blocks for future forks can also be applied across Prysm without issues.
type executionPayload struct {
p *enginev1.ExecutionPayload
}
// WrappedExecutionPayload is a constructor which wraps a protobuf execution payload into an interface.
func WrappedExecutionPayload(p *enginev1.ExecutionPayload) (interfaces.ExecutionData, error) {
w := executionPayload{p: p}
if w.IsNil() {
return nil, ErrNilObjectWrapped
}
return w, nil
}
// IsNil checks if the underlying data is nil.
func (e executionPayload) IsNil() bool {
return e.p == nil
}
// MarshalSSZ --
func (e executionPayload) MarshalSSZ() ([]byte, error) {
return e.p.MarshalSSZ()
}
// MarshalSSZTo --
func (e executionPayload) MarshalSSZTo(dst []byte) ([]byte, error) {
return e.p.MarshalSSZTo(dst)
}
// SizeSSZ --
func (e executionPayload) SizeSSZ() int {
return e.p.SizeSSZ()
}
// UnmarshalSSZ --
func (e executionPayload) UnmarshalSSZ(buf []byte) error {
return e.p.UnmarshalSSZ(buf)
}
// HashTreeRoot --
func (e executionPayload) HashTreeRoot() ([32]byte, error) {
return e.p.HashTreeRoot()
}
// HashTreeRootWith --
func (e executionPayload) HashTreeRootWith(hh *fastssz.Hasher) error {
return e.p.HashTreeRootWith(hh)
}
// Proto --
func (e executionPayload) Proto() proto.Message {
return e.p
}
// ParentHash --
func (e executionPayload) ParentHash() []byte {
return e.p.ParentHash
}
// FeeRecipient --
func (e executionPayload) FeeRecipient() []byte {
return e.p.FeeRecipient
}
// StateRoot --
func (e executionPayload) StateRoot() []byte {
return e.p.StateRoot
}
// ReceiptsRoot --
func (e executionPayload) ReceiptsRoot() []byte {
return e.p.ReceiptsRoot
}
// LogsBloom --
func (e executionPayload) LogsBloom() []byte {
return e.p.LogsBloom
}
// PrevRandao --
func (e executionPayload) PrevRandao() []byte {
return e.p.PrevRandao
}
// BlockNumber --
func (e executionPayload) BlockNumber() uint64 {
return e.p.BlockNumber
}
// GasLimit --
func (e executionPayload) GasLimit() uint64 {
return e.p.GasLimit
}
// GasUsed --
func (e executionPayload) GasUsed() uint64 {
return e.p.GasUsed
}
// Timestamp --
func (e executionPayload) Timestamp() uint64 {
return e.p.Timestamp
}
// ExtraData --
func (e executionPayload) ExtraData() []byte {
return e.p.ExtraData
}
// BaseFeePerGas --
func (e executionPayload) BaseFeePerGas() []byte {
return e.p.BaseFeePerGas
}
// BlockHash --
func (e executionPayload) BlockHash() []byte {
return e.p.BlockHash
}
// Transactions --
func (e executionPayload) Transactions() ([][]byte, error) {
return e.p.Transactions, nil
}
// TransactionsRoot --
func (executionPayload) TransactionsRoot() ([]byte, error) {
return nil, ErrUnsupportedField
}
// executionPayloadHeader is a convenience wrapper around a blinded beacon block body's execution header data structure
// This wrapper allows us to conform to a common interface so that beacon
// blocks for future forks can also be applied across Prysm without issues.
type executionPayloadHeader struct {
p *enginev1.ExecutionPayloadHeader
}
// WrappedExecutionPayloadHeader is a constructor which wraps a protobuf execution header into an interface.
func WrappedExecutionPayloadHeader(p *enginev1.ExecutionPayloadHeader) (interfaces.ExecutionData, error) {
w := executionPayloadHeader{p: p}
if w.IsNil() {
return nil, ErrNilObjectWrapped
}
return w, nil
}
// IsNil checks if the underlying data is nil.
func (e executionPayloadHeader) IsNil() bool {
return e.p == nil
}
// MarshalSSZ --
func (e executionPayloadHeader) MarshalSSZ() ([]byte, error) {
return e.p.MarshalSSZ()
}
// MarshalSSZTo --
func (e executionPayloadHeader) MarshalSSZTo(dst []byte) ([]byte, error) {
return e.p.MarshalSSZTo(dst)
}
// SizeSSZ --
func (e executionPayloadHeader) SizeSSZ() int {
return e.p.SizeSSZ()
}
// UnmarshalSSZ --
func (e executionPayloadHeader) UnmarshalSSZ(buf []byte) error {
return e.p.UnmarshalSSZ(buf)
}
// HashTreeRoot --
func (e executionPayloadHeader) HashTreeRoot() ([32]byte, error) {
return e.p.HashTreeRoot()
}
// HashTreeRootWith --
func (e executionPayloadHeader) HashTreeRootWith(hh *fastssz.Hasher) error {
return e.p.HashTreeRootWith(hh)
}
// Proto --
func (e executionPayloadHeader) Proto() proto.Message {
return e.p
}
// ParentHash --
func (e executionPayloadHeader) ParentHash() []byte {
return e.p.ParentHash
}
// FeeRecipient --
func (e executionPayloadHeader) FeeRecipient() []byte {
return e.p.FeeRecipient
}
// StateRoot --
func (e executionPayloadHeader) StateRoot() []byte {
return e.p.StateRoot
}
// ReceiptsRoot --
func (e executionPayloadHeader) ReceiptsRoot() []byte {
return e.p.ReceiptsRoot
}
// LogsBloom --
func (e executionPayloadHeader) LogsBloom() []byte {
return e.p.LogsBloom
}
// PrevRandao --
func (e executionPayloadHeader) PrevRandao() []byte {
return e.p.PrevRandao
}
// BlockNumber --
func (e executionPayloadHeader) BlockNumber() uint64 {
return e.p.BlockNumber
}
// GasLimit --
func (e executionPayloadHeader) GasLimit() uint64 {
return e.p.GasLimit
}
// GasUsed --
func (e executionPayloadHeader) GasUsed() uint64 {
return e.p.GasUsed
}
// Timestamp --
func (e executionPayloadHeader) Timestamp() uint64 {
return e.p.Timestamp
}
// ExtraData --
func (e executionPayloadHeader) ExtraData() []byte {
return e.p.ExtraData
}
// BaseFeePerGas --
func (e executionPayloadHeader) BaseFeePerGas() []byte {
return e.p.BaseFeePerGas
}
// BlockHash --
func (e executionPayloadHeader) BlockHash() []byte {
return e.p.BlockHash
}
// Transactions --
func (executionPayloadHeader) Transactions() ([][]byte, error) {
return nil, ErrUnsupportedField
}
// TransactionsRoot --
func (e executionPayloadHeader) TransactionsRoot() ([]byte, error) {
return e.p.TransactionsRoot, nil
}
// PayloadToHeader converts `payload` into execution payload header format.
func PayloadToHeader(payload interfaces.ExecutionData) (*enginev1.ExecutionPayloadHeader, error) {
txs, err := payload.Transactions()
if err != nil {
return nil, err
}
txRoot, err := ssz.TransactionsRoot(txs)
if err != nil {
return nil, err
}
return &enginev1.ExecutionPayloadHeader{
ParentHash: bytesutil.SafeCopyBytes(payload.ParentHash()),
FeeRecipient: bytesutil.SafeCopyBytes(payload.FeeRecipient()),
StateRoot: bytesutil.SafeCopyBytes(payload.StateRoot()),
ReceiptsRoot: bytesutil.SafeCopyBytes(payload.ReceiptsRoot()),
LogsBloom: bytesutil.SafeCopyBytes(payload.LogsBloom()),
PrevRandao: bytesutil.SafeCopyBytes(payload.PrevRandao()),
BlockNumber: payload.BlockNumber(),
GasLimit: payload.GasLimit(),
GasUsed: payload.GasUsed(),
Timestamp: payload.Timestamp(),
ExtraData: bytesutil.SafeCopyBytes(payload.ExtraData()),
BaseFeePerGas: bytesutil.SafeCopyBytes(payload.BaseFeePerGas()),
BlockHash: bytesutil.SafeCopyBytes(payload.BlockHash()),
TransactionsRoot: txRoot[:],
}, nil
}
// IsEmptyExecutionData checks if an execution data is empty underneath. If a single field has
// a non-zero value, this function will return false.
func IsEmptyExecutionData(data interfaces.ExecutionData) (bool, error) {
if !bytes.Equal(data.ParentHash(), make([]byte, fieldparams.RootLength)) {
return false, nil
}
if !bytes.Equal(data.FeeRecipient(), make([]byte, fieldparams.FeeRecipientLength)) {
return false, nil
}
if !bytes.Equal(data.StateRoot(), make([]byte, fieldparams.RootLength)) {
return false, nil
}
if !bytes.Equal(data.ReceiptsRoot(), make([]byte, fieldparams.RootLength)) {
return false, nil
}
if !bytes.Equal(data.LogsBloom(), make([]byte, fieldparams.LogsBloomLength)) {
return false, nil
}
if !bytes.Equal(data.PrevRandao(), make([]byte, fieldparams.RootLength)) {
return false, nil
}
if !bytes.Equal(data.BaseFeePerGas(), make([]byte, fieldparams.RootLength)) {
return false, nil
}
if !bytes.Equal(data.BlockHash(), make([]byte, fieldparams.RootLength)) {
return false, nil
}
txs, err := data.Transactions()
switch {
case errors.Is(err, ErrUnsupportedField):
case err != nil:
return false, err
default:
if len(txs) != 0 {
return false, nil
}
}
txsRoot, err := data.TransactionsRoot()
switch {
case errors.Is(err, ErrUnsupportedField):
case err != nil:
return false, err
default:
if !bytes.Equal(txsRoot, make([]byte, fieldparams.RootLength)) {
return false, nil
}
}
if len(data.ExtraData()) != 0 {
return false, nil
}
if data.BlockNumber() != 0 {
return false, nil
}
if data.GasLimit() != 0 {
return false, nil
}
if data.GasUsed() != 0 {
return false, nil
}
if data.Timestamp() != 0 {
return false, nil
}
return true, nil
}

View File

@@ -0,0 +1,124 @@
package wrapper_test
import (
"testing"
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
)
func TestWrapExecutionPayload(t *testing.T) {
data := &enginev1.ExecutionPayload{GasUsed: 54}
wsb, err := wrapper.WrappedExecutionPayload(data)
require.NoError(t, err)
assert.DeepEqual(t, data, wsb.Proto())
}
func TestWrapExecutionPayloadHeader(t *testing.T) {
data := &enginev1.ExecutionPayloadHeader{GasUsed: 54}
wsb, err := wrapper.WrappedExecutionPayloadHeader(data)
require.NoError(t, err)
assert.DeepEqual(t, data, wsb.Proto())
}
func TestWrapExecutionPayload_IsNil(t *testing.T) {
_, err := wrapper.WrappedExecutionPayload(nil)
require.Equal(t, wrapper.ErrNilObjectWrapped, err)
data := &enginev1.ExecutionPayload{GasUsed: 54}
wsb, err := wrapper.WrappedExecutionPayload(data)
require.NoError(t, err)
assert.Equal(t, false, wsb.IsNil())
}
func TestWrapExecutionPayloadHeader_IsNil(t *testing.T) {
_, err := wrapper.WrappedExecutionPayloadHeader(nil)
require.Equal(t, wrapper.ErrNilObjectWrapped, err)
data := &enginev1.ExecutionPayloadHeader{GasUsed: 54}
wsb, err := wrapper.WrappedExecutionPayloadHeader(data)
require.NoError(t, err)
assert.Equal(t, false, wsb.IsNil())
}
func TestWrapExecutionPayload_SSZ(t *testing.T) {
wsb := createWrappedPayload(t)
rt, err := wsb.HashTreeRoot()
assert.NoError(t, err)
assert.NotEmpty(t, rt)
var b []byte
b, err = wsb.MarshalSSZTo(b)
assert.NoError(t, err)
assert.NotEqual(t, 0, len(b))
encoded, err := wsb.MarshalSSZ()
require.NoError(t, err)
assert.NotEqual(t, 0, wsb.SizeSSZ())
assert.NoError(t, wsb.UnmarshalSSZ(encoded))
}
func TestWrapExecutionPayloadHeader_SSZ(t *testing.T) {
wsb := createWrappedPayloadHeader(t)
rt, err := wsb.HashTreeRoot()
assert.NoError(t, err)
assert.NotEmpty(t, rt)
var b []byte
b, err = wsb.MarshalSSZTo(b)
assert.NoError(t, err)
assert.NotEqual(t, 0, len(b))
encoded, err := wsb.MarshalSSZ()
require.NoError(t, err)
assert.NotEqual(t, 0, wsb.SizeSSZ())
assert.NoError(t, wsb.UnmarshalSSZ(encoded))
}
func createWrappedPayload(t testing.TB) interfaces.ExecutionData {
wsb, err := wrapper.WrappedExecutionPayload(&enginev1.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),
BlockNumber: 0,
GasLimit: 0,
GasUsed: 0,
Timestamp: 0,
ExtraData: make([]byte, 0),
BaseFeePerGas: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, fieldparams.RootLength),
Transactions: make([][]byte, 0),
})
require.NoError(t, err)
return wsb
}
func createWrappedPayloadHeader(t testing.TB) interfaces.ExecutionData {
wsb, err := wrapper.WrappedExecutionPayloadHeader(&enginev1.ExecutionPayloadHeader{
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),
BlockNumber: 0,
GasLimit: 0,
GasUsed: 0,
Timestamp: 0,
ExtraData: make([]byte, 0),
BaseFeePerGas: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, fieldparams.RootLength),
TransactionsRoot: make([]byte, fieldparams.RootLength),
})
require.NoError(t, err)
return wsb
}