diff --git a/crates/op-consensus/src/receipt/mod.rs b/crates/op-consensus/src/receipt/mod.rs index 9067a33d8..541def24c 100644 --- a/crates/op-consensus/src/receipt/mod.rs +++ b/crates/op-consensus/src/receipt/mod.rs @@ -41,6 +41,9 @@ mod tests { use alloy_primitives::{address, b256, bytes, hex, Bytes, LogData}; use alloy_rlp::{Decodable, Encodable}; + #[cfg(not(feature = "std"))] + use alloc::{vec, vec::Vec}; + // Test vector from: https://eips.ethereum.org/EIPS/eip-2481 #[test] fn encode_legacy_receipt() { diff --git a/crates/op-consensus/src/transaction/envelope.rs b/crates/op-consensus/src/transaction/envelope.rs index a06f483cd..b166da1b1 100644 --- a/crates/op-consensus/src/transaction/envelope.rs +++ b/crates/op-consensus/src/transaction/envelope.rs @@ -280,146 +280,10 @@ impl Encodable2718 for OpTxEnvelope { #[cfg(test)] mod tests { use super::*; - use alloy_consensus::SignableTransaction; - use alloy_eips::eip2930::{AccessList, AccessListItem}; - use alloy_primitives::{hex, Address, Bytes, Signature, TxKind, B256, U256}; - use std::{fs, path::PathBuf, vec}; + use alloy_primitives::{Address, Bytes, TxKind, B256, U256}; #[cfg(not(feature = "std"))] - use std::vec::Vec; - - #[test] - #[cfg(feature = "k256")] - // Test vector from https://etherscan.io/tx/0xce4dc6d7a7549a98ee3b071b67e970879ff51b5b95d1c340bacd80fa1e1aab31 - fn test_decode_live_1559_tx() { - use alloy_primitives::address; - - let raw_tx = alloy_primitives::hex::decode("02f86f0102843b9aca0085029e7822d68298f094d9e1459a7a482635700cbc20bbaf52d495ab9c9680841b55ba3ac080a0c199674fcb29f353693dd779c017823b954b3c69dffa3cd6b2a6ff7888798039a028ca912de909e7e6cdef9cdcaf24c54dd8c1032946dfa1d85c206b32a9064fe8").unwrap(); - let res = OpTxEnvelope::decode(&mut raw_tx.as_slice()).unwrap(); - - assert_eq!(res.tx_type(), OpTxType::Eip1559); - - let tx = match res { - OpTxEnvelope::Eip1559(tx) => tx, - _ => unreachable!(), - }; - - assert_eq!(tx.tx().to, TxKind::Call(address!("D9e1459A7A482635700cBc20BBAF52D495Ab9C96"))); - let from = tx.recover_signer().unwrap(); - assert_eq!(from, address!("001e2b7dE757bA469a57bF6b23d982458a07eFcE")); - } - - #[test] - #[cfg(feature = "k256")] - // Test vector from https://etherscan.io/tx/0x280cde7cdefe4b188750e76c888f13bd05ce9a4d7767730feefe8a0e50ca6fc4 - fn test_decode_live_legacy_tx() { - use alloy_primitives::address; - - let raw_tx = alloy_primitives::hex::decode("f9015482078b8505d21dba0083022ef1947a250d5630b4cf539739df2c5dacb4c659f2488d880c46549a521b13d8b8e47ff36ab50000000000000000000000000000000000000000000066ab5a608bd00a23f2fe000000000000000000000000000000000000000000000000000000000000008000000000000000000000000048c04ed5691981c42154c6167398f95e8f38a7ff00000000000000000000000000000000000000000000000000000000632ceac70000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006c6ee5e31d828de241282b9606c8e98ea48526e225a0c9077369501641a92ef7399ff81c21639ed4fd8fc69cb793cfa1dbfab342e10aa0615facb2f1bcf3274a354cfe384a38d0cc008a11c2dd23a69111bc6930ba27a8").unwrap(); - let res = OpTxEnvelope::decode(&mut raw_tx.as_slice()).unwrap(); - assert_eq!(res.tx_type(), OpTxType::Legacy); - - let tx = match res { - OpTxEnvelope::Legacy(tx) => tx, - _ => unreachable!(), - }; - - assert_eq!(tx.tx().to, TxKind::Call(address!("7a250d5630B4cF539739dF2C5dAcb4c659F2488D"))); - assert_eq!( - tx.hash().to_string(), - "0x280cde7cdefe4b188750e76c888f13bd05ce9a4d7767730feefe8a0e50ca6fc4" - ); - let from = tx.recover_signer().unwrap(); - assert_eq!(from, address!("a12e1462d0ceD572f396F58B6E2D03894cD7C8a4")); - } - - #[test] - #[cfg(feature = "k256")] - // Test vector from https://sepolia.etherscan.io/tx/0x9a22ccb0029bc8b0ddd073be1a1d923b7ae2b2ea52100bae0db4424f9107e9c0 - // Blobscan: https://sepolia.blobscan.com/tx/0x9a22ccb0029bc8b0ddd073be1a1d923b7ae2b2ea52100bae0db4424f9107e9c0 - fn test_decode_live_4844_tx() { - use alloy_consensus::Transaction; - use alloy_primitives::{address, b256}; - - // https://sepolia.etherscan.io/getRawTx?tx=0x9a22ccb0029bc8b0ddd073be1a1d923b7ae2b2ea52100bae0db4424f9107e9c0 - let raw_tx = alloy_primitives::hex::decode("0x03f9011d83aa36a7820fa28477359400852e90edd0008252089411e9ca82a3a762b4b5bd264d4173a242e7a770648080c08504a817c800f8a5a0012ec3d6f66766bedb002a190126b3549fce0047de0d4c25cffce0dc1c57921aa00152d8e24762ff22b1cfd9f8c0683786a7ca63ba49973818b3d1e9512cd2cec4a0013b98c6c83e066d5b14af2b85199e3d4fc7d1e778dd53130d180f5077e2d1c7a001148b495d6e859114e670ca54fb6e2657f0cbae5b08063605093a4b3dc9f8f1a0011ac212f13c5dff2b2c6b600a79635103d6f580a4221079951181b25c7e654901a0c8de4cced43169f9aa3d36506363b2d2c44f6c49fc1fd91ea114c86f3757077ea01e11fdd0d1934eda0492606ee0bb80a7bf8f35cc5f86ec60fe5031ba48bfd544").unwrap(); - let res = OpTxEnvelope::decode(&mut raw_tx.as_slice()).unwrap(); - assert_eq!(res.tx_type(), OpTxType::Eip4844); - - let tx = match res { - OpTxEnvelope::Eip4844(tx) => tx, - _ => unreachable!(), - }; - - assert_eq!( - tx.tx().to(), - TxKind::Call(address!("11E9CA82A3a762b4B5bd264d4173a242e7a77064")) - ); - - // Assert this is the correct variant of the EIP-4844 enum, which only contains the tx. - assert!(matches!(tx.tx(), TxEip4844Variant::TxEip4844(_))); - - assert_eq!( - tx.tx().tx().blob_versioned_hashes, - vec![ - b256!("012ec3d6f66766bedb002a190126b3549fce0047de0d4c25cffce0dc1c57921a"), - b256!("0152d8e24762ff22b1cfd9f8c0683786a7ca63ba49973818b3d1e9512cd2cec4"), - b256!("013b98c6c83e066d5b14af2b85199e3d4fc7d1e778dd53130d180f5077e2d1c7"), - b256!("01148b495d6e859114e670ca54fb6e2657f0cbae5b08063605093a4b3dc9f8f1"), - b256!("011ac212f13c5dff2b2c6b600a79635103d6f580a4221079951181b25c7e6549") - ] - ); - - let from = tx.recover_signer().unwrap(); - assert_eq!(from, address!("A83C816D4f9b2783761a22BA6FADB0eB0606D7B2")); - } - - fn test_encode_decode_roundtrip>(tx: T) - where - Signed: Into, - { - let signature = Signature::test_signature(); - let tx_signed = tx.into_signed(signature); - let tx_envelope: OpTxEnvelope = tx_signed.into(); - let encoded = tx_envelope.encoded_2718(); - let decoded = OpTxEnvelope::decode_2718(&mut encoded.as_ref()).unwrap(); - assert_eq!(encoded.len(), tx_envelope.encode_2718_len()); - assert_eq!(decoded, tx_envelope); - } - - #[test] - fn test_encode_decode_eip1559() { - let tx = TxEip1559 { - chain_id: 1u64, - nonce: 2, - max_fee_per_gas: 3, - max_priority_fee_per_gas: 4, - gas_limit: 5, - to: TxKind::Call(Address::left_padding_from(&[6])), - value: U256::from(7_u64), - input: Bytes::from(vec![8]), - access_list: Default::default(), - }; - test_encode_decode_roundtrip(tx); - } - - #[test] - fn test_encode_decode_eip2930() { - let tx = TxEip2930 { - chain_id: 1u64, - nonce: 2, - gas_price: 3, - gas_limit: 4, - to: TxKind::Call(Address::left_padding_from(&[5])), - value: U256::from(6_u64), - input: Bytes::from(vec![7]), - access_list: AccessList(vec![AccessListItem { - address: Address::left_padding_from(&[8]), - storage_keys: vec![B256::left_padding_from(&[9])], - }]), - }; - test_encode_decode_roundtrip(tx); - } + use alloc::vec; #[test] fn test_encode_decode_deposit() { @@ -440,153 +304,6 @@ mod tests { assert_eq!(decoded, tx_envelope); } - #[test] - fn test_encode_decode_transaction_list() { - let signature = Signature::test_signature(); - let tx = OpTxEnvelope::Eip1559( - TxEip1559 { - chain_id: 1u64, - nonce: 2, - max_fee_per_gas: 3, - max_priority_fee_per_gas: 4, - gas_limit: 5, - to: TxKind::Call(Address::left_padding_from(&[6])), - value: U256::from(7_u64), - input: Bytes::from(vec![8]), - access_list: Default::default(), - } - .into_signed(signature), - ); - let transactions = vec![tx.clone(), tx]; - let encoded = alloy_rlp::encode(&transactions); - let decoded = Vec::::decode(&mut &encoded[..]).unwrap(); - assert_eq!(transactions, decoded); - } - - #[test] - fn decode_encode_known_rpc_transaction() { - // test data pulled from hive test that sends blob transactions - let network_data_path = - PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("testdata/rpc_blob_transaction.rlp"); - let data = fs::read_to_string(network_data_path).expect("Unable to read file"); - let hex_data = hex::decode(data.trim()).unwrap(); - - let tx: OpTxEnvelope = OpTxEnvelope::decode_2718(&mut hex_data.as_slice()).unwrap(); - let encoded = tx.encoded_2718(); - assert_eq!(encoded, hex_data); - assert_eq!(tx.encode_2718_len(), hex_data.len()); - } - - #[cfg(feature = "serde")] - fn test_serde_roundtrip>(tx: T) - where - Signed: Into, - { - let signature = Signature::test_signature(); - let tx_envelope: OpTxEnvelope = tx.into_signed(signature).into(); - - let serialized = serde_json::to_string(&tx_envelope).unwrap(); - let deserialized: OpTxEnvelope = serde_json::from_str(&serialized).unwrap(); - - assert_eq!(tx_envelope, deserialized); - } - - #[test] - #[cfg(feature = "serde")] - fn test_serde_roundtrip_legacy() { - let tx = TxLegacy { - chain_id: Some(1), - nonce: 100, - gas_price: 3_000_000_000, - gas_limit: 50_000, - to: TxKind::Call(Address::default()), - value: U256::from(10e18), - input: Bytes::new(), - }; - test_serde_roundtrip(tx); - } - - #[test] - #[cfg(feature = "serde")] - fn test_serde_roundtrip_eip1559() { - let tx = TxEip1559 { - chain_id: 1, - nonce: 100, - max_fee_per_gas: 50_000_000_000, - max_priority_fee_per_gas: 1_000_000_000_000, - gas_limit: 1_000_000, - to: TxKind::Create, - value: U256::from(10e18), - input: Bytes::new(), - access_list: AccessList(vec![AccessListItem { - address: Address::random(), - storage_keys: vec![B256::random()], - }]), - }; - test_serde_roundtrip(tx); - } - - #[test] - #[cfg(feature = "serde")] - fn test_serde_roundtrip_eip2930() { - let tx = TxEip2930 { - chain_id: u64::MAX, - nonce: u64::MAX, - gas_price: u128::MAX, - gas_limit: u128::MAX, - to: TxKind::Call(Address::random()), - value: U256::MAX, - input: Bytes::new(), - access_list: Default::default(), - }; - test_serde_roundtrip(tx); - } - - #[test] - #[cfg(feature = "serde")] - fn test_serde_roundtrip_eip4844() { - use alloy_consensus::BlobTransactionSidecar; - - let tx = TxEip4844Variant::TxEip4844(TxEip4844 { - chain_id: 1, - nonce: 100, - max_fee_per_gas: 50_000_000_000, - max_priority_fee_per_gas: 1_000_000_000_000, - gas_limit: 1_000_000, - to: Address::random(), - value: U256::from(10e18), - input: Bytes::new(), - access_list: AccessList(vec![AccessListItem { - address: Address::random(), - storage_keys: vec![B256::random()], - }]), - blob_versioned_hashes: vec![B256::random()], - max_fee_per_blob_gas: 0, - }); - test_serde_roundtrip(tx); - - let tx = TxEip4844Variant::TxEip4844WithSidecar(TxEip4844WithSidecar { - tx: TxEip4844 { - chain_id: 1, - nonce: 100, - max_fee_per_gas: 50_000_000_000, - max_priority_fee_per_gas: 1_000_000_000_000, - gas_limit: 1_000_000, - to: Address::random(), - value: U256::from(10e18), - input: Bytes::new(), - access_list: AccessList(vec![AccessListItem { - address: Address::random(), - storage_keys: vec![B256::random()], - }]), - blob_versioned_hashes: vec![B256::random()], - max_fee_per_blob_gas: 0, - }, - sidecar: BlobTransactionSidecar { ..Default::default() }, - }); - test_serde_roundtrip(tx); - } - #[test] #[cfg(feature = "serde")] fn test_serde_roundtrip_deposit() { diff --git a/crates/op-consensus/src/transaction/mod.rs b/crates/op-consensus/src/transaction/mod.rs index 49ecf8082..9e4cb8f7c 100644 --- a/crates/op-consensus/src/transaction/mod.rs +++ b/crates/op-consensus/src/transaction/mod.rs @@ -1,6 +1,3 @@ -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; - mod optimism; pub use optimism::TxDeposit; diff --git a/crates/op-consensus/src/transaction/optimism.rs b/crates/op-consensus/src/transaction/optimism.rs index 3b7eb305e..915bc1e72 100644 --- a/crates/op-consensus/src/transaction/optimism.rs +++ b/crates/op-consensus/src/transaction/optimism.rs @@ -5,9 +5,6 @@ use alloy_rlp::{ }; use core::mem; -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; - /// Deposit transactions, also known as deposits are initiated on L1, and executed on L2. #[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] diff --git a/crates/op-consensus/src/transaction/typed.rs b/crates/op-consensus/src/transaction/typed.rs index 89307811c..d8fc41cda 100644 --- a/crates/op-consensus/src/transaction/typed.rs +++ b/crates/op-consensus/src/transaction/typed.rs @@ -109,6 +109,22 @@ impl OpTypedTransaction { _ => None, } } + + /// Return the inner EIP-4844 transaction if it exists. + pub const fn eip4844(&self) -> Option<&TxEip4844Variant> { + match self { + Self::Eip4844(tx) => Some(tx), + _ => None, + } + } + + /// Return the inner deposit transaction if it exists. + pub const fn deposit(&self) -> Option<&TxDeposit> { + match self { + Self::Deposit(tx) => Some(tx), + _ => None, + } + } } impl Transaction for OpTypedTransaction {