From 7832ded0cb51540cc4f57c7c6d280340a8fbd457 Mon Sep 17 00:00:00 2001 From: Oliver Nordbjerg Date: Mon, 23 Sep 2024 08:59:12 +0200 Subject: [PATCH] feat: add set code tx helper to e2e utils --- crates/e2e-test-utils/src/transaction.rs | 50 +++++++++++++++++++++--- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/crates/e2e-test-utils/src/transaction.rs b/crates/e2e-test-utils/src/transaction.rs index 4fc282edd627..10bce216e157 100644 --- a/crates/e2e-test-utils/src/transaction.rs +++ b/crates/e2e-test-utils/src/transaction.rs @@ -3,9 +3,11 @@ use alloy_network::{ eip2718::Encodable2718, Ethereum, EthereumWallet, TransactionBuilder, TransactionBuilder4844, }; use alloy_primitives::{hex, Address, Bytes, TxKind, B256, U256}; -use alloy_rpc_types::{TransactionInput, TransactionRequest}; +use alloy_rpc_types::{Authorization, TransactionInput, TransactionRequest}; +use alloy_signer::SignerSync; use alloy_signer_local::PrivateKeySigner; use eyre::Ok; +use reth_primitives::eip7702::SignedAuthorization; /// Helper for transaction operations #[derive(Debug)] @@ -14,7 +16,7 @@ pub struct TransactionTestContext; impl TransactionTestContext { /// Creates a static transfer and signs it, returning an envelope. pub async fn transfer_tx(chain_id: u64, wallet: PrivateKeySigner) -> TxEnvelope { - let tx = tx(chain_id, 21000, None, 0); + let tx = tx(chain_id, 21000, None, None, 0); Self::sign_tx(wallet, tx).await } @@ -31,7 +33,7 @@ impl TransactionTestContext { init_code: Bytes, wallet: PrivateKeySigner, ) -> TxEnvelope { - let tx = tx(chain_id, gas, Some(init_code), 0); + let tx = tx(chain_id, gas, Some(init_code), None, 0); Self::sign_tx(wallet, tx).await } @@ -46,12 +48,41 @@ impl TransactionTestContext { signed.encoded_2718().into() } + /// Creates an EIP-7702 set code transaction and signs it, returning an envelope. + /// + /// The EIP-7702 will delegate the code of the signer to the contract at `delegate_to`. + pub async fn set_code_tx( + chain_id: u64, + delegate_to: Address, + wallet: PrivateKeySigner, + ) -> TxEnvelope { + let authorization = + Authorization { chain_id: U256::from(chain_id), address: delegate_to, nonce: 0 }; + let signature = wallet + .sign_hash_sync(&authorization.signature_hash()) + .expect("could not sign authorization"); + let tx = tx(chain_id, 48100, None, Some(authorization.into_signed(signature)), 0); + Self::sign_tx(wallet, tx).await + } + + /// Creates an EIP-7702 set code transaction and signs it, returning bytes. + /// + /// The EIP-7702 will delegate the code of the signer to the contract at `delegate_to`. + pub async fn set_code_tx_bytes( + chain_id: u64, + delegate_to: Address, + wallet: PrivateKeySigner, + ) -> Bytes { + let signed = Self::set_code_tx(chain_id, delegate_to, wallet).await; + signed.encoded_2718().into() + } + /// Creates a tx with blob sidecar and sign it pub async fn tx_with_blobs( chain_id: u64, wallet: PrivateKeySigner, ) -> eyre::Result { - let mut tx = tx(chain_id, 210000, None, 0); + let mut tx = tx(chain_id, 210000, None, None, 0); let mut builder = SidecarBuilder::::new(); builder.ingest(b"dummy blob"); @@ -85,7 +116,7 @@ impl TransactionTestContext { nonce: u64, ) -> Bytes { let l1_block_info = Bytes::from_static(&hex!("7ef9015aa044bae9d41b8380d781187b426c6fe43df5fb2fb57bd4466ef6a701e1f01e015694deaddeaddeaddeaddeaddeaddeaddeaddead000194420000000000000000000000000000000000001580808408f0d18001b90104015d8eb900000000000000000000000000000000000000000000000000000000008057650000000000000000000000000000000000000000000000000000000063d96d10000000000000000000000000000000000000000000000000000000000009f35273d89754a1e0387b89520d989d3be9c37c1f32495a88faf1ea05c61121ab0d1900000000000000000000000000000000000000000000000000000000000000010000000000000000000000002d679b567db6187c0c8323fa982cfb88b74dbcc7000000000000000000000000000000000000000000000000000000000000083400000000000000000000000000000000000000000000000000000000000f4240")); - let tx = tx(chain_id, 210000, Some(l1_block_info), nonce); + let tx = tx(chain_id, 210000, Some(l1_block_info), None, nonce); let signer = EthereumWallet::from(wallet); >::build(tx, &signer) .await @@ -112,7 +143,13 @@ impl TransactionTestContext { } /// Creates a type 2 transaction -fn tx(chain_id: u64, gas: u128, data: Option, nonce: u64) -> TransactionRequest { +fn tx( + chain_id: u64, + gas: u128, + data: Option, + delegate_to: Option, + nonce: u64, +) -> TransactionRequest { TransactionRequest { nonce: Some(nonce), value: Some(U256::from(100)), @@ -122,6 +159,7 @@ fn tx(chain_id: u64, gas: u128, data: Option, nonce: u64) -> TransactionR max_priority_fee_per_gas: Some(20e9 as u128), chain_id: Some(chain_id), input: TransactionInput { input: None, data }, + authorization_list: delegate_to.map(|addr| vec![addr]), ..Default::default() } }