mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 07:58:22 -05:00
* Fix IsExecutionEnabled for blinded blocks The TransactionsRoot of a blinded block may be non-zero, anyway we do not insert the header in the state until IsExecutionEnabled is true. This last check was failing on blinded blocks because it was actively checking that the root should be zero, when it needn't be. Superseeds #11068 * fix test * test case Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
352 lines
8.6 KiB
Go
352 lines
8.6 KiB
Go
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
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// 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
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|