Electra attestation interfaces (#13937)

* config values

* block protos

* get_committee_indices

* proto and ssz

* attestation interface

* Revert "Auxiliary commit to revert individual files from deadb2183723511721b3288c7168808a4fa97c64"

This reverts commit 32ad5009537bc5ec0e6caf9f52143d380d00be85.

* todos

* get_attesting_indices

* Revert "Auxiliary commit to revert individual files from dd2789723f90b15eb1f874b561d88d11dcc9c0bf"

This reverts commit f39644ed3cb6f3964fc6c86fdf4bd5de2a9668c8.

* beacon spec changes

* Fix pending attestation. Build ok

* Electra: add electra version

* Electra: consensus types

* gocognit exclusion

* @potuz's suggestion

* build fix

* interfaces for indexed att and slashing

* indexed att usage

* BuildSignedBeaconBlockFromExecutionPayload

* slashing usage

* grpc stubs

* remove unused methods

* Electra attestation interfaces

* cleanup

* tests

* make linter happy

* simple casting

* test fixes

* Fix spectest failures

* Regen pb and ssz files

* Handle "not ok" type assertion cases

* Setters that check version should always return an error. SetAttesterSlashings and SetAttestations

* gofmt

* Fix TestMinSpanChunksSlice_CheckSlashable

---------

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Preston Van Loon <preston@pvl.dev>
This commit is contained in:
Radosław Kapka
2024-05-01 06:29:38 +09:00
committed by GitHub
parent ae16d5f52c
commit 2c5a2e8ec7
174 changed files with 3463 additions and 1792 deletions

View File

@@ -187,6 +187,11 @@ func (executionPayload) PbDeneb() (*enginev1.ExecutionPayloadDeneb, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbElectra --
func (executionPayload) PbElectra() (*enginev1.ExecutionPayloadElectra, error) {
return nil, consensus_types.ErrUnsupportedField
}
// ValueInWei --
func (executionPayload) ValueInWei() (math.Wei, error) {
return nil, consensus_types.ErrUnsupportedField
@@ -197,6 +202,16 @@ func (executionPayload) ValueInGwei() (uint64, error) {
return 0, consensus_types.ErrUnsupportedField
}
// DepositReceipts --
func (e executionPayload) DepositReceipts() ([]*enginev1.DepositReceipt, error) {
return nil, consensus_types.ErrUnsupportedField
}
// WithdrawalRequests --
func (e executionPayload) WithdrawalRequests() ([]*enginev1.ExecutionLayerWithdrawalRequest, error) {
return nil, 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.
@@ -353,6 +368,11 @@ func (e executionPayloadHeader) ExcessBlobGas() (uint64, error) {
return 0, consensus_types.ErrUnsupportedField
}
// PbElectra --
func (e executionPayloadHeader) PbElectra() (*enginev1.ExecutionPayloadElectra, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbDeneb --
func (executionPayloadHeader) PbDeneb() (*enginev1.ExecutionPayloadDeneb, error) {
return nil, consensus_types.ErrUnsupportedField
@@ -378,6 +398,16 @@ func (executionPayloadHeader) ValueInGwei() (uint64, error) {
return 0, consensus_types.ErrUnsupportedField
}
// DepositReceipts --
func (e executionPayloadHeader) DepositReceipts() ([]*enginev1.DepositReceipt, error) {
return nil, consensus_types.ErrUnsupportedField
}
// WithdrawalRequests --
func (e executionPayloadHeader) WithdrawalRequests() ([]*enginev1.ExecutionLayerWithdrawalRequest, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PayloadToHeader converts `payload` into execution payload header format.
func PayloadToHeader(payload interfaces.ExecutionData) (*enginev1.ExecutionPayloadHeader, error) {
txs, err := payload.Transactions()
@@ -564,6 +594,11 @@ func (e executionPayloadCapella) ExcessBlobGas() (uint64, error) {
return 0, consensus_types.ErrUnsupportedField
}
// PbElectra --
func (executionPayloadCapella) PbElectra() (*enginev1.ExecutionPayloadElectra, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbDeneb --
func (executionPayloadCapella) PbDeneb() (*enginev1.ExecutionPayloadDeneb, error) {
return nil, consensus_types.ErrUnsupportedField
@@ -589,6 +624,16 @@ func (e executionPayloadCapella) ValueInGwei() (uint64, error) {
return e.gweiValue, nil
}
// DepositReceipts --
func (e executionPayloadCapella) DepositReceipts() ([]*enginev1.DepositReceipt, error) {
return nil, consensus_types.ErrUnsupportedField
}
// WithdrawalRequests --
func (e executionPayloadCapella) WithdrawalRequests() ([]*enginev1.ExecutionLayerWithdrawalRequest, error) {
return nil, 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.
@@ -747,6 +792,11 @@ func (e executionPayloadHeaderCapella) ExcessBlobGas() (uint64, error) {
return 0, consensus_types.ErrUnsupportedField
}
// PbElectra --
func (executionPayloadHeaderCapella) PbElectra() (*enginev1.ExecutionPayloadElectra, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbDeneb --
func (executionPayloadHeaderCapella) PbDeneb() (*enginev1.ExecutionPayloadDeneb, error) {
return nil, consensus_types.ErrUnsupportedField
@@ -772,6 +822,16 @@ func (e executionPayloadHeaderCapella) ValueInGwei() (uint64, error) {
return e.gweiValue, nil
}
// DepositReceipts --
func (e executionPayloadHeaderCapella) DepositReceipts() ([]*enginev1.DepositReceipt, error) {
return nil, consensus_types.ErrUnsupportedField
}
// WithdrawalRequests --
func (e executionPayloadHeaderCapella) WithdrawalRequests() ([]*enginev1.ExecutionLayerWithdrawalRequest, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PayloadToHeaderCapella converts `payload` into execution payload header format.
func PayloadToHeaderCapella(payload interfaces.ExecutionData) (*enginev1.ExecutionPayloadHeaderCapella, error) {
txs, err := payload.Transactions()
@@ -858,6 +918,73 @@ func PayloadToHeaderDeneb(payload interfaces.ExecutionData) (*enginev1.Execution
}, nil
}
// PayloadToHeaderElectra converts `payload` into execution payload header format.
func PayloadToHeaderElectra(payload interfaces.ExecutionData) (*enginev1.ExecutionPayloadHeaderElectra, 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
}
depositReceipts, err := payload.DepositReceipts()
if err != nil {
return nil, err
}
depositReceiptsRoot, err := ssz.DepositReceiptSliceRoot(depositReceipts, fieldparams.MaxDepositReceiptsPerPayload)
if err != nil {
return nil, err
}
withdrawalRequests, err := payload.WithdrawalRequests()
if err != nil {
return nil, err
}
withdrawalRequestsRoot, err := ssz.WithdrawalRequestSliceRoot(withdrawalRequests, fieldparams.MaxWithdrawalRequestsPerPayload)
if err != nil {
return nil, err
}
return &enginev1.ExecutionPayloadHeaderElectra{
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,
DepositReceiptsRoot: depositReceiptsRoot[:],
WithdrawalRequestsRoot: withdrawalRequestsRoot[:],
}, 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) {
@@ -915,6 +1042,29 @@ func IsEmptyExecutionData(data interfaces.ExecutionData) (bool, error) {
if data.Timestamp() != 0 {
return false, nil
}
drs, err := data.DepositReceipts()
switch {
case errors.Is(err, consensus_types.ErrUnsupportedField):
case err != nil:
return false, err
default:
if len(drs) != 0 {
return false, nil
}
}
wrs, err := data.WithdrawalRequests()
switch {
case errors.Is(err, consensus_types.ErrUnsupportedField):
case err != nil:
return false, err
default:
if len(wrs) != 0 {
return false, nil
}
}
return true, nil
}
@@ -1071,6 +1221,11 @@ func (e executionPayloadHeaderDeneb) ExcessBlobGas() (uint64, error) {
return e.p.ExcessBlobGas, nil
}
// PbElectra --
func (executionPayloadHeaderDeneb) PbElectra() (*enginev1.ExecutionPayloadElectra, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbDeneb --
func (executionPayloadHeaderDeneb) PbDeneb() (*enginev1.ExecutionPayloadDeneb, error) {
return nil, consensus_types.ErrUnsupportedField
@@ -1096,6 +1251,16 @@ func (e executionPayloadHeaderDeneb) ValueInGwei() (uint64, error) {
return e.gweiValue, nil
}
// DepositReceipts --
func (e executionPayloadHeaderDeneb) DepositReceipts() ([]*enginev1.DepositReceipt, error) {
return nil, consensus_types.ErrUnsupportedField
}
// WithdrawalRequests --
func (e executionPayloadHeaderDeneb) WithdrawalRequests() ([]*enginev1.ExecutionLayerWithdrawalRequest, error) {
return nil, consensus_types.ErrUnsupportedField
}
// IsBlinded returns true if the underlying data is blinded.
func (e executionPayloadHeaderDeneb) IsBlinded() bool {
return true
@@ -1267,6 +1432,11 @@ func (e executionPayloadDeneb) PbDeneb() (*enginev1.ExecutionPayloadDeneb, error
return e.p, nil
}
// PbElectra --
func (e executionPayloadDeneb) PbElectra() (*enginev1.ExecutionPayloadElectra, error) {
return nil, consensus_types.ErrUnsupportedField
}
// ValueInWei --
func (e executionPayloadDeneb) ValueInWei() (math.Wei, error) {
return e.weiValue, nil
@@ -1277,11 +1447,415 @@ func (e executionPayloadDeneb) ValueInGwei() (uint64, error) {
return e.gweiValue, nil
}
// DepositReceipts --
func (e executionPayloadDeneb) DepositReceipts() ([]*enginev1.DepositReceipt, error) {
return nil, consensus_types.ErrUnsupportedField
}
// WithdrawalRequests --
func (e executionPayloadDeneb) WithdrawalRequests() ([]*enginev1.ExecutionLayerWithdrawalRequest, error) {
return nil, consensus_types.ErrUnsupportedField
}
// IsBlinded returns true if the underlying data is blinded.
func (e executionPayloadDeneb) IsBlinded() bool {
return false
}
// executionPayloadHeaderElectra 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 executionPayloadHeaderElectra struct {
p *enginev1.ExecutionPayloadHeaderElectra
weiValue math.Wei
gweiValue uint64
}
// WrappedExecutionPayloadHeaderElectra is a constructor which wraps a protobuf execution header into an interface.
func WrappedExecutionPayloadHeaderElectra(p *enginev1.ExecutionPayloadHeaderElectra, value math.Wei) (interfaces.ExecutionData, error) {
w := executionPayloadHeaderElectra{p: p, weiValue: value, gweiValue: uint64(math.WeiToGwei(value))}
if w.IsNil() {
return nil, consensus_types.ErrNilObjectWrapped
}
return w, nil
}
// IsNil checks if the underlying data is nil.
func (e executionPayloadHeaderElectra) IsNil() bool {
return e.p == nil
}
// MarshalSSZ --
func (e executionPayloadHeaderElectra) MarshalSSZ() ([]byte, error) {
return e.p.MarshalSSZ()
}
// MarshalSSZTo --
func (e executionPayloadHeaderElectra) MarshalSSZTo(dst []byte) ([]byte, error) {
return e.p.MarshalSSZTo(dst)
}
// SizeSSZ --
func (e executionPayloadHeaderElectra) SizeSSZ() int {
return e.p.SizeSSZ()
}
// UnmarshalSSZ --
func (e executionPayloadHeaderElectra) UnmarshalSSZ(buf []byte) error {
return e.p.UnmarshalSSZ(buf)
}
// HashTreeRoot --
func (e executionPayloadHeaderElectra) HashTreeRoot() ([32]byte, error) {
return e.p.HashTreeRoot()
}
// HashTreeRootWith --
func (e executionPayloadHeaderElectra) HashTreeRootWith(hh *fastssz.Hasher) error {
return e.p.HashTreeRootWith(hh)
}
// Proto --
func (e executionPayloadHeaderElectra) Proto() proto.Message {
return e.p
}
// ParentHash --
func (e executionPayloadHeaderElectra) ParentHash() []byte {
return e.p.ParentHash
}
// FeeRecipient --
func (e executionPayloadHeaderElectra) FeeRecipient() []byte {
return e.p.FeeRecipient
}
// StateRoot --
func (e executionPayloadHeaderElectra) StateRoot() []byte {
return e.p.StateRoot
}
// ReceiptsRoot --
func (e executionPayloadHeaderElectra) ReceiptsRoot() []byte {
return e.p.ReceiptsRoot
}
// LogsBloom --
func (e executionPayloadHeaderElectra) LogsBloom() []byte {
return e.p.LogsBloom
}
// PrevRandao --
func (e executionPayloadHeaderElectra) PrevRandao() []byte {
return e.p.PrevRandao
}
// BlockNumber --
func (e executionPayloadHeaderElectra) BlockNumber() uint64 {
return e.p.BlockNumber
}
// GasLimit --
func (e executionPayloadHeaderElectra) GasLimit() uint64 {
return e.p.GasLimit
}
// GasUsed --
func (e executionPayloadHeaderElectra) GasUsed() uint64 {
return e.p.GasUsed
}
// Timestamp --
func (e executionPayloadHeaderElectra) Timestamp() uint64 {
return e.p.Timestamp
}
// ExtraData --
func (e executionPayloadHeaderElectra) ExtraData() []byte {
return e.p.ExtraData
}
// BaseFeePerGas --
func (e executionPayloadHeaderElectra) BaseFeePerGas() []byte {
return e.p.BaseFeePerGas
}
// BlockHash --
func (e executionPayloadHeaderElectra) BlockHash() []byte {
return e.p.BlockHash
}
// Transactions --
func (executionPayloadHeaderElectra) Transactions() ([][]byte, error) {
return nil, consensus_types.ErrUnsupportedField
}
// TransactionsRoot --
func (e executionPayloadHeaderElectra) TransactionsRoot() ([]byte, error) {
return e.p.TransactionsRoot, nil
}
// Withdrawals --
func (e executionPayloadHeaderElectra) Withdrawals() ([]*enginev1.Withdrawal, error) {
return nil, consensus_types.ErrUnsupportedField
}
// WithdrawalsRoot --
func (e executionPayloadHeaderElectra) WithdrawalsRoot() ([]byte, error) {
return e.p.WithdrawalsRoot, nil
}
// BlobGasUsed --
func (e executionPayloadHeaderElectra) BlobGasUsed() (uint64, error) {
return e.p.BlobGasUsed, nil
}
// ExcessBlobGas --
func (e executionPayloadHeaderElectra) ExcessBlobGas() (uint64, error) {
return e.p.ExcessBlobGas, nil
}
// PbElectra --
func (e executionPayloadHeaderElectra) PbElectra() (*enginev1.ExecutionPayloadElectra, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbDeneb --
func (executionPayloadHeaderElectra) PbDeneb() (*enginev1.ExecutionPayloadDeneb, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbBellatrix --
func (executionPayloadHeaderElectra) PbBellatrix() (*enginev1.ExecutionPayload, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbCapella --
func (executionPayloadHeaderElectra) PbCapella() (*enginev1.ExecutionPayloadCapella, error) {
return nil, consensus_types.ErrUnsupportedField
}
// ValueInWei --
func (e executionPayloadHeaderElectra) ValueInWei() (math.Wei, error) {
return e.weiValue, nil
}
// ValueInGwei --
func (e executionPayloadHeaderElectra) ValueInGwei() (uint64, error) {
return e.gweiValue, nil
}
// DepositReceipts --
func (e executionPayloadHeaderElectra) DepositReceipts() ([]*enginev1.DepositReceipt, error) {
return nil, consensus_types.ErrUnsupportedField
}
// WithdrawalRequests --
func (e executionPayloadHeaderElectra) WithdrawalRequests() ([]*enginev1.ExecutionLayerWithdrawalRequest, error) {
return nil, consensus_types.ErrUnsupportedField
}
// IsBlinded returns true if the underlying data is blinded.
func (e executionPayloadHeaderElectra) IsBlinded() bool {
return true
}
// executionPayloadElectra 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 executionPayloadElectra struct {
p *enginev1.ExecutionPayloadElectra
weiValue math.Wei
gweiValue uint64
}
// WrappedExecutionPayloadElectra is a constructor which wraps a protobuf execution payload into an interface.
func WrappedExecutionPayloadElectra(p *enginev1.ExecutionPayloadElectra, value math.Wei) (interfaces.ExecutionData, error) {
w := executionPayloadElectra{p: p, weiValue: value, gweiValue: uint64(math.WeiToGwei(value))}
if w.IsNil() {
return nil, consensus_types.ErrNilObjectWrapped
}
return w, nil
}
// IsNil checks if the underlying data is nil.
func (e executionPayloadElectra) IsNil() bool {
return e.p == nil
}
// MarshalSSZ --
func (e executionPayloadElectra) MarshalSSZ() ([]byte, error) {
return e.p.MarshalSSZ()
}
// MarshalSSZTo --
func (e executionPayloadElectra) MarshalSSZTo(dst []byte) ([]byte, error) {
return e.p.MarshalSSZTo(dst)
}
// SizeSSZ --
func (e executionPayloadElectra) SizeSSZ() int {
return e.p.SizeSSZ()
}
// UnmarshalSSZ --
func (e executionPayloadElectra) UnmarshalSSZ(buf []byte) error {
return e.p.UnmarshalSSZ(buf)
}
// HashTreeRoot --
func (e executionPayloadElectra) HashTreeRoot() ([32]byte, error) {
return e.p.HashTreeRoot()
}
// HashTreeRootWith --
func (e executionPayloadElectra) HashTreeRootWith(hh *fastssz.Hasher) error {
return e.p.HashTreeRootWith(hh)
}
// Proto --
func (e executionPayloadElectra) Proto() proto.Message {
return e.p
}
// ParentHash --
func (e executionPayloadElectra) ParentHash() []byte {
return e.p.ParentHash
}
// FeeRecipient --
func (e executionPayloadElectra) FeeRecipient() []byte {
return e.p.FeeRecipient
}
// StateRoot --
func (e executionPayloadElectra) StateRoot() []byte {
return e.p.StateRoot
}
// ReceiptsRoot --
func (e executionPayloadElectra) ReceiptsRoot() []byte {
return e.p.ReceiptsRoot
}
// LogsBloom --
func (e executionPayloadElectra) LogsBloom() []byte {
return e.p.LogsBloom
}
// PrevRandao --
func (e executionPayloadElectra) PrevRandao() []byte {
return e.p.PrevRandao
}
// BlockNumber --
func (e executionPayloadElectra) BlockNumber() uint64 {
return e.p.BlockNumber
}
// GasLimit --
func (e executionPayloadElectra) GasLimit() uint64 {
return e.p.GasLimit
}
// GasUsed --
func (e executionPayloadElectra) GasUsed() uint64 {
return e.p.GasUsed
}
// Timestamp --
func (e executionPayloadElectra) Timestamp() uint64 {
return e.p.Timestamp
}
// ExtraData --
func (e executionPayloadElectra) ExtraData() []byte {
return e.p.ExtraData
}
// BaseFeePerGas --
func (e executionPayloadElectra) BaseFeePerGas() []byte {
return e.p.BaseFeePerGas
}
// BlockHash --
func (e executionPayloadElectra) BlockHash() []byte {
return e.p.BlockHash
}
// Transactions --
func (e executionPayloadElectra) Transactions() ([][]byte, error) {
return e.p.Transactions, nil
}
// TransactionsRoot --
func (e executionPayloadElectra) TransactionsRoot() ([]byte, error) {
return nil, consensus_types.ErrUnsupportedField
}
// Withdrawals --
func (e executionPayloadElectra) Withdrawals() ([]*enginev1.Withdrawal, error) {
return e.p.Withdrawals, nil
}
// WithdrawalsRoot --
func (e executionPayloadElectra) WithdrawalsRoot() ([]byte, error) {
return nil, consensus_types.ErrUnsupportedField
}
func (e executionPayloadElectra) BlobGasUsed() (uint64, error) {
return e.p.BlobGasUsed, nil
}
func (e executionPayloadElectra) ExcessBlobGas() (uint64, error) {
return e.p.ExcessBlobGas, nil
}
// PbBellatrix --
func (e executionPayloadElectra) PbBellatrix() (*enginev1.ExecutionPayload, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbCapella --
func (e executionPayloadElectra) PbCapella() (*enginev1.ExecutionPayloadCapella, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbDeneb --
func (e executionPayloadElectra) PbDeneb() (*enginev1.ExecutionPayloadDeneb, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbElectra --
func (e executionPayloadElectra) PbElectra() (*enginev1.ExecutionPayloadElectra, error) {
return e.p, nil
}
// ValueInWei --
func (e executionPayloadElectra) ValueInWei() (math.Wei, error) {
return e.weiValue, nil
}
// ValueInGwei --
func (e executionPayloadElectra) ValueInGwei() (uint64, error) {
return e.gweiValue, nil
}
// DepositReceipts --
func (e executionPayloadElectra) DepositReceipts() ([]*enginev1.DepositReceipt, error) {
return e.p.DepositReceipts, nil
}
// WithdrawalRequests --
func (e executionPayloadElectra) WithdrawalRequests() ([]*enginev1.ExecutionLayerWithdrawalRequest, error) {
return e.p.WithdrawalRequests, nil
}
// IsBlinded returns true if the underlying data is blinded.
func (e executionPayloadElectra) IsBlinded() bool {
return false
}
// PayloadValueToWei returns a Wei value given the payload's value
func PayloadValueToWei(value []byte) math.Wei {
// We have to convert big endian to little endian because the value is coming from the execution layer.

View File

@@ -67,6 +67,14 @@ func NewSignedBeaconBlock(i interface{}) (interfaces.SignedBeaconBlock, error) {
return initBlindedSignedBlockFromProtoDeneb(b)
case *eth.GenericSignedBeaconBlock_BlindedDeneb:
return initBlindedSignedBlockFromProtoDeneb(b.BlindedDeneb)
case *eth.GenericSignedBeaconBlock_Electra:
return initSignedBlockFromProtoElectra(b.Electra.Block)
case *eth.SignedBeaconBlockElectra:
return initSignedBlockFromProtoElectra(b)
case *eth.SignedBlindedBeaconBlockElectra:
return initBlindedSignedBlockFromProtoElectra(b)
case *eth.GenericSignedBeaconBlock_BlindedElectra:
return initBlindedSignedBlockFromProtoElectra(b.BlindedElectra)
default:
return nil, errors.Wrapf(ErrUnsupportedSignedBeaconBlock, "unable to create block from type %T", i)
}
@@ -109,6 +117,14 @@ func NewBeaconBlock(i interface{}) (interfaces.ReadOnlyBeaconBlock, error) {
return initBlindedBlockFromProtoDeneb(b)
case *eth.GenericBeaconBlock_BlindedDeneb:
return initBlindedBlockFromProtoDeneb(b.BlindedDeneb)
case *eth.GenericBeaconBlock_Electra:
return initBlockFromProtoElectra(b.Electra.Block)
case *eth.BeaconBlockElectra:
return initBlockFromProtoElectra(b)
case *eth.BlindedBeaconBlockElectra:
return initBlindedBlockFromProtoElectra(b)
case *eth.GenericBeaconBlock_BlindedElectra:
return initBlindedBlockFromProtoElectra(b.BlindedElectra)
default:
return nil, errors.Wrapf(errUnsupportedBeaconBlock, "unable to create block from type %T", i)
}
@@ -135,6 +151,10 @@ func NewBeaconBlockBody(i interface{}) (interfaces.ReadOnlyBeaconBlockBody, erro
return initBlockBodyFromProtoDeneb(b)
case *eth.BlindedBeaconBlockBodyDeneb:
return initBlindedBlockBodyFromProtoDeneb(b)
case *eth.BeaconBlockBodyElectra:
return initBlockBodyFromProtoElectra(b)
case *eth.BlindedBeaconBlockBodyElectra:
return initBlindedBlockBodyFromProtoElectra(b)
default:
return nil, errors.Wrapf(errUnsupportedBeaconBlockBody, "unable to create block body from type %T", i)
}
@@ -201,6 +221,19 @@ func BuildSignedBeaconBlock(blk interfaces.ReadOnlyBeaconBlock, signature []byte
return nil, errIncorrectBlockVersion
}
return NewSignedBeaconBlock(&eth.SignedBeaconBlockDeneb{Block: pb, Signature: signature})
case version.Electra:
if blk.IsBlinded() {
pb, ok := pb.(*eth.BlindedBeaconBlockElectra)
if !ok {
return nil, errIncorrectBlockVersion
}
return NewSignedBeaconBlock(&eth.SignedBlindedBeaconBlockElectra{Message: pb, Signature: signature})
}
pb, ok := pb.(*eth.BeaconBlockElectra)
if !ok {
return nil, errIncorrectBlockVersion
}
return NewSignedBeaconBlock(&eth.SignedBeaconBlockElectra{Block: pb, Signature: signature})
default:
return nil, errUnsupportedBeaconBlock
}
@@ -208,9 +241,7 @@ func BuildSignedBeaconBlock(blk interfaces.ReadOnlyBeaconBlock, signature []byte
// BuildSignedBeaconBlockFromExecutionPayload takes a signed, blinded beacon block and converts into
// a full, signed beacon block by specifying an execution payload.
func BuildSignedBeaconBlockFromExecutionPayload(
blk interfaces.ReadOnlySignedBeaconBlock, payload interface{},
) (interfaces.SignedBeaconBlock, error) {
func BuildSignedBeaconBlockFromExecutionPayload(blk interfaces.ReadOnlySignedBeaconBlock, payload interface{}) (interfaces.SignedBeaconBlock, error) { // nolint:gocognit
if err := BeaconBlockIsNil(blk); err != nil {
return nil, err
}
@@ -232,6 +263,8 @@ func BuildSignedBeaconBlockFromExecutionPayload(
wrappedPayload, wrapErr = WrappedExecutionPayloadCapella(p, big.NewInt(0))
case *enginev1.ExecutionPayloadDeneb:
wrappedPayload, wrapErr = WrappedExecutionPayloadDeneb(p, big.NewInt(0))
case *enginev1.ExecutionPayloadElectra:
wrappedPayload, wrapErr = WrappedExecutionPayloadElectra(p, big.NewInt(0))
default:
return nil, fmt.Errorf("%T is not a type of execution payload", p)
}
@@ -272,6 +305,28 @@ func BuildSignedBeaconBlockFromExecutionPayload(
var fullBlock interface{}
switch p := payload.(type) {
case *enginev1.ExecutionPayload:
var atts []*eth.Attestation
if b.Body().Attestations() != nil {
atts = make([]*eth.Attestation, len(b.Body().Attestations()))
for i, att := range b.Body().Attestations() {
a, ok := att.(*eth.Attestation)
if !ok {
return nil, fmt.Errorf("attestation has wrong type (expected %T, got %T)", &eth.Attestation{}, att)
}
atts[i] = a
}
}
var attSlashings []*eth.AttesterSlashing
if b.Body().AttesterSlashings() != nil {
attSlashings = make([]*eth.AttesterSlashing, len(b.Body().AttesterSlashings()))
for i, slashing := range b.Body().AttesterSlashings() {
s, ok := slashing.(*eth.AttesterSlashing)
if !ok {
return nil, fmt.Errorf("attester slashing has wrong type (expected %T, got %T)", &eth.AttesterSlashing{}, slashing)
}
attSlashings[i] = s
}
}
fullBlock = &eth.SignedBeaconBlockBellatrix{
Block: &eth.BeaconBlockBellatrix{
Slot: b.Slot(),
@@ -283,8 +338,8 @@ func BuildSignedBeaconBlockFromExecutionPayload(
Eth1Data: b.Body().Eth1Data(),
Graffiti: graffiti[:],
ProposerSlashings: b.Body().ProposerSlashings(),
AttesterSlashings: b.Body().AttesterSlashings(),
Attestations: b.Body().Attestations(),
AttesterSlashings: attSlashings,
Attestations: atts,
Deposits: b.Body().Deposits(),
VoluntaryExits: b.Body().VoluntaryExits(),
SyncAggregate: syncAgg,
@@ -298,6 +353,28 @@ func BuildSignedBeaconBlockFromExecutionPayload(
if err != nil {
return nil, err
}
var atts []*eth.Attestation
if b.Body().Attestations() != nil {
atts = make([]*eth.Attestation, len(b.Body().Attestations()))
for i, att := range b.Body().Attestations() {
a, ok := att.(*eth.Attestation)
if !ok {
return nil, fmt.Errorf("attestation has wrong type (expected %T, got %T)", &eth.Attestation{}, att)
}
atts[i] = a
}
}
var attSlashings []*eth.AttesterSlashing
if b.Body().AttesterSlashings() != nil {
attSlashings = make([]*eth.AttesterSlashing, len(b.Body().AttesterSlashings()))
for i, slashing := range b.Body().AttesterSlashings() {
s, ok := slashing.(*eth.AttesterSlashing)
if !ok {
return nil, fmt.Errorf("attester slashing has wrong type (expected %T, got %T)", &eth.AttesterSlashing{}, slashing)
}
attSlashings[i] = s
}
}
fullBlock = &eth.SignedBeaconBlockCapella{
Block: &eth.BeaconBlockCapella{
Slot: b.Slot(),
@@ -309,8 +386,8 @@ func BuildSignedBeaconBlockFromExecutionPayload(
Eth1Data: b.Body().Eth1Data(),
Graffiti: graffiti[:],
ProposerSlashings: b.Body().ProposerSlashings(),
AttesterSlashings: b.Body().AttesterSlashings(),
Attestations: b.Body().Attestations(),
AttesterSlashings: attSlashings,
Attestations: atts,
Deposits: b.Body().Deposits(),
VoluntaryExits: b.Body().VoluntaryExits(),
SyncAggregate: syncAgg,
@@ -329,6 +406,28 @@ func BuildSignedBeaconBlockFromExecutionPayload(
if err != nil {
return nil, err
}
var atts []*eth.Attestation
if b.Body().Attestations() != nil {
atts = make([]*eth.Attestation, len(b.Body().Attestations()))
for i, att := range b.Body().Attestations() {
a, ok := att.(*eth.Attestation)
if !ok {
return nil, fmt.Errorf("attestation has wrong type (expected %T, got %T)", &eth.Attestation{}, att)
}
atts[i] = a
}
}
var attSlashings []*eth.AttesterSlashing
if b.Body().AttesterSlashings() != nil {
attSlashings = make([]*eth.AttesterSlashing, len(b.Body().AttesterSlashings()))
for i, slashing := range b.Body().AttesterSlashings() {
s, ok := slashing.(*eth.AttesterSlashing)
if !ok {
return nil, fmt.Errorf("attester slashing has wrong type (expected %T, got %T)", &eth.AttesterSlashing{}, slashing)
}
attSlashings[i] = s
}
}
fullBlock = &eth.SignedBeaconBlockDeneb{
Block: &eth.BeaconBlockDeneb{
Slot: b.Slot(),
@@ -340,8 +439,8 @@ func BuildSignedBeaconBlockFromExecutionPayload(
Eth1Data: b.Body().Eth1Data(),
Graffiti: graffiti[:],
ProposerSlashings: b.Body().ProposerSlashings(),
AttesterSlashings: b.Body().AttesterSlashings(),
Attestations: b.Body().Attestations(),
AttesterSlashings: attSlashings,
Attestations: atts,
Deposits: b.Body().Deposits(),
VoluntaryExits: b.Body().VoluntaryExits(),
SyncAggregate: syncAgg,
@@ -352,6 +451,65 @@ func BuildSignedBeaconBlockFromExecutionPayload(
},
Signature: sig[:],
}
case *enginev1.ExecutionPayloadElectra:
blsToExecutionChanges, err := b.Body().BLSToExecutionChanges()
if err != nil {
return nil, err
}
commitments, err := b.Body().BlobKzgCommitments()
if err != nil {
return nil, err
}
consolidations, err := b.Body().Consolidations()
if err != nil {
return nil, err
}
var atts []*eth.AttestationElectra
if b.Body().Attestations() != nil {
atts = make([]*eth.AttestationElectra, len(b.Body().Attestations()))
for i, att := range b.Body().Attestations() {
a, ok := att.(*eth.AttestationElectra)
if !ok {
return nil, fmt.Errorf("attestation has wrong type (expected %T, got %T)", &eth.Attestation{}, att)
}
atts[i] = a
}
}
var attSlashings []*eth.AttesterSlashingElectra
if b.Body().AttesterSlashings() != nil {
attSlashings = make([]*eth.AttesterSlashingElectra, len(b.Body().AttesterSlashings()))
for i, slashing := range b.Body().AttesterSlashings() {
s, ok := slashing.(*eth.AttesterSlashingElectra)
if !ok {
return nil, fmt.Errorf("attester slashing has wrong type (expected %T, got %T)", &eth.AttesterSlashing{}, slashing)
}
attSlashings[i] = s
}
}
fullBlock = &eth.SignedBeaconBlockElectra{
Block: &eth.BeaconBlockElectra{
Slot: b.Slot(),
ProposerIndex: b.ProposerIndex(),
ParentRoot: parentRoot[:],
StateRoot: stateRoot[:],
Body: &eth.BeaconBlockBodyElectra{
RandaoReveal: randaoReveal[:],
Eth1Data: b.Body().Eth1Data(),
Graffiti: graffiti[:],
ProposerSlashings: b.Body().ProposerSlashings(),
AttesterSlashings: attSlashings,
Attestations: atts,
Deposits: b.Body().Deposits(),
VoluntaryExits: b.Body().VoluntaryExits(),
SyncAggregate: syncAgg,
ExecutionPayload: p,
BlsToExecutionChanges: blsToExecutionChanges,
BlobKzgCommitments: commitments,
Consolidations: consolidations,
},
},
Signature: sig[:],
}
default:
return nil, fmt.Errorf("%T is not a type of execution payload", p)
}

View File

@@ -81,6 +81,14 @@ func (b *SignedBeaconBlock) Copy() (interfaces.SignedBeaconBlock, error) {
}
cp := eth.CopySignedBeaconBlockDeneb(pb.(*eth.SignedBeaconBlockDeneb))
return initSignedBlockFromProtoDeneb(cp)
case version.Electra:
if b.IsBlinded() {
cp := eth.CopySignedBlindedBeaconBlockElectra(pb.(*eth.SignedBlindedBeaconBlockElectra))
return initBlindedSignedBlockFromProtoElectra(cp)
}
cp := eth.CopySignedBeaconBlockElectra(pb.(*eth.SignedBeaconBlockElectra))
return initSignedBlockFromProtoElectra(cp)
default:
return nil, errIncorrectBlockVersion
}
@@ -128,6 +136,15 @@ func (b *SignedBeaconBlock) PbGenericBlock() (*eth.GenericSignedBeaconBlock, err
return &eth.GenericSignedBeaconBlock{
Block: &eth.GenericSignedBeaconBlock_Deneb{Deneb: pb.(*eth.SignedBeaconBlockContentsDeneb)},
}, nil
case version.Electra:
if b.IsBlinded() {
return &eth.GenericSignedBeaconBlock{
Block: &eth.GenericSignedBeaconBlock_BlindedElectra{BlindedElectra: pb.(*eth.SignedBlindedBeaconBlockElectra)},
}, nil
}
return &eth.GenericSignedBeaconBlock{
Block: &eth.GenericSignedBeaconBlock_Electra{Electra: pb.(*eth.SignedBeaconBlockContentsElectra)},
}, nil
default:
return nil, errIncorrectBlockVersion
}
@@ -330,6 +347,37 @@ func (b *SignedBeaconBlock) ToBlinded() (interfaces.ReadOnlySignedBeaconBlock, e
},
Signature: b.signature[:],
})
case *enginev1.ExecutionPayloadElectra:
header, err := PayloadToHeaderElectra(payload)
if err != nil {
return nil, err
}
return initBlindedSignedBlockFromProtoElectra(
&eth.SignedBlindedBeaconBlockElectra{
Message: &eth.BlindedBeaconBlockElectra{
Slot: b.block.slot,
ProposerIndex: b.block.proposerIndex,
ParentRoot: b.block.parentRoot[:],
StateRoot: b.block.stateRoot[:],
Body: &eth.BlindedBeaconBlockBodyElectra{
RandaoReveal: b.block.body.randaoReveal[:],
Eth1Data: b.block.body.eth1Data,
Graffiti: b.block.body.graffiti[:],
ProposerSlashings: b.block.body.proposerSlashings,
AttesterSlashings: b.block.body.attesterSlashingsElectra,
Attestations: b.block.body.attestationsElectra,
Deposits: b.block.body.deposits,
VoluntaryExits: b.block.body.voluntaryExits,
SyncAggregate: b.block.body.syncAggregate,
ExecutionPayloadHeader: header,
BlsToExecutionChanges: b.block.body.blsToExecutionChanges,
BlobKzgCommitments: b.block.body.blobKzgCommitments,
Consolidations: b.block.body.signedConsolidations,
},
},
Signature: b.signature[:],
})
default:
return nil, fmt.Errorf("%T is not an execution payload header", p)
}
@@ -459,6 +507,11 @@ func (b *SignedBeaconBlock) MarshalSSZ() ([]byte, error) {
return pb.(*eth.SignedBlindedBeaconBlockDeneb).MarshalSSZ()
}
return pb.(*eth.SignedBeaconBlockDeneb).MarshalSSZ()
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.SignedBlindedBeaconBlockElectra).MarshalSSZ()
}
return pb.(*eth.SignedBeaconBlockElectra).MarshalSSZ()
default:
return []byte{}, errIncorrectBlockVersion
}
@@ -491,6 +544,11 @@ func (b *SignedBeaconBlock) MarshalSSZTo(dst []byte) ([]byte, error) {
return pb.(*eth.SignedBlindedBeaconBlockDeneb).MarshalSSZTo(dst)
}
return pb.(*eth.SignedBeaconBlockDeneb).MarshalSSZTo(dst)
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.SignedBlindedBeaconBlockElectra).MarshalSSZTo(dst)
}
return pb.(*eth.SignedBeaconBlockElectra).MarshalSSZTo(dst)
default:
return []byte{}, errIncorrectBlockVersion
}
@@ -527,6 +585,11 @@ func (b *SignedBeaconBlock) SizeSSZ() int {
return pb.(*eth.SignedBlindedBeaconBlockDeneb).SizeSSZ()
}
return pb.(*eth.SignedBeaconBlockDeneb).SizeSSZ()
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.SignedBlindedBeaconBlockElectra).SizeSSZ()
}
return pb.(*eth.SignedBeaconBlockElectra).SizeSSZ()
default:
panic(incorrectBlockVersion)
}
@@ -622,6 +685,28 @@ func (b *SignedBeaconBlock) UnmarshalSSZ(buf []byte) error {
return err
}
}
case version.Electra:
if b.IsBlinded() {
pb := &eth.SignedBlindedBeaconBlockElectra{}
if err := pb.UnmarshalSSZ(buf); err != nil {
return err
}
var err error
newBlock, err = initBlindedSignedBlockFromProtoElectra(pb)
if err != nil {
return err
}
} else {
pb := &eth.SignedBeaconBlockElectra{}
if err := pb.UnmarshalSSZ(buf); err != nil {
return err
}
var err error
newBlock, err = initSignedBlockFromProtoElectra(pb)
if err != nil {
return err
}
}
default:
return errIncorrectBlockVersion
}
@@ -695,6 +780,11 @@ func (b *BeaconBlock) HashTreeRoot() ([field_params.RootLength]byte, error) {
return pb.(*eth.BlindedBeaconBlockDeneb).HashTreeRoot()
}
return pb.(*eth.BeaconBlockDeneb).HashTreeRoot()
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.BlindedBeaconBlockElectra).HashTreeRoot()
}
return pb.(*eth.BeaconBlockElectra).HashTreeRoot()
default:
return [field_params.RootLength]byte{}, errIncorrectBlockVersion
}
@@ -726,6 +816,11 @@ func (b *BeaconBlock) HashTreeRootWith(h *ssz.Hasher) error {
return pb.(*eth.BlindedBeaconBlockDeneb).HashTreeRootWith(h)
}
return pb.(*eth.BeaconBlockDeneb).HashTreeRootWith(h)
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.BlindedBeaconBlockElectra).HashTreeRootWith(h)
}
return pb.(*eth.BeaconBlockElectra).HashTreeRootWith(h)
default:
return errIncorrectBlockVersion
}
@@ -758,6 +853,11 @@ func (b *BeaconBlock) MarshalSSZ() ([]byte, error) {
return pb.(*eth.BlindedBeaconBlockDeneb).MarshalSSZ()
}
return pb.(*eth.BeaconBlockDeneb).MarshalSSZ()
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.BlindedBeaconBlockElectra).MarshalSSZ()
}
return pb.(*eth.BeaconBlockElectra).MarshalSSZ()
default:
return []byte{}, errIncorrectBlockVersion
}
@@ -790,6 +890,11 @@ func (b *BeaconBlock) MarshalSSZTo(dst []byte) ([]byte, error) {
return pb.(*eth.BlindedBeaconBlockDeneb).MarshalSSZTo(dst)
}
return pb.(*eth.BeaconBlockDeneb).MarshalSSZTo(dst)
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.BlindedBeaconBlockElectra).MarshalSSZTo(dst)
}
return pb.(*eth.BeaconBlockElectra).MarshalSSZTo(dst)
default:
return []byte{}, errIncorrectBlockVersion
}
@@ -826,6 +931,11 @@ func (b *BeaconBlock) SizeSSZ() int {
return pb.(*eth.BlindedBeaconBlockDeneb).SizeSSZ()
}
return pb.(*eth.BeaconBlockDeneb).SizeSSZ()
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.BlindedBeaconBlockElectra).SizeSSZ()
}
return pb.(*eth.BeaconBlockElectra).SizeSSZ()
default:
panic(incorrectBodyVersion)
}
@@ -921,6 +1031,28 @@ func (b *BeaconBlock) UnmarshalSSZ(buf []byte) error {
return err
}
}
case version.Electra:
if b.IsBlinded() {
pb := &eth.BlindedBeaconBlockElectra{}
if err := pb.UnmarshalSSZ(buf); err != nil {
return err
}
var err error
newBlock, err = initBlindedBlockFromProtoElectra(pb)
if err != nil {
return err
}
} else {
pb := &eth.BeaconBlockElectra{}
if err := pb.UnmarshalSSZ(buf); err != nil {
return err
}
var err error
newBlock, err = initBlockFromProtoElectra(pb)
if err != nil {
return err
}
}
default:
return errIncorrectBlockVersion
}
@@ -954,6 +1086,11 @@ func (b *BeaconBlock) AsSignRequestObject() (validatorpb.SignRequestObject, erro
return &validatorpb.SignRequest_BlindedBlockDeneb{BlindedBlockDeneb: pb.(*eth.BlindedBeaconBlockDeneb)}, nil
}
return &validatorpb.SignRequest_BlockDeneb{BlockDeneb: pb.(*eth.BeaconBlockDeneb)}, nil
case version.Electra:
if b.IsBlinded() {
return &validatorpb.SignRequest_BlindedBlockElectra{BlindedBlockElectra: pb.(*eth.BlindedBeaconBlockElectra)}, nil
}
return &validatorpb.SignRequest_BlockElectra{BlockElectra: pb.(*eth.BeaconBlockElectra)}, nil
default:
return nil, errIncorrectBlockVersion
}
@@ -996,6 +1133,13 @@ func (b *BeaconBlock) Copy() (interfaces.ReadOnlyBeaconBlock, error) {
}
cp := eth.CopyBeaconBlockDeneb(pb.(*eth.BeaconBlockDeneb))
return initBlockFromProtoDeneb(cp)
case version.Electra:
if b.IsBlinded() {
cp := eth.CopyBlindedBeaconBlockElectra(pb.(*eth.BlindedBeaconBlockElectra))
return initBlindedBlockFromProtoElectra(cp)
}
cp := eth.CopyBeaconBlockElectra(pb.(*eth.BeaconBlockElectra))
return initBlockFromProtoElectra(cp)
default:
return nil, errIncorrectBlockVersion
}
@@ -1027,13 +1171,49 @@ func (b *BeaconBlockBody) ProposerSlashings() []*eth.ProposerSlashing {
}
// AttesterSlashings returns the attester slashings in the block.
func (b *BeaconBlockBody) AttesterSlashings() []*eth.AttesterSlashing {
return b.attesterSlashings
func (b *BeaconBlockBody) AttesterSlashings() []interfaces.AttesterSlashing {
var slashings []interfaces.AttesterSlashing
if b.version < version.Electra {
if b.attesterSlashings == nil {
return nil
}
slashings = make([]interfaces.AttesterSlashing, len(b.attesterSlashings))
for i, s := range b.attesterSlashings {
slashings[i] = s
}
} else {
if b.attesterSlashingsElectra == nil {
return nil
}
slashings = make([]interfaces.AttesterSlashing, len(b.attesterSlashingsElectra))
for i, s := range b.attesterSlashingsElectra {
slashings[i] = s
}
}
return slashings
}
// Attestations returns the stored attestations in the block.
func (b *BeaconBlockBody) Attestations() []*eth.Attestation {
return b.attestations
func (b *BeaconBlockBody) Attestations() []interfaces.Attestation {
var atts []interfaces.Attestation
if b.version < version.Electra {
if b.attestations == nil {
return nil
}
atts = make([]interfaces.Attestation, len(b.attestations))
for i, a := range b.attestations {
atts[i] = a
}
} else {
if b.attestationsElectra == nil {
return nil
}
atts = make([]interfaces.Attestation, len(b.attestationsElectra))
for i, a := range b.attestations {
atts[i] = a
}
}
return atts
}
// Deposits returns the stored deposits in the block.
@@ -1079,13 +1259,20 @@ func (b *BeaconBlockBody) BlobKzgCommitments() ([][]byte, error) {
switch b.version {
case version.Phase0, version.Altair, version.Bellatrix, version.Capella:
return nil, consensus_types.ErrNotSupported("BlobKzgCommitments", b.version)
case version.Deneb:
case version.Deneb, version.Electra:
return b.blobKzgCommitments, nil
default:
return nil, errIncorrectBlockVersion
}
}
func (b *BeaconBlockBody) Consolidations() ([]*eth.SignedConsolidation, error) {
if b.version < version.Electra {
return nil, consensus_types.ErrNotSupported("Consolidations", b.version)
}
return b.signedConsolidations, nil
}
// Version returns the version of the beacon block body
func (b *BeaconBlockBody) Version() int {
return b.version
@@ -1117,6 +1304,11 @@ func (b *BeaconBlockBody) HashTreeRoot() ([field_params.RootLength]byte, error)
return pb.(*eth.BlindedBeaconBlockBodyDeneb).HashTreeRoot()
}
return pb.(*eth.BeaconBlockBodyDeneb).HashTreeRoot()
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.BlindedBeaconBlockBodyElectra).HashTreeRoot()
}
return pb.(*eth.BeaconBlockBodyElectra).HashTreeRoot()
default:
return [field_params.RootLength]byte{}, errIncorrectBodyVersion
}

View File

@@ -356,16 +356,16 @@ func Test_BeaconBlockBody_ProposerSlashings(t *testing.T) {
}
func Test_BeaconBlockBody_AttesterSlashings(t *testing.T) {
as := make([]*eth.AttesterSlashing, 0)
as := make([]interfaces.AttesterSlashing, 0)
bb := &SignedBeaconBlock{block: &BeaconBlock{body: &BeaconBlockBody{}}}
bb.SetAttesterSlashings(as)
require.NoError(t, bb.SetAttesterSlashings(as))
assert.DeepSSZEqual(t, as, bb.Block().Body().AttesterSlashings())
}
func Test_BeaconBlockBody_Attestations(t *testing.T) {
a := make([]*eth.Attestation, 0)
a := make([]interfaces.Attestation, 0)
bb := &SignedBeaconBlock{block: &BeaconBlock{body: &BeaconBlockBody{}}}
bb.SetAttestations(a)
require.NoError(t, bb.SetAttestations(a))
assert.DeepSSZEqual(t, a, bb.Block().Body().Attestations())
}

View File

@@ -13,7 +13,7 @@ import (
)
// Proto converts the signed beacon block to a protobuf object.
func (b *SignedBeaconBlock) Proto() (proto.Message, error) {
func (b *SignedBeaconBlock) Proto() (proto.Message, error) { // nolint:gocognit
if b == nil {
return nil, errNilBlock
}
@@ -131,13 +131,40 @@ func (b *SignedBeaconBlock) Proto() (proto.Message, error) {
Block: block,
Signature: b.signature[:],
}, nil
case version.Electra:
if b.IsBlinded() {
var block *eth.BlindedBeaconBlockElectra
if blockMessage != nil {
var ok bool
block, ok = blockMessage.(*eth.BlindedBeaconBlockElectra)
if !ok {
return nil, errIncorrectBlockVersion
}
}
return &eth.SignedBlindedBeaconBlockElectra{
Message: block,
Signature: b.signature[:],
}, nil
}
var block *eth.BeaconBlockElectra
if blockMessage != nil {
var ok bool
block, ok = blockMessage.(*eth.BeaconBlockElectra)
if !ok {
return nil, errIncorrectBlockVersion
}
}
return &eth.SignedBeaconBlockElectra{
Block: block,
Signature: b.signature[:],
}, nil
default:
return nil, errors.New("unsupported signed beacon block version")
}
}
// Proto converts the beacon block to a protobuf object.
func (b *BeaconBlock) Proto() (proto.Message, error) {
func (b *BeaconBlock) Proto() (proto.Message, error) { // nolint:gocognit
if b == nil {
return nil, nil
}
@@ -279,6 +306,40 @@ func (b *BeaconBlock) Proto() (proto.Message, error) {
StateRoot: b.stateRoot[:],
Body: body,
}, nil
case version.Electra:
if b.IsBlinded() {
var body *eth.BlindedBeaconBlockBodyElectra
if bodyMessage != nil {
var ok bool
body, ok = bodyMessage.(*eth.BlindedBeaconBlockBodyElectra)
if !ok {
return nil, errIncorrectBodyVersion
}
}
return &eth.BlindedBeaconBlockElectra{
Slot: b.slot,
ProposerIndex: b.proposerIndex,
ParentRoot: b.parentRoot[:],
StateRoot: b.stateRoot[:],
Body: body,
}, nil
}
var body *eth.BeaconBlockBodyElectra
if bodyMessage != nil {
var ok bool
body, ok = bodyMessage.(*eth.BeaconBlockBodyElectra)
if !ok {
return nil, errIncorrectBodyVersion
}
}
return &eth.BeaconBlockElectra{
Slot: b.slot,
ProposerIndex: b.proposerIndex,
ParentRoot: b.parentRoot[:],
StateRoot: b.stateRoot[:],
Body: body,
}, nil
default:
return nil, errors.New("unsupported beacon block version")
}
@@ -449,6 +510,56 @@ func (b *BeaconBlockBody) Proto() (proto.Message, error) {
BlsToExecutionChanges: b.blsToExecutionChanges,
BlobKzgCommitments: b.blobKzgCommitments,
}, nil
case version.Electra:
if b.IsBlinded() {
var ph *enginev1.ExecutionPayloadHeaderElectra
var ok bool
if b.executionPayloadHeader != nil {
ph, ok = b.executionPayloadHeader.Proto().(*enginev1.ExecutionPayloadHeaderElectra)
if !ok {
return nil, errPayloadHeaderWrongType
}
}
return &eth.BlindedBeaconBlockBodyElectra{
RandaoReveal: b.randaoReveal[:],
Eth1Data: b.eth1Data,
Graffiti: b.graffiti[:],
ProposerSlashings: b.proposerSlashings,
AttesterSlashings: b.attesterSlashingsElectra,
Attestations: b.attestationsElectra,
Deposits: b.deposits,
VoluntaryExits: b.voluntaryExits,
SyncAggregate: b.syncAggregate,
ExecutionPayloadHeader: ph,
BlsToExecutionChanges: b.blsToExecutionChanges,
BlobKzgCommitments: b.blobKzgCommitments,
Consolidations: b.signedConsolidations,
}, nil
}
var p *enginev1.ExecutionPayloadElectra
var ok bool
if b.executionPayload != nil {
p, ok = b.executionPayload.Proto().(*enginev1.ExecutionPayloadElectra)
if !ok {
return nil, errPayloadWrongType
}
}
return &eth.BeaconBlockBodyElectra{
RandaoReveal: b.randaoReveal[:],
Eth1Data: b.eth1Data,
Graffiti: b.graffiti[:],
ProposerSlashings: b.proposerSlashings,
AttesterSlashings: b.attesterSlashingsElectra,
Attestations: b.attestationsElectra,
Deposits: b.deposits,
VoluntaryExits: b.voluntaryExits,
SyncAggregate: b.syncAggregate,
ExecutionPayload: p,
BlsToExecutionChanges: b.blsToExecutionChanges,
BlobKzgCommitments: b.blobKzgCommitments,
Consolidations: b.signedConsolidations,
}, nil
default:
return nil, errors.New("unsupported beacon block body version")
}
@@ -539,6 +650,23 @@ func initSignedBlockFromProtoDeneb(pb *eth.SignedBeaconBlockDeneb) (*SignedBeaco
return b, nil
}
func initSignedBlockFromProtoElectra(pb *eth.SignedBeaconBlockElectra) (*SignedBeaconBlock, error) {
if pb == nil {
return nil, errNilBlock
}
block, err := initBlockFromProtoElectra(pb.Block)
if err != nil {
return nil, err
}
b := &SignedBeaconBlock{
version: version.Electra,
block: block,
signature: bytesutil.ToBytes96(pb.Signature),
}
return b, nil
}
func initBlindedSignedBlockFromProtoBellatrix(pb *eth.SignedBlindedBeaconBlockBellatrix) (*SignedBeaconBlock, error) {
if pb == nil {
return nil, errNilBlock
@@ -590,6 +718,23 @@ func initBlindedSignedBlockFromProtoDeneb(pb *eth.SignedBlindedBeaconBlockDeneb)
return b, nil
}
func initBlindedSignedBlockFromProtoElectra(pb *eth.SignedBlindedBeaconBlockElectra) (*SignedBeaconBlock, error) {
if pb == nil {
return nil, errNilBlock
}
block, err := initBlindedBlockFromProtoElectra(pb.Message)
if err != nil {
return nil, err
}
b := &SignedBeaconBlock{
version: version.Electra,
block: block,
signature: bytesutil.ToBytes96(pb.Signature),
}
return b, nil
}
func initBlockFromProtoPhase0(pb *eth.BeaconBlock) (*BeaconBlock, error) {
if pb == nil {
return nil, errNilBlock
@@ -710,6 +855,26 @@ func initBlockFromProtoDeneb(pb *eth.BeaconBlockDeneb) (*BeaconBlock, error) {
return b, nil
}
func initBlockFromProtoElectra(pb *eth.BeaconBlockElectra) (*BeaconBlock, error) {
if pb == nil {
return nil, errNilBlock
}
body, err := initBlockBodyFromProtoElectra(pb.Body)
if err != nil {
return nil, err
}
b := &BeaconBlock{
version: version.Electra,
slot: pb.Slot,
proposerIndex: pb.ProposerIndex,
parentRoot: bytesutil.ToBytes32(pb.ParentRoot),
stateRoot: bytesutil.ToBytes32(pb.StateRoot),
body: body,
}
return b, nil
}
func initBlindedBlockFromProtoCapella(pb *eth.BlindedBeaconBlockCapella) (*BeaconBlock, error) {
if pb == nil {
return nil, errNilBlock
@@ -750,6 +915,26 @@ func initBlindedBlockFromProtoDeneb(pb *eth.BlindedBeaconBlockDeneb) (*BeaconBlo
return b, nil
}
func initBlindedBlockFromProtoElectra(pb *eth.BlindedBeaconBlockElectra) (*BeaconBlock, error) {
if pb == nil {
return nil, errNilBlock
}
body, err := initBlindedBlockBodyFromProtoElectra(pb.Body)
if err != nil {
return nil, err
}
b := &BeaconBlock{
version: version.Electra,
slot: pb.Slot,
proposerIndex: pb.ProposerIndex,
parentRoot: bytesutil.ToBytes32(pb.ParentRoot),
stateRoot: bytesutil.ToBytes32(pb.StateRoot),
body: body,
}
return b, nil
}
func initBlockBodyFromProtoPhase0(pb *eth.BeaconBlockBody) (*BeaconBlockBody, error) {
if pb == nil {
return nil, errNilBlockBody
@@ -950,3 +1135,61 @@ func initBlindedBlockBodyFromProtoDeneb(pb *eth.BlindedBeaconBlockBodyDeneb) (*B
}
return b, nil
}
func initBlockBodyFromProtoElectra(pb *eth.BeaconBlockBodyElectra) (*BeaconBlockBody, error) {
if pb == nil {
return nil, errNilBlockBody
}
p, err := WrappedExecutionPayloadElectra(pb.ExecutionPayload, big.NewInt(0))
// We allow the payload to be nil
if err != nil && err != consensus_types.ErrNilObjectWrapped {
return nil, err
}
b := &BeaconBlockBody{
version: version.Electra,
randaoReveal: bytesutil.ToBytes96(pb.RandaoReveal),
eth1Data: pb.Eth1Data,
graffiti: bytesutil.ToBytes32(pb.Graffiti),
proposerSlashings: pb.ProposerSlashings,
attesterSlashingsElectra: pb.AttesterSlashings,
attestationsElectra: pb.Attestations,
deposits: pb.Deposits,
voluntaryExits: pb.VoluntaryExits,
syncAggregate: pb.SyncAggregate,
executionPayload: p,
blsToExecutionChanges: pb.BlsToExecutionChanges,
blobKzgCommitments: pb.BlobKzgCommitments,
signedConsolidations: pb.Consolidations,
}
return b, nil
}
func initBlindedBlockBodyFromProtoElectra(pb *eth.BlindedBeaconBlockBodyElectra) (*BeaconBlockBody, error) {
if pb == nil {
return nil, errNilBlockBody
}
ph, err := WrappedExecutionPayloadHeaderElectra(pb.ExecutionPayloadHeader, big.NewInt(0))
// We allow the payload to be nil
if err != nil && err != consensus_types.ErrNilObjectWrapped {
return nil, err
}
b := &BeaconBlockBody{
version: version.Electra,
randaoReveal: bytesutil.ToBytes96(pb.RandaoReveal),
eth1Data: pb.Eth1Data,
graffiti: bytesutil.ToBytes32(pb.Graffiti),
proposerSlashings: pb.ProposerSlashings,
attesterSlashingsElectra: pb.AttesterSlashings,
attestationsElectra: pb.Attestations,
deposits: pb.Deposits,
voluntaryExits: pb.VoluntaryExits,
syncAggregate: pb.SyncAggregate,
executionPayloadHeader: ph,
blsToExecutionChanges: pb.BlsToExecutionChanges,
blobKzgCommitments: pb.BlobKzgCommitments,
signedConsolidations: pb.Consolidations,
}
return b, nil
}

View File

@@ -1,6 +1,8 @@
package blocks
import (
"fmt"
consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types"
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
@@ -64,14 +66,56 @@ func (b *SignedBeaconBlock) SetProposerSlashings(p []*eth.ProposerSlashing) {
// SetAttesterSlashings sets the attester slashings in the block.
// This function is not thread safe, it is only used during block creation.
func (b *SignedBeaconBlock) SetAttesterSlashings(a []*eth.AttesterSlashing) {
b.block.body.attesterSlashings = a
func (b *SignedBeaconBlock) SetAttesterSlashings(slashings []interfaces.AttesterSlashing) error {
if b.version < version.Electra {
blockSlashings := make([]*eth.AttesterSlashing, 0, len(slashings))
for _, slashing := range slashings {
s, ok := slashing.(*eth.AttesterSlashing)
if !ok {
return fmt.Errorf("slashing of type %T is not *eth.AttesterSlashing", slashing)
}
blockSlashings = append(blockSlashings, s)
}
b.block.body.attesterSlashings = blockSlashings
} else {
blockSlashings := make([]*eth.AttesterSlashingElectra, 0, len(slashings))
for _, slashing := range slashings {
s, ok := slashing.(*eth.AttesterSlashingElectra)
if !ok {
return fmt.Errorf("slashing of type %T is not *eth.AttesterSlashingElectra", slashing)
}
blockSlashings = append(blockSlashings, s)
}
b.block.body.attesterSlashingsElectra = blockSlashings
}
return nil
}
// SetAttestations sets the attestations in the block.
// This function is not thread safe, it is only used during block creation.
func (b *SignedBeaconBlock) SetAttestations(a []*eth.Attestation) {
b.block.body.attestations = a
func (b *SignedBeaconBlock) SetAttestations(atts []interfaces.Attestation) error {
if b.version < version.Electra {
blockAtts := make([]*eth.Attestation, 0, len(atts))
for _, att := range atts {
a, ok := att.(*eth.Attestation)
if !ok {
return fmt.Errorf("attestation of type %T is not *eth.Attestation", att)
}
blockAtts = append(blockAtts, a)
}
b.block.body.attestations = blockAtts
} else {
blockAtts := make([]*eth.AttestationElectra, 0, len(atts))
for _, att := range atts {
a, ok := att.(*eth.AttestationElectra)
if !ok {
return fmt.Errorf("attestation of type %T is not *eth.AttestationElectra", att)
}
blockAtts = append(blockAtts, a)
}
b.block.body.attestationsElectra = blockAtts
}
return nil
}
// SetDeposits sets the deposits in the block.
@@ -122,13 +166,9 @@ func (b *SignedBeaconBlock) SetBLSToExecutionChanges(blsToExecutionChanges []*et
// SetBlobKzgCommitments sets the blob kzg commitments in the block.
func (b *SignedBeaconBlock) SetBlobKzgCommitments(c [][]byte) error {
switch b.version {
case version.Phase0, version.Altair, version.Bellatrix, version.Capella:
if b.version < version.Deneb {
return consensus_types.ErrNotSupported("SetBlobKzgCommitments", b.version)
case version.Deneb:
b.block.body.blobKzgCommitments = c
return nil
default:
return errIncorrectBlockVersion
}
b.block.body.blobKzgCommitments = c
return nil
}

View File

@@ -38,20 +38,23 @@ var (
// BeaconBlockBody is the main beacon block body structure. It can represent any block type.
type BeaconBlockBody struct {
version int
randaoReveal [field_params.BLSSignatureLength]byte
eth1Data *eth.Eth1Data
graffiti [field_params.RootLength]byte
proposerSlashings []*eth.ProposerSlashing
attesterSlashings []*eth.AttesterSlashing
attestations []*eth.Attestation
deposits []*eth.Deposit
voluntaryExits []*eth.SignedVoluntaryExit
syncAggregate *eth.SyncAggregate
executionPayload interfaces.ExecutionData
executionPayloadHeader interfaces.ExecutionData
blsToExecutionChanges []*eth.SignedBLSToExecutionChange
blobKzgCommitments [][]byte
version int
randaoReveal [field_params.BLSSignatureLength]byte
eth1Data *eth.Eth1Data
graffiti [field_params.RootLength]byte
proposerSlashings []*eth.ProposerSlashing
attesterSlashings []*eth.AttesterSlashing
attesterSlashingsElectra []*eth.AttesterSlashingElectra
attestations []*eth.Attestation
attestationsElectra []*eth.AttestationElectra
deposits []*eth.Deposit
voluntaryExits []*eth.SignedVoluntaryExit
syncAggregate *eth.SyncAggregate
executionPayload interfaces.ExecutionData
executionPayloadHeader interfaces.ExecutionData
blsToExecutionChanges []*eth.SignedBLSToExecutionChange
blobKzgCommitments [][]byte
signedConsolidations []*eth.SignedConsolidation
}
// BeaconBlock is the main beacon block structure. It can represent any block type.

View File

@@ -17,6 +17,7 @@ go_library(
"//proto/prysm/v1alpha1/validator-client:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_fastssz//:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
],
)

View File

@@ -2,6 +2,7 @@ package interfaces
import (
ssz "github.com/prysmaticlabs/fastssz"
"github.com/prysmaticlabs/go-bitfield"
field_params "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/math"
@@ -66,8 +67,8 @@ type ReadOnlyBeaconBlockBody interface {
Eth1Data() *ethpb.Eth1Data
Graffiti() [field_params.RootLength]byte
ProposerSlashings() []*ethpb.ProposerSlashing
AttesterSlashings() []*ethpb.AttesterSlashing
Attestations() []*ethpb.Attestation
AttesterSlashings() []AttesterSlashing
Attestations() []Attestation
Deposits() []*ethpb.Deposit
VoluntaryExits() []*ethpb.SignedVoluntaryExit
SyncAggregate() (*ethpb.SyncAggregate, error)
@@ -77,6 +78,7 @@ type ReadOnlyBeaconBlockBody interface {
Execution() (ExecutionData, error)
BLSToExecutionChanges() ([]*ethpb.SignedBLSToExecutionChange, error)
BlobKzgCommitments() ([][]byte, error)
Consolidations() ([]*ethpb.SignedConsolidation, error)
}
type SignedBeaconBlock interface {
@@ -87,8 +89,8 @@ type SignedBeaconBlock interface {
SetSyncAggregate(*ethpb.SyncAggregate) error
SetVoluntaryExits([]*ethpb.SignedVoluntaryExit)
SetDeposits([]*ethpb.Deposit)
SetAttestations([]*ethpb.Attestation)
SetAttesterSlashings([]*ethpb.AttesterSlashing)
SetAttestations([]Attestation) error
SetAttesterSlashings([]AttesterSlashing) error
SetProposerSlashings([]*ethpb.ProposerSlashing)
SetGraffiti([]byte)
SetEth1Data(*ethpb.Eth1Data)
@@ -132,6 +134,45 @@ type ExecutionData interface {
PbCapella() (*enginev1.ExecutionPayloadCapella, error)
PbBellatrix() (*enginev1.ExecutionPayload, error)
PbDeneb() (*enginev1.ExecutionPayloadDeneb, error)
PbElectra() (*enginev1.ExecutionPayloadElectra, error)
ValueInWei() (math.Wei, error)
ValueInGwei() (uint64, error)
DepositReceipts() ([]*enginev1.DepositReceipt, error)
WithdrawalRequests() ([]*enginev1.ExecutionLayerWithdrawalRequest, error)
}
type Attestation interface {
proto.Message
ssz.Marshaler
ssz.Unmarshaler
ssz.HashRoot
Version() int
GetAggregationBits() bitfield.Bitlist
GetData() *ethpb.AttestationData
GetCommitteeBitsVal() bitfield.Bitfield
GetSignature() []byte
}
type AttesterSlashing interface {
proto.Message
ssz.Marshaler
ssz.Unmarshaler
ssz.HashRoot
Version() int
GetFirstAttestation() ethpb.IndexedAtt
GetSecondAttestation() ethpb.IndexedAtt
}
// TODO: this is ugly. The proper way to do this is to create a Copy() function on the interface and implement it. But this results in a circular dependency.
// CopyAttestation copies the provided attestation object.
func CopyAttestation(att Attestation) Attestation {
a, ok := att.(*ethpb.Attestation)
if ok {
return ethpb.CopyAttestation(a)
}
ae, ok := att.(*ethpb.AttestationElectra)
if ok {
return ethpb.CopyAttestationElectra(ae)
}
return nil
}

View File

@@ -224,7 +224,7 @@ func (BeaconBlockBody) ProposerSlashings() []*eth.ProposerSlashing {
panic("implement me")
}
func (BeaconBlockBody) AttesterSlashings() []*eth.AttesterSlashing {
func (BeaconBlockBody) AttesterSlashings() []interfaces.AttesterSlashing {
panic("implement me")
}
@@ -280,7 +280,7 @@ func (b *BeaconBlockBody) SetProposerSlashings([]*eth.ProposerSlashing) {
panic("implement me")
}
func (b *BeaconBlockBody) SetAttesterSlashings([]*eth.AttesterSlashing) {
func (b *BeaconBlockBody) SetAttesterSlashings([]interfaces.AttesterSlashing) {
panic("implement me")
}
@@ -313,7 +313,11 @@ func (b *BeaconBlockBody) BlobKzgCommitments() ([][]byte, error) {
panic("implement me")
}
func (b *BeaconBlockBody) Attestations() []*eth.Attestation {
func (b *BeaconBlockBody) Attestations() []interfaces.Attestation {
panic("implement me")
}
func (b *BeaconBlockBody) Consolidations() ([]*eth.SignedConsolidation, error) {
panic("implement me")
}