mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 23:18:15 -05:00
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:
@@ -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",
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 := ðpb.SignedBeaconBlockBellatrix{
|
||||
Block: ðpb.BeaconBlockBellatrix{Slot: 66},
|
||||
Block: ðpb.BeaconBlockBellatrix{Slot: 66, Body: ðpb.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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
371
consensus-types/wrapper/execution.go
Normal file
371
consensus-types/wrapper/execution.go
Normal 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
|
||||
}
|
||||
124
consensus-types/wrapper/execution_test.go
Normal file
124
consensus-types/wrapper/execution_test.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user