Skip to content

Commit 0532376

Browse files
sfromentmpaulucci
andauthored
feat(l1): add From for Transaction -> GenericTransaction (#3227)
**Motivation** Adding an easy way to get a GenericTransaction from any Transaction <!-- Why does this pull request exist? What are its goals? --> **Description** Adding the 2 missing From and one for the enum This will allow people who use the ethClient to make estimate_gas and eth_call request, more easily and maybe other request in the future might benefit from it <!-- A clear and concise general description of the changes this PR introduces --> <!-- Link to issues: Resolves #111, Resolves #222 --> BTW I don't know which scope I shall use Signed-off-by: Sacha Froment <[email protected]> Co-authored-by: Martin Paulucci <[email protected]>
1 parent 05d3c12 commit 0532376

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed

crates/common/types/transaction.rs

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2368,6 +2368,72 @@ mod serde_impl {
23682368
}
23692369
}
23702370
}
2371+
2372+
impl From<LegacyTransaction> for GenericTransaction {
2373+
fn from(value: LegacyTransaction) -> Self {
2374+
Self {
2375+
r#type: TxType::Legacy,
2376+
nonce: Some(value.nonce),
2377+
to: value.to,
2378+
from: Address::default(),
2379+
gas: Some(value.gas),
2380+
value: value.value,
2381+
gas_price: value.gas_price,
2382+
max_priority_fee_per_gas: None,
2383+
max_fee_per_gas: None,
2384+
max_fee_per_blob_gas: None,
2385+
access_list: vec![],
2386+
authorization_list: None,
2387+
blob_versioned_hashes: vec![],
2388+
blobs: vec![],
2389+
chain_id: None,
2390+
input: value.data,
2391+
}
2392+
}
2393+
}
2394+
2395+
impl From<EIP2930Transaction> for GenericTransaction {
2396+
fn from(value: EIP2930Transaction) -> Self {
2397+
Self {
2398+
r#type: TxType::EIP2930,
2399+
nonce: Some(value.nonce),
2400+
to: value.to,
2401+
from: Address::default(),
2402+
gas: Some(value.gas_limit),
2403+
value: value.value,
2404+
gas_price: value.gas_price,
2405+
max_priority_fee_per_gas: None,
2406+
max_fee_per_gas: None,
2407+
max_fee_per_blob_gas: None,
2408+
access_list: value
2409+
.access_list
2410+
.into_iter()
2411+
.map(|(address, storage_keys)| AccessListEntry {
2412+
address,
2413+
storage_keys,
2414+
})
2415+
.collect(),
2416+
authorization_list: None,
2417+
blob_versioned_hashes: vec![],
2418+
blobs: vec![],
2419+
chain_id: Some(value.chain_id),
2420+
input: value.data,
2421+
}
2422+
}
2423+
}
2424+
2425+
impl From<Transaction> for GenericTransaction {
2426+
fn from(value: Transaction) -> Self {
2427+
match value {
2428+
Transaction::LegacyTransaction(tx) => tx.into(),
2429+
Transaction::EIP2930Transaction(tx) => tx.into(),
2430+
Transaction::EIP1559Transaction(tx) => tx.into(),
2431+
Transaction::EIP4844Transaction(tx) => tx.into(),
2432+
Transaction::EIP7702Transaction(tx) => tx.into(),
2433+
Transaction::PrivilegedL2Transaction(tx) => tx.into(),
2434+
}
2435+
}
2436+
}
23712437
}
23722438

23732439
mod mempool {
@@ -2904,4 +2970,72 @@ mod tests {
29042970
assert_eq!(deserialized_tx, privileged_l2);
29052971
Ok(())
29062972
}
2973+
2974+
#[test]
2975+
fn test_legacy_transaction_into_generic() {
2976+
let legacy_tx = LegacyTransaction {
2977+
nonce: 1,
2978+
gas_price: 20_000_000_000,
2979+
gas: 21000,
2980+
to: TxKind::Call(
2981+
Address::from_str("0x742d35Cc6634C0532925a3b844Bc454e4438f44e").unwrap(),
2982+
),
2983+
value: U256::from(1_000_000_000_000_000_000u64),
2984+
data: Bytes::default(),
2985+
v: U256::from(27),
2986+
r: U256::from(1),
2987+
s: U256::from(1),
2988+
};
2989+
2990+
let generic_tx: GenericTransaction = legacy_tx.into();
2991+
assert_eq!(generic_tx.r#type, TxType::Legacy);
2992+
assert_eq!(generic_tx.nonce, Some(1));
2993+
assert_eq!(generic_tx.gas_price, 20_000_000_000);
2994+
assert_eq!(generic_tx.gas, Some(21000));
2995+
assert_eq!(generic_tx.max_priority_fee_per_gas, None);
2996+
assert_eq!(generic_tx.max_fee_per_gas, None);
2997+
assert_eq!(generic_tx.access_list.len(), 0);
2998+
assert_eq!(generic_tx.chain_id, None);
2999+
}
3000+
3001+
#[test]
3002+
fn test_eip2930_transaction_into_generic() {
3003+
let access_list = vec![(
3004+
Address::from_str("0x742d35Cc6634C0532925a3b844Bc454e4438f44e").unwrap(),
3005+
vec![
3006+
H256::from_str(
3007+
"0x1234567890123456789012345678901234567890123456789012345678901234",
3008+
)
3009+
.unwrap(),
3010+
],
3011+
)];
3012+
3013+
let eip2930_tx = EIP2930Transaction {
3014+
chain_id: 1,
3015+
nonce: 1,
3016+
gas_price: 20_000_000_000,
3017+
gas_limit: 21000,
3018+
to: TxKind::Call(
3019+
Address::from_str("0x742d35Cc6634C0532925a3b844Bc454e4438f44e").unwrap(),
3020+
),
3021+
value: U256::from(1_000_000_000_000_000_000u64),
3022+
data: Bytes::default(),
3023+
access_list: access_list.clone(),
3024+
signature_y_parity: false,
3025+
signature_r: U256::from(1),
3026+
signature_s: U256::from(1),
3027+
};
3028+
3029+
let generic_tx: GenericTransaction = eip2930_tx.into();
3030+
assert_eq!(generic_tx.r#type, TxType::EIP2930);
3031+
assert_eq!(generic_tx.nonce, Some(1));
3032+
assert_eq!(generic_tx.gas_price, 20_000_000_000);
3033+
assert_eq!(generic_tx.gas, Some(21000));
3034+
assert_eq!(generic_tx.max_priority_fee_per_gas, None);
3035+
assert_eq!(generic_tx.max_fee_per_gas, None);
3036+
assert_eq!(generic_tx.chain_id, Some(1));
3037+
assert_eq!(generic_tx.access_list.len(), 1);
3038+
assert_eq!(generic_tx.access_list[0].address, access_list[0].0);
3039+
assert_eq!(generic_tx.access_list[0].storage_keys, access_list[0].1);
3040+
}
29073041
}

0 commit comments

Comments
 (0)