diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index f191698bf1..d80dafb523 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -108,7 +108,10 @@ pub use ethers_core::{ utils as rpc_utils, }; pub use revm_primitives::{B160 as H160, B256 as H256, U256}; -pub use ruint::{aliases::U128, UintTryTo}; +pub use ruint::{ + aliases::{U128, U8}, + UintTryTo, +}; #[doc(hidden)] mod __reexport { diff --git a/crates/primitives/src/transaction/meta.rs b/crates/primitives/src/transaction/meta.rs index d3fcdaa537..810bd8f721 100644 --- a/crates/primitives/src/transaction/meta.rs +++ b/crates/primitives/src/transaction/meta.rs @@ -11,4 +11,6 @@ pub struct TransactionMeta { pub block_hash: H256, /// Number of the block. pub block_number: u64, + /// Base fee of the block. + pub base_fee: Option, } diff --git a/crates/primitives/src/transaction/tx_type.rs b/crates/primitives/src/transaction/tx_type.rs index 449a91f25b..428e06f453 100644 --- a/crates/primitives/src/transaction/tx_type.rs +++ b/crates/primitives/src/transaction/tx_type.rs @@ -1,3 +1,4 @@ +use crate::U8; use reth_codecs::{derive_arbitrary, Compact}; use serde::{Deserialize, Serialize}; @@ -34,6 +35,12 @@ impl From for u8 { } } +impl From for U8 { + fn from(value: TxType) -> Self { + U8::from(u8::from(value)) + } +} + impl Compact for TxType { fn to_compact(self, _: &mut B) -> usize where diff --git a/crates/rpc/rpc-types/src/eth/transaction/receipt.rs b/crates/rpc/rpc-types/src/eth/transaction/receipt.rs index a373d1b98e..9e0f2250f2 100644 --- a/crates/rpc/rpc-types/src/eth/transaction/receipt.rs +++ b/crates/rpc/rpc-types/src/eth/transaction/receipt.rs @@ -1,5 +1,5 @@ use crate::Log; -use reth_primitives::{Address, Bloom, H256, U128, U256, U64}; +use reth_primitives::{Address, Bloom, H256, U128, U256, U64, U8}; use serde::{Deserialize, Serialize}; /// Transaction receipt @@ -42,5 +42,5 @@ pub struct TransactionReceipt { pub effective_gas_price: U128, /// EIP-2718 Transaction type, Some(1) for AccessList transaction, None for Legacy #[serde(rename = "type")] - pub transaction_type: U256, + pub transaction_type: U8, } diff --git a/crates/rpc/rpc/src/eth/api/transactions.rs b/crates/rpc/rpc/src/eth/api/transactions.rs index 288e5b0db2..7302d36866 100644 --- a/crates/rpc/rpc/src/eth/api/transactions.rs +++ b/crates/rpc/rpc/src/eth/api/transactions.rs @@ -12,10 +12,9 @@ use async_trait::async_trait; use reth_network_api::NetworkInfo; use reth_primitives::{ Address, BlockId, BlockNumberOrTag, Bytes, FromRecoveredTransaction, IntoRecoveredTransaction, - Receipt, SealedBlock, Transaction as PrimitiveTransaction, + Receipt, SealedBlock, TransactionKind::{Call, Create}, - TransactionMeta, TransactionSigned, TransactionSignedEcRecovered, TxEip1559, TxEip2930, - TxLegacy, H256, U128, U256, U64, + TransactionMeta, TransactionSigned, TransactionSignedEcRecovered, H256, U128, U256, U64, }; use reth_provider::{BlockProvider, EvmEnvProvider, StateProviderBox, StateProviderFactory}; use reth_revm::{ @@ -575,25 +574,6 @@ where None => return Err(EthApiError::UnknownBlockNumber), }; - let mut res_receipt = TransactionReceipt { - transaction_hash: Some(meta.tx_hash), - transaction_index: Some(U256::from(meta.index)), - block_hash: Some(meta.block_hash), - block_number: Some(U256::from(meta.block_number)), - from: transaction.signer(), - to: None, - cumulative_gas_used: U256::from(receipt.cumulative_gas_used), - gas_used: None, - contract_address: None, - logs: vec![], - effective_gas_price: U128::from(0), - transaction_type: U256::from(0), - // TODO: set state root after the block - state_root: None, - logs_bloom: receipt.bloom_slow(), - status_code: if receipt.success { Some(U64::from(1)) } else { Some(U64::from(0)) }, - }; - // get the previous transaction cumulative gas used let gas_used = if meta.index == 0 { receipt.cumulative_gas_used @@ -604,7 +584,28 @@ where .map(|prev_receipt| receipt.cumulative_gas_used - prev_receipt.cumulative_gas_used) .unwrap_or_default() }; - res_receipt.gas_used = Some(U256::from(gas_used)); + + let mut res_receipt = TransactionReceipt { + transaction_hash: Some(meta.tx_hash), + transaction_index: Some(U256::from(meta.index)), + block_hash: Some(meta.block_hash), + block_number: Some(U256::from(meta.block_number)), + from: transaction.signer(), + to: None, + cumulative_gas_used: U256::from(receipt.cumulative_gas_used), + gas_used: Some(U256::from(gas_used)), + contract_address: None, + logs: Vec::with_capacity(receipt.logs.len()), + effective_gas_price: transaction + .effective_gas_price(meta.base_fee) + .map(U128::from) + .unwrap_or(U128::ZERO), + transaction_type: tx.transaction.tx_type().into(), + // TODO pre-byzantium receipts have a post-transaction state root + state_root: None, + logs_bloom: receipt.bloom_slow(), + status_code: if receipt.success { Some(U64::from(1)) } else { Some(U64::from(0)) }, + }; match tx.transaction.kind() { Create => { @@ -616,26 +617,6 @@ where } } - match tx.transaction { - PrimitiveTransaction::Legacy(TxLegacy { gas_price, .. }) => { - res_receipt.transaction_type = U256::from(0); - res_receipt.effective_gas_price = U128::from(gas_price); - } - PrimitiveTransaction::Eip2930(TxEip2930 { gas_price, .. }) => { - res_receipt.transaction_type = U256::from(1); - res_receipt.effective_gas_price = U128::from(gas_price); - } - PrimitiveTransaction::Eip1559(TxEip1559 { - max_fee_per_gas, - max_priority_fee_per_gas, - .. - }) => { - res_receipt.transaction_type = U256::from(2); - res_receipt.effective_gas_price = - U128::from(max_fee_per_gas + max_priority_fee_per_gas) - } - } - // get number of logs in the block let mut num_logs = 0; for prev_receipt in all_receipts.iter().take(meta.index as usize) { diff --git a/crates/storage/provider/src/providers/database.rs b/crates/storage/provider/src/providers/database.rs index f4f7722cf1..dd611659e6 100644 --- a/crates/storage/provider/src/providers/database.rs +++ b/crates/storage/provider/src/providers/database.rs @@ -252,8 +252,8 @@ impl TransactionsProvider for ShareableDatabase { if let Some(block_number) = transaction_cursor.seek(transaction_id).map(|b| b.map(|(_, bn)| bn))? { - if let Some(block_hash) = - tx.get::(block_number)? + if let Some((header, block_hash)) = + read_sealed_header(tx, block_number)? { if let Some(block_body) = tx.get::(block_number)? @@ -269,6 +269,7 @@ impl TransactionsProvider for ShareableDatabase { index, block_hash, block_number, + base_fee: header.base_fee_per_gas, }; return Ok(Some((transaction.into(), meta))) @@ -464,6 +465,25 @@ impl EvmEnvProvider for ShareableDatabase { } } +/// Fetches Header and its hash +#[inline] +fn read_sealed_header<'a, TX>( + tx: &TX, + block_number: u64, +) -> std::result::Result, reth_interfaces::db::Error> +where + TX: DbTx<'a> + Send + Sync, +{ + let block_hash = match tx.get::(block_number)? { + Some(block_hash) => block_hash, + None => return Ok(None), + }; + match tx.get::(block_number)? { + Some(header) => Ok(Some((header, block_hash))), + None => Ok(None), + } +} + /// Fetches checks if the block number is the latest block number. #[inline] fn is_latest_block_number<'a, TX>(