From 38e4c7e0fa35dc786247b9361c39e767916a4792 Mon Sep 17 00:00:00 2001 From: Pia Date: Tue, 26 Mar 2024 14:05:59 +0900 Subject: [PATCH 1/4] feat: TransactionReceipt to ReceiptEnvelope --- .../rpc-types/src/eth/transaction/receipt.rs | 57 ++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/crates/rpc-types/src/eth/transaction/receipt.rs b/crates/rpc-types/src/eth/transaction/receipt.rs index b2ae4d6c3b3..28492c1df15 100644 --- a/crates/rpc-types/src/eth/transaction/receipt.rs +++ b/crates/rpc-types/src/eth/transaction/receipt.rs @@ -1,5 +1,6 @@ -use crate::{other::OtherFields, Log}; -use alloy_primitives::{Address, Bloom, B256, U128, U256, U64, U8}; +use crate::{other::OtherFields, ConversionError, Log}; +use alloy_consensus::{Receipt, ReceiptEnvelope, ReceiptWithBloom, TxType}; +use alloy_primitives::{Address, Bloom, Log as PrimitivesLog, LogData, B256, U128, U256, U64, U8}; use serde::{Deserialize, Serialize}; /// Transaction receipt @@ -69,4 +70,56 @@ impl TransactionReceipt { } Some(self.from.create(nonce)) } + + /// Returns `true` if the transaction was successful. + /// A transaction is considered successful if the status code is `1`. + fn success(&self) -> bool { + match &self.status_code { + Some(status) => status == &U64::from(1), + None => false, + } + } + + /// Returns the logs emitted by the transaction. + /// Converts the logs from the RPC type to the internal type. + fn logs(&self) -> Vec> { + let mut logs = Vec::new(); + for log in &self.logs { + let rpc_log: Log = log.clone(); + let log_data = LogData::try_from(rpc_log).unwrap_or_default(); + let result = PrimitivesLog { address: log.address, data: log_data }; + logs.push(result); + } + + logs + } +} + +impl TryFrom for ReceiptWithBloom { + type Error = ConversionError; + + fn try_from(tx_receipt: TransactionReceipt) -> Result { + let receipt_with_bloom = ReceiptWithBloom { + receipt: Receipt { + success: tx_receipt.success(), + cumulative_gas_used: tx_receipt.cumulative_gas_used.to::(), + logs: tx_receipt.logs(), + }, + bloom: tx_receipt.logs_bloom, + }; + Ok(receipt_with_bloom) + } +} + +impl TryFrom for ReceiptEnvelope { + type Error = ConversionError; + + fn try_from(tx_receipt: TransactionReceipt) -> Result { + match tx_receipt.transaction_type.to::().try_into()? { + TxType::Legacy => Ok(ReceiptEnvelope::Legacy(tx_receipt.try_into()?)), + TxType::Eip2930 => Ok(ReceiptEnvelope::Eip2930(tx_receipt.try_into()?)), + TxType::Eip1559 => Ok(ReceiptEnvelope::Eip1559(tx_receipt.try_into()?)), + TxType::Eip4844 => Ok(ReceiptEnvelope::Eip4844(tx_receipt.try_into()?)), + } + } } From b54743826cc1f18aeefee56260f9ba6e106bc81d Mon Sep 17 00:00:00 2001 From: Pia Date: Tue, 26 Mar 2024 14:36:54 +0900 Subject: [PATCH 2/4] test for try from --- .../rpc-types/src/eth/transaction/receipt.rs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/crates/rpc-types/src/eth/transaction/receipt.rs b/crates/rpc-types/src/eth/transaction/receipt.rs index 28492c1df15..87d92a113bf 100644 --- a/crates/rpc-types/src/eth/transaction/receipt.rs +++ b/crates/rpc-types/src/eth/transaction/receipt.rs @@ -123,3 +123,37 @@ impl TryFrom for ReceiptEnvelope { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn try_from_transaction_receipt_to_receipts_envelope_4844() { + // cast rpc eth_getTransactionReceipt + // 0x9c1fbda4f649ac806ab0faefbe94e1a60282eb374ead6aa01bac042f52b28a8c --rpc-url mainnet + let rpc_tx_receipt = r#"{"blobGasPrice":"0x1","blobGasUsed":"0x20000","blockHash":"0xa2917e0758c98640d868182838c93bb12f0d07b6b17efe6b62d9df42c7643791","blockNumber":"0x1286d1d","contractAddress":null,"cumulativeGasUsed":"0x56b224","effectiveGasPrice":"0xd364c1438","from":"0x40c35d4faf69234986cb599890c2d2ef546074a9","gasUsed":"0x5208","logs":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","status":"0x1","to":"0x0000000000000000000000000000000000000000","transactionHash":"0x9c1fbda4f649ac806ab0faefbe94e1a60282eb374ead6aa01bac042f52b28a8c","transactionIndex":"0x46","type":"0x3"}"#; + let transaction_receipt: TransactionReceipt = serde_json::from_str(rpc_tx_receipt).unwrap(); + + let receipt_with_bloom = ReceiptWithBloom { + receipt: Receipt { success: true, cumulative_gas_used: 0x56b224, logs: vec![] }, + bloom: Bloom::default(), + }; + + let receipt_envelope: ReceiptEnvelope = transaction_receipt.try_into().unwrap(); + + assert_eq!(receipt_envelope, ReceiptEnvelope::Eip4844(receipt_with_bloom)); + } + + #[test] + fn try_from_transaction_receipt_to_receipts_envelope_1559() { + // cast rpc eth_getTransactionReceipt + // 0xd271efca8906538124cca4213bc61aa3def380cf5e3b068b3215c09d87219c99 --rpc-url mainnet + let rpc_tx_receipt = r#"{"blockHash":"0x851a0e708a669d9f9838c251b72d0b616b7f38c3ad38fa20a23c1144791bbdd6","blockNumber":"0x129cc66","contractAddress":null,"cumulativeGasUsed":"0x71a71f","effectiveGasPrice":"0x465e36461","from":"0xcb96aca8719987d15aecd066b7a1ad5d4d92fdd3","gasUsed":"0x74d8","logs":[{"address":"0x06450dee7fd2fb8e39061434babcfc05599a6fb8","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x000000000000000000000000cb96aca8719987d15aecd066b7a1ad5d4d92fdd3","0x00000000000000000000000085f7459e29d5626b5d2f16c00a97e0c48ce1654e"],"data":"0x000000000000000000000000000000000000000000198b0b16f55ce58edc0000","blockNumber":"0x129cc66","transactionHash":"0xd271efca8906538124cca4213bc61aa3def380cf5e3b068b3215c09d87219c99","transactionIndex":"0x7a","blockHash":"0x851a0e708a669d9f9838c251b72d0b616b7f38c3ad38fa20a23c1144791bbdd6","logIndex":"0xa9","removed":false}],"logsBloom":"0x0000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000a00010000c000000000008400010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000","status":"0x1","to":"0x06450dee7fd2fb8e39061434babcfc05599a6fb8","transactionHash":"0xd271efca8906538124cca4213bc61aa3def380cf5e3b068b3215c09d87219c99","transactionIndex":"0x7a","type":"0x2"}"#; + let transaction_receipt: TransactionReceipt = serde_json::from_str(rpc_tx_receipt).unwrap(); + + let receipt_envelope: ReceiptEnvelope = transaction_receipt.try_into().unwrap(); + + assert_eq!(receipt_envelope.tx_type(), TxType::Eip1559); + } +} From 720162dd3b00b5a8c55dcc74573b8f7a2d59649e Mon Sep 17 00:00:00 2001 From: Pia Date: Tue, 26 Mar 2024 22:24:03 +0900 Subject: [PATCH 3/4] fix review --- .../rpc-types/src/eth/transaction/receipt.rs | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/crates/rpc-types/src/eth/transaction/receipt.rs b/crates/rpc-types/src/eth/transaction/receipt.rs index 87d92a113bf..44dd80f549a 100644 --- a/crates/rpc-types/src/eth/transaction/receipt.rs +++ b/crates/rpc-types/src/eth/transaction/receipt.rs @@ -1,6 +1,7 @@ use crate::{other::OtherFields, ConversionError, Log}; use alloy_consensus::{Receipt, ReceiptEnvelope, ReceiptWithBloom, TxType}; -use alloy_primitives::{Address, Bloom, Log as PrimitivesLog, LogData, B256, U128, U256, U64, U8}; +use alloy_primitives::{Address, Bloom, B256, U128, U256, U64, U8}; +use itertools::Itertools; use serde::{Deserialize, Serialize}; /// Transaction receipt @@ -75,23 +76,18 @@ impl TransactionReceipt { /// A transaction is considered successful if the status code is `1`. fn success(&self) -> bool { match &self.status_code { - Some(status) => status == &U64::from(1), + Some(status) => status.to::() == 1, None => false, } } - /// Returns the logs emitted by the transaction. - /// Converts the logs from the RPC type to the internal type. - fn logs(&self) -> Vec> { - let mut logs = Vec::new(); - for log in &self.logs { - let rpc_log: Log = log.clone(); - let log_data = LogData::try_from(rpc_log).unwrap_or_default(); - let result = PrimitivesLog { address: log.address, data: log_data }; - logs.push(result); - } - - logs + /// Returns an iterator over the logs for prmitives type conversion. + fn logs_iter( + &self, + ) -> impl Iterator> + '_ { + self.logs.iter().map(|log| { + alloy_primitives::Log::new_unchecked(log.address, log.topics.clone(), log.data.clone()) + }) } } @@ -103,7 +99,7 @@ impl TryFrom for ReceiptWithBloom { receipt: Receipt { success: tx_receipt.success(), cumulative_gas_used: tx_receipt.cumulative_gas_used.to::(), - logs: tx_receipt.logs(), + logs: tx_receipt.logs_iter().collect_vec(), }, bloom: tx_receipt.logs_bloom, }; From ecee42d3eb70652b4cd7acb3a071b67217351ed3 Mon Sep 17 00:00:00 2001 From: Pia Date: Wed, 27 Mar 2024 09:59:45 +0900 Subject: [PATCH 4/4] into_logs, into_receipt_with_bloom --- .../rpc-types/src/eth/transaction/receipt.rs | 51 +++++++++++-------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/crates/rpc-types/src/eth/transaction/receipt.rs b/crates/rpc-types/src/eth/transaction/receipt.rs index 44dd80f549a..014a59aec9d 100644 --- a/crates/rpc-types/src/eth/transaction/receipt.rs +++ b/crates/rpc-types/src/eth/transaction/receipt.rs @@ -1,7 +1,6 @@ use crate::{other::OtherFields, ConversionError, Log}; use alloy_consensus::{Receipt, ReceiptEnvelope, ReceiptWithBloom, TxType}; use alloy_primitives::{Address, Bloom, B256, U128, U256, U64, U8}; -use itertools::Itertools; use serde::{Deserialize, Serialize}; /// Transaction receipt @@ -81,13 +80,31 @@ impl TransactionReceipt { } } - /// Returns an iterator over the logs for prmitives type conversion. - fn logs_iter( - &self, - ) -> impl Iterator> + '_ { - self.logs.iter().map(|log| { - alloy_primitives::Log::new_unchecked(log.address, log.topics.clone(), log.data.clone()) - }) + /// Consumes the type and returns a vector of logs. + fn into_logs(self) -> Vec> { + self.logs + .into_iter() + .map(|log| { + alloy_primitives::Log::new_unchecked( + log.address, + log.topics.clone(), + log.data.clone(), + ) + }) + .collect() + } + + /// Consumes the type and converts the transaction receipt into a receipt with bloom. + fn into_receipt_with_bloom(self) -> ReceiptWithBloom { + let logs_bloom = self.logs_bloom; + ReceiptWithBloom::new( + Receipt { + success: self.success(), + cumulative_gas_used: self.cumulative_gas_used.to::(), + logs: self.into_logs(), + }, + logs_bloom, + ) } } @@ -95,15 +112,7 @@ impl TryFrom for ReceiptWithBloom { type Error = ConversionError; fn try_from(tx_receipt: TransactionReceipt) -> Result { - let receipt_with_bloom = ReceiptWithBloom { - receipt: Receipt { - success: tx_receipt.success(), - cumulative_gas_used: tx_receipt.cumulative_gas_used.to::(), - logs: tx_receipt.logs_iter().collect_vec(), - }, - bloom: tx_receipt.logs_bloom, - }; - Ok(receipt_with_bloom) + Ok(tx_receipt.into_receipt_with_bloom()) } } @@ -112,10 +121,10 @@ impl TryFrom for ReceiptEnvelope { fn try_from(tx_receipt: TransactionReceipt) -> Result { match tx_receipt.transaction_type.to::().try_into()? { - TxType::Legacy => Ok(ReceiptEnvelope::Legacy(tx_receipt.try_into()?)), - TxType::Eip2930 => Ok(ReceiptEnvelope::Eip2930(tx_receipt.try_into()?)), - TxType::Eip1559 => Ok(ReceiptEnvelope::Eip1559(tx_receipt.try_into()?)), - TxType::Eip4844 => Ok(ReceiptEnvelope::Eip4844(tx_receipt.try_into()?)), + TxType::Legacy => Ok(ReceiptEnvelope::Legacy(tx_receipt.into_receipt_with_bloom())), + TxType::Eip2930 => Ok(ReceiptEnvelope::Eip2930(tx_receipt.into_receipt_with_bloom())), + TxType::Eip1559 => Ok(ReceiptEnvelope::Eip1559(tx_receipt.into_receipt_with_bloom())), + TxType::Eip4844 => Ok(ReceiptEnvelope::Eip4844(tx_receipt.into_receipt_with_bloom())), } } }