Skip to content

Commit

Permalink
deposit fn in OpTypedTransaction
Browse files Browse the repository at this point in the history
  • Loading branch information
clabby committed Apr 13, 2024
1 parent fbe40e6 commit b15ea35
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 291 deletions.
3 changes: 3 additions & 0 deletions crates/op-consensus/src/receipt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
287 changes: 2 additions & 285 deletions crates/op-consensus/src/transaction/envelope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: SignableTransaction<Signature>>(tx: T)
where
Signed<T>: Into<OpTxEnvelope>,
{
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() {
Expand All @@ -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::<OpTxEnvelope>::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<T: SignableTransaction<Signature>>(tx: T)
where
Signed<T>: Into<OpTxEnvelope>,
{
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() {
Expand Down
3 changes: 0 additions & 3 deletions crates/op-consensus/src/transaction/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;

mod optimism;
pub use optimism::TxDeposit;

Expand Down
3 changes: 0 additions & 3 deletions crates/op-consensus/src/transaction/optimism.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))]
Expand Down
16 changes: 16 additions & 0 deletions crates/op-consensus/src/transaction/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit b15ea35

Please sign in to comment.