From 8345c271cc13dcd87f8e9fa7041de145db8c6831 Mon Sep 17 00:00:00 2001 From: james-prysm <90280386+james-prysm@users.noreply.github.com> Date: Fri, 21 Feb 2025 10:12:01 -0600 Subject: [PATCH] Code Cleanup: payload conversions and fixing gocognit ignores (#14953) * created new converstions_execution files moving the from and to consensus functions for execution related items, also created a placeholder for block_execution with the intent of adding execution types there * moving execution types from block.go to block_execution.go * migrating more types and logic * adding all the to consensus functions for payloads * changelog * linting * updating unit tests for conversions * fixing linting * forgot to fix test * updating name based on feedback --- api/server/structs/BUILD.bazel | 10 +- api/server/structs/block.go | 118 -- api/server/structs/block_execution.go | 157 +++ api/server/structs/conversions.go | 120 -- api/server/structs/conversions_block.go | 1003 +---------------- .../structs/conversions_block_execution.go | 973 ++++++++++++++++ .../conversions_block_execution_test.go | 563 +++++++++ api/server/structs/other.go | 20 - ...james-prysm_cleanup-payload-conversions.md | 7 + 9 files changed, 1761 insertions(+), 1210 deletions(-) create mode 100644 api/server/structs/block_execution.go create mode 100644 api/server/structs/conversions_block_execution.go create mode 100644 api/server/structs/conversions_block_execution_test.go create mode 100644 changelog/james-prysm_cleanup-payload-conversions.md diff --git a/api/server/structs/BUILD.bazel b/api/server/structs/BUILD.bazel index 1651247213..a0decbcaab 100644 --- a/api/server/structs/BUILD.bazel +++ b/api/server/structs/BUILD.bazel @@ -4,9 +4,11 @@ go_library( name = "go_default_library", srcs = [ "block.go", + "block_execution.go", "conversions.go", "conversions_blob.go", "conversions_block.go", + "conversions_block_execution.go", "conversions_lightclient.go", "conversions_state.go", "endpoints_beacon.go", @@ -47,10 +49,16 @@ go_library( go_test( name = "go_default_test", - srcs = ["conversions_test.go"], + srcs = [ + "conversions_block_execution_test.go", + "conversions_test.go", + ], embed = [":go_default_library"], deps = [ + "//proto/engine/v1:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//testing/require:go_default_library", + "@com_github_ethereum_go_ethereum//common:go_default_library", + "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", ], ) diff --git a/api/server/structs/block.go b/api/server/structs/block.go index e4586a3ef8..cb25e484c7 100644 --- a/api/server/structs/block.go +++ b/api/server/structs/block.go @@ -186,40 +186,6 @@ type BlindedBeaconBlockBodyBellatrix struct { ExecutionPayloadHeader *ExecutionPayloadHeader `json:"execution_payload_header"` } -type ExecutionPayload struct { - ParentHash string `json:"parent_hash"` - FeeRecipient string `json:"fee_recipient"` - StateRoot string `json:"state_root"` - ReceiptsRoot string `json:"receipts_root"` - LogsBloom string `json:"logs_bloom"` - PrevRandao string `json:"prev_randao"` - BlockNumber string `json:"block_number"` - GasLimit string `json:"gas_limit"` - GasUsed string `json:"gas_used"` - Timestamp string `json:"timestamp"` - ExtraData string `json:"extra_data"` - BaseFeePerGas string `json:"base_fee_per_gas"` - BlockHash string `json:"block_hash"` - Transactions []string `json:"transactions"` -} - -type ExecutionPayloadHeader struct { - ParentHash string `json:"parent_hash"` - FeeRecipient string `json:"fee_recipient"` - StateRoot string `json:"state_root"` - ReceiptsRoot string `json:"receipts_root"` - LogsBloom string `json:"logs_bloom"` - PrevRandao string `json:"prev_randao"` - BlockNumber string `json:"block_number"` - GasLimit string `json:"gas_limit"` - GasUsed string `json:"gas_used"` - Timestamp string `json:"timestamp"` - ExtraData string `json:"extra_data"` - BaseFeePerGas string `json:"base_fee_per_gas"` - BlockHash string `json:"block_hash"` - TransactionsRoot string `json:"transactions_root"` -} - // ---------------------------------------------------------------------------- // Capella // ---------------------------------------------------------------------------- @@ -298,42 +264,6 @@ type BlindedBeaconBlockBodyCapella struct { BLSToExecutionChanges []*SignedBLSToExecutionChange `json:"bls_to_execution_changes"` } -type ExecutionPayloadCapella struct { - ParentHash string `json:"parent_hash"` - FeeRecipient string `json:"fee_recipient"` - StateRoot string `json:"state_root"` - ReceiptsRoot string `json:"receipts_root"` - LogsBloom string `json:"logs_bloom"` - PrevRandao string `json:"prev_randao"` - BlockNumber string `json:"block_number"` - GasLimit string `json:"gas_limit"` - GasUsed string `json:"gas_used"` - Timestamp string `json:"timestamp"` - ExtraData string `json:"extra_data"` - BaseFeePerGas string `json:"base_fee_per_gas"` - BlockHash string `json:"block_hash"` - Transactions []string `json:"transactions"` - Withdrawals []*Withdrawal `json:"withdrawals"` -} - -type ExecutionPayloadHeaderCapella struct { - ParentHash string `json:"parent_hash"` - FeeRecipient string `json:"fee_recipient"` - StateRoot string `json:"state_root"` - ReceiptsRoot string `json:"receipts_root"` - LogsBloom string `json:"logs_bloom"` - PrevRandao string `json:"prev_randao"` - BlockNumber string `json:"block_number"` - GasLimit string `json:"gas_limit"` - GasUsed string `json:"gas_used"` - Timestamp string `json:"timestamp"` - ExtraData string `json:"extra_data"` - BaseFeePerGas string `json:"base_fee_per_gas"` - BlockHash string `json:"block_hash"` - TransactionsRoot string `json:"transactions_root"` - WithdrawalsRoot string `json:"withdrawals_root"` -} - // ---------------------------------------------------------------------------- // Deneb // ---------------------------------------------------------------------------- @@ -426,46 +356,6 @@ type BlindedBeaconBlockBodyDeneb struct { BlobKzgCommitments []string `json:"blob_kzg_commitments"` } -type ExecutionPayloadDeneb struct { - ParentHash string `json:"parent_hash"` - FeeRecipient string `json:"fee_recipient"` - StateRoot string `json:"state_root"` - ReceiptsRoot string `json:"receipts_root"` - LogsBloom string `json:"logs_bloom"` - PrevRandao string `json:"prev_randao"` - BlockNumber string `json:"block_number"` - GasLimit string `json:"gas_limit"` - GasUsed string `json:"gas_used"` - Timestamp string `json:"timestamp"` - ExtraData string `json:"extra_data"` - BaseFeePerGas string `json:"base_fee_per_gas"` - BlockHash string `json:"block_hash"` - Transactions []string `json:"transactions"` - Withdrawals []*Withdrawal `json:"withdrawals"` - BlobGasUsed string `json:"blob_gas_used"` - ExcessBlobGas string `json:"excess_blob_gas"` -} - -type ExecutionPayloadHeaderDeneb struct { - ParentHash string `json:"parent_hash"` - FeeRecipient string `json:"fee_recipient"` - StateRoot string `json:"state_root"` - ReceiptsRoot string `json:"receipts_root"` - LogsBloom string `json:"logs_bloom"` - PrevRandao string `json:"prev_randao"` - BlockNumber string `json:"block_number"` - GasLimit string `json:"gas_limit"` - GasUsed string `json:"gas_used"` - Timestamp string `json:"timestamp"` - ExtraData string `json:"extra_data"` - BaseFeePerGas string `json:"base_fee_per_gas"` - BlockHash string `json:"block_hash"` - TransactionsRoot string `json:"transactions_root"` - WithdrawalsRoot string `json:"withdrawals_root"` - BlobGasUsed string `json:"blob_gas_used"` - ExcessBlobGas string `json:"excess_blob_gas"` -} - // ---------------------------------------------------------------------------- // Electra // ---------------------------------------------------------------------------- @@ -560,14 +450,6 @@ type BlindedBeaconBlockBodyElectra struct { ExecutionRequests *ExecutionRequests `json:"execution_requests"` } -type ( - ExecutionRequests struct { - Deposits []*DepositRequest `json:"deposits"` - Withdrawals []*WithdrawalRequest `json:"withdrawals"` - Consolidations []*ConsolidationRequest `json:"consolidations"` - } -) - // ---------------------------------------------------------------------------- // Fulu // ---------------------------------------------------------------------------- diff --git a/api/server/structs/block_execution.go b/api/server/structs/block_execution.go new file mode 100644 index 0000000000..ab4f418313 --- /dev/null +++ b/api/server/structs/block_execution.go @@ -0,0 +1,157 @@ +package structs + +// ---------------------------------------------------------------------------- +// Bellatrix +// ---------------------------------------------------------------------------- + +type ExecutionPayload struct { + ParentHash string `json:"parent_hash"` + FeeRecipient string `json:"fee_recipient"` + StateRoot string `json:"state_root"` + ReceiptsRoot string `json:"receipts_root"` + LogsBloom string `json:"logs_bloom"` + PrevRandao string `json:"prev_randao"` + BlockNumber string `json:"block_number"` + GasLimit string `json:"gas_limit"` + GasUsed string `json:"gas_used"` + Timestamp string `json:"timestamp"` + ExtraData string `json:"extra_data"` + BaseFeePerGas string `json:"base_fee_per_gas"` + BlockHash string `json:"block_hash"` + Transactions []string `json:"transactions"` +} + +type ExecutionPayloadHeader struct { + ParentHash string `json:"parent_hash"` + FeeRecipient string `json:"fee_recipient"` + StateRoot string `json:"state_root"` + ReceiptsRoot string `json:"receipts_root"` + LogsBloom string `json:"logs_bloom"` + PrevRandao string `json:"prev_randao"` + BlockNumber string `json:"block_number"` + GasLimit string `json:"gas_limit"` + GasUsed string `json:"gas_used"` + Timestamp string `json:"timestamp"` + ExtraData string `json:"extra_data"` + BaseFeePerGas string `json:"base_fee_per_gas"` + BlockHash string `json:"block_hash"` + TransactionsRoot string `json:"transactions_root"` +} + +// ---------------------------------------------------------------------------- +// Capella +// ---------------------------------------------------------------------------- + +type ExecutionPayloadCapella struct { + ParentHash string `json:"parent_hash"` + FeeRecipient string `json:"fee_recipient"` + StateRoot string `json:"state_root"` + ReceiptsRoot string `json:"receipts_root"` + LogsBloom string `json:"logs_bloom"` + PrevRandao string `json:"prev_randao"` + BlockNumber string `json:"block_number"` + GasLimit string `json:"gas_limit"` + GasUsed string `json:"gas_used"` + Timestamp string `json:"timestamp"` + ExtraData string `json:"extra_data"` + BaseFeePerGas string `json:"base_fee_per_gas"` + BlockHash string `json:"block_hash"` + Transactions []string `json:"transactions"` + Withdrawals []*Withdrawal `json:"withdrawals"` +} + +type ExecutionPayloadHeaderCapella struct { + ParentHash string `json:"parent_hash"` + FeeRecipient string `json:"fee_recipient"` + StateRoot string `json:"state_root"` + ReceiptsRoot string `json:"receipts_root"` + LogsBloom string `json:"logs_bloom"` + PrevRandao string `json:"prev_randao"` + BlockNumber string `json:"block_number"` + GasLimit string `json:"gas_limit"` + GasUsed string `json:"gas_used"` + Timestamp string `json:"timestamp"` + ExtraData string `json:"extra_data"` + BaseFeePerGas string `json:"base_fee_per_gas"` + BlockHash string `json:"block_hash"` + TransactionsRoot string `json:"transactions_root"` + WithdrawalsRoot string `json:"withdrawals_root"` +} + +// ---------------------------------------------------------------------------- +// Deneb +// ---------------------------------------------------------------------------- + +type ExecutionPayloadDeneb struct { + ParentHash string `json:"parent_hash"` + FeeRecipient string `json:"fee_recipient"` + StateRoot string `json:"state_root"` + ReceiptsRoot string `json:"receipts_root"` + LogsBloom string `json:"logs_bloom"` + PrevRandao string `json:"prev_randao"` + BlockNumber string `json:"block_number"` + GasLimit string `json:"gas_limit"` + GasUsed string `json:"gas_used"` + Timestamp string `json:"timestamp"` + ExtraData string `json:"extra_data"` + BaseFeePerGas string `json:"base_fee_per_gas"` + BlockHash string `json:"block_hash"` + Transactions []string `json:"transactions"` + Withdrawals []*Withdrawal `json:"withdrawals"` + BlobGasUsed string `json:"blob_gas_used"` + ExcessBlobGas string `json:"excess_blob_gas"` +} + +type ExecutionPayloadHeaderDeneb struct { + ParentHash string `json:"parent_hash"` + FeeRecipient string `json:"fee_recipient"` + StateRoot string `json:"state_root"` + ReceiptsRoot string `json:"receipts_root"` + LogsBloom string `json:"logs_bloom"` + PrevRandao string `json:"prev_randao"` + BlockNumber string `json:"block_number"` + GasLimit string `json:"gas_limit"` + GasUsed string `json:"gas_used"` + Timestamp string `json:"timestamp"` + ExtraData string `json:"extra_data"` + BaseFeePerGas string `json:"base_fee_per_gas"` + BlockHash string `json:"block_hash"` + TransactionsRoot string `json:"transactions_root"` + WithdrawalsRoot string `json:"withdrawals_root"` + BlobGasUsed string `json:"blob_gas_used"` + ExcessBlobGas string `json:"excess_blob_gas"` +} + +// ---------------------------------------------------------------------------- +// Electra +// ---------------------------------------------------------------------------- + +type ExecutionRequests struct { + Deposits []*DepositRequest `json:"deposits"` + Withdrawals []*WithdrawalRequest `json:"withdrawals"` + Consolidations []*ConsolidationRequest `json:"consolidations"` +} + +type DepositRequest struct { + Pubkey string `json:"pubkey"` + WithdrawalCredentials string `json:"withdrawal_credentials"` + Amount string `json:"amount"` + Signature string `json:"signature"` + Index string `json:"index"` +} + +type WithdrawalRequest struct { + SourceAddress string `json:"source_address"` + ValidatorPubkey string `json:"validator_pubkey"` + Amount string `json:"amount"` +} + +type ConsolidationRequest struct { + SourceAddress string `json:"source_address"` + SourcePubkey string `json:"source_pubkey"` + TargetPubkey string `json:"target_pubkey"` +} + +// ---------------------------------------------------------------------------- +// Fulu +// ---------------------------------------------------------------------------- diff --git a/api/server/structs/conversions.go b/api/server/structs/conversions.go index ea2fc0ab93..ac305763f6 100644 --- a/api/server/structs/conversions.go +++ b/api/server/structs/conversions.go @@ -889,126 +889,6 @@ func WithdrawalFromConsensus(w *enginev1.Withdrawal) *Withdrawal { } } -func WithdrawalRequestsFromConsensus(ws []*enginev1.WithdrawalRequest) []*WithdrawalRequest { - result := make([]*WithdrawalRequest, len(ws)) - for i, w := range ws { - result[i] = WithdrawalRequestFromConsensus(w) - } - return result -} - -func WithdrawalRequestFromConsensus(w *enginev1.WithdrawalRequest) *WithdrawalRequest { - return &WithdrawalRequest{ - SourceAddress: hexutil.Encode(w.SourceAddress), - ValidatorPubkey: hexutil.Encode(w.ValidatorPubkey), - Amount: fmt.Sprintf("%d", w.Amount), - } -} - -func (w *WithdrawalRequest) ToConsensus() (*enginev1.WithdrawalRequest, error) { - src, err := bytesutil.DecodeHexWithLength(w.SourceAddress, common.AddressLength) - if err != nil { - return nil, server.NewDecodeError(err, "SourceAddress") - } - pubkey, err := bytesutil.DecodeHexWithLength(w.ValidatorPubkey, fieldparams.BLSPubkeyLength) - if err != nil { - return nil, server.NewDecodeError(err, "ValidatorPubkey") - } - amount, err := strconv.ParseUint(w.Amount, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Amount") - } - return &enginev1.WithdrawalRequest{ - SourceAddress: src, - ValidatorPubkey: pubkey, - Amount: amount, - }, nil -} - -func ConsolidationRequestsFromConsensus(cs []*enginev1.ConsolidationRequest) []*ConsolidationRequest { - result := make([]*ConsolidationRequest, len(cs)) - for i, c := range cs { - result[i] = ConsolidationRequestFromConsensus(c) - } - return result -} - -func ConsolidationRequestFromConsensus(c *enginev1.ConsolidationRequest) *ConsolidationRequest { - return &ConsolidationRequest{ - SourceAddress: hexutil.Encode(c.SourceAddress), - SourcePubkey: hexutil.Encode(c.SourcePubkey), - TargetPubkey: hexutil.Encode(c.TargetPubkey), - } -} - -func (c *ConsolidationRequest) ToConsensus() (*enginev1.ConsolidationRequest, error) { - srcAddress, err := bytesutil.DecodeHexWithLength(c.SourceAddress, common.AddressLength) - if err != nil { - return nil, server.NewDecodeError(err, "SourceAddress") - } - srcPubkey, err := bytesutil.DecodeHexWithLength(c.SourcePubkey, fieldparams.BLSPubkeyLength) - if err != nil { - return nil, server.NewDecodeError(err, "SourcePubkey") - } - targetPubkey, err := bytesutil.DecodeHexWithLength(c.TargetPubkey, fieldparams.BLSPubkeyLength) - if err != nil { - return nil, server.NewDecodeError(err, "TargetPubkey") - } - return &enginev1.ConsolidationRequest{ - SourceAddress: srcAddress, - SourcePubkey: srcPubkey, - TargetPubkey: targetPubkey, - }, nil -} - -func DepositRequestsFromConsensus(ds []*enginev1.DepositRequest) []*DepositRequest { - result := make([]*DepositRequest, len(ds)) - for i, d := range ds { - result[i] = DepositRequestFromConsensus(d) - } - return result -} - -func DepositRequestFromConsensus(d *enginev1.DepositRequest) *DepositRequest { - return &DepositRequest{ - Pubkey: hexutil.Encode(d.Pubkey), - WithdrawalCredentials: hexutil.Encode(d.WithdrawalCredentials), - Amount: fmt.Sprintf("%d", d.Amount), - Signature: hexutil.Encode(d.Signature), - Index: fmt.Sprintf("%d", d.Index), - } -} - -func (d *DepositRequest) ToConsensus() (*enginev1.DepositRequest, error) { - pubkey, err := bytesutil.DecodeHexWithLength(d.Pubkey, fieldparams.BLSPubkeyLength) - if err != nil { - return nil, server.NewDecodeError(err, "Pubkey") - } - withdrawalCredentials, err := bytesutil.DecodeHexWithLength(d.WithdrawalCredentials, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "WithdrawalCredentials") - } - amount, err := strconv.ParseUint(d.Amount, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Amount") - } - sig, err := bytesutil.DecodeHexWithLength(d.Signature, fieldparams.BLSSignatureLength) - if err != nil { - return nil, server.NewDecodeError(err, "Signature") - } - index, err := strconv.ParseUint(d.Index, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Index") - } - return &enginev1.DepositRequest{ - Pubkey: pubkey, - WithdrawalCredentials: withdrawalCredentials, - Amount: amount, - Signature: sig, - Index: index, - }, nil -} - func ProposerSlashingsToConsensus(src []*ProposerSlashing) ([]*eth.ProposerSlashing, error) { if src == nil { return nil, server.NewDecodeError(errNilValue, "ProposerSlashings") diff --git a/api/server/structs/conversions_block.go b/api/server/structs/conversions_block.go index b4cc1ceb1d..166ac2573b 100644 --- a/api/server/structs/conversions_block.go +++ b/api/server/structs/conversions_block.go @@ -9,7 +9,6 @@ import ( "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/v5/api/server" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" - "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/container/slice" @@ -281,58 +280,6 @@ func SignedBeaconBlockPhase0FromConsensus(b *eth.SignedBeaconBlock) *SignedBeaco } } -func ExecutionPayloadFromConsensus(payload *enginev1.ExecutionPayload) (*ExecutionPayload, error) { - baseFeePerGas, err := sszBytesToUint256String(payload.BaseFeePerGas) - if err != nil { - return nil, err - } - transactions := make([]string, len(payload.Transactions)) - for i, tx := range payload.Transactions { - transactions[i] = hexutil.Encode(tx) - } - - return &ExecutionPayload{ - ParentHash: hexutil.Encode(payload.ParentHash), - FeeRecipient: hexutil.Encode(payload.FeeRecipient), - StateRoot: hexutil.Encode(payload.StateRoot), - ReceiptsRoot: hexutil.Encode(payload.ReceiptsRoot), - LogsBloom: hexutil.Encode(payload.LogsBloom), - PrevRandao: hexutil.Encode(payload.PrevRandao), - BlockNumber: fmt.Sprintf("%d", payload.BlockNumber), - GasLimit: fmt.Sprintf("%d", payload.GasLimit), - GasUsed: fmt.Sprintf("%d", payload.GasUsed), - Timestamp: fmt.Sprintf("%d", payload.Timestamp), - ExtraData: hexutil.Encode(payload.ExtraData), - BaseFeePerGas: baseFeePerGas, - BlockHash: hexutil.Encode(payload.BlockHash), - Transactions: transactions, - }, nil -} - -func ExecutionPayloadHeaderFromConsensus(payload *enginev1.ExecutionPayloadHeader) (*ExecutionPayloadHeader, error) { - baseFeePerGas, err := sszBytesToUint256String(payload.BaseFeePerGas) - if err != nil { - return nil, err - } - - return &ExecutionPayloadHeader{ - ParentHash: hexutil.Encode(payload.ParentHash), - FeeRecipient: hexutil.Encode(payload.FeeRecipient), - StateRoot: hexutil.Encode(payload.StateRoot), - ReceiptsRoot: hexutil.Encode(payload.ReceiptsRoot), - LogsBloom: hexutil.Encode(payload.LogsBloom), - PrevRandao: hexutil.Encode(payload.PrevRandao), - BlockNumber: fmt.Sprintf("%d", payload.BlockNumber), - GasLimit: fmt.Sprintf("%d", payload.GasLimit), - GasUsed: fmt.Sprintf("%d", payload.GasUsed), - Timestamp: fmt.Sprintf("%d", payload.Timestamp), - ExtraData: hexutil.Encode(payload.ExtraData), - BaseFeePerGas: baseFeePerGas, - BlockHash: hexutil.Encode(payload.BlockHash), - TransactionsRoot: hexutil.Encode(payload.TransactionsRoot), - }, nil -} - // ---------------------------------------------------------------------------- // Altair // ---------------------------------------------------------------------------- @@ -612,68 +559,9 @@ func (b *BeaconBlockBellatrix) ToConsensus() (*eth.BeaconBlockBellatrix, error) if err != nil { return nil, server.NewDecodeError(err, "Body.SyncAggregate.SyncCommitteeSignature") } - payloadParentHash, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.ParentHash, common.HashLength) + payload, err := b.Body.ExecutionPayload.ToConsensus() if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ParentHash") - } - payloadFeeRecipient, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.FeeRecipient, fieldparams.FeeRecipientLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.FeeRecipient") - } - payloadStateRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.StateRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.StateRoot") - } - payloadReceiptsRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.ReceiptsRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ReceiptsRoot") - } - payloadLogsBloom, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.LogsBloom, fieldparams.LogsBloomLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.LogsBloom") - } - payloadPrevRandao, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.PrevRandao, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.PrevRandao") - } - payloadBlockNumber, err := strconv.ParseUint(b.Body.ExecutionPayload.BlockNumber, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.BlockNumber") - } - payloadGasLimit, err := strconv.ParseUint(b.Body.ExecutionPayload.GasLimit, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.GasLimit") - } - payloadGasUsed, err := strconv.ParseUint(b.Body.ExecutionPayload.GasUsed, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.GasUsed") - } - payloadTimestamp, err := strconv.ParseUint(b.Body.ExecutionPayload.Timestamp, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.Timestamp") - } - payloadExtraData, err := bytesutil.DecodeHexWithMaxLength(b.Body.ExecutionPayload.ExtraData, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ExtraData") - } - payloadBaseFeePerGas, err := bytesutil.Uint256ToSSZBytes(b.Body.ExecutionPayload.BaseFeePerGas) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.BaseFeePerGas") - } - payloadBlockHash, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.BlockHash, common.HashLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.BlockHash") - } - err = slice.VerifyMaxLength(b.Body.ExecutionPayload.Transactions, fieldparams.MaxTxsPerPayloadLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.Transactions") - } - payloadTxs := make([][]byte, len(b.Body.ExecutionPayload.Transactions)) - for i, tx := range b.Body.ExecutionPayload.Transactions { - payloadTxs[i], err = bytesutil.DecodeHexWithMaxLength(tx, fieldparams.MaxBytesPerTxLength) - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionPayload.Transactions[%d]", i)) - } + return nil, server.NewDecodeError(err, "Body.ExecutionPayload") } return ð.BeaconBlockBellatrix{ @@ -698,22 +586,7 @@ func (b *BeaconBlockBellatrix) ToConsensus() (*eth.BeaconBlockBellatrix, error) SyncCommitteeBits: syncCommitteeBits, SyncCommitteeSignature: syncCommitteeSig, }, - ExecutionPayload: &enginev1.ExecutionPayload{ - ParentHash: payloadParentHash, - FeeRecipient: payloadFeeRecipient, - StateRoot: payloadStateRoot, - ReceiptsRoot: payloadReceiptsRoot, - LogsBloom: payloadLogsBloom, - PrevRandao: payloadPrevRandao, - BlockNumber: payloadBlockNumber, - GasLimit: payloadGasLimit, - GasUsed: payloadGasUsed, - Timestamp: payloadTimestamp, - ExtraData: payloadExtraData, - BaseFeePerGas: payloadBaseFeePerGas, - BlockHash: payloadBlockHash, - Transactions: payloadTxs, - }, + ExecutionPayload: payload, }, }, nil } @@ -827,61 +700,9 @@ func (b *BlindedBeaconBlockBellatrix) ToConsensus() (*eth.BlindedBeaconBlockBell if err != nil { return nil, server.NewDecodeError(err, "Body.SyncAggregate.SyncCommitteeSignature") } - payloadParentHash, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.ParentHash, common.HashLength) + payload, err := b.Body.ExecutionPayloadHeader.ToConsensus() if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.ParentHash") - } - payloadFeeRecipient, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.FeeRecipient, fieldparams.FeeRecipientLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.FeeRecipient") - } - payloadStateRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.StateRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.StateRoot") - } - payloadReceiptsRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.ReceiptsRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.ReceiptsRoot") - } - payloadLogsBloom, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.LogsBloom, fieldparams.LogsBloomLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.LogsBloom") - } - payloadPrevRandao, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.PrevRandao, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.PrevRandao") - } - payloadBlockNumber, err := strconv.ParseUint(b.Body.ExecutionPayloadHeader.BlockNumber, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.BlockNumber") - } - payloadGasLimit, err := strconv.ParseUint(b.Body.ExecutionPayloadHeader.GasLimit, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.GasLimit") - } - payloadGasUsed, err := strconv.ParseUint(b.Body.ExecutionPayloadHeader.GasUsed, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.GasUsed") - } - payloadTimestamp, err := strconv.ParseUint(b.Body.ExecutionPayloadHeader.Timestamp, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.Timestamp") - } - payloadExtraData, err := bytesutil.DecodeHexWithMaxLength(b.Body.ExecutionPayloadHeader.ExtraData, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.ExtraData") - } - payloadBaseFeePerGas, err := bytesutil.Uint256ToSSZBytes(b.Body.ExecutionPayloadHeader.BaseFeePerGas) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.BaseFeePerGas") - } - payloadBlockHash, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.BlockHash, common.HashLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.BlockHash") - } - payloadTxsRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.TransactionsRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.TransactionsRoot") + return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader") } return ð.BlindedBeaconBlockBellatrix{ Slot: primitives.Slot(slot), @@ -905,22 +726,7 @@ func (b *BlindedBeaconBlockBellatrix) ToConsensus() (*eth.BlindedBeaconBlockBell SyncCommitteeBits: syncCommitteeBits, SyncCommitteeSignature: syncCommitteeSig, }, - ExecutionPayloadHeader: &enginev1.ExecutionPayloadHeader{ - ParentHash: payloadParentHash, - FeeRecipient: payloadFeeRecipient, - StateRoot: payloadStateRoot, - ReceiptsRoot: payloadReceiptsRoot, - LogsBloom: payloadLogsBloom, - PrevRandao: payloadPrevRandao, - BlockNumber: payloadBlockNumber, - GasLimit: payloadGasLimit, - GasUsed: payloadGasUsed, - Timestamp: payloadTimestamp, - ExtraData: payloadExtraData, - BaseFeePerGas: payloadBaseFeePerGas, - BlockHash: payloadBlockHash, - TransactionsRoot: payloadTxsRoot, - }, + ExecutionPayloadHeader: payload, }, }, nil } @@ -1118,98 +924,12 @@ func (b *BeaconBlockCapella) ToConsensus() (*eth.BeaconBlockCapella, error) { if err != nil { return nil, server.NewDecodeError(err, "Body.SyncAggregate.SyncCommitteeSignature") } - payloadParentHash, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.ParentHash, common.HashLength) + + payload, err := b.Body.ExecutionPayload.ToConsensus() if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ParentHash") - } - payloadFeeRecipient, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.FeeRecipient, fieldparams.FeeRecipientLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.FeeRecipient") - } - payloadStateRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.StateRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.StateRoot") - } - payloadReceiptsRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.ReceiptsRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ReceiptsRoot") - } - payloadLogsBloom, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.LogsBloom, fieldparams.LogsBloomLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.LogsBloom") - } - payloadPrevRandao, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.PrevRandao, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.PrevRandao") - } - payloadBlockNumber, err := strconv.ParseUint(b.Body.ExecutionPayload.BlockNumber, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.BlockNumber") - } - payloadGasLimit, err := strconv.ParseUint(b.Body.ExecutionPayload.GasLimit, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.GasLimit") - } - payloadGasUsed, err := strconv.ParseUint(b.Body.ExecutionPayload.GasUsed, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.GasUsed") - } - payloadTimestamp, err := strconv.ParseUint(b.Body.ExecutionPayload.Timestamp, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.Timestamp") - } - payloadExtraData, err := bytesutil.DecodeHexWithMaxLength(b.Body.ExecutionPayload.ExtraData, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ExtraData") - } - payloadBaseFeePerGas, err := bytesutil.Uint256ToSSZBytes(b.Body.ExecutionPayload.BaseFeePerGas) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.BaseFeePerGas") - } - payloadBlockHash, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.BlockHash, common.HashLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.BlockHash") - } - err = slice.VerifyMaxLength(b.Body.ExecutionPayload.Transactions, fieldparams.MaxTxsPerPayloadLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.Transactions") - } - payloadTxs := make([][]byte, len(b.Body.ExecutionPayload.Transactions)) - for i, tx := range b.Body.ExecutionPayload.Transactions { - payloadTxs[i], err = bytesutil.DecodeHexWithMaxLength(tx, fieldparams.MaxBytesPerTxLength) - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionPayload.Transactions[%d]", i)) - } - } - err = slice.VerifyMaxLength(b.Body.ExecutionPayload.Withdrawals, fieldparams.MaxWithdrawalsPerPayload) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.Withdrawals") - } - withdrawals := make([]*enginev1.Withdrawal, len(b.Body.ExecutionPayload.Withdrawals)) - for i, w := range b.Body.ExecutionPayload.Withdrawals { - withdrawalIndex, err := strconv.ParseUint(w.WithdrawalIndex, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionPayload.Withdrawals[%d].WithdrawalIndex", i)) - } - validatorIndex, err := strconv.ParseUint(w.ValidatorIndex, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionPayload.Withdrawals[%d].ValidatorIndex", i)) - } - address, err := bytesutil.DecodeHexWithLength(w.ExecutionAddress, common.AddressLength) - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionPayload.Withdrawals[%d].ExecutionAddress", i)) - } - amount, err := strconv.ParseUint(w.Amount, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionPayload.Withdrawals[%d].Amount", i)) - } - withdrawals[i] = &enginev1.Withdrawal{ - Index: withdrawalIndex, - ValidatorIndex: primitives.ValidatorIndex(validatorIndex), - Address: address, - Amount: amount, - } + return nil, server.NewDecodeError(err, "Body.ExecutionPayload") } + blsChanges, err := SignedBLSChangesToConsensus(b.Body.BLSToExecutionChanges) if err != nil { return nil, server.NewDecodeError(err, "Body.BLSToExecutionChanges") @@ -1237,23 +957,7 @@ func (b *BeaconBlockCapella) ToConsensus() (*eth.BeaconBlockCapella, error) { SyncCommitteeBits: syncCommitteeBits, SyncCommitteeSignature: syncCommitteeSig, }, - ExecutionPayload: &enginev1.ExecutionPayloadCapella{ - ParentHash: payloadParentHash, - FeeRecipient: payloadFeeRecipient, - StateRoot: payloadStateRoot, - ReceiptsRoot: payloadReceiptsRoot, - LogsBloom: payloadLogsBloom, - PrevRandao: payloadPrevRandao, - BlockNumber: payloadBlockNumber, - GasLimit: payloadGasLimit, - GasUsed: payloadGasUsed, - Timestamp: payloadTimestamp, - ExtraData: payloadExtraData, - BaseFeePerGas: payloadBaseFeePerGas, - BlockHash: payloadBlockHash, - Transactions: payloadTxs, - Withdrawals: withdrawals, - }, + ExecutionPayload: payload, BlsToExecutionChanges: blsChanges, }, }, nil @@ -1368,66 +1072,12 @@ func (b *BlindedBeaconBlockCapella) ToConsensus() (*eth.BlindedBeaconBlockCapell if err != nil { return nil, server.NewDecodeError(err, "Body.SyncAggregate.SyncCommitteeSignature") } - payloadParentHash, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.ParentHash, common.HashLength) + + payload, err := b.Body.ExecutionPayloadHeader.ToConsensus() if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.ParentHash") - } - payloadFeeRecipient, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.FeeRecipient, fieldparams.FeeRecipientLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.FeeRecipient") - } - payloadStateRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.StateRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.StateRoot") - } - payloadReceiptsRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.ReceiptsRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.ReceiptsRoot") - } - payloadLogsBloom, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.LogsBloom, fieldparams.LogsBloomLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.LogsBloom") - } - payloadPrevRandao, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.PrevRandao, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.PrevRandao") - } - payloadBlockNumber, err := strconv.ParseUint(b.Body.ExecutionPayloadHeader.BlockNumber, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.BlockNumber") - } - payloadGasLimit, err := strconv.ParseUint(b.Body.ExecutionPayloadHeader.GasLimit, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.GasLimit") - } - payloadGasUsed, err := strconv.ParseUint(b.Body.ExecutionPayloadHeader.GasUsed, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.GasUsed") - } - payloadTimestamp, err := strconv.ParseUint(b.Body.ExecutionPayloadHeader.Timestamp, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.Timestamp") - } - payloadExtraData, err := bytesutil.DecodeHexWithMaxLength(b.Body.ExecutionPayloadHeader.ExtraData, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.ExtraData") - } - payloadBaseFeePerGas, err := bytesutil.Uint256ToSSZBytes(b.Body.ExecutionPayloadHeader.BaseFeePerGas) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.BaseFeePerGas") - } - payloadBlockHash, err := bytesutil.DecodeHexWithMaxLength(b.Body.ExecutionPayloadHeader.BlockHash, common.HashLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.BlockHash") - } - payloadTxsRoot, err := bytesutil.DecodeHexWithMaxLength(b.Body.ExecutionPayloadHeader.TransactionsRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.TransactionsRoot") - } - payloadWithdrawalsRoot, err := bytesutil.DecodeHexWithMaxLength(b.Body.ExecutionPayloadHeader.WithdrawalsRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.WithdrawalsRoot") + return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader") } + blsChanges, err := SignedBLSChangesToConsensus(b.Body.BLSToExecutionChanges) if err != nil { return nil, server.NewDecodeError(err, "Body.BLSToExecutionChanges") @@ -1455,24 +1105,8 @@ func (b *BlindedBeaconBlockCapella) ToConsensus() (*eth.BlindedBeaconBlockCapell SyncCommitteeBits: syncCommitteeBits, SyncCommitteeSignature: syncCommitteeSig, }, - ExecutionPayloadHeader: &enginev1.ExecutionPayloadHeaderCapella{ - ParentHash: payloadParentHash, - FeeRecipient: payloadFeeRecipient, - StateRoot: payloadStateRoot, - ReceiptsRoot: payloadReceiptsRoot, - LogsBloom: payloadLogsBloom, - PrevRandao: payloadPrevRandao, - BlockNumber: payloadBlockNumber, - GasLimit: payloadGasLimit, - GasUsed: payloadGasUsed, - Timestamp: payloadTimestamp, - ExtraData: payloadExtraData, - BaseFeePerGas: payloadBaseFeePerGas, - BlockHash: payloadBlockHash, - TransactionsRoot: payloadTxsRoot, - WithdrawalsRoot: payloadWithdrawalsRoot, - }, - BlsToExecutionChanges: blsChanges, + ExecutionPayloadHeader: payload, + BlsToExecutionChanges: blsChanges, }, }, nil } @@ -1559,60 +1193,6 @@ func SignedBeaconBlockCapellaFromConsensus(b *eth.SignedBeaconBlockCapella) (*Si }, nil } -func ExecutionPayloadCapellaFromConsensus(payload *enginev1.ExecutionPayloadCapella) (*ExecutionPayloadCapella, error) { - baseFeePerGas, err := sszBytesToUint256String(payload.BaseFeePerGas) - if err != nil { - return nil, err - } - transactions := make([]string, len(payload.Transactions)) - for i, tx := range payload.Transactions { - transactions[i] = hexutil.Encode(tx) - } - - return &ExecutionPayloadCapella{ - ParentHash: hexutil.Encode(payload.ParentHash), - FeeRecipient: hexutil.Encode(payload.FeeRecipient), - StateRoot: hexutil.Encode(payload.StateRoot), - ReceiptsRoot: hexutil.Encode(payload.ReceiptsRoot), - LogsBloom: hexutil.Encode(payload.LogsBloom), - PrevRandao: hexutil.Encode(payload.PrevRandao), - BlockNumber: fmt.Sprintf("%d", payload.BlockNumber), - GasLimit: fmt.Sprintf("%d", payload.GasLimit), - GasUsed: fmt.Sprintf("%d", payload.GasUsed), - Timestamp: fmt.Sprintf("%d", payload.Timestamp), - ExtraData: hexutil.Encode(payload.ExtraData), - BaseFeePerGas: baseFeePerGas, - BlockHash: hexutil.Encode(payload.BlockHash), - Transactions: transactions, - Withdrawals: WithdrawalsFromConsensus(payload.Withdrawals), - }, nil -} - -func ExecutionPayloadHeaderCapellaFromConsensus(payload *enginev1.ExecutionPayloadHeaderCapella) (*ExecutionPayloadHeaderCapella, error) { - baseFeePerGas, err := sszBytesToUint256String(payload.BaseFeePerGas) - if err != nil { - return nil, err - } - - return &ExecutionPayloadHeaderCapella{ - ParentHash: hexutil.Encode(payload.ParentHash), - FeeRecipient: hexutil.Encode(payload.FeeRecipient), - StateRoot: hexutil.Encode(payload.StateRoot), - ReceiptsRoot: hexutil.Encode(payload.ReceiptsRoot), - LogsBloom: hexutil.Encode(payload.LogsBloom), - PrevRandao: hexutil.Encode(payload.PrevRandao), - BlockNumber: fmt.Sprintf("%d", payload.BlockNumber), - GasLimit: fmt.Sprintf("%d", payload.GasLimit), - GasUsed: fmt.Sprintf("%d", payload.GasUsed), - Timestamp: fmt.Sprintf("%d", payload.Timestamp), - ExtraData: hexutil.Encode(payload.ExtraData), - BaseFeePerGas: baseFeePerGas, - BlockHash: hexutil.Encode(payload.BlockHash), - TransactionsRoot: hexutil.Encode(payload.TransactionsRoot), - WithdrawalsRoot: hexutil.Encode(payload.WithdrawalsRoot), - }, nil -} - // ---------------------------------------------------------------------------- // Deneb // ---------------------------------------------------------------------------- @@ -1776,106 +1356,9 @@ func (b *BeaconBlockDeneb) ToConsensus() (*eth.BeaconBlockDeneb, error) { if err != nil { return nil, server.NewDecodeError(err, "Body.SyncAggregate.SyncCommitteeSignature") } - payloadParentHash, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.ParentHash, common.HashLength) + payload, err := b.Body.ExecutionPayload.ToConsensus() if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ParentHash") - } - payloadFeeRecipient, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.FeeRecipient, fieldparams.FeeRecipientLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.FeeRecipient") - } - payloadStateRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.StateRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.StateRoot") - } - payloadReceiptsRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.ReceiptsRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ReceiptsRoot") - } - payloadLogsBloom, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.LogsBloom, fieldparams.LogsBloomLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.LogsBloom") - } - payloadPrevRandao, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.PrevRandao, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.PrevRandao") - } - payloadBlockNumber, err := strconv.ParseUint(b.Body.ExecutionPayload.BlockNumber, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.BlockNumber") - } - payloadGasLimit, err := strconv.ParseUint(b.Body.ExecutionPayload.GasLimit, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.GasLimit") - } - payloadGasUsed, err := strconv.ParseUint(b.Body.ExecutionPayload.GasUsed, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.GasUsed") - } - payloadTimestamp, err := strconv.ParseUint(b.Body.ExecutionPayload.Timestamp, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.Timestamp") - } - payloadExtraData, err := bytesutil.DecodeHexWithMaxLength(b.Body.ExecutionPayload.ExtraData, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ExtraData") - } - payloadBaseFeePerGas, err := bytesutil.Uint256ToSSZBytes(b.Body.ExecutionPayload.BaseFeePerGas) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.BaseFeePerGas") - } - payloadBlockHash, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.BlockHash, common.HashLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.BlockHash") - } - err = slice.VerifyMaxLength(b.Body.ExecutionPayload.Transactions, fieldparams.MaxTxsPerPayloadLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.Transactions") - } - txs := make([][]byte, len(b.Body.ExecutionPayload.Transactions)) - for i, tx := range b.Body.ExecutionPayload.Transactions { - txs[i], err = bytesutil.DecodeHexWithMaxLength(tx, fieldparams.MaxBytesPerTxLength) - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionPayload.Transactions[%d]", i)) - } - } - err = slice.VerifyMaxLength(b.Body.ExecutionPayload.Withdrawals, fieldparams.MaxWithdrawalsPerPayload) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.Withdrawals") - } - withdrawals := make([]*enginev1.Withdrawal, len(b.Body.ExecutionPayload.Withdrawals)) - for i, w := range b.Body.ExecutionPayload.Withdrawals { - withdrawalIndex, err := strconv.ParseUint(w.WithdrawalIndex, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionPayload.Withdrawals[%d].WithdrawalIndex", i)) - } - validatorIndex, err := strconv.ParseUint(w.ValidatorIndex, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionPayload.Withdrawals[%d].ValidatorIndex", i)) - } - address, err := bytesutil.DecodeHexWithLength(w.ExecutionAddress, common.AddressLength) - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionPayload.Withdrawals[%d].ExecutionAddress", i)) - } - amount, err := strconv.ParseUint(w.Amount, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionPayload.Withdrawals[%d].Amount", i)) - } - withdrawals[i] = &enginev1.Withdrawal{ - Index: withdrawalIndex, - ValidatorIndex: primitives.ValidatorIndex(validatorIndex), - Address: address, - Amount: amount, - } - } - - payloadBlobGasUsed, err := strconv.ParseUint(b.Body.ExecutionPayload.BlobGasUsed, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.BlobGasUsed") - } - payloadExcessBlobGas, err := strconv.ParseUint(b.Body.ExecutionPayload.ExcessBlobGas, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ExcessBlobGas") + return nil, server.NewDecodeError(err, "Body.ExecutionPayload") } blsChanges, err := SignedBLSChangesToConsensus(b.Body.BLSToExecutionChanges) if err != nil { @@ -1915,25 +1398,7 @@ func (b *BeaconBlockDeneb) ToConsensus() (*eth.BeaconBlockDeneb, error) { SyncCommitteeBits: syncCommitteeBits, SyncCommitteeSignature: syncCommitteeSig, }, - ExecutionPayload: &enginev1.ExecutionPayloadDeneb{ - ParentHash: payloadParentHash, - FeeRecipient: payloadFeeRecipient, - StateRoot: payloadStateRoot, - ReceiptsRoot: payloadReceiptsRoot, - LogsBloom: payloadLogsBloom, - PrevRandao: payloadPrevRandao, - BlockNumber: payloadBlockNumber, - GasLimit: payloadGasLimit, - GasUsed: payloadGasUsed, - Timestamp: payloadTimestamp, - ExtraData: payloadExtraData, - BaseFeePerGas: payloadBaseFeePerGas, - BlockHash: payloadBlockHash, - Transactions: txs, - Withdrawals: withdrawals, - BlobGasUsed: payloadBlobGasUsed, - ExcessBlobGas: payloadExcessBlobGas, - }, + ExecutionPayload: payload, BlsToExecutionChanges: blsChanges, BlobKzgCommitments: blobKzgCommitments, }, @@ -2077,76 +1542,10 @@ func (b *BlindedBeaconBlockDeneb) ToConsensus() (*eth.BlindedBeaconBlockDeneb, e if err != nil { return nil, server.NewDecodeError(err, "Body.SyncAggregate.SyncCommitteeSignature") } - payloadParentHash, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.ParentHash, common.HashLength) + payload, err := b.Body.ExecutionPayloadHeader.ToConsensus() if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.ParentHash") + return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader") } - payloadFeeRecipient, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.FeeRecipient, fieldparams.FeeRecipientLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.FeeRecipient") - } - payloadStateRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.StateRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.StateRoot") - } - payloadReceiptsRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.ReceiptsRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.ReceiptsRoot") - } - payloadLogsBloom, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.LogsBloom, fieldparams.LogsBloomLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.LogsBloom") - } - payloadPrevRandao, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.PrevRandao, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.PrevRandao") - } - payloadBlockNumber, err := strconv.ParseUint(b.Body.ExecutionPayloadHeader.BlockNumber, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.BlockNumber") - } - payloadGasLimit, err := strconv.ParseUint(b.Body.ExecutionPayloadHeader.GasLimit, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.GasLimit") - } - payloadGasUsed, err := strconv.ParseUint(b.Body.ExecutionPayloadHeader.GasUsed, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.GasUsed") - } - payloadTimestamp, err := strconv.ParseUint(b.Body.ExecutionPayloadHeader.Timestamp, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.Timestamp") - } - payloadExtraData, err := bytesutil.DecodeHexWithMaxLength(b.Body.ExecutionPayloadHeader.ExtraData, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.ExtraData") - } - payloadBaseFeePerGas, err := bytesutil.Uint256ToSSZBytes(b.Body.ExecutionPayloadHeader.BaseFeePerGas) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.BaseFeePerGas") - } - payloadBlockHash, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.BlockHash, common.HashLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.BlockHash") - } - payloadTxsRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.TransactionsRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.TransactionsRoot") - } - payloadWithdrawalsRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayloadHeader.WithdrawalsRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.WithdrawalsRoot") - } - - payloadBlobGasUsed, err := strconv.ParseUint(b.Body.ExecutionPayloadHeader.BlobGasUsed, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.BlobGasUsed") - } - payloadExcessBlobGas, err := strconv.ParseUint(b.Body.ExecutionPayloadHeader.ExcessBlobGas, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ExcessBlobGas") - } - blsChanges, err := SignedBLSChangesToConsensus(b.Body.BLSToExecutionChanges) if err != nil { return nil, server.NewDecodeError(err, "Body.BLSToExecutionChanges") @@ -2186,27 +1585,9 @@ func (b *BlindedBeaconBlockDeneb) ToConsensus() (*eth.BlindedBeaconBlockDeneb, e SyncCommitteeBits: syncCommitteeBits, SyncCommitteeSignature: syncCommitteeSig, }, - ExecutionPayloadHeader: &enginev1.ExecutionPayloadHeaderDeneb{ - ParentHash: payloadParentHash, - FeeRecipient: payloadFeeRecipient, - StateRoot: payloadStateRoot, - ReceiptsRoot: payloadReceiptsRoot, - LogsBloom: payloadLogsBloom, - PrevRandao: payloadPrevRandao, - BlockNumber: payloadBlockNumber, - GasLimit: payloadGasLimit, - GasUsed: payloadGasUsed, - Timestamp: payloadTimestamp, - ExtraData: payloadExtraData, - BaseFeePerGas: payloadBaseFeePerGas, - BlockHash: payloadBlockHash, - TransactionsRoot: payloadTxsRoot, - WithdrawalsRoot: payloadWithdrawalsRoot, - BlobGasUsed: payloadBlobGasUsed, - ExcessBlobGas: payloadExcessBlobGas, - }, - BlsToExecutionChanges: blsChanges, - BlobKzgCommitments: blobKzgCommitments, + ExecutionPayloadHeader: payload, + BlsToExecutionChanges: blsChanges, + BlobKzgCommitments: blobKzgCommitments, }, }, nil } @@ -2313,19 +1694,14 @@ func SignedBlindedBeaconBlockDenebFromConsensus(b *eth.SignedBlindedBeaconBlockD } func BeaconBlockDenebFromConsensus(b *eth.BeaconBlockDeneb) (*BeaconBlockDeneb, error) { - baseFeePerGas, err := sszBytesToUint256String(b.Body.ExecutionPayload.BaseFeePerGas) - if err != nil { - return nil, err - } - transactions := make([]string, len(b.Body.ExecutionPayload.Transactions)) - for i, tx := range b.Body.ExecutionPayload.Transactions { - transactions[i] = hexutil.Encode(tx) - } blobKzgCommitments := make([]string, len(b.Body.BlobKzgCommitments)) for i := range b.Body.BlobKzgCommitments { blobKzgCommitments[i] = hexutil.Encode(b.Body.BlobKzgCommitments[i]) } - + payload, err := ExecutionPayloadDenebFromConsensus(b.Body.ExecutionPayload) + if err != nil { + return nil, err + } return &BeaconBlockDeneb{ Slot: fmt.Sprintf("%d", b.Slot), ProposerIndex: fmt.Sprintf("%d", b.ProposerIndex), @@ -2344,25 +1720,7 @@ func BeaconBlockDenebFromConsensus(b *eth.BeaconBlockDeneb) (*BeaconBlockDeneb, SyncCommitteeBits: hexutil.Encode(b.Body.SyncAggregate.SyncCommitteeBits), SyncCommitteeSignature: hexutil.Encode(b.Body.SyncAggregate.SyncCommitteeSignature), }, - ExecutionPayload: &ExecutionPayloadDeneb{ - ParentHash: hexutil.Encode(b.Body.ExecutionPayload.ParentHash), - FeeRecipient: hexutil.Encode(b.Body.ExecutionPayload.FeeRecipient), - StateRoot: hexutil.Encode(b.Body.ExecutionPayload.StateRoot), - ReceiptsRoot: hexutil.Encode(b.Body.ExecutionPayload.ReceiptsRoot), - LogsBloom: hexutil.Encode(b.Body.ExecutionPayload.LogsBloom), - PrevRandao: hexutil.Encode(b.Body.ExecutionPayload.PrevRandao), - BlockNumber: fmt.Sprintf("%d", b.Body.ExecutionPayload.BlockNumber), - GasLimit: fmt.Sprintf("%d", b.Body.ExecutionPayload.GasLimit), - GasUsed: fmt.Sprintf("%d", b.Body.ExecutionPayload.GasUsed), - Timestamp: fmt.Sprintf("%d", b.Body.ExecutionPayload.Timestamp), - ExtraData: hexutil.Encode(b.Body.ExecutionPayload.ExtraData), - BaseFeePerGas: baseFeePerGas, - BlockHash: hexutil.Encode(b.Body.ExecutionPayload.BlockHash), - Transactions: transactions, - Withdrawals: WithdrawalsFromConsensus(b.Body.ExecutionPayload.Withdrawals), - BlobGasUsed: fmt.Sprintf("%d", b.Body.ExecutionPayload.BlobGasUsed), - ExcessBlobGas: fmt.Sprintf("%d", b.Body.ExecutionPayload.ExcessBlobGas), - }, + ExecutionPayload: payload, BLSToExecutionChanges: SignedBLSChangesFromConsensus(b.Body.BlsToExecutionChanges), BlobKzgCommitments: blobKzgCommitments, }, @@ -2380,64 +1738,6 @@ func SignedBeaconBlockDenebFromConsensus(b *eth.SignedBeaconBlockDeneb) (*Signed }, nil } -func ExecutionPayloadDenebFromConsensus(payload *enginev1.ExecutionPayloadDeneb) (*ExecutionPayloadDeneb, error) { - baseFeePerGas, err := sszBytesToUint256String(payload.BaseFeePerGas) - if err != nil { - return nil, err - } - transactions := make([]string, len(payload.Transactions)) - for i, tx := range payload.Transactions { - transactions[i] = hexutil.Encode(tx) - } - - return &ExecutionPayloadDeneb{ - ParentHash: hexutil.Encode(payload.ParentHash), - FeeRecipient: hexutil.Encode(payload.FeeRecipient), - StateRoot: hexutil.Encode(payload.StateRoot), - ReceiptsRoot: hexutil.Encode(payload.ReceiptsRoot), - LogsBloom: hexutil.Encode(payload.LogsBloom), - PrevRandao: hexutil.Encode(payload.PrevRandao), - BlockNumber: fmt.Sprintf("%d", payload.BlockNumber), - GasLimit: fmt.Sprintf("%d", payload.GasLimit), - GasUsed: fmt.Sprintf("%d", payload.GasUsed), - Timestamp: fmt.Sprintf("%d", payload.Timestamp), - ExtraData: hexutil.Encode(payload.ExtraData), - BaseFeePerGas: baseFeePerGas, - BlockHash: hexutil.Encode(payload.BlockHash), - Transactions: transactions, - Withdrawals: WithdrawalsFromConsensus(payload.Withdrawals), - BlobGasUsed: fmt.Sprintf("%d", payload.BlobGasUsed), - ExcessBlobGas: fmt.Sprintf("%d", payload.ExcessBlobGas), - }, nil -} - -func ExecutionPayloadHeaderDenebFromConsensus(payload *enginev1.ExecutionPayloadHeaderDeneb) (*ExecutionPayloadHeaderDeneb, error) { - baseFeePerGas, err := sszBytesToUint256String(payload.BaseFeePerGas) - if err != nil { - return nil, err - } - - return &ExecutionPayloadHeaderDeneb{ - ParentHash: hexutil.Encode(payload.ParentHash), - FeeRecipient: hexutil.Encode(payload.FeeRecipient), - StateRoot: hexutil.Encode(payload.StateRoot), - ReceiptsRoot: hexutil.Encode(payload.ReceiptsRoot), - LogsBloom: hexutil.Encode(payload.LogsBloom), - PrevRandao: hexutil.Encode(payload.PrevRandao), - BlockNumber: fmt.Sprintf("%d", payload.BlockNumber), - GasLimit: fmt.Sprintf("%d", payload.GasLimit), - GasUsed: fmt.Sprintf("%d", payload.GasUsed), - Timestamp: fmt.Sprintf("%d", payload.Timestamp), - ExtraData: hexutil.Encode(payload.ExtraData), - BaseFeePerGas: baseFeePerGas, - BlockHash: hexutil.Encode(payload.BlockHash), - TransactionsRoot: hexutil.Encode(payload.TransactionsRoot), - WithdrawalsRoot: hexutil.Encode(payload.WithdrawalsRoot), - BlobGasUsed: fmt.Sprintf("%d", payload.BlobGasUsed), - ExcessBlobGas: fmt.Sprintf("%d", payload.ExcessBlobGas), - }, nil -} - // ---------------------------------------------------------------------------- // Electra // ---------------------------------------------------------------------------- @@ -2520,7 +1820,6 @@ func (b *BeaconBlockContentsElectra) ToConsensus() (*eth.BeaconBlockContentsElec }, nil } -// nolint:gocognit func (b *BeaconBlockElectra) ToConsensus() (*eth.BeaconBlockElectra, error) { if b == nil { return nil, errNilValue @@ -2537,6 +1836,9 @@ func (b *BeaconBlockElectra) ToConsensus() (*eth.BeaconBlockElectra, error) { if b.Body.ExecutionPayload == nil { return nil, server.NewDecodeError(errNilValue, "Body.ExecutionPayload") } + if b.Body.ExecutionRequests == nil { + return nil, server.NewDecodeError(errNilValue, "Body.ExecutionRequests") + } slot, err := strconv.ParseUint(b.Slot, 10, 64) if err != nil { @@ -2602,143 +1904,10 @@ func (b *BeaconBlockElectra) ToConsensus() (*eth.BeaconBlockElectra, error) { if err != nil { return nil, server.NewDecodeError(err, "Body.SyncAggregate.SyncCommitteeSignature") } - payloadParentHash, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.ParentHash, common.HashLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ParentHash") - } - payloadFeeRecipient, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.FeeRecipient, fieldparams.FeeRecipientLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.FeeRecipient") - } - payloadStateRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.StateRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.StateRoot") - } - payloadReceiptsRoot, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.ReceiptsRoot, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ReceiptsRoot") - } - payloadLogsBloom, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.LogsBloom, fieldparams.LogsBloomLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.LogsBloom") - } - payloadPrevRandao, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.PrevRandao, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.PrevRandao") - } - payloadBlockNumber, err := strconv.ParseUint(b.Body.ExecutionPayload.BlockNumber, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.BlockNumber") - } - payloadGasLimit, err := strconv.ParseUint(b.Body.ExecutionPayload.GasLimit, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.GasLimit") - } - payloadGasUsed, err := strconv.ParseUint(b.Body.ExecutionPayload.GasUsed, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.GasUsed") - } - payloadTimestamp, err := strconv.ParseUint(b.Body.ExecutionPayload.Timestamp, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayloadHeader.Timestamp") - } - payloadExtraData, err := bytesutil.DecodeHexWithMaxLength(b.Body.ExecutionPayload.ExtraData, fieldparams.RootLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ExtraData") - } - payloadBaseFeePerGas, err := bytesutil.Uint256ToSSZBytes(b.Body.ExecutionPayload.BaseFeePerGas) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.BaseFeePerGas") - } - payloadBlockHash, err := bytesutil.DecodeHexWithLength(b.Body.ExecutionPayload.BlockHash, common.HashLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.BlockHash") - } - err = slice.VerifyMaxLength(b.Body.ExecutionPayload.Transactions, fieldparams.MaxTxsPerPayloadLength) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.Transactions") - } - txs := make([][]byte, len(b.Body.ExecutionPayload.Transactions)) - for i, tx := range b.Body.ExecutionPayload.Transactions { - txs[i], err = bytesutil.DecodeHexWithMaxLength(tx, fieldparams.MaxBytesPerTxLength) - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionPayload.Transactions[%d]", i)) - } - } - err = slice.VerifyMaxLength(b.Body.ExecutionPayload.Withdrawals, fieldparams.MaxWithdrawalsPerPayload) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.Withdrawals") - } - withdrawals := make([]*enginev1.Withdrawal, len(b.Body.ExecutionPayload.Withdrawals)) - for i, w := range b.Body.ExecutionPayload.Withdrawals { - withdrawalIndex, err := strconv.ParseUint(w.WithdrawalIndex, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionPayload.Withdrawals[%d].WithdrawalIndex", i)) - } - validatorIndex, err := strconv.ParseUint(w.ValidatorIndex, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionPayload.Withdrawals[%d].ValidatorIndex", i)) - } - address, err := bytesutil.DecodeHexWithLength(w.ExecutionAddress, common.AddressLength) - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionPayload.Withdrawals[%d].ExecutionAddress", i)) - } - amount, err := strconv.ParseUint(w.Amount, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionPayload.Withdrawals[%d].Amount", i)) - } - withdrawals[i] = &enginev1.Withdrawal{ - Index: withdrawalIndex, - ValidatorIndex: primitives.ValidatorIndex(validatorIndex), - Address: address, - Amount: amount, - } - } - payloadBlobGasUsed, err := strconv.ParseUint(b.Body.ExecutionPayload.BlobGasUsed, 10, 64) + payload, err := b.Body.ExecutionPayload.ToConsensus() if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.BlobGasUsed") - } - payloadExcessBlobGas, err := strconv.ParseUint(b.Body.ExecutionPayload.ExcessBlobGas, 10, 64) - if err != nil { - return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ExcessBlobGas") - } - - if b.Body.ExecutionRequests == nil { - return nil, server.NewDecodeError(errors.New("nil execution requests"), "Body.ExequtionRequests") - } - - if err = slice.VerifyMaxLength(b.Body.ExecutionRequests.Deposits, params.BeaconConfig().MaxDepositRequestsPerPayload); err != nil { - return nil, err - } - depositRequests := make([]*enginev1.DepositRequest, len(b.Body.ExecutionRequests.Deposits)) - for i, d := range b.Body.ExecutionRequests.Deposits { - depositRequests[i], err = d.ToConsensus() - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionRequests.Deposits[%d]", i)) - } - } - - if err = slice.VerifyMaxLength(b.Body.ExecutionRequests.Withdrawals, params.BeaconConfig().MaxWithdrawalRequestsPerPayload); err != nil { - return nil, err - } - withdrawalRequests := make([]*enginev1.WithdrawalRequest, len(b.Body.ExecutionRequests.Withdrawals)) - for i, w := range b.Body.ExecutionRequests.Withdrawals { - withdrawalRequests[i], err = w.ToConsensus() - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionRequests.Withdrawals[%d]", i)) - } - } - - if err = slice.VerifyMaxLength(b.Body.ExecutionRequests.Consolidations, params.BeaconConfig().MaxConsolidationsRequestsPerPayload); err != nil { - return nil, err - } - consolidationRequests := make([]*enginev1.ConsolidationRequest, len(b.Body.ExecutionRequests.Consolidations)) - for i, c := range b.Body.ExecutionRequests.Consolidations { - consolidationRequests[i], err = c.ToConsensus() - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionRequests.Consolidations[%d]", i)) - } + return nil, server.NewDecodeError(err, "Body.ExecutionPayload") } blsChanges, err := SignedBLSChangesToConsensus(b.Body.BLSToExecutionChanges) @@ -2757,6 +1926,12 @@ func (b *BeaconBlockElectra) ToConsensus() (*eth.BeaconBlockElectra, error) { } blobKzgCommitments[i] = kzg } + + requests, err := b.Body.ExecutionRequests.ToConsensus() + if err != nil { + return nil, server.NewDecodeError(err, "Body.ExecutionRequests") + } + return ð.BeaconBlockElectra{ Slot: primitives.Slot(slot), ProposerIndex: primitives.ValidatorIndex(proposerIndex), @@ -2779,32 +1954,10 @@ func (b *BeaconBlockElectra) ToConsensus() (*eth.BeaconBlockElectra, error) { SyncCommitteeBits: syncCommitteeBits, SyncCommitteeSignature: syncCommitteeSig, }, - ExecutionPayload: &enginev1.ExecutionPayloadDeneb{ - ParentHash: payloadParentHash, - FeeRecipient: payloadFeeRecipient, - StateRoot: payloadStateRoot, - ReceiptsRoot: payloadReceiptsRoot, - LogsBloom: payloadLogsBloom, - PrevRandao: payloadPrevRandao, - BlockNumber: payloadBlockNumber, - GasLimit: payloadGasLimit, - GasUsed: payloadGasUsed, - Timestamp: payloadTimestamp, - ExtraData: payloadExtraData, - BaseFeePerGas: payloadBaseFeePerGas, - BlockHash: payloadBlockHash, - Transactions: txs, - Withdrawals: withdrawals, - BlobGasUsed: payloadBlobGasUsed, - ExcessBlobGas: payloadExcessBlobGas, - }, + ExecutionPayload: payload, BlsToExecutionChanges: blsChanges, BlobKzgCommitments: blobKzgCommitments, - ExecutionRequests: &enginev1.ExecutionRequests{ - Deposits: depositRequests, - Withdrawals: withdrawalRequests, - Consolidations: consolidationRequests, - }, + ExecutionRequests: requests, }, }, nil } @@ -2881,6 +2034,9 @@ func (b *BlindedBeaconBlockElectra) ToConsensus() (*eth.BlindedBeaconBlockElectr if b.Body.ExecutionPayloadHeader == nil { return nil, server.NewDecodeError(errNilValue, "Body.ExecutionPayloadHeader") } + if b.Body.ExecutionRequests == nil { + return nil, server.NewDecodeError(errNilValue, "Body.ExecutionRequests") + } slot, err := strconv.ParseUint(b.Slot, 10, 64) if err != nil { @@ -3015,43 +2171,6 @@ func (b *BlindedBeaconBlockElectra) ToConsensus() (*eth.BlindedBeaconBlockElectr return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ExcessBlobGas") } - if b.Body.ExecutionRequests == nil { - return nil, server.NewDecodeError(errors.New("nil execution requests"), "Body.ExecutionRequests") - } - - if err = slice.VerifyMaxLength(b.Body.ExecutionRequests.Deposits, params.BeaconConfig().MaxDepositRequestsPerPayload); err != nil { - return nil, err - } - depositRequests := make([]*enginev1.DepositRequest, len(b.Body.ExecutionRequests.Deposits)) - for i, d := range b.Body.ExecutionRequests.Deposits { - depositRequests[i], err = d.ToConsensus() - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionRequests.Deposits[%d]", i)) - } - } - - if err = slice.VerifyMaxLength(b.Body.ExecutionRequests.Withdrawals, params.BeaconConfig().MaxWithdrawalRequestsPerPayload); err != nil { - return nil, err - } - withdrawalRequests := make([]*enginev1.WithdrawalRequest, len(b.Body.ExecutionRequests.Withdrawals)) - for i, w := range b.Body.ExecutionRequests.Withdrawals { - withdrawalRequests[i], err = w.ToConsensus() - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionRequests.Withdrawals[%d]", i)) - } - } - - if err = slice.VerifyMaxLength(b.Body.ExecutionRequests.Consolidations, params.BeaconConfig().MaxConsolidationsRequestsPerPayload); err != nil { - return nil, err - } - consolidationRequests := make([]*enginev1.ConsolidationRequest, len(b.Body.ExecutionRequests.Consolidations)) - for i, c := range b.Body.ExecutionRequests.Consolidations { - consolidationRequests[i], err = c.ToConsensus() - if err != nil { - return nil, server.NewDecodeError(err, fmt.Sprintf("Body.ExecutionRequests.Consolidations[%d]", i)) - } - } - blsChanges, err := SignedBLSChangesToConsensus(b.Body.BLSToExecutionChanges) if err != nil { return nil, server.NewDecodeError(err, "Body.BLSToExecutionChanges") @@ -3069,6 +2188,11 @@ func (b *BlindedBeaconBlockElectra) ToConsensus() (*eth.BlindedBeaconBlockElectr blobKzgCommitments[i] = kzg } + requests, err := b.Body.ExecutionRequests.ToConsensus() + if err != nil { + return nil, server.NewDecodeError(err, "Body.ExecutionRequests") + } + return ð.BlindedBeaconBlockElectra{ Slot: primitives.Slot(slot), ProposerIndex: primitives.ValidatorIndex(proposerIndex), @@ -3112,11 +2236,7 @@ func (b *BlindedBeaconBlockElectra) ToConsensus() (*eth.BlindedBeaconBlockElectr }, BlsToExecutionChanges: blsChanges, BlobKzgCommitments: blobKzgCommitments, - ExecutionRequests: &enginev1.ExecutionRequests{ - Deposits: depositRequests, - Withdrawals: withdrawalRequests, - Consolidations: consolidationRequests, - }, + ExecutionRequests: requests, }, }, nil } @@ -3212,14 +2332,6 @@ func BeaconBlockContentsElectraFromConsensus(b *eth.BeaconBlockContentsElectra) }, nil } -func ExecutionRequestsFromConsensus(er *enginev1.ExecutionRequests) *ExecutionRequests { - return &ExecutionRequests{ - Deposits: DepositRequestsFromConsensus(er.Deposits), - Withdrawals: WithdrawalRequestsFromConsensus(er.Withdrawals), - Consolidations: ConsolidationRequestsFromConsensus(er.Consolidations), - } -} - func SignedBlindedBeaconBlockElectraFromConsensus(b *eth.SignedBlindedBeaconBlockElectra) (*SignedBlindedBeaconBlockElectra, error) { block, err := BlindedBeaconBlockElectraFromConsensus(b.Message) if err != nil { @@ -3278,11 +2390,6 @@ func SignedBeaconBlockElectraFromConsensus(b *eth.SignedBeaconBlockElectra) (*Si }, nil } -var ( - ExecutionPayloadElectraFromConsensus = ExecutionPayloadDenebFromConsensus - ExecutionPayloadHeaderElectraFromConsensus = ExecutionPayloadHeaderDenebFromConsensus -) - // ---------------------------------------------------------------------------- // Fulu // ---------------------------------------------------------------------------- @@ -3778,9 +2885,3 @@ func SignedBeaconBlockFuluFromConsensus(b *eth.SignedBeaconBlockFulu) (*SignedBe Signature: hexutil.Encode(b.Signature), }, nil } - -var ( - ExecutionPayloadFuluFromConsensus = ExecutionPayloadDenebFromConsensus - ExecutionPayloadHeaderFuluFromConsensus = ExecutionPayloadHeaderDenebFromConsensus - BeaconBlockFuluFromConsensus = BeaconBlockElectraFromConsensus -) diff --git a/api/server/structs/conversions_block_execution.go b/api/server/structs/conversions_block_execution.go new file mode 100644 index 0000000000..c3cfc49dbf --- /dev/null +++ b/api/server/structs/conversions_block_execution.go @@ -0,0 +1,973 @@ +package structs + +import ( + "fmt" + "strconv" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/prysmaticlabs/prysm/v5/api/server" + fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" + "github.com/prysmaticlabs/prysm/v5/config/params" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" + "github.com/prysmaticlabs/prysm/v5/container/slice" + "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" + enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" +) + +// ---------------------------------------------------------------------------- +// Bellatrix +// ---------------------------------------------------------------------------- + +func ExecutionPayloadFromConsensus(payload *enginev1.ExecutionPayload) (*ExecutionPayload, error) { + baseFeePerGas, err := sszBytesToUint256String(payload.BaseFeePerGas) + if err != nil { + return nil, err + } + transactions := make([]string, len(payload.Transactions)) + for i, tx := range payload.Transactions { + transactions[i] = hexutil.Encode(tx) + } + + return &ExecutionPayload{ + ParentHash: hexutil.Encode(payload.ParentHash), + FeeRecipient: hexutil.Encode(payload.FeeRecipient), + StateRoot: hexutil.Encode(payload.StateRoot), + ReceiptsRoot: hexutil.Encode(payload.ReceiptsRoot), + LogsBloom: hexutil.Encode(payload.LogsBloom), + PrevRandao: hexutil.Encode(payload.PrevRandao), + BlockNumber: fmt.Sprintf("%d", payload.BlockNumber), + GasLimit: fmt.Sprintf("%d", payload.GasLimit), + GasUsed: fmt.Sprintf("%d", payload.GasUsed), + Timestamp: fmt.Sprintf("%d", payload.Timestamp), + ExtraData: hexutil.Encode(payload.ExtraData), + BaseFeePerGas: baseFeePerGas, + BlockHash: hexutil.Encode(payload.BlockHash), + Transactions: transactions, + }, nil +} + +func (e *ExecutionPayload) ToConsensus() (*enginev1.ExecutionPayload, error) { + if e == nil { + return nil, server.NewDecodeError(errNilValue, "ExecutionPayload") + } + payloadParentHash, err := bytesutil.DecodeHexWithLength(e.ParentHash, common.HashLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.ParentHash") + } + payloadFeeRecipient, err := bytesutil.DecodeHexWithLength(e.FeeRecipient, fieldparams.FeeRecipientLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.FeeRecipient") + } + payloadStateRoot, err := bytesutil.DecodeHexWithLength(e.StateRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.StateRoot") + } + payloadReceiptsRoot, err := bytesutil.DecodeHexWithLength(e.ReceiptsRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.ReceiptsRoot") + } + payloadLogsBloom, err := bytesutil.DecodeHexWithLength(e.LogsBloom, fieldparams.LogsBloomLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.LogsBloom") + } + payloadPrevRandao, err := bytesutil.DecodeHexWithLength(e.PrevRandao, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.PrevRandao") + } + payloadBlockNumber, err := strconv.ParseUint(e.BlockNumber, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.BlockNumber") + } + payloadGasLimit, err := strconv.ParseUint(e.GasLimit, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.GasLimit") + } + payloadGasUsed, err := strconv.ParseUint(e.GasUsed, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.GasUsed") + } + payloadTimestamp, err := strconv.ParseUint(e.Timestamp, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.Timestamp") + } + payloadExtraData, err := bytesutil.DecodeHexWithMaxLength(e.ExtraData, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.ExtraData") + } + payloadBaseFeePerGas, err := bytesutil.Uint256ToSSZBytes(e.BaseFeePerGas) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.BaseFeePerGas") + } + payloadBlockHash, err := bytesutil.DecodeHexWithLength(e.BlockHash, common.HashLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.BlockHash") + } + err = slice.VerifyMaxLength(e.Transactions, fieldparams.MaxTxsPerPayloadLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.Transactions") + } + payloadTxs := make([][]byte, len(e.Transactions)) + for i, tx := range e.Transactions { + payloadTxs[i], err = bytesutil.DecodeHexWithMaxLength(tx, fieldparams.MaxBytesPerTxLength) + if err != nil { + return nil, server.NewDecodeError(err, fmt.Sprintf("ExecutionPayload.Transactions[%d]", i)) + } + } + return &enginev1.ExecutionPayload{ + ParentHash: payloadParentHash, + FeeRecipient: payloadFeeRecipient, + StateRoot: payloadStateRoot, + ReceiptsRoot: payloadReceiptsRoot, + LogsBloom: payloadLogsBloom, + PrevRandao: payloadPrevRandao, + BlockNumber: payloadBlockNumber, + GasLimit: payloadGasLimit, + GasUsed: payloadGasUsed, + Timestamp: payloadTimestamp, + ExtraData: payloadExtraData, + BaseFeePerGas: payloadBaseFeePerGas, + BlockHash: payloadBlockHash, + Transactions: payloadTxs, + }, nil +} + +func ExecutionPayloadHeaderFromConsensus(payload *enginev1.ExecutionPayloadHeader) (*ExecutionPayloadHeader, error) { + baseFeePerGas, err := sszBytesToUint256String(payload.BaseFeePerGas) + if err != nil { + return nil, err + } + + return &ExecutionPayloadHeader{ + ParentHash: hexutil.Encode(payload.ParentHash), + FeeRecipient: hexutil.Encode(payload.FeeRecipient), + StateRoot: hexutil.Encode(payload.StateRoot), + ReceiptsRoot: hexutil.Encode(payload.ReceiptsRoot), + LogsBloom: hexutil.Encode(payload.LogsBloom), + PrevRandao: hexutil.Encode(payload.PrevRandao), + BlockNumber: fmt.Sprintf("%d", payload.BlockNumber), + GasLimit: fmt.Sprintf("%d", payload.GasLimit), + GasUsed: fmt.Sprintf("%d", payload.GasUsed), + Timestamp: fmt.Sprintf("%d", payload.Timestamp), + ExtraData: hexutil.Encode(payload.ExtraData), + BaseFeePerGas: baseFeePerGas, + BlockHash: hexutil.Encode(payload.BlockHash), + TransactionsRoot: hexutil.Encode(payload.TransactionsRoot), + }, nil +} + +func (e *ExecutionPayloadHeader) ToConsensus() (*enginev1.ExecutionPayloadHeader, error) { + if e == nil { + return nil, server.NewDecodeError(errNilValue, "ExecutionPayloadHeader") + } + payloadParentHash, err := bytesutil.DecodeHexWithLength(e.ParentHash, common.HashLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.ParentHash") + } + payloadFeeRecipient, err := bytesutil.DecodeHexWithLength(e.FeeRecipient, fieldparams.FeeRecipientLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.FeeRecipient") + } + payloadStateRoot, err := bytesutil.DecodeHexWithLength(e.StateRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.StateRoot") + } + payloadReceiptsRoot, err := bytesutil.DecodeHexWithLength(e.ReceiptsRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.ReceiptsRoot") + } + payloadLogsBloom, err := bytesutil.DecodeHexWithLength(e.LogsBloom, fieldparams.LogsBloomLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.LogsBloom") + } + payloadPrevRandao, err := bytesutil.DecodeHexWithLength(e.PrevRandao, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.PrevRandao") + } + payloadBlockNumber, err := strconv.ParseUint(e.BlockNumber, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.BlockNumber") + } + payloadGasLimit, err := strconv.ParseUint(e.GasLimit, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.GasLimit") + } + payloadGasUsed, err := strconv.ParseUint(e.GasUsed, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.GasUsed") + } + payloadTimestamp, err := strconv.ParseUint(e.Timestamp, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.Timestamp") + } + payloadExtraData, err := bytesutil.DecodeHexWithMaxLength(e.ExtraData, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.ExtraData") + } + payloadBaseFeePerGas, err := bytesutil.Uint256ToSSZBytes(e.BaseFeePerGas) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.BaseFeePerGas") + } + payloadBlockHash, err := bytesutil.DecodeHexWithLength(e.BlockHash, common.HashLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.BlockHash") + } + payloadTxsRoot, err := bytesutil.DecodeHexWithLength(e.TransactionsRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.TransactionsRoot") + } + + return &enginev1.ExecutionPayloadHeader{ + ParentHash: payloadParentHash, + FeeRecipient: payloadFeeRecipient, + StateRoot: payloadStateRoot, + ReceiptsRoot: payloadReceiptsRoot, + LogsBloom: payloadLogsBloom, + PrevRandao: payloadPrevRandao, + BlockNumber: payloadBlockNumber, + GasLimit: payloadGasLimit, + GasUsed: payloadGasUsed, + Timestamp: payloadTimestamp, + ExtraData: payloadExtraData, + BaseFeePerGas: payloadBaseFeePerGas, + BlockHash: payloadBlockHash, + TransactionsRoot: payloadTxsRoot, + }, nil +} + +// ---------------------------------------------------------------------------- +// Capella +// ---------------------------------------------------------------------------- + +func ExecutionPayloadCapellaFromConsensus(payload *enginev1.ExecutionPayloadCapella) (*ExecutionPayloadCapella, error) { + baseFeePerGas, err := sszBytesToUint256String(payload.BaseFeePerGas) + if err != nil { + return nil, err + } + transactions := make([]string, len(payload.Transactions)) + for i, tx := range payload.Transactions { + transactions[i] = hexutil.Encode(tx) + } + + return &ExecutionPayloadCapella{ + ParentHash: hexutil.Encode(payload.ParentHash), + FeeRecipient: hexutil.Encode(payload.FeeRecipient), + StateRoot: hexutil.Encode(payload.StateRoot), + ReceiptsRoot: hexutil.Encode(payload.ReceiptsRoot), + LogsBloom: hexutil.Encode(payload.LogsBloom), + PrevRandao: hexutil.Encode(payload.PrevRandao), + BlockNumber: fmt.Sprintf("%d", payload.BlockNumber), + GasLimit: fmt.Sprintf("%d", payload.GasLimit), + GasUsed: fmt.Sprintf("%d", payload.GasUsed), + Timestamp: fmt.Sprintf("%d", payload.Timestamp), + ExtraData: hexutil.Encode(payload.ExtraData), + BaseFeePerGas: baseFeePerGas, + BlockHash: hexutil.Encode(payload.BlockHash), + Transactions: transactions, + Withdrawals: WithdrawalsFromConsensus(payload.Withdrawals), + }, nil +} + +func (e *ExecutionPayloadCapella) ToConsensus() (*enginev1.ExecutionPayloadCapella, error) { + if e == nil { + return nil, server.NewDecodeError(errNilValue, "ExecutionPayload") + } + payloadParentHash, err := bytesutil.DecodeHexWithLength(e.ParentHash, common.HashLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.ParentHash") + } + payloadFeeRecipient, err := bytesutil.DecodeHexWithLength(e.FeeRecipient, fieldparams.FeeRecipientLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.FeeRecipient") + } + payloadStateRoot, err := bytesutil.DecodeHexWithLength(e.StateRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.StateRoot") + } + payloadReceiptsRoot, err := bytesutil.DecodeHexWithLength(e.ReceiptsRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.ReceiptsRoot") + } + payloadLogsBloom, err := bytesutil.DecodeHexWithLength(e.LogsBloom, fieldparams.LogsBloomLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.LogsBloom") + } + payloadPrevRandao, err := bytesutil.DecodeHexWithLength(e.PrevRandao, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.PrevRandao") + } + payloadBlockNumber, err := strconv.ParseUint(e.BlockNumber, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.BlockNumber") + } + payloadGasLimit, err := strconv.ParseUint(e.GasLimit, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.GasLimit") + } + payloadGasUsed, err := strconv.ParseUint(e.GasUsed, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.GasUsed") + } + payloadTimestamp, err := strconv.ParseUint(e.Timestamp, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.Timestamp") + } + payloadExtraData, err := bytesutil.DecodeHexWithMaxLength(e.ExtraData, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.ExtraData") + } + payloadBaseFeePerGas, err := bytesutil.Uint256ToSSZBytes(e.BaseFeePerGas) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.BaseFeePerGas") + } + payloadBlockHash, err := bytesutil.DecodeHexWithLength(e.BlockHash, common.HashLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.BlockHash") + } + err = slice.VerifyMaxLength(e.Transactions, fieldparams.MaxTxsPerPayloadLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.Transactions") + } + payloadTxs := make([][]byte, len(e.Transactions)) + for i, tx := range e.Transactions { + payloadTxs[i], err = bytesutil.DecodeHexWithMaxLength(tx, fieldparams.MaxBytesPerTxLength) + if err != nil { + return nil, server.NewDecodeError(err, fmt.Sprintf("ExecutionPayload.Transactions[%d]", i)) + } + } + err = slice.VerifyMaxLength(e.Withdrawals, fieldparams.MaxWithdrawalsPerPayload) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.Withdrawals") + } + withdrawals := make([]*enginev1.Withdrawal, len(e.Withdrawals)) + for i, w := range e.Withdrawals { + withdrawalIndex, err := strconv.ParseUint(w.WithdrawalIndex, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, fmt.Sprintf("ExecutionPayload.Withdrawals[%d].WithdrawalIndex", i)) + } + validatorIndex, err := strconv.ParseUint(w.ValidatorIndex, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, fmt.Sprintf("ExecutionPayload.Withdrawals[%d].ValidatorIndex", i)) + } + address, err := bytesutil.DecodeHexWithLength(w.ExecutionAddress, common.AddressLength) + if err != nil { + return nil, server.NewDecodeError(err, fmt.Sprintf("ExecutionPayload.Withdrawals[%d].ExecutionAddress", i)) + } + amount, err := strconv.ParseUint(w.Amount, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, fmt.Sprintf("ExecutionPayload.Withdrawals[%d].Amount", i)) + } + withdrawals[i] = &enginev1.Withdrawal{ + Index: withdrawalIndex, + ValidatorIndex: primitives.ValidatorIndex(validatorIndex), + Address: address, + Amount: amount, + } + } + return &enginev1.ExecutionPayloadCapella{ + ParentHash: payloadParentHash, + FeeRecipient: payloadFeeRecipient, + StateRoot: payloadStateRoot, + ReceiptsRoot: payloadReceiptsRoot, + LogsBloom: payloadLogsBloom, + PrevRandao: payloadPrevRandao, + BlockNumber: payloadBlockNumber, + GasLimit: payloadGasLimit, + GasUsed: payloadGasUsed, + Timestamp: payloadTimestamp, + ExtraData: payloadExtraData, + BaseFeePerGas: payloadBaseFeePerGas, + BlockHash: payloadBlockHash, + Transactions: payloadTxs, + Withdrawals: withdrawals, + }, nil +} + +func ExecutionPayloadHeaderCapellaFromConsensus(payload *enginev1.ExecutionPayloadHeaderCapella) (*ExecutionPayloadHeaderCapella, error) { + baseFeePerGas, err := sszBytesToUint256String(payload.BaseFeePerGas) + if err != nil { + return nil, err + } + + return &ExecutionPayloadHeaderCapella{ + ParentHash: hexutil.Encode(payload.ParentHash), + FeeRecipient: hexutil.Encode(payload.FeeRecipient), + StateRoot: hexutil.Encode(payload.StateRoot), + ReceiptsRoot: hexutil.Encode(payload.ReceiptsRoot), + LogsBloom: hexutil.Encode(payload.LogsBloom), + PrevRandao: hexutil.Encode(payload.PrevRandao), + BlockNumber: fmt.Sprintf("%d", payload.BlockNumber), + GasLimit: fmt.Sprintf("%d", payload.GasLimit), + GasUsed: fmt.Sprintf("%d", payload.GasUsed), + Timestamp: fmt.Sprintf("%d", payload.Timestamp), + ExtraData: hexutil.Encode(payload.ExtraData), + BaseFeePerGas: baseFeePerGas, + BlockHash: hexutil.Encode(payload.BlockHash), + TransactionsRoot: hexutil.Encode(payload.TransactionsRoot), + WithdrawalsRoot: hexutil.Encode(payload.WithdrawalsRoot), + }, nil +} + +func (e *ExecutionPayloadHeaderCapella) ToConsensus() (*enginev1.ExecutionPayloadHeaderCapella, error) { + if e == nil { + return nil, server.NewDecodeError(errNilValue, "ExecutionPayloadHeader") + } + payloadParentHash, err := bytesutil.DecodeHexWithLength(e.ParentHash, common.HashLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.ParentHash") + } + payloadFeeRecipient, err := bytesutil.DecodeHexWithLength(e.FeeRecipient, fieldparams.FeeRecipientLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.FeeRecipient") + } + payloadStateRoot, err := bytesutil.DecodeHexWithLength(e.StateRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.StateRoot") + } + payloadReceiptsRoot, err := bytesutil.DecodeHexWithLength(e.ReceiptsRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.ReceiptsRoot") + } + payloadLogsBloom, err := bytesutil.DecodeHexWithLength(e.LogsBloom, fieldparams.LogsBloomLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.LogsBloom") + } + payloadPrevRandao, err := bytesutil.DecodeHexWithLength(e.PrevRandao, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.PrevRandao") + } + payloadBlockNumber, err := strconv.ParseUint(e.BlockNumber, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.BlockNumber") + } + payloadGasLimit, err := strconv.ParseUint(e.GasLimit, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.GasLimit") + } + payloadGasUsed, err := strconv.ParseUint(e.GasUsed, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.GasUsed") + } + payloadTimestamp, err := strconv.ParseUint(e.Timestamp, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.Timestamp") + } + payloadExtraData, err := bytesutil.DecodeHexWithMaxLength(e.ExtraData, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.ExtraData") + } + payloadBaseFeePerGas, err := bytesutil.Uint256ToSSZBytes(e.BaseFeePerGas) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.BaseFeePerGas") + } + payloadBlockHash, err := bytesutil.DecodeHexWithMaxLength(e.BlockHash, common.HashLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.BlockHash") + } + payloadTxsRoot, err := bytesutil.DecodeHexWithMaxLength(e.TransactionsRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.TransactionsRoot") + } + payloadWithdrawalsRoot, err := bytesutil.DecodeHexWithMaxLength(e.WithdrawalsRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.WithdrawalsRoot") + } + return &enginev1.ExecutionPayloadHeaderCapella{ + ParentHash: payloadParentHash, + FeeRecipient: payloadFeeRecipient, + StateRoot: payloadStateRoot, + ReceiptsRoot: payloadReceiptsRoot, + LogsBloom: payloadLogsBloom, + PrevRandao: payloadPrevRandao, + BlockNumber: payloadBlockNumber, + GasLimit: payloadGasLimit, + GasUsed: payloadGasUsed, + Timestamp: payloadTimestamp, + ExtraData: payloadExtraData, + BaseFeePerGas: payloadBaseFeePerGas, + BlockHash: payloadBlockHash, + TransactionsRoot: payloadTxsRoot, + WithdrawalsRoot: payloadWithdrawalsRoot, + }, nil +} + +// ---------------------------------------------------------------------------- +// Deneb +// ---------------------------------------------------------------------------- + +func ExecutionPayloadDenebFromConsensus(payload *enginev1.ExecutionPayloadDeneb) (*ExecutionPayloadDeneb, error) { + baseFeePerGas, err := sszBytesToUint256String(payload.BaseFeePerGas) + if err != nil { + return nil, err + } + transactions := make([]string, len(payload.Transactions)) + for i, tx := range payload.Transactions { + transactions[i] = hexutil.Encode(tx) + } + + return &ExecutionPayloadDeneb{ + ParentHash: hexutil.Encode(payload.ParentHash), + FeeRecipient: hexutil.Encode(payload.FeeRecipient), + StateRoot: hexutil.Encode(payload.StateRoot), + ReceiptsRoot: hexutil.Encode(payload.ReceiptsRoot), + LogsBloom: hexutil.Encode(payload.LogsBloom), + PrevRandao: hexutil.Encode(payload.PrevRandao), + BlockNumber: fmt.Sprintf("%d", payload.BlockNumber), + GasLimit: fmt.Sprintf("%d", payload.GasLimit), + GasUsed: fmt.Sprintf("%d", payload.GasUsed), + Timestamp: fmt.Sprintf("%d", payload.Timestamp), + ExtraData: hexutil.Encode(payload.ExtraData), + BaseFeePerGas: baseFeePerGas, + BlockHash: hexutil.Encode(payload.BlockHash), + Transactions: transactions, + Withdrawals: WithdrawalsFromConsensus(payload.Withdrawals), + BlobGasUsed: fmt.Sprintf("%d", payload.BlobGasUsed), + ExcessBlobGas: fmt.Sprintf("%d", payload.ExcessBlobGas), + }, nil +} + +func (e *ExecutionPayloadDeneb) ToConsensus() (*enginev1.ExecutionPayloadDeneb, error) { + if e == nil { + return nil, server.NewDecodeError(errNilValue, "ExecutionPayload") + } + payloadParentHash, err := bytesutil.DecodeHexWithLength(e.ParentHash, common.HashLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.ParentHash") + } + payloadFeeRecipient, err := bytesutil.DecodeHexWithLength(e.FeeRecipient, fieldparams.FeeRecipientLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.FeeRecipient") + } + payloadStateRoot, err := bytesutil.DecodeHexWithLength(e.StateRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.StateRoot") + } + payloadReceiptsRoot, err := bytesutil.DecodeHexWithLength(e.ReceiptsRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.ReceiptsRoot") + } + payloadLogsBloom, err := bytesutil.DecodeHexWithLength(e.LogsBloom, fieldparams.LogsBloomLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.LogsBloom") + } + payloadPrevRandao, err := bytesutil.DecodeHexWithLength(e.PrevRandao, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.PrevRandao") + } + payloadBlockNumber, err := strconv.ParseUint(e.BlockNumber, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.BlockNumber") + } + payloadGasLimit, err := strconv.ParseUint(e.GasLimit, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.GasLimit") + } + payloadGasUsed, err := strconv.ParseUint(e.GasUsed, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.GasUsed") + } + payloadTimestamp, err := strconv.ParseUint(e.Timestamp, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.Timestamp") + } + payloadExtraData, err := bytesutil.DecodeHexWithMaxLength(e.ExtraData, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.ExtraData") + } + payloadBaseFeePerGas, err := bytesutil.Uint256ToSSZBytes(e.BaseFeePerGas) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.BaseFeePerGas") + } + payloadBlockHash, err := bytesutil.DecodeHexWithLength(e.BlockHash, common.HashLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.BlockHash") + } + err = slice.VerifyMaxLength(e.Transactions, fieldparams.MaxTxsPerPayloadLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.Transactions") + } + txs := make([][]byte, len(e.Transactions)) + for i, tx := range e.Transactions { + txs[i], err = bytesutil.DecodeHexWithMaxLength(tx, fieldparams.MaxBytesPerTxLength) + if err != nil { + return nil, server.NewDecodeError(err, fmt.Sprintf("ExecutionPayload.Transactions[%d]", i)) + } + } + err = slice.VerifyMaxLength(e.Withdrawals, fieldparams.MaxWithdrawalsPerPayload) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.Withdrawals") + } + withdrawals := make([]*enginev1.Withdrawal, len(e.Withdrawals)) + for i, w := range e.Withdrawals { + withdrawalIndex, err := strconv.ParseUint(w.WithdrawalIndex, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, fmt.Sprintf("ExecutionPayload.Withdrawals[%d].WithdrawalIndex", i)) + } + validatorIndex, err := strconv.ParseUint(w.ValidatorIndex, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, fmt.Sprintf("ExecutionPayload.Withdrawals[%d].ValidatorIndex", i)) + } + address, err := bytesutil.DecodeHexWithLength(w.ExecutionAddress, common.AddressLength) + if err != nil { + return nil, server.NewDecodeError(err, fmt.Sprintf("ExecutionPayload.Withdrawals[%d].ExecutionAddress", i)) + } + amount, err := strconv.ParseUint(w.Amount, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, fmt.Sprintf("ExecutionPayload.Withdrawals[%d].Amount", i)) + } + withdrawals[i] = &enginev1.Withdrawal{ + Index: withdrawalIndex, + ValidatorIndex: primitives.ValidatorIndex(validatorIndex), + Address: address, + Amount: amount, + } + } + + payloadBlobGasUsed, err := strconv.ParseUint(e.BlobGasUsed, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.BlobGasUsed") + } + payloadExcessBlobGas, err := strconv.ParseUint(e.ExcessBlobGas, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.ExcessBlobGas") + } + return &enginev1.ExecutionPayloadDeneb{ + ParentHash: payloadParentHash, + FeeRecipient: payloadFeeRecipient, + StateRoot: payloadStateRoot, + ReceiptsRoot: payloadReceiptsRoot, + LogsBloom: payloadLogsBloom, + PrevRandao: payloadPrevRandao, + BlockNumber: payloadBlockNumber, + GasLimit: payloadGasLimit, + GasUsed: payloadGasUsed, + Timestamp: payloadTimestamp, + ExtraData: payloadExtraData, + BaseFeePerGas: payloadBaseFeePerGas, + BlockHash: payloadBlockHash, + Transactions: txs, + Withdrawals: withdrawals, + BlobGasUsed: payloadBlobGasUsed, + ExcessBlobGas: payloadExcessBlobGas, + }, nil +} + +func ExecutionPayloadHeaderDenebFromConsensus(payload *enginev1.ExecutionPayloadHeaderDeneb) (*ExecutionPayloadHeaderDeneb, error) { + baseFeePerGas, err := sszBytesToUint256String(payload.BaseFeePerGas) + if err != nil { + return nil, err + } + + return &ExecutionPayloadHeaderDeneb{ + ParentHash: hexutil.Encode(payload.ParentHash), + FeeRecipient: hexutil.Encode(payload.FeeRecipient), + StateRoot: hexutil.Encode(payload.StateRoot), + ReceiptsRoot: hexutil.Encode(payload.ReceiptsRoot), + LogsBloom: hexutil.Encode(payload.LogsBloom), + PrevRandao: hexutil.Encode(payload.PrevRandao), + BlockNumber: fmt.Sprintf("%d", payload.BlockNumber), + GasLimit: fmt.Sprintf("%d", payload.GasLimit), + GasUsed: fmt.Sprintf("%d", payload.GasUsed), + Timestamp: fmt.Sprintf("%d", payload.Timestamp), + ExtraData: hexutil.Encode(payload.ExtraData), + BaseFeePerGas: baseFeePerGas, + BlockHash: hexutil.Encode(payload.BlockHash), + TransactionsRoot: hexutil.Encode(payload.TransactionsRoot), + WithdrawalsRoot: hexutil.Encode(payload.WithdrawalsRoot), + BlobGasUsed: fmt.Sprintf("%d", payload.BlobGasUsed), + ExcessBlobGas: fmt.Sprintf("%d", payload.ExcessBlobGas), + }, nil +} + +func (e *ExecutionPayloadHeaderDeneb) ToConsensus() (*enginev1.ExecutionPayloadHeaderDeneb, error) { + if e == nil { + return nil, server.NewDecodeError(errNilValue, "ExecutionPayloadHeader") + } + payloadParentHash, err := bytesutil.DecodeHexWithLength(e.ParentHash, common.HashLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.ParentHash") + } + payloadFeeRecipient, err := bytesutil.DecodeHexWithLength(e.FeeRecipient, fieldparams.FeeRecipientLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.FeeRecipient") + } + payloadStateRoot, err := bytesutil.DecodeHexWithLength(e.StateRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.StateRoot") + } + payloadReceiptsRoot, err := bytesutil.DecodeHexWithLength(e.ReceiptsRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.ReceiptsRoot") + } + payloadLogsBloom, err := bytesutil.DecodeHexWithLength(e.LogsBloom, fieldparams.LogsBloomLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.LogsBloom") + } + payloadPrevRandao, err := bytesutil.DecodeHexWithLength(e.PrevRandao, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.PrevRandao") + } + payloadBlockNumber, err := strconv.ParseUint(e.BlockNumber, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.BlockNumber") + } + payloadGasLimit, err := strconv.ParseUint(e.GasLimit, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.GasLimit") + } + payloadGasUsed, err := strconv.ParseUint(e.GasUsed, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.GasUsed") + } + payloadTimestamp, err := strconv.ParseUint(e.Timestamp, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.Timestamp") + } + payloadExtraData, err := bytesutil.DecodeHexWithMaxLength(e.ExtraData, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.ExtraData") + } + payloadBaseFeePerGas, err := bytesutil.Uint256ToSSZBytes(e.BaseFeePerGas) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.BaseFeePerGas") + } + payloadBlockHash, err := bytesutil.DecodeHexWithLength(e.BlockHash, common.HashLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.BlockHash") + } + payloadTxsRoot, err := bytesutil.DecodeHexWithLength(e.TransactionsRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.TransactionsRoot") + } + payloadWithdrawalsRoot, err := bytesutil.DecodeHexWithLength(e.WithdrawalsRoot, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayloadHeader.WithdrawalsRoot") + } + payloadBlobGasUsed, err := strconv.ParseUint(e.BlobGasUsed, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.BlobGasUsed") + } + payloadExcessBlobGas, err := strconv.ParseUint(e.ExcessBlobGas, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "ExecutionPayload.ExcessBlobGas") + } + return &enginev1.ExecutionPayloadHeaderDeneb{ + ParentHash: payloadParentHash, + FeeRecipient: payloadFeeRecipient, + StateRoot: payloadStateRoot, + ReceiptsRoot: payloadReceiptsRoot, + LogsBloom: payloadLogsBloom, + PrevRandao: payloadPrevRandao, + BlockNumber: payloadBlockNumber, + GasLimit: payloadGasLimit, + GasUsed: payloadGasUsed, + Timestamp: payloadTimestamp, + ExtraData: payloadExtraData, + BaseFeePerGas: payloadBaseFeePerGas, + BlockHash: payloadBlockHash, + TransactionsRoot: payloadTxsRoot, + WithdrawalsRoot: payloadWithdrawalsRoot, + BlobGasUsed: payloadBlobGasUsed, + ExcessBlobGas: payloadExcessBlobGas, + }, nil +} + +// ---------------------------------------------------------------------------- +// Electra +// ---------------------------------------------------------------------------- + +var ( + ExecutionPayloadElectraFromConsensus = ExecutionPayloadDenebFromConsensus + ExecutionPayloadHeaderElectraFromConsensus = ExecutionPayloadHeaderDenebFromConsensus +) + +func WithdrawalRequestsFromConsensus(ws []*enginev1.WithdrawalRequest) []*WithdrawalRequest { + result := make([]*WithdrawalRequest, len(ws)) + for i, w := range ws { + result[i] = WithdrawalRequestFromConsensus(w) + } + return result +} + +func WithdrawalRequestFromConsensus(w *enginev1.WithdrawalRequest) *WithdrawalRequest { + return &WithdrawalRequest{ + SourceAddress: hexutil.Encode(w.SourceAddress), + ValidatorPubkey: hexutil.Encode(w.ValidatorPubkey), + Amount: fmt.Sprintf("%d", w.Amount), + } +} + +func (w *WithdrawalRequest) ToConsensus() (*enginev1.WithdrawalRequest, error) { + if w == nil { + return nil, server.NewDecodeError(errNilValue, "WithdrawalRequest") + } + src, err := bytesutil.DecodeHexWithLength(w.SourceAddress, common.AddressLength) + if err != nil { + return nil, server.NewDecodeError(err, "SourceAddress") + } + pubkey, err := bytesutil.DecodeHexWithLength(w.ValidatorPubkey, fieldparams.BLSPubkeyLength) + if err != nil { + return nil, server.NewDecodeError(err, "ValidatorPubkey") + } + amount, err := strconv.ParseUint(w.Amount, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "Amount") + } + return &enginev1.WithdrawalRequest{ + SourceAddress: src, + ValidatorPubkey: pubkey, + Amount: amount, + }, nil +} + +func ConsolidationRequestsFromConsensus(cs []*enginev1.ConsolidationRequest) []*ConsolidationRequest { + result := make([]*ConsolidationRequest, len(cs)) + for i, c := range cs { + result[i] = ConsolidationRequestFromConsensus(c) + } + return result +} + +func ConsolidationRequestFromConsensus(c *enginev1.ConsolidationRequest) *ConsolidationRequest { + return &ConsolidationRequest{ + SourceAddress: hexutil.Encode(c.SourceAddress), + SourcePubkey: hexutil.Encode(c.SourcePubkey), + TargetPubkey: hexutil.Encode(c.TargetPubkey), + } +} + +func (c *ConsolidationRequest) ToConsensus() (*enginev1.ConsolidationRequest, error) { + if c == nil { + return nil, server.NewDecodeError(errNilValue, "ConsolidationRequest") + } + srcAddress, err := bytesutil.DecodeHexWithLength(c.SourceAddress, common.AddressLength) + if err != nil { + return nil, server.NewDecodeError(err, "SourceAddress") + } + srcPubkey, err := bytesutil.DecodeHexWithLength(c.SourcePubkey, fieldparams.BLSPubkeyLength) + if err != nil { + return nil, server.NewDecodeError(err, "SourcePubkey") + } + targetPubkey, err := bytesutil.DecodeHexWithLength(c.TargetPubkey, fieldparams.BLSPubkeyLength) + if err != nil { + return nil, server.NewDecodeError(err, "TargetPubkey") + } + return &enginev1.ConsolidationRequest{ + SourceAddress: srcAddress, + SourcePubkey: srcPubkey, + TargetPubkey: targetPubkey, + }, nil +} + +func DepositRequestsFromConsensus(ds []*enginev1.DepositRequest) []*DepositRequest { + result := make([]*DepositRequest, len(ds)) + for i, d := range ds { + result[i] = DepositRequestFromConsensus(d) + } + return result +} + +func DepositRequestFromConsensus(d *enginev1.DepositRequest) *DepositRequest { + return &DepositRequest{ + Pubkey: hexutil.Encode(d.Pubkey), + WithdrawalCredentials: hexutil.Encode(d.WithdrawalCredentials), + Amount: fmt.Sprintf("%d", d.Amount), + Signature: hexutil.Encode(d.Signature), + Index: fmt.Sprintf("%d", d.Index), + } +} + +func (d *DepositRequest) ToConsensus() (*enginev1.DepositRequest, error) { + if d == nil { + return nil, server.NewDecodeError(errNilValue, "DepositRequest") + } + pubkey, err := bytesutil.DecodeHexWithLength(d.Pubkey, fieldparams.BLSPubkeyLength) + if err != nil { + return nil, server.NewDecodeError(err, "Pubkey") + } + withdrawalCredentials, err := bytesutil.DecodeHexWithLength(d.WithdrawalCredentials, fieldparams.RootLength) + if err != nil { + return nil, server.NewDecodeError(err, "WithdrawalCredentials") + } + amount, err := strconv.ParseUint(d.Amount, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "Amount") + } + sig, err := bytesutil.DecodeHexWithLength(d.Signature, fieldparams.BLSSignatureLength) + if err != nil { + return nil, server.NewDecodeError(err, "Signature") + } + index, err := strconv.ParseUint(d.Index, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "Index") + } + return &enginev1.DepositRequest{ + Pubkey: pubkey, + WithdrawalCredentials: withdrawalCredentials, + Amount: amount, + Signature: sig, + Index: index, + }, nil +} + +func ExecutionRequestsFromConsensus(er *enginev1.ExecutionRequests) *ExecutionRequests { + return &ExecutionRequests{ + Deposits: DepositRequestsFromConsensus(er.Deposits), + Withdrawals: WithdrawalRequestsFromConsensus(er.Withdrawals), + Consolidations: ConsolidationRequestsFromConsensus(er.Consolidations), + } +} + +func (e *ExecutionRequests) ToConsensus() (*enginev1.ExecutionRequests, error) { + if e == nil { + return nil, server.NewDecodeError(errNilValue, "ExecutionRequests") + } + var err error + if err = slice.VerifyMaxLength(e.Deposits, params.BeaconConfig().MaxDepositRequestsPerPayload); err != nil { + return nil, err + } + depositRequests := make([]*enginev1.DepositRequest, len(e.Deposits)) + for i, d := range e.Deposits { + depositRequests[i], err = d.ToConsensus() + if err != nil { + return nil, server.NewDecodeError(err, fmt.Sprintf("ExecutionRequests.Deposits[%d]", i)) + } + } + + if err = slice.VerifyMaxLength(e.Withdrawals, params.BeaconConfig().MaxWithdrawalRequestsPerPayload); err != nil { + return nil, err + } + withdrawalRequests := make([]*enginev1.WithdrawalRequest, len(e.Withdrawals)) + for i, w := range e.Withdrawals { + withdrawalRequests[i], err = w.ToConsensus() + if err != nil { + return nil, server.NewDecodeError(err, fmt.Sprintf("ExecutionRequests.Withdrawals[%d]", i)) + } + } + + if err = slice.VerifyMaxLength(e.Consolidations, params.BeaconConfig().MaxConsolidationsRequestsPerPayload); err != nil { + return nil, err + } + consolidationRequests := make([]*enginev1.ConsolidationRequest, len(e.Consolidations)) + for i, c := range e.Consolidations { + consolidationRequests[i], err = c.ToConsensus() + if err != nil { + return nil, server.NewDecodeError(err, fmt.Sprintf("ExecutionRequests.Consolidations[%d]", i)) + } + } + return &enginev1.ExecutionRequests{ + Deposits: depositRequests, + Withdrawals: withdrawalRequests, + Consolidations: consolidationRequests, + }, nil +} + +// ---------------------------------------------------------------------------- +// Fulu +// ---------------------------------------------------------------------------- + +var ( + ExecutionPayloadFuluFromConsensus = ExecutionPayloadDenebFromConsensus + ExecutionPayloadHeaderFuluFromConsensus = ExecutionPayloadHeaderDenebFromConsensus + BeaconBlockFuluFromConsensus = BeaconBlockElectraFromConsensus +) diff --git a/api/server/structs/conversions_block_execution_test.go b/api/server/structs/conversions_block_execution_test.go new file mode 100644 index 0000000000..1ef680288d --- /dev/null +++ b/api/server/structs/conversions_block_execution_test.go @@ -0,0 +1,563 @@ +package structs + +import ( + "fmt" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" + "github.com/prysmaticlabs/prysm/v5/testing/require" +) + +func fillByteSlice(sliceLength int, value byte) []byte { + bytes := make([]byte, sliceLength) + + for index := range bytes { + bytes[index] = value + } + + return bytes +} + +// TestExecutionPayloadFromConsensus_HappyPath checks the +// ExecutionPayloadFromConsensus function under normal conditions. +func TestExecutionPayloadFromConsensus_HappyPath(t *testing.T) { + consensusPayload := &enginev1.ExecutionPayload{ + ParentHash: fillByteSlice(common.HashLength, 0xaa), + FeeRecipient: fillByteSlice(20, 0xbb), + StateRoot: fillByteSlice(32, 0xcc), + ReceiptsRoot: fillByteSlice(32, 0xdd), + LogsBloom: fillByteSlice(256, 0xee), + PrevRandao: fillByteSlice(32, 0xff), + BlockNumber: 12345, + GasLimit: 15000000, + GasUsed: 8000000, + Timestamp: 1680000000, + ExtraData: fillByteSlice(8, 0x11), + BaseFeePerGas: fillByteSlice(32, 0x01), + BlockHash: fillByteSlice(common.HashLength, 0x22), + Transactions: [][]byte{ + fillByteSlice(10, 0x33), + fillByteSlice(10, 0x44), + }, + } + + result, err := ExecutionPayloadFromConsensus(consensusPayload) + require.NoError(t, err) + require.NotNil(t, result) + require.Equal(t, hexutil.Encode(consensusPayload.ParentHash), result.ParentHash) + require.Equal(t, hexutil.Encode(consensusPayload.FeeRecipient), result.FeeRecipient) + require.Equal(t, hexutil.Encode(consensusPayload.StateRoot), result.StateRoot) + require.Equal(t, hexutil.Encode(consensusPayload.ReceiptsRoot), result.ReceiptsRoot) + require.Equal(t, fmt.Sprintf("%d", consensusPayload.BlockNumber), result.BlockNumber) +} + +// TestExecutionPayload_ToConsensus_HappyPath checks the +// (*ExecutionPayload).ToConsensus function under normal conditions. +func TestExecutionPayload_ToConsensus_HappyPath(t *testing.T) { + payload := &ExecutionPayload{ + ParentHash: hexutil.Encode(fillByteSlice(common.HashLength, 0xaa)), + FeeRecipient: hexutil.Encode(fillByteSlice(20, 0xbb)), + StateRoot: hexutil.Encode(fillByteSlice(32, 0xcc)), + ReceiptsRoot: hexutil.Encode(fillByteSlice(32, 0xdd)), + LogsBloom: hexutil.Encode(fillByteSlice(256, 0xee)), + PrevRandao: hexutil.Encode(fillByteSlice(32, 0xff)), + BlockNumber: "12345", + GasLimit: "15000000", + GasUsed: "8000000", + Timestamp: "1680000000", + ExtraData: "0x11111111", + BaseFeePerGas: "1234", + BlockHash: hexutil.Encode(fillByteSlice(common.HashLength, 0x22)), + Transactions: []string{ + hexutil.Encode(fillByteSlice(10, 0x33)), + hexutil.Encode(fillByteSlice(10, 0x44)), + }, + } + + result, err := payload.ToConsensus() + require.NoError(t, err) + require.DeepEqual(t, result.ParentHash, fillByteSlice(common.HashLength, 0xaa)) + require.DeepEqual(t, result.FeeRecipient, fillByteSlice(20, 0xbb)) + require.DeepEqual(t, result.StateRoot, fillByteSlice(32, 0xcc)) +} + +// TestExecutionPayloadHeaderFromConsensus_HappyPath checks the +// ExecutionPayloadHeaderFromConsensus function under normal conditions. +func TestExecutionPayloadHeaderFromConsensus_HappyPath(t *testing.T) { + consensusHeader := &enginev1.ExecutionPayloadHeader{ + ParentHash: fillByteSlice(common.HashLength, 0xaa), + FeeRecipient: fillByteSlice(20, 0xbb), + StateRoot: fillByteSlice(32, 0xcc), + ReceiptsRoot: fillByteSlice(32, 0xdd), + LogsBloom: fillByteSlice(256, 0xee), + PrevRandao: fillByteSlice(32, 0xff), + BlockNumber: 9999, + GasLimit: 5000000, + GasUsed: 2500000, + Timestamp: 1111111111, + ExtraData: fillByteSlice(4, 0x12), + BaseFeePerGas: fillByteSlice(32, 0x34), + BlockHash: fillByteSlice(common.HashLength, 0x56), + TransactionsRoot: fillByteSlice(32, 0x78), + } + + result, err := ExecutionPayloadHeaderFromConsensus(consensusHeader) + require.NoError(t, err) + require.NotNil(t, result) + require.Equal(t, hexutil.Encode(consensusHeader.ParentHash), result.ParentHash) + require.Equal(t, fmt.Sprintf("%d", consensusHeader.BlockNumber), result.BlockNumber) +} + +// TestExecutionPayloadHeader_ToConsensus_HappyPath checks the +// (*ExecutionPayloadHeader).ToConsensus function under normal conditions. +func TestExecutionPayloadHeader_ToConsensus_HappyPath(t *testing.T) { + header := &ExecutionPayloadHeader{ + ParentHash: hexutil.Encode(fillByteSlice(common.HashLength, 0xaa)), + FeeRecipient: hexutil.Encode(fillByteSlice(20, 0xbb)), + StateRoot: hexutil.Encode(fillByteSlice(32, 0xcc)), + ReceiptsRoot: hexutil.Encode(fillByteSlice(32, 0xdd)), + LogsBloom: hexutil.Encode(fillByteSlice(256, 0xee)), + PrevRandao: hexutil.Encode(fillByteSlice(32, 0xff)), + BlockNumber: "9999", + GasLimit: "5000000", + GasUsed: "2500000", + Timestamp: "1111111111", + ExtraData: "0x1234abcd", + BaseFeePerGas: "1234", + BlockHash: hexutil.Encode(fillByteSlice(common.HashLength, 0x56)), + TransactionsRoot: hexutil.Encode(fillByteSlice(32, 0x78)), + } + + result, err := header.ToConsensus() + require.NoError(t, err) + require.DeepEqual(t, hexutil.Encode(result.ParentHash), header.ParentHash) + require.DeepEqual(t, hexutil.Encode(result.FeeRecipient), header.FeeRecipient) + require.DeepEqual(t, hexutil.Encode(result.StateRoot), header.StateRoot) +} + +// TestExecutionPayloadCapellaFromConsensus_HappyPath checks the +// ExecutionPayloadCapellaFromConsensus function under normal conditions. +func TestExecutionPayloadCapellaFromConsensus_HappyPath(t *testing.T) { + capellaPayload := &enginev1.ExecutionPayloadCapella{ + ParentHash: fillByteSlice(common.HashLength, 0xaa), + FeeRecipient: fillByteSlice(20, 0xbb), + StateRoot: fillByteSlice(32, 0xcc), + ReceiptsRoot: fillByteSlice(32, 0xdd), + LogsBloom: fillByteSlice(256, 0xee), + PrevRandao: fillByteSlice(32, 0xff), + BlockNumber: 123, + GasLimit: 9876543, + GasUsed: 1234567, + Timestamp: 5555555, + ExtraData: fillByteSlice(6, 0x11), + BaseFeePerGas: fillByteSlice(32, 0x22), + BlockHash: fillByteSlice(common.HashLength, 0x33), + Transactions: [][]byte{ + fillByteSlice(5, 0x44), + }, + Withdrawals: []*enginev1.Withdrawal{ + { + Index: 1, + ValidatorIndex: 2, + Address: fillByteSlice(20, 0xaa), + Amount: 100, + }, + }, + } + + result, err := ExecutionPayloadCapellaFromConsensus(capellaPayload) + require.NoError(t, err) + require.NotNil(t, result) + require.Equal(t, hexutil.Encode(capellaPayload.ParentHash), result.ParentHash) + require.Equal(t, len(capellaPayload.Transactions), len(result.Transactions)) + require.Equal(t, len(capellaPayload.Withdrawals), len(result.Withdrawals)) +} + +// TestExecutionPayloadCapella_ToConsensus_HappyPath checks the +// (*ExecutionPayloadCapella).ToConsensus function under normal conditions. +func TestExecutionPayloadCapella_ToConsensus_HappyPath(t *testing.T) { + capella := &ExecutionPayloadCapella{ + ParentHash: hexutil.Encode(fillByteSlice(common.HashLength, 0xaa)), + FeeRecipient: hexutil.Encode(fillByteSlice(20, 0xbb)), + StateRoot: hexutil.Encode(fillByteSlice(32, 0xcc)), + ReceiptsRoot: hexutil.Encode(fillByteSlice(32, 0xdd)), + LogsBloom: hexutil.Encode(fillByteSlice(256, 0xee)), + PrevRandao: hexutil.Encode(fillByteSlice(32, 0xff)), + BlockNumber: "123", + GasLimit: "9876543", + GasUsed: "1234567", + Timestamp: "5555555", + ExtraData: hexutil.Encode(fillByteSlice(6, 0x11)), + BaseFeePerGas: "1234", + BlockHash: hexutil.Encode(fillByteSlice(common.HashLength, 0x33)), + Transactions: []string{ + hexutil.Encode(fillByteSlice(5, 0x44)), + }, + Withdrawals: []*Withdrawal{ + { + WithdrawalIndex: "1", + ValidatorIndex: "2", + ExecutionAddress: hexutil.Encode(fillByteSlice(20, 0xaa)), + Amount: "100", + }, + }, + } + + result, err := capella.ToConsensus() + require.NoError(t, err) + require.DeepEqual(t, hexutil.Encode(result.ParentHash), capella.ParentHash) + require.DeepEqual(t, hexutil.Encode(result.FeeRecipient), capella.FeeRecipient) + require.DeepEqual(t, hexutil.Encode(result.StateRoot), capella.StateRoot) +} + +// TestExecutionPayloadDenebFromConsensus_HappyPath checks the +// ExecutionPayloadDenebFromConsensus function under normal conditions. +func TestExecutionPayloadDenebFromConsensus_HappyPath(t *testing.T) { + denebPayload := &enginev1.ExecutionPayloadDeneb{ + ParentHash: fillByteSlice(common.HashLength, 0xaa), + FeeRecipient: fillByteSlice(20, 0xbb), + StateRoot: fillByteSlice(32, 0xcc), + ReceiptsRoot: fillByteSlice(32, 0xdd), + LogsBloom: fillByteSlice(256, 0xee), + PrevRandao: fillByteSlice(32, 0xff), + BlockNumber: 999, + GasLimit: 2222222, + GasUsed: 1111111, + Timestamp: 666666, + ExtraData: fillByteSlice(6, 0x11), + BaseFeePerGas: fillByteSlice(32, 0x22), + BlockHash: fillByteSlice(common.HashLength, 0x33), + Transactions: [][]byte{ + fillByteSlice(5, 0x44), + }, + Withdrawals: []*enginev1.Withdrawal{ + { + Index: 1, + ValidatorIndex: 2, + Address: fillByteSlice(20, 0xaa), + Amount: 100, + }, + }, + BlobGasUsed: 1234, + ExcessBlobGas: 5678, + } + + result, err := ExecutionPayloadDenebFromConsensus(denebPayload) + require.NoError(t, err) + require.Equal(t, hexutil.Encode(denebPayload.ParentHash), result.ParentHash) + require.Equal(t, len(denebPayload.Transactions), len(result.Transactions)) + require.Equal(t, len(denebPayload.Withdrawals), len(result.Withdrawals)) + require.Equal(t, "1234", result.BlobGasUsed) + require.Equal(t, fmt.Sprintf("%d", denebPayload.BlockNumber), result.BlockNumber) +} + +// TestExecutionPayloadDeneb_ToConsensus_HappyPath checks the +// (*ExecutionPayloadDeneb).ToConsensus function under normal conditions. +func TestExecutionPayloadDeneb_ToConsensus_HappyPath(t *testing.T) { + deneb := &ExecutionPayloadDeneb{ + ParentHash: hexutil.Encode(fillByteSlice(common.HashLength, 0xaa)), + FeeRecipient: hexutil.Encode(fillByteSlice(20, 0xbb)), + StateRoot: hexutil.Encode(fillByteSlice(32, 0xcc)), + ReceiptsRoot: hexutil.Encode(fillByteSlice(32, 0xdd)), + LogsBloom: hexutil.Encode(fillByteSlice(256, 0xee)), + PrevRandao: hexutil.Encode(fillByteSlice(32, 0xff)), + BlockNumber: "999", + GasLimit: "2222222", + GasUsed: "1111111", + Timestamp: "666666", + ExtraData: hexutil.Encode(fillByteSlice(6, 0x11)), + BaseFeePerGas: "1234", + BlockHash: hexutil.Encode(fillByteSlice(common.HashLength, 0x33)), + Transactions: []string{ + hexutil.Encode(fillByteSlice(5, 0x44)), + }, + Withdrawals: []*Withdrawal{ + { + WithdrawalIndex: "1", + ValidatorIndex: "2", + ExecutionAddress: hexutil.Encode(fillByteSlice(20, 0xaa)), + Amount: "100", + }, + }, + BlobGasUsed: "1234", + ExcessBlobGas: "5678", + } + + result, err := deneb.ToConsensus() + require.NoError(t, err) + require.DeepEqual(t, hexutil.Encode(result.ParentHash), deneb.ParentHash) + require.DeepEqual(t, hexutil.Encode(result.FeeRecipient), deneb.FeeRecipient) + require.Equal(t, result.BlockNumber, uint64(999)) +} + +func TestExecutionPayloadHeaderCapellaFromConsensus_HappyPath(t *testing.T) { + capellaHeader := &enginev1.ExecutionPayloadHeaderCapella{ + ParentHash: fillByteSlice(common.HashLength, 0xaa), + FeeRecipient: fillByteSlice(20, 0xbb), + StateRoot: fillByteSlice(32, 0xcc), + ReceiptsRoot: fillByteSlice(32, 0xdd), + LogsBloom: fillByteSlice(256, 0xee), + PrevRandao: fillByteSlice(32, 0xff), + BlockNumber: 555, + GasLimit: 1111111, + GasUsed: 222222, + Timestamp: 3333333333, + ExtraData: fillByteSlice(4, 0x12), + BaseFeePerGas: fillByteSlice(32, 0x34), + BlockHash: fillByteSlice(common.HashLength, 0x56), + TransactionsRoot: fillByteSlice(32, 0x78), + WithdrawalsRoot: fillByteSlice(32, 0x99), + } + + result, err := ExecutionPayloadHeaderCapellaFromConsensus(capellaHeader) + require.NoError(t, err) + require.Equal(t, hexutil.Encode(capellaHeader.ParentHash), result.ParentHash) + require.DeepEqual(t, hexutil.Encode(capellaHeader.WithdrawalsRoot), result.WithdrawalsRoot) +} + +func TestExecutionPayloadHeaderCapella_ToConsensus_HappyPath(t *testing.T) { + header := &ExecutionPayloadHeaderCapella{ + ParentHash: hexutil.Encode(fillByteSlice(common.HashLength, 0xaa)), + FeeRecipient: hexutil.Encode(fillByteSlice(20, 0xbb)), + StateRoot: hexutil.Encode(fillByteSlice(32, 0xcc)), + ReceiptsRoot: hexutil.Encode(fillByteSlice(32, 0xdd)), + LogsBloom: hexutil.Encode(fillByteSlice(256, 0xee)), + PrevRandao: hexutil.Encode(fillByteSlice(32, 0xff)), + BlockNumber: "555", + GasLimit: "1111111", + GasUsed: "222222", + Timestamp: "3333333333", + ExtraData: "0x1234abcd", + BaseFeePerGas: "1234", + BlockHash: hexutil.Encode(fillByteSlice(common.HashLength, 0x56)), + TransactionsRoot: hexutil.Encode(fillByteSlice(32, 0x78)), + WithdrawalsRoot: hexutil.Encode(fillByteSlice(32, 0x99)), + } + + result, err := header.ToConsensus() + require.NoError(t, err) + require.DeepEqual(t, hexutil.Encode(result.ParentHash), header.ParentHash) + require.DeepEqual(t, hexutil.Encode(result.FeeRecipient), header.FeeRecipient) + require.DeepEqual(t, hexutil.Encode(result.StateRoot), header.StateRoot) + require.DeepEqual(t, hexutil.Encode(result.ReceiptsRoot), header.ReceiptsRoot) + require.DeepEqual(t, hexutil.Encode(result.WithdrawalsRoot), header.WithdrawalsRoot) +} + +func TestExecutionPayloadHeaderDenebFromConsensus_HappyPath(t *testing.T) { + denebHeader := &enginev1.ExecutionPayloadHeaderDeneb{ + ParentHash: fillByteSlice(common.HashLength, 0xaa), + FeeRecipient: fillByteSlice(20, 0xbb), + StateRoot: fillByteSlice(32, 0xcc), + ReceiptsRoot: fillByteSlice(32, 0xdd), + LogsBloom: fillByteSlice(256, 0xee), + PrevRandao: fillByteSlice(32, 0xff), + BlockNumber: 999, + GasLimit: 5000000, + GasUsed: 2500000, + Timestamp: 4444444444, + ExtraData: fillByteSlice(4, 0x12), + BaseFeePerGas: fillByteSlice(32, 0x34), + BlockHash: fillByteSlice(common.HashLength, 0x56), + TransactionsRoot: fillByteSlice(32, 0x78), + WithdrawalsRoot: fillByteSlice(32, 0x99), + BlobGasUsed: 1234, + ExcessBlobGas: 5678, + } + + result, err := ExecutionPayloadHeaderDenebFromConsensus(denebHeader) + require.NoError(t, err) + require.Equal(t, hexutil.Encode(denebHeader.ParentHash), result.ParentHash) + require.DeepEqual(t, hexutil.Encode(denebHeader.FeeRecipient), result.FeeRecipient) + require.DeepEqual(t, hexutil.Encode(denebHeader.StateRoot), result.StateRoot) + require.DeepEqual(t, fmt.Sprintf("%d", denebHeader.BlobGasUsed), result.BlobGasUsed) +} + +func TestExecutionPayloadHeaderDeneb_ToConsensus_HappyPath(t *testing.T) { + header := &ExecutionPayloadHeaderDeneb{ + ParentHash: hexutil.Encode(fillByteSlice(common.HashLength, 0xaa)), + FeeRecipient: hexutil.Encode(fillByteSlice(20, 0xbb)), + StateRoot: hexutil.Encode(fillByteSlice(32, 0xcc)), + ReceiptsRoot: hexutil.Encode(fillByteSlice(32, 0xdd)), + LogsBloom: hexutil.Encode(fillByteSlice(256, 0xee)), + PrevRandao: hexutil.Encode(fillByteSlice(32, 0xff)), + BlockNumber: "999", + GasLimit: "5000000", + GasUsed: "2500000", + Timestamp: "4444444444", + ExtraData: "0x1234abcd", + BaseFeePerGas: "1234", + BlockHash: hexutil.Encode(fillByteSlice(common.HashLength, 0x56)), + TransactionsRoot: hexutil.Encode(fillByteSlice(32, 0x78)), + WithdrawalsRoot: hexutil.Encode(fillByteSlice(32, 0x99)), + BlobGasUsed: "1234", + ExcessBlobGas: "5678", + } + + result, err := header.ToConsensus() + require.NoError(t, err) + require.DeepEqual(t, hexutil.Encode(result.ParentHash), header.ParentHash) + require.DeepEqual(t, result.BlobGasUsed, uint64(1234)) + require.DeepEqual(t, result.ExcessBlobGas, uint64(5678)) + require.DeepEqual(t, result.BlockNumber, uint64(999)) +} + +func TestWithdrawalRequestsFromConsensus_HappyPath(t *testing.T) { + consensusRequests := []*enginev1.WithdrawalRequest{ + { + SourceAddress: fillByteSlice(20, 0xbb), + ValidatorPubkey: fillByteSlice(48, 0xbb), + Amount: 12345, + }, + { + SourceAddress: fillByteSlice(20, 0xcc), + ValidatorPubkey: fillByteSlice(48, 0xcc), + Amount: 54321, + }, + } + + result := WithdrawalRequestsFromConsensus(consensusRequests) + require.DeepEqual(t, len(result), len(consensusRequests)) + require.DeepEqual(t, result[0].Amount, fmt.Sprintf("%d", consensusRequests[0].Amount)) +} + +func TestWithdrawalRequestFromConsensus_HappyPath(t *testing.T) { + req := &enginev1.WithdrawalRequest{ + SourceAddress: fillByteSlice(20, 0xbb), + ValidatorPubkey: fillByteSlice(48, 0xbb), + Amount: 42, + } + result := WithdrawalRequestFromConsensus(req) + require.NotNil(t, result) + require.DeepEqual(t, result.SourceAddress, hexutil.Encode(fillByteSlice(20, 0xbb))) +} + +func TestWithdrawalRequest_ToConsensus_HappyPath(t *testing.T) { + withdrawalReq := &WithdrawalRequest{ + SourceAddress: hexutil.Encode(fillByteSlice(20, 111)), + ValidatorPubkey: hexutil.Encode(fillByteSlice(48, 123)), + Amount: "12345", + } + result, err := withdrawalReq.ToConsensus() + require.NoError(t, err) + require.DeepEqual(t, result.Amount, uint64(12345)) +} + +func TestConsolidationRequestsFromConsensus_HappyPath(t *testing.T) { + consensusRequests := []*enginev1.ConsolidationRequest{ + { + SourceAddress: fillByteSlice(20, 111), + SourcePubkey: fillByteSlice(48, 112), + TargetPubkey: fillByteSlice(48, 113), + }, + } + result := ConsolidationRequestsFromConsensus(consensusRequests) + require.DeepEqual(t, len(result), len(consensusRequests)) + require.DeepEqual(t, result[0].SourceAddress, "0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f") +} + +func TestDepositRequestsFromConsensus_HappyPath(t *testing.T) { + ds := []*enginev1.DepositRequest{ + { + Pubkey: fillByteSlice(48, 0xbb), + WithdrawalCredentials: fillByteSlice(32, 0xdd), + Amount: 98765, + Signature: fillByteSlice(96, 0xff), + Index: 111, + }, + } + result := DepositRequestsFromConsensus(ds) + require.DeepEqual(t, len(result), len(ds)) + require.DeepEqual(t, result[0].Amount, "98765") +} + +func TestDepositRequest_ToConsensus_HappyPath(t *testing.T) { + req := &DepositRequest{ + Pubkey: hexutil.Encode(fillByteSlice(48, 0xbb)), + WithdrawalCredentials: hexutil.Encode(fillByteSlice(32, 0xaa)), + Amount: "123", + Signature: hexutil.Encode(fillByteSlice(96, 0xdd)), + Index: "456", + } + + result, err := req.ToConsensus() + require.NoError(t, err) + require.DeepEqual(t, result.Amount, uint64(123)) + require.DeepEqual(t, result.Signature, fillByteSlice(96, 0xdd)) +} + +func TestExecutionRequestsFromConsensus_HappyPath(t *testing.T) { + er := &enginev1.ExecutionRequests{ + Deposits: []*enginev1.DepositRequest{ + { + Pubkey: fillByteSlice(48, 0xba), + WithdrawalCredentials: fillByteSlice(32, 0xaa), + Amount: 33, + Signature: fillByteSlice(96, 0xff), + Index: 44, + }, + }, + Withdrawals: []*enginev1.WithdrawalRequest{ + { + SourceAddress: fillByteSlice(20, 0xaa), + ValidatorPubkey: fillByteSlice(48, 0xba), + Amount: 555, + }, + }, + Consolidations: []*enginev1.ConsolidationRequest{ + { + SourceAddress: fillByteSlice(20, 0xdd), + SourcePubkey: fillByteSlice(48, 0xdd), + TargetPubkey: fillByteSlice(48, 0xcc), + }, + }, + } + + result := ExecutionRequestsFromConsensus(er) + require.NotNil(t, result) + require.Equal(t, 1, len(result.Deposits)) + require.Equal(t, "33", result.Deposits[0].Amount) + require.Equal(t, 1, len(result.Withdrawals)) + require.Equal(t, "555", result.Withdrawals[0].Amount) + require.Equal(t, 1, len(result.Consolidations)) + require.Equal(t, "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", result.Consolidations[0].TargetPubkey) +} + +func TestExecutionRequests_ToConsensus_HappyPath(t *testing.T) { + execReq := &ExecutionRequests{ + Deposits: []*DepositRequest{ + { + Pubkey: hexutil.Encode(fillByteSlice(48, 0xbb)), + WithdrawalCredentials: hexutil.Encode(fillByteSlice(32, 0xaa)), + Amount: "33", + Signature: hexutil.Encode(fillByteSlice(96, 0xff)), + Index: "44", + }, + }, + Withdrawals: []*WithdrawalRequest{ + { + SourceAddress: hexutil.Encode(fillByteSlice(20, 0xdd)), + ValidatorPubkey: hexutil.Encode(fillByteSlice(48, 0xbb)), + Amount: "555", + }, + }, + Consolidations: []*ConsolidationRequest{ + { + SourceAddress: hexutil.Encode(fillByteSlice(20, 0xcc)), + SourcePubkey: hexutil.Encode(fillByteSlice(48, 0xbb)), + TargetPubkey: hexutil.Encode(fillByteSlice(48, 0xcc)), + }, + }, + } + + result, err := execReq.ToConsensus() + require.NoError(t, err) + + require.Equal(t, 1, len(result.Deposits)) + require.Equal(t, uint64(33), result.Deposits[0].Amount) + require.Equal(t, 1, len(result.Withdrawals)) + require.Equal(t, uint64(555), result.Withdrawals[0].Amount) + require.Equal(t, 1, len(result.Consolidations)) + require.DeepEqual(t, fillByteSlice(48, 0xcc), result.Consolidations[0].TargetPubkey) +} diff --git a/api/server/structs/other.go b/api/server/structs/other.go index ef5a00c56f..66457d31cb 100644 --- a/api/server/structs/other.go +++ b/api/server/structs/other.go @@ -244,26 +244,6 @@ type Withdrawal struct { Amount string `json:"amount"` } -type DepositRequest struct { - Pubkey string `json:"pubkey"` - WithdrawalCredentials string `json:"withdrawal_credentials"` - Amount string `json:"amount"` - Signature string `json:"signature"` - Index string `json:"index"` -} - -type WithdrawalRequest struct { - SourceAddress string `json:"source_address"` - ValidatorPubkey string `json:"validator_pubkey"` - Amount string `json:"amount"` -} - -type ConsolidationRequest struct { - SourceAddress string `json:"source_address"` - SourcePubkey string `json:"source_pubkey"` - TargetPubkey string `json:"target_pubkey"` -} - type PendingDeposit struct { Pubkey string `json:"pubkey"` WithdrawalCredentials string `json:"withdrawal_credentials"` diff --git a/changelog/james-prysm_cleanup-payload-conversions.md b/changelog/james-prysm_cleanup-payload-conversions.md new file mode 100644 index 0000000000..c932564e31 --- /dev/null +++ b/changelog/james-prysm_cleanup-payload-conversions.md @@ -0,0 +1,7 @@ +### Ignored + +- code cleanup on payload types and payload conversions + +### Fixed + +- fixed gocognit in block conversions between json and proto types \ No newline at end of file