diff --git a/crates/consensus/src/transaction/deposit.rs b/crates/consensus/src/transaction/deposit.rs index d336b2056..2810d5e7f 100644 --- a/crates/consensus/src/transaction/deposit.rs +++ b/crates/consensus/src/transaction/deposit.rs @@ -8,9 +8,7 @@ use alloy_eips::{ eip2930::AccessList, }; use alloy_primitives::{Address, B256, Bytes, ChainId, Signature, TxHash, TxKind, U256, keccak256}; -use alloy_rlp::{ - Buf, BufMut, Decodable, EMPTY_STRING_CODE, Encodable, Error as DecodeError, Header, -}; +use alloy_rlp::{BufMut, Decodable, Encodable, Header}; use core::mem; /// Deposit transactions, also known as deposits are initiated on L1, and executed on L2. @@ -28,8 +26,8 @@ pub struct TxDeposit { #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "TxKind::is_create"))] pub to: TxKind, /// The ETH value to mint on L2. - #[cfg_attr(feature = "serde", serde(default, with = "alloy_serde::quantity::opt"))] - pub mint: Option, + #[cfg_attr(feature = "serde", serde(default, with = "alloy_serde::quantity"))] + pub mint: u128, /// The ETH value to send to the recipient account. pub value: U256, /// The gas limit for the L2 transaction. @@ -70,12 +68,7 @@ impl TxDeposit { source_hash: Decodable::decode(buf)?, from: Decodable::decode(buf)?, to: Decodable::decode(buf)?, - mint: if *buf.first().ok_or(DecodeError::InputTooShort)? == EMPTY_STRING_CODE { - buf.advance(1); - None - } else { - Some(Decodable::decode(buf)?) - }, + mint: Decodable::decode(buf)?, value: Decodable::decode(buf)?, gas_limit: Decodable::decode(buf)?, is_system_transaction: Decodable::decode(buf)?, @@ -110,7 +103,7 @@ impl TxDeposit { self.source_hash.length() + self.from.length() + self.to.length() - + self.mint.map_or(1, |mint| mint.length()) + + self.mint.length() + self.value.length() + self.gas_limit.length() + self.is_system_transaction.length() @@ -123,11 +116,7 @@ impl TxDeposit { self.source_hash.encode(out); self.from.encode(out); self.to.encode(out); - if let Some(mint) = self.mint { - mint.encode(out); - } else { - out.put_u8(EMPTY_STRING_CODE); - } + self.mint.encode(out); self.value.encode(out); self.gas_limit.encode(out); self.is_system_transaction.encode(out); @@ -140,7 +129,7 @@ impl TxDeposit { mem::size_of::() + // source_hash mem::size_of::
() + // from self.to.size() + // to - mem::size_of::>() + // mint + mem::size_of::() + // mint mem::size_of::() + // value mem::size_of::() + // gas_limit mem::size_of::() + // is_system_transaction @@ -352,8 +341,8 @@ pub trait DepositTransaction: Transaction { /// Returns the optional mint value of the deposit transaction. /// /// # Returns - /// An `Option` representing the ETH value to mint on L2, if any. - fn mint(&self) -> Option; + /// An `u128` representing the ETH value to mint on L2, if any. + fn mint(&self) -> u128; /// Indicates whether the transaction is exempt from the L2 gas limit. /// @@ -369,7 +358,7 @@ impl DepositTransaction for TxDeposit { } #[inline] - fn mint(&self) -> Option { + fn mint(&self) -> u128 { self.mint } @@ -414,7 +403,7 @@ mod tests { source_hash: B256::with_last_byte(42), from: Address::default(), to: TxKind::default(), - mint: Some(100), + mint: 100, value: U256::from(1000), gas_limit: 50000, is_system_transaction: true, @@ -422,7 +411,7 @@ mod tests { }; assert_eq!(tx.source_hash(), Some(B256::with_last_byte(42))); - assert_eq!(tx.mint(), Some(100)); + assert_eq!(tx.mint(), 100); assert!(tx.is_system_transaction()); } @@ -432,7 +421,7 @@ mod tests { source_hash: B256::default(), from: Address::default(), to: TxKind::default(), - mint: None, + mint: 0, value: U256::default(), gas_limit: 50000, is_system_transaction: false, @@ -440,7 +429,7 @@ mod tests { }; assert_eq!(tx.source_hash(), Some(B256::default())); - assert_eq!(tx.mint(), None); + assert_eq!(tx.mint(), 0); assert!(!tx.is_system_transaction()); } @@ -451,7 +440,7 @@ mod tests { source_hash: B256::default(), from: Address::default(), to: TxKind::Call(contract_address), - mint: Some(200), + mint: 200, value: U256::from(500), gas_limit: 100000, is_system_transaction: false, @@ -459,7 +448,7 @@ mod tests { }; assert_eq!(tx.source_hash(), Some(B256::default())); - assert_eq!(tx.mint(), Some(200)); + assert_eq!(tx.mint(), 200); assert!(!tx.is_system_transaction()); assert_eq!(tx.kind(), TxKind::Call(contract_address)); } @@ -481,7 +470,7 @@ mod tests { source_hash: B256::default(), from: Address::default(), to: TxKind::default(), - mint: Some(100), + mint: 100, value: U256::default(), gas_limit: 50000, is_system_transaction: true, @@ -501,7 +490,7 @@ mod tests { source_hash: B256::default(), from: Address::default(), to: TxKind::default(), - mint: Some(100), + mint: 100, value: U256::default(), gas_limit: 50000, is_system_transaction: true, @@ -523,7 +512,7 @@ mod tests { source_hash: B256::default(), from: Address::default(), to: TxKind::default(), - mint: Some(100), + mint: 100, value: U256::default(), gas_limit: 50000, is_system_transaction: true, @@ -539,7 +528,7 @@ mod tests { source_hash: B256::default(), from: Address::default(), to: TxKind::default(), - mint: Some(100), + mint: 100, value: U256::default(), gas_limit: 50000, is_system_transaction: true, @@ -561,7 +550,7 @@ mod tests { source_hash: B256::default(), from: Address::default(), to: TxKind::default(), - mint: Some(100), + mint: 100, value: U256::default(), gas_limit: 50000, is_system_transaction: true, @@ -573,6 +562,30 @@ mod tests { assert!(total_len > len_without_header); } + #[test] + fn test_deposit_tx_roundtrip() { + let raw_txs = [ + "7ef8f8a0871ec5fb6afe7e5ae950bbb4cfd7d7cb277b413e67da806d50834a814b14c9f494deaddeaddeaddeaddeaddeaddeaddeaddead00019442000000000000000000000000000000000000158080830f424080b8a4440a5e20000008dd00101c12000000000000000400000000681c941f0000000001566261000000000000000000000000000000000000000000000000000000005f629c020000000000000000000000000000000000000000000000000000000000000001937badfbcce566e0ba932a3f7659644aa0c6ef019541d3134a1d8cb9f84d45c70000000000000000000000005050f69a9786f081509234f1a7f4684b5e5b76c9", + ]; + + for raw_tx_hex in raw_txs { + let raw_tx = hex::decode(raw_tx_hex).unwrap(); + + let tx = TxDeposit::decode_2718(&mut raw_tx.as_ref()).unwrap(); + let mut encoded = BytesMut::new(); + tx.encode_2718(&mut encoded); + assert_eq!(&encoded[..], &raw_tx[..], "Encoded bytes don't match original"); + + let tx_from_fields = TxDeposit::rlp_decode(&mut &raw_tx[1..]).unwrap(); + let mut encoded_fields = BytesMut::new(); + tx_from_fields.rlp_encode(&mut encoded_fields); + assert_eq!( + &encoded_fields[..], + &raw_tx[1..], + "RLP encoded fields don't match original" + ); + } + } } /// Bincode-compatible [`TxDeposit`] serde implementation. @@ -605,7 +618,7 @@ pub(super) mod serde_bincode_compat { #[serde(default)] to: TxKind, #[serde(default)] - mint: Option, + mint: u128, value: U256, gas_limit: u64, is_system_transaction: bool, diff --git a/crates/consensus/src/transaction/envelope.rs b/crates/consensus/src/transaction/envelope.rs index 48a190c22..664b95037 100644 --- a/crates/consensus/src/transaction/envelope.rs +++ b/crates/consensus/src/transaction/envelope.rs @@ -943,7 +943,7 @@ mod tests { let tx = TxDeposit { source_hash: B256::left_padding_from(&[0xde, 0xad]), from: Address::left_padding_from(&[0xbe, 0xef]), - mint: Some(1), + mint: 1, gas_limit: 2, to: TxKind::Call(Address::left_padding_from(&[3])), value: U256::from(4_u64), @@ -967,7 +967,7 @@ mod tests { input: Bytes::new(), source_hash: U256::MAX.into(), from: Address::random(), - mint: Some(u128::MAX), + mint: u128::MAX, is_system_transaction: false, }; let tx_envelope = OpTxEnvelope::Deposit(tx.seal_slow()); @@ -987,7 +987,7 @@ mod tests { let tx = OpTxEnvelope::decode_2718(&mut b[..].as_ref()).unwrap(); let deposit = tx.as_deposit().unwrap(); - assert!(deposit.mint.is_none()); + assert_eq!(deposit.mint, 0); } #[test]