mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-07 22:54:17 -05:00
1173 lines
30 KiB
Go
1173 lines
30 KiB
Go
package blocks
|
|
|
|
import (
|
|
"bytes"
|
|
|
|
fieldparams "github.com/OffchainLabs/prysm/v7/config/fieldparams"
|
|
consensus_types "github.com/OffchainLabs/prysm/v7/consensus-types"
|
|
"github.com/OffchainLabs/prysm/v7/consensus-types/interfaces"
|
|
"github.com/OffchainLabs/prysm/v7/encoding/bytesutil"
|
|
"github.com/OffchainLabs/prysm/v7/encoding/ssz"
|
|
enginev1 "github.com/OffchainLabs/prysm/v7/proto/engine/v1"
|
|
"github.com/pkg/errors"
|
|
fastssz "github.com/prysmaticlabs/fastssz"
|
|
"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
|
|
}
|
|
|
|
// NewWrappedExecutionData creates an appropriate execution payload wrapper based on the incoming type.
|
|
func NewWrappedExecutionData(v proto.Message) (interfaces.ExecutionData, error) {
|
|
if v == nil {
|
|
return nil, consensus_types.ErrNilObjectWrapped
|
|
}
|
|
switch pbStruct := v.(type) {
|
|
case *enginev1.ExecutionPayload:
|
|
return WrappedExecutionPayload(pbStruct)
|
|
case *enginev1.ExecutionPayloadCapella:
|
|
return WrappedExecutionPayloadCapella(pbStruct)
|
|
case *enginev1.ExecutionPayloadCapellaWithValue:
|
|
return WrappedExecutionPayloadCapella(pbStruct.Payload)
|
|
case *enginev1.ExecutionPayloadDeneb:
|
|
return WrappedExecutionPayloadDeneb(pbStruct)
|
|
case *enginev1.ExecutionPayloadDenebWithValueAndBlobsBundle:
|
|
return WrappedExecutionPayloadDeneb(pbStruct.Payload)
|
|
case *enginev1.ExecutionBundleElectra:
|
|
// note: no payload changes in electra so using deneb
|
|
return WrappedExecutionPayloadDeneb(pbStruct.Payload)
|
|
case *enginev1.ExecutionBundleFulu:
|
|
return WrappedExecutionPayloadDeneb(pbStruct.Payload)
|
|
case *enginev1.ExecutionPayloadHeader:
|
|
return WrappedExecutionPayloadHeader(pbStruct)
|
|
case *enginev1.ExecutionPayloadHeaderCapella:
|
|
return WrappedExecutionPayloadHeaderCapella(pbStruct)
|
|
case *enginev1.ExecutionPayloadHeaderDeneb:
|
|
return WrappedExecutionPayloadHeaderDeneb(pbStruct)
|
|
default:
|
|
return nil, errors.Wrapf(ErrUnsupportedVersion, "type %T", pbStruct)
|
|
}
|
|
}
|
|
|
|
var _ interfaces.ExecutionData = &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, consensus_types.ErrNilObjectWrapped
|
|
}
|
|
return w, nil
|
|
}
|
|
|
|
// IsNil checks if the underlying data is nil.
|
|
func (e executionPayload) IsNil() bool {
|
|
return e.p == nil
|
|
}
|
|
|
|
// IsBlinded returns true if the underlying data is blinded.
|
|
func (executionPayload) IsBlinded() bool {
|
|
return false
|
|
}
|
|
|
|
// 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, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// Withdrawals --
|
|
func (executionPayload) Withdrawals() ([]*enginev1.Withdrawal, error) {
|
|
return nil, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// WithdrawalsRoot --
|
|
func (executionPayload) WithdrawalsRoot() ([]byte, error) {
|
|
return nil, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// BlobGasUsed --
|
|
func (e executionPayload) BlobGasUsed() (uint64, error) {
|
|
return 0, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// ExcessBlobGas --
|
|
func (e executionPayload) ExcessBlobGas() (uint64, error) {
|
|
return 0, consensus_types.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
|
|
}
|
|
|
|
var _ interfaces.ExecutionData = &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, consensus_types.ErrNilObjectWrapped
|
|
}
|
|
return w, nil
|
|
}
|
|
|
|
// IsNil checks if the underlying data is nil.
|
|
func (e executionPayloadHeader) IsNil() bool {
|
|
return e.p == nil
|
|
}
|
|
|
|
// IsBlinded returns true if the underlying data is a header.
|
|
func (executionPayloadHeader) IsBlinded() bool {
|
|
return true
|
|
}
|
|
|
|
// 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, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// TransactionsRoot --
|
|
func (e executionPayloadHeader) TransactionsRoot() ([]byte, error) {
|
|
return e.p.TransactionsRoot, nil
|
|
}
|
|
|
|
// Withdrawals --
|
|
func (executionPayloadHeader) Withdrawals() ([]*enginev1.Withdrawal, error) {
|
|
return nil, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// WithdrawalsRoot --
|
|
func (executionPayloadHeader) WithdrawalsRoot() ([]byte, error) {
|
|
return nil, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// BlobGasUsed --
|
|
func (e executionPayloadHeader) BlobGasUsed() (uint64, error) {
|
|
return 0, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// ExcessBlobGas --
|
|
func (e executionPayloadHeader) ExcessBlobGas() (uint64, error) {
|
|
return 0, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// executionPayloadCapella 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 executionPayloadCapella struct {
|
|
p *enginev1.ExecutionPayloadCapella
|
|
}
|
|
|
|
var _ interfaces.ExecutionData = &executionPayloadCapella{}
|
|
|
|
// WrappedExecutionPayloadCapella is a constructor which wraps a protobuf execution payload into an interface.
|
|
func WrappedExecutionPayloadCapella(p *enginev1.ExecutionPayloadCapella) (interfaces.ExecutionData, error) {
|
|
w := executionPayloadCapella{p: p}
|
|
if w.IsNil() {
|
|
return nil, consensus_types.ErrNilObjectWrapped
|
|
}
|
|
return w, nil
|
|
}
|
|
|
|
// IsNil checks if the underlying data is nil.
|
|
func (e executionPayloadCapella) IsNil() bool {
|
|
return e.p == nil
|
|
}
|
|
|
|
// IsBlinded returns true if the underlying data is blinded.
|
|
func (executionPayloadCapella) IsBlinded() bool {
|
|
return false
|
|
}
|
|
|
|
// MarshalSSZ --
|
|
func (e executionPayloadCapella) MarshalSSZ() ([]byte, error) {
|
|
return e.p.MarshalSSZ()
|
|
}
|
|
|
|
// MarshalSSZTo --
|
|
func (e executionPayloadCapella) MarshalSSZTo(dst []byte) ([]byte, error) {
|
|
return e.p.MarshalSSZTo(dst)
|
|
}
|
|
|
|
// SizeSSZ --
|
|
func (e executionPayloadCapella) SizeSSZ() int {
|
|
return e.p.SizeSSZ()
|
|
}
|
|
|
|
// UnmarshalSSZ --
|
|
func (e executionPayloadCapella) UnmarshalSSZ(buf []byte) error {
|
|
return e.p.UnmarshalSSZ(buf)
|
|
}
|
|
|
|
// HashTreeRoot --
|
|
func (e executionPayloadCapella) HashTreeRoot() ([32]byte, error) {
|
|
return e.p.HashTreeRoot()
|
|
}
|
|
|
|
// HashTreeRootWith --
|
|
func (e executionPayloadCapella) HashTreeRootWith(hh *fastssz.Hasher) error {
|
|
return e.p.HashTreeRootWith(hh)
|
|
}
|
|
|
|
// Proto --
|
|
func (e executionPayloadCapella) Proto() proto.Message {
|
|
return e.p
|
|
}
|
|
|
|
// ParentHash --
|
|
func (e executionPayloadCapella) ParentHash() []byte {
|
|
return e.p.ParentHash
|
|
}
|
|
|
|
// FeeRecipient --
|
|
func (e executionPayloadCapella) FeeRecipient() []byte {
|
|
return e.p.FeeRecipient
|
|
}
|
|
|
|
// StateRoot --
|
|
func (e executionPayloadCapella) StateRoot() []byte {
|
|
return e.p.StateRoot
|
|
}
|
|
|
|
// ReceiptsRoot --
|
|
func (e executionPayloadCapella) ReceiptsRoot() []byte {
|
|
return e.p.ReceiptsRoot
|
|
}
|
|
|
|
// LogsBloom --
|
|
func (e executionPayloadCapella) LogsBloom() []byte {
|
|
return e.p.LogsBloom
|
|
}
|
|
|
|
// PrevRandao --
|
|
func (e executionPayloadCapella) PrevRandao() []byte {
|
|
return e.p.PrevRandao
|
|
}
|
|
|
|
// BlockNumber --
|
|
func (e executionPayloadCapella) BlockNumber() uint64 {
|
|
return e.p.BlockNumber
|
|
}
|
|
|
|
// GasLimit --
|
|
func (e executionPayloadCapella) GasLimit() uint64 {
|
|
return e.p.GasLimit
|
|
}
|
|
|
|
// GasUsed --
|
|
func (e executionPayloadCapella) GasUsed() uint64 {
|
|
return e.p.GasUsed
|
|
}
|
|
|
|
// Timestamp --
|
|
func (e executionPayloadCapella) Timestamp() uint64 {
|
|
return e.p.Timestamp
|
|
}
|
|
|
|
// ExtraData --
|
|
func (e executionPayloadCapella) ExtraData() []byte {
|
|
return e.p.ExtraData
|
|
}
|
|
|
|
// BaseFeePerGas --
|
|
func (e executionPayloadCapella) BaseFeePerGas() []byte {
|
|
return e.p.BaseFeePerGas
|
|
}
|
|
|
|
// BlockHash --
|
|
func (e executionPayloadCapella) BlockHash() []byte {
|
|
return e.p.BlockHash
|
|
}
|
|
|
|
// Transactions --
|
|
func (e executionPayloadCapella) Transactions() ([][]byte, error) {
|
|
return e.p.Transactions, nil
|
|
}
|
|
|
|
// TransactionsRoot --
|
|
func (executionPayloadCapella) TransactionsRoot() ([]byte, error) {
|
|
return nil, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// Withdrawals --
|
|
func (e executionPayloadCapella) Withdrawals() ([]*enginev1.Withdrawal, error) {
|
|
return e.p.Withdrawals, nil
|
|
}
|
|
|
|
// WithdrawalsRoot --
|
|
func (executionPayloadCapella) WithdrawalsRoot() ([]byte, error) {
|
|
return nil, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// BlobGasUsed --
|
|
func (e executionPayloadCapella) BlobGasUsed() (uint64, error) {
|
|
return 0, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// ExcessBlobGas --
|
|
func (e executionPayloadCapella) ExcessBlobGas() (uint64, error) {
|
|
return 0, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// executionPayloadHeaderCapella 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 executionPayloadHeaderCapella struct {
|
|
p *enginev1.ExecutionPayloadHeaderCapella
|
|
}
|
|
|
|
var _ interfaces.ExecutionData = &executionPayloadHeaderCapella{}
|
|
|
|
// WrappedExecutionPayloadHeaderCapella is a constructor which wraps a protobuf execution header into an interface.
|
|
func WrappedExecutionPayloadHeaderCapella(p *enginev1.ExecutionPayloadHeaderCapella) (interfaces.ExecutionData, error) {
|
|
w := executionPayloadHeaderCapella{p: p}
|
|
if w.IsNil() {
|
|
return nil, consensus_types.ErrNilObjectWrapped
|
|
}
|
|
return w, nil
|
|
}
|
|
|
|
// IsNil checks if the underlying data is nil.
|
|
func (e executionPayloadHeaderCapella) IsNil() bool {
|
|
return e.p == nil
|
|
}
|
|
|
|
// IsBlinded returns true if the underlying data is blinded.
|
|
func (executionPayloadHeaderCapella) IsBlinded() bool {
|
|
return true
|
|
}
|
|
|
|
// MarshalSSZ --
|
|
func (e executionPayloadHeaderCapella) MarshalSSZ() ([]byte, error) {
|
|
return e.p.MarshalSSZ()
|
|
}
|
|
|
|
// MarshalSSZTo --
|
|
func (e executionPayloadHeaderCapella) MarshalSSZTo(dst []byte) ([]byte, error) {
|
|
return e.p.MarshalSSZTo(dst)
|
|
}
|
|
|
|
// SizeSSZ --
|
|
func (e executionPayloadHeaderCapella) SizeSSZ() int {
|
|
return e.p.SizeSSZ()
|
|
}
|
|
|
|
// UnmarshalSSZ --
|
|
func (e executionPayloadHeaderCapella) UnmarshalSSZ(buf []byte) error {
|
|
return e.p.UnmarshalSSZ(buf)
|
|
}
|
|
|
|
// HashTreeRoot --
|
|
func (e executionPayloadHeaderCapella) HashTreeRoot() ([32]byte, error) {
|
|
return e.p.HashTreeRoot()
|
|
}
|
|
|
|
// HashTreeRootWith --
|
|
func (e executionPayloadHeaderCapella) HashTreeRootWith(hh *fastssz.Hasher) error {
|
|
return e.p.HashTreeRootWith(hh)
|
|
}
|
|
|
|
// Proto --
|
|
func (e executionPayloadHeaderCapella) Proto() proto.Message {
|
|
return e.p
|
|
}
|
|
|
|
// ParentHash --
|
|
func (e executionPayloadHeaderCapella) ParentHash() []byte {
|
|
return e.p.ParentHash
|
|
}
|
|
|
|
// FeeRecipient --
|
|
func (e executionPayloadHeaderCapella) FeeRecipient() []byte {
|
|
return e.p.FeeRecipient
|
|
}
|
|
|
|
// StateRoot --
|
|
func (e executionPayloadHeaderCapella) StateRoot() []byte {
|
|
return e.p.StateRoot
|
|
}
|
|
|
|
// ReceiptsRoot --
|
|
func (e executionPayloadHeaderCapella) ReceiptsRoot() []byte {
|
|
return e.p.ReceiptsRoot
|
|
}
|
|
|
|
// LogsBloom --
|
|
func (e executionPayloadHeaderCapella) LogsBloom() []byte {
|
|
return e.p.LogsBloom
|
|
}
|
|
|
|
// PrevRandao --
|
|
func (e executionPayloadHeaderCapella) PrevRandao() []byte {
|
|
return e.p.PrevRandao
|
|
}
|
|
|
|
// BlockNumber --
|
|
func (e executionPayloadHeaderCapella) BlockNumber() uint64 {
|
|
return e.p.BlockNumber
|
|
}
|
|
|
|
// GasLimit --
|
|
func (e executionPayloadHeaderCapella) GasLimit() uint64 {
|
|
return e.p.GasLimit
|
|
}
|
|
|
|
// GasUsed --
|
|
func (e executionPayloadHeaderCapella) GasUsed() uint64 {
|
|
return e.p.GasUsed
|
|
}
|
|
|
|
// Timestamp --
|
|
func (e executionPayloadHeaderCapella) Timestamp() uint64 {
|
|
return e.p.Timestamp
|
|
}
|
|
|
|
// ExtraData --
|
|
func (e executionPayloadHeaderCapella) ExtraData() []byte {
|
|
return e.p.ExtraData
|
|
}
|
|
|
|
// BaseFeePerGas --
|
|
func (e executionPayloadHeaderCapella) BaseFeePerGas() []byte {
|
|
return e.p.BaseFeePerGas
|
|
}
|
|
|
|
// BlockHash --
|
|
func (e executionPayloadHeaderCapella) BlockHash() []byte {
|
|
return e.p.BlockHash
|
|
}
|
|
|
|
// Transactions --
|
|
func (executionPayloadHeaderCapella) Transactions() ([][]byte, error) {
|
|
return nil, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// TransactionsRoot --
|
|
func (e executionPayloadHeaderCapella) TransactionsRoot() ([]byte, error) {
|
|
return e.p.TransactionsRoot, nil
|
|
}
|
|
|
|
// Withdrawals --
|
|
func (executionPayloadHeaderCapella) Withdrawals() ([]*enginev1.Withdrawal, error) {
|
|
return nil, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// WithdrawalsRoot --
|
|
func (e executionPayloadHeaderCapella) WithdrawalsRoot() ([]byte, error) {
|
|
return e.p.WithdrawalsRoot, nil
|
|
}
|
|
|
|
// BlobGasUsed --
|
|
func (e executionPayloadHeaderCapella) BlobGasUsed() (uint64, error) {
|
|
return 0, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// ExcessBlobGas --
|
|
func (e executionPayloadHeaderCapella) ExcessBlobGas() (uint64, error) {
|
|
return 0, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// PayloadToHeaderCapella converts `payload` into execution payload header format.
|
|
func PayloadToHeaderCapella(payload interfaces.ExecutionData) (*enginev1.ExecutionPayloadHeaderCapella, error) {
|
|
txs, err := payload.Transactions()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
txRoot, err := ssz.TransactionsRoot(txs)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
withdrawals, err := payload.Withdrawals()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
withdrawalsRoot, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &enginev1.ExecutionPayloadHeaderCapella{
|
|
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[:],
|
|
WithdrawalsRoot: withdrawalsRoot[:],
|
|
}, nil
|
|
}
|
|
|
|
// PayloadToHeaderDeneb converts `payload` into execution payload header format.
|
|
func PayloadToHeaderDeneb(payload interfaces.ExecutionData) (*enginev1.ExecutionPayloadHeaderDeneb, error) {
|
|
txs, err := payload.Transactions()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
txRoot, err := ssz.TransactionsRoot(txs)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
withdrawals, err := payload.Withdrawals()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
withdrawalsRoot, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
blobGasUsed, err := payload.BlobGasUsed()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
excessBlobGas, err := payload.ExcessBlobGas()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &enginev1.ExecutionPayloadHeaderDeneb{
|
|
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[:],
|
|
WithdrawalsRoot: withdrawalsRoot[:],
|
|
BlobGasUsed: blobGasUsed,
|
|
ExcessBlobGas: excessBlobGas,
|
|
}, nil
|
|
}
|
|
|
|
var (
|
|
PayloadToHeaderElectra = PayloadToHeaderDeneb
|
|
PayloadToHeaderFulu = PayloadToHeaderDeneb
|
|
)
|
|
|
|
// 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 data == nil {
|
|
return true, nil
|
|
}
|
|
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, consensus_types.ErrUnsupportedField):
|
|
case err != nil:
|
|
return false, err
|
|
default:
|
|
if len(txs) != 0 {
|
|
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
|
|
}
|
|
|
|
// executionPayloadHeaderDeneb 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 executionPayloadHeaderDeneb struct {
|
|
p *enginev1.ExecutionPayloadHeaderDeneb
|
|
}
|
|
|
|
var _ interfaces.ExecutionData = &executionPayloadHeaderDeneb{}
|
|
|
|
// WrappedExecutionPayloadHeaderDeneb is a constructor which wraps a protobuf execution header into an interface.
|
|
func WrappedExecutionPayloadHeaderDeneb(p *enginev1.ExecutionPayloadHeaderDeneb) (interfaces.ExecutionData, error) {
|
|
w := executionPayloadHeaderDeneb{p: p}
|
|
if w.IsNil() {
|
|
return nil, consensus_types.ErrNilObjectWrapped
|
|
}
|
|
return w, nil
|
|
}
|
|
|
|
// IsNil checks if the underlying data is nil.
|
|
func (e executionPayloadHeaderDeneb) IsNil() bool {
|
|
return e.p == nil
|
|
}
|
|
|
|
// MarshalSSZ --
|
|
func (e executionPayloadHeaderDeneb) MarshalSSZ() ([]byte, error) {
|
|
return e.p.MarshalSSZ()
|
|
}
|
|
|
|
// MarshalSSZTo --
|
|
func (e executionPayloadHeaderDeneb) MarshalSSZTo(dst []byte) ([]byte, error) {
|
|
return e.p.MarshalSSZTo(dst)
|
|
}
|
|
|
|
// SizeSSZ --
|
|
func (e executionPayloadHeaderDeneb) SizeSSZ() int {
|
|
return e.p.SizeSSZ()
|
|
}
|
|
|
|
// UnmarshalSSZ --
|
|
func (e executionPayloadHeaderDeneb) UnmarshalSSZ(buf []byte) error {
|
|
return e.p.UnmarshalSSZ(buf)
|
|
}
|
|
|
|
// HashTreeRoot --
|
|
func (e executionPayloadHeaderDeneb) HashTreeRoot() ([32]byte, error) {
|
|
return e.p.HashTreeRoot()
|
|
}
|
|
|
|
// HashTreeRootWith --
|
|
func (e executionPayloadHeaderDeneb) HashTreeRootWith(hh *fastssz.Hasher) error {
|
|
return e.p.HashTreeRootWith(hh)
|
|
}
|
|
|
|
// Proto --
|
|
func (e executionPayloadHeaderDeneb) Proto() proto.Message {
|
|
return e.p
|
|
}
|
|
|
|
// ParentHash --
|
|
func (e executionPayloadHeaderDeneb) ParentHash() []byte {
|
|
return e.p.ParentHash
|
|
}
|
|
|
|
// FeeRecipient --
|
|
func (e executionPayloadHeaderDeneb) FeeRecipient() []byte {
|
|
return e.p.FeeRecipient
|
|
}
|
|
|
|
// StateRoot --
|
|
func (e executionPayloadHeaderDeneb) StateRoot() []byte {
|
|
return e.p.StateRoot
|
|
}
|
|
|
|
// ReceiptsRoot --
|
|
func (e executionPayloadHeaderDeneb) ReceiptsRoot() []byte {
|
|
return e.p.ReceiptsRoot
|
|
}
|
|
|
|
// LogsBloom --
|
|
func (e executionPayloadHeaderDeneb) LogsBloom() []byte {
|
|
return e.p.LogsBloom
|
|
}
|
|
|
|
// PrevRandao --
|
|
func (e executionPayloadHeaderDeneb) PrevRandao() []byte {
|
|
return e.p.PrevRandao
|
|
}
|
|
|
|
// BlockNumber --
|
|
func (e executionPayloadHeaderDeneb) BlockNumber() uint64 {
|
|
return e.p.BlockNumber
|
|
}
|
|
|
|
// GasLimit --
|
|
func (e executionPayloadHeaderDeneb) GasLimit() uint64 {
|
|
return e.p.GasLimit
|
|
}
|
|
|
|
// GasUsed --
|
|
func (e executionPayloadHeaderDeneb) GasUsed() uint64 {
|
|
return e.p.GasUsed
|
|
}
|
|
|
|
// Timestamp --
|
|
func (e executionPayloadHeaderDeneb) Timestamp() uint64 {
|
|
return e.p.Timestamp
|
|
}
|
|
|
|
// ExtraData --
|
|
func (e executionPayloadHeaderDeneb) ExtraData() []byte {
|
|
return e.p.ExtraData
|
|
}
|
|
|
|
// BaseFeePerGas --
|
|
func (e executionPayloadHeaderDeneb) BaseFeePerGas() []byte {
|
|
return e.p.BaseFeePerGas
|
|
}
|
|
|
|
// BlockHash --
|
|
func (e executionPayloadHeaderDeneb) BlockHash() []byte {
|
|
return e.p.BlockHash
|
|
}
|
|
|
|
// Transactions --
|
|
func (executionPayloadHeaderDeneb) Transactions() ([][]byte, error) {
|
|
return nil, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// TransactionsRoot --
|
|
func (e executionPayloadHeaderDeneb) TransactionsRoot() ([]byte, error) {
|
|
return e.p.TransactionsRoot, nil
|
|
}
|
|
|
|
// Withdrawals --
|
|
func (e executionPayloadHeaderDeneb) Withdrawals() ([]*enginev1.Withdrawal, error) {
|
|
return nil, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// WithdrawalsRoot --
|
|
func (e executionPayloadHeaderDeneb) WithdrawalsRoot() ([]byte, error) {
|
|
return e.p.WithdrawalsRoot, nil
|
|
}
|
|
|
|
// BlobGasUsed --
|
|
func (e executionPayloadHeaderDeneb) BlobGasUsed() (uint64, error) {
|
|
return e.p.BlobGasUsed, nil
|
|
}
|
|
|
|
// ExcessBlobGas --
|
|
func (e executionPayloadHeaderDeneb) ExcessBlobGas() (uint64, error) {
|
|
return e.p.ExcessBlobGas, nil
|
|
}
|
|
|
|
// IsBlinded returns true if the underlying data is blinded.
|
|
func (e executionPayloadHeaderDeneb) IsBlinded() bool {
|
|
return true
|
|
}
|
|
|
|
// executionPayloadDeneb 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 executionPayloadDeneb struct {
|
|
p *enginev1.ExecutionPayloadDeneb
|
|
}
|
|
|
|
var _ interfaces.ExecutionData = &executionPayloadDeneb{}
|
|
|
|
// WrappedExecutionPayloadDeneb is a constructor which wraps a protobuf execution payload into an interface.
|
|
func WrappedExecutionPayloadDeneb(p *enginev1.ExecutionPayloadDeneb) (interfaces.ExecutionData, error) {
|
|
w := executionPayloadDeneb{p: p}
|
|
if w.IsNil() {
|
|
return nil, consensus_types.ErrNilObjectWrapped
|
|
}
|
|
return w, nil
|
|
}
|
|
|
|
// IsNil checks if the underlying data is nil.
|
|
func (e executionPayloadDeneb) IsNil() bool {
|
|
return e.p == nil
|
|
}
|
|
|
|
// MarshalSSZ --
|
|
func (e executionPayloadDeneb) MarshalSSZ() ([]byte, error) {
|
|
return e.p.MarshalSSZ()
|
|
}
|
|
|
|
// MarshalSSZTo --
|
|
func (e executionPayloadDeneb) MarshalSSZTo(dst []byte) ([]byte, error) {
|
|
return e.p.MarshalSSZTo(dst)
|
|
}
|
|
|
|
// SizeSSZ --
|
|
func (e executionPayloadDeneb) SizeSSZ() int {
|
|
return e.p.SizeSSZ()
|
|
}
|
|
|
|
// UnmarshalSSZ --
|
|
func (e executionPayloadDeneb) UnmarshalSSZ(buf []byte) error {
|
|
return e.p.UnmarshalSSZ(buf)
|
|
}
|
|
|
|
// HashTreeRoot --
|
|
func (e executionPayloadDeneb) HashTreeRoot() ([32]byte, error) {
|
|
return e.p.HashTreeRoot()
|
|
}
|
|
|
|
// HashTreeRootWith --
|
|
func (e executionPayloadDeneb) HashTreeRootWith(hh *fastssz.Hasher) error {
|
|
return e.p.HashTreeRootWith(hh)
|
|
}
|
|
|
|
// Proto --
|
|
func (e executionPayloadDeneb) Proto() proto.Message {
|
|
return e.p
|
|
}
|
|
|
|
// ParentHash --
|
|
func (e executionPayloadDeneb) ParentHash() []byte {
|
|
return e.p.ParentHash
|
|
}
|
|
|
|
// FeeRecipient --
|
|
func (e executionPayloadDeneb) FeeRecipient() []byte {
|
|
return e.p.FeeRecipient
|
|
}
|
|
|
|
// StateRoot --
|
|
func (e executionPayloadDeneb) StateRoot() []byte {
|
|
return e.p.StateRoot
|
|
}
|
|
|
|
// ReceiptsRoot --
|
|
func (e executionPayloadDeneb) ReceiptsRoot() []byte {
|
|
return e.p.ReceiptsRoot
|
|
}
|
|
|
|
// LogsBloom --
|
|
func (e executionPayloadDeneb) LogsBloom() []byte {
|
|
return e.p.LogsBloom
|
|
}
|
|
|
|
// PrevRandao --
|
|
func (e executionPayloadDeneb) PrevRandao() []byte {
|
|
return e.p.PrevRandao
|
|
}
|
|
|
|
// BlockNumber --
|
|
func (e executionPayloadDeneb) BlockNumber() uint64 {
|
|
return e.p.BlockNumber
|
|
}
|
|
|
|
// GasLimit --
|
|
func (e executionPayloadDeneb) GasLimit() uint64 {
|
|
return e.p.GasLimit
|
|
}
|
|
|
|
// GasUsed --
|
|
func (e executionPayloadDeneb) GasUsed() uint64 {
|
|
return e.p.GasUsed
|
|
}
|
|
|
|
// Timestamp --
|
|
func (e executionPayloadDeneb) Timestamp() uint64 {
|
|
return e.p.Timestamp
|
|
}
|
|
|
|
// ExtraData --
|
|
func (e executionPayloadDeneb) ExtraData() []byte {
|
|
return e.p.ExtraData
|
|
}
|
|
|
|
// BaseFeePerGas --
|
|
func (e executionPayloadDeneb) BaseFeePerGas() []byte {
|
|
return e.p.BaseFeePerGas
|
|
}
|
|
|
|
// BlockHash --
|
|
func (e executionPayloadDeneb) BlockHash() []byte {
|
|
return e.p.BlockHash
|
|
}
|
|
|
|
// Transactions --
|
|
func (e executionPayloadDeneb) Transactions() ([][]byte, error) {
|
|
return e.p.Transactions, nil
|
|
}
|
|
|
|
// TransactionsRoot --
|
|
func (e executionPayloadDeneb) TransactionsRoot() ([]byte, error) {
|
|
return nil, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
// Withdrawals --
|
|
func (e executionPayloadDeneb) Withdrawals() ([]*enginev1.Withdrawal, error) {
|
|
return e.p.Withdrawals, nil
|
|
}
|
|
|
|
// WithdrawalsRoot --
|
|
func (e executionPayloadDeneb) WithdrawalsRoot() ([]byte, error) {
|
|
return nil, consensus_types.ErrUnsupportedField
|
|
}
|
|
|
|
func (e executionPayloadDeneb) BlobGasUsed() (uint64, error) {
|
|
return e.p.BlobGasUsed, nil
|
|
}
|
|
|
|
func (e executionPayloadDeneb) ExcessBlobGas() (uint64, error) {
|
|
return e.p.ExcessBlobGas, nil
|
|
}
|
|
|
|
// IsBlinded returns true if the underlying data is blinded.
|
|
func (e executionPayloadDeneb) IsBlinded() bool {
|
|
return false
|
|
}
|