From 94a369b9df99107370ab570e858104e474b39d8d Mon Sep 17 00:00:00 2001 From: sean Date: Sun, 5 Feb 2023 16:39:15 -0500 Subject: [PATCH] blob tx decoding --- beacon_node/execution_layer/src/lib.rs | 144 ++++++++++++++----------- consensus/types/src/transaction.rs | 2 +- 2 files changed, 83 insertions(+), 63 deletions(-) diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index c670b14c98..85ed0e25ae 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -21,15 +21,14 @@ use sensitive_url::SensitiveUrl; use serde::{Deserialize, Serialize}; use slog::{crit, debug, error, info, trace, warn, Logger}; use slot_clock::SlotClock; +use ssz::Encode; use std::collections::HashMap; -use std::default::default; use std::fmt; use std::future::Future; use std::io::Write; use std::path::PathBuf; use std::sync::Arc; use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; -use ethers_core::types::transaction::eip2930::AccessListItem; use strum::AsRefStr; use task_executor::TaskExecutor; use tokio::{ @@ -42,7 +41,8 @@ use types::transaction::{AccessTuple, BlobTransaction}; use types::{AbstractExecPayload, BeaconStateError, Blob, ExecPayload, KzgCommitment}; use types::{ BlindedPayload, BlockType, ChainSpec, Epoch, ExecutionBlockHash, ForkName, - ProposerPreparationData, PublicKeyBytes, Signature, SignedBeaconBlock, Slot, Uint256, + ProposerPreparationData, PublicKeyBytes, Signature, SignedBeaconBlock, Slot, + Transaction as SszTransaction, Uint256, }; use types::{ ExecutionPayload, ExecutionPayloadCapella, ExecutionPayloadEip4844, ExecutionPayloadMerge, @@ -1616,67 +1616,13 @@ impl ExecutionLayer { return Ok(None); }; - let transactions = VariableList::new( + let transactions = VariableList::from( block .transactions() - .iter() - .map(|transaction: Transaction| { - let tx_type = transaction - .transaction_type - .ok_or(ApiError::BlobTxConversionError)?.as_u64(); - let tx = if BLOB_TX_TYPE as u64 == tx_type { - let chain_id = transaction - .chain_id - .ok_or(ApiError::BlobTxConversionError)?; - let nonce = transaction.nonce.as_u64(); - let max_priority_fee_per_gas = transaction - .max_priority_fee_per_gas - .ok_or(ApiError::BlobTxConversionError)?; - let max_fee_per_gas = transaction - .max_fee_per_gas - .ok_or(ApiError::BlobTxConversionError)?; - let gas = transaction.gas.as_u64(); - let to = transaction.to; - let value = transaction.value; - let data = VariableList::from(transaction.input.to_vec()); - let access_list = VariableList::from(transaction - .access_list - .ok_or(ApiError::BlobTxConversionError)? - .0 - .into_iter().map(|access_tuple| Ok(AccessTuple { - address: access_tuple.address, - storage_keys: VariableList::from( - access_tuple - .storage_keys, - ), - })) - .collect::, ApiError>>()?); - let max_fee_per_data_gas = transaction.other.get("max_fee_per_data_gas").ok_or(ApiError::BlobTxConversionError)?; - let data_str = max_fee_per_data_gas.as_str().ok_or(ApiError::BlobTxConversionError)?; - let blob_versioned_hashes = transaction.other.get("blob_versioned_hashes").ok_or(ApiError::BlobTxConversionError)?; - Ok(BlobTransaction { - chain_id, - nonce, - max_priority_fee_per_gas, - max_fee_per_gas, - gas, - to, - value, - data, - access_list, - max_fee_per_data_gas, - blob_versioned_hashes, - }); - vec![] - } else { - transaction.rlp().to_vec() - }; - VariableList::new(tx) - }) - .collect::>() - .map_err(ApiError::DeserializeTransaction)?, - ) - .map_err(ApiError::DeserializeTransactions)?; + .into_iter() + .map(ethers_tx_to_bytes::) + .collect::, ApiError>>()?, + ); let payload = match block { ExecutionBlockWithTransactions::Merge(merge_block) => { @@ -2135,6 +2081,80 @@ fn noop(_: &ExecutionLayer, _: &ExecutionPayload) -> Option( + transaction: &Transaction, +) -> Result, ApiError> { + + let tx_type = transaction + .transaction_type + .ok_or(ApiError::BlobTxConversionError)? + .as_u64(); + let tx = if BLOB_TX_TYPE as u64 == tx_type { + let chain_id = transaction + .chain_id + .ok_or(ApiError::BlobTxConversionError)?; + let nonce = std::cmp::min(transaction.nonce, Uint256::from(u64::MAX)).as_u64(); + let max_priority_fee_per_gas = transaction + .max_priority_fee_per_gas + .ok_or(ApiError::BlobTxConversionError)?; + let max_fee_per_gas = transaction + .max_fee_per_gas + .ok_or(ApiError::BlobTxConversionError)?; + let gas = std::cmp::min(transaction.gas, Uint256::from(u64::MAX)).as_u64(); + let to = transaction.to; + let value = transaction.value; + let data = VariableList::from(transaction.input.to_vec()); + + let access_list = VariableList::from( + transaction + .access_list.as_ref() + .ok_or(ApiError::BlobTxConversionError)? + .0 + .iter() + .map(|access_tuple| { + Ok(AccessTuple { + address: access_tuple.address, + storage_keys: VariableList::from(access_tuple.storage_keys.clone()), + }) + }) + .collect::, ApiError>>()?, + ); + let max_fee_per_data_gas = transaction + .other + .get("max_fee_per_data_gas") + .ok_or(ApiError::BlobTxConversionError)? + .as_str() + .ok_or(ApiError::BlobTxConversionError)? + .parse() + .map_err(|_| ApiError::BlobTxConversionError)?; + let blob_versioned_hashes = serde_json::from_str( + transaction + .other + .get("blob_versioned_hashes") + .ok_or(ApiError::BlobTxConversionError)? + .as_str() + .ok_or(ApiError::BlobTxConversionError)?, + )?; + BlobTransaction { + chain_id, + nonce, + max_priority_fee_per_gas, + max_fee_per_gas, + gas, + to, + value, + data, + access_list, + max_fee_per_data_gas, + blob_versioned_hashes, + } + .as_ssz_bytes() + } else { + transaction.rlp().to_vec() + }; + Ok(VariableList::from(tx)) +} + #[cfg(test)] /// Returns the duration since the unix epoch. fn timestamp_now() -> u64 { diff --git a/consensus/types/src/transaction.rs b/consensus/types/src/transaction.rs index d1c3a797d2..73dee84ad3 100644 --- a/consensus/types/src/transaction.rs +++ b/consensus/types/src/transaction.rs @@ -1,4 +1,4 @@ -use crate::{Hash256, Transaction, Uint256, VersionedHash}; +use crate::{Hash256, Uint256, VersionedHash}; use ethereum_types::Address; use ssz_derive::{Decode, Encode}; use ssz_types::typenum::U16777216;