Skip to content

refactor(l2): rewrite integration tests #2681

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
May 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions crates/l2/sdk/src/l1_to_l2_tx_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
use crate::calldata::{self, Value};
use bytes::Bytes;
use ethrex_common::{Address, U256};
use ethrex_rpc::{
clients::{eth::errors::CalldataEncodeError, EthClientError, Overrides},
EthClient,
};
use keccak_hash::H256;
use secp256k1::SecretKey;

pub struct L1ToL2TransactionData {
pub to: Address,
pub recipient: Address,
pub gas_limit: u64,
pub calldata: Bytes,
}

impl L1ToL2TransactionData {
/// Creates a new L1ToL2TransactionData instance.
///
/// # Arguments
///
/// * `to` - The address of the contract to call on L2.
/// * `recipient` - The address of the recipient on L2 that will receive the
/// L1 transaction value.
/// * `gas_limit` - The gas limit for the transaction on L2.
/// * `calldata` - The calldata to send to the contract on L2.
pub fn new(to: Address, recipient: Address, gas_limit: u64, calldata: Bytes) -> Self {
Self {
to,
recipient,
gas_limit,
calldata,
}
}

/// Creates a new `L1ToL2TransactionData` instance for a deposit transaction.
///
/// In deposit transactions, the `to` and the `recipient` are the same, and
/// the `calldata` is empty.
///
/// # Arguments
///
/// * `recipient` - The address of the recipient on L2 that will receive the
/// L1 transaction value (the deposit).
/// * `gas_limit` - The gas limit for the transaction on L2.
pub fn new_deposit_data(recipient: Address, gas_limit: u64) -> Self {
Self {
to: recipient,
recipient,
gas_limit,
calldata: Bytes::from_static(b""),
}
}

/// Encodes the `L1ToL2TransactionData` into a calldata.
pub fn to_calldata(&self) -> Result<Vec<u8>, CalldataEncodeError> {
let values = vec![Value::Tuple(vec![
Value::Address(self.to),
Value::Address(self.recipient),
Value::Uint(U256::from(self.gas_limit)),
Value::Bytes(self.calldata.clone()),
])];
calldata::encode_calldata("deposit((address,address,uint256,bytes))", &values)
}
}

/// This function is used to send a transaction on L2 from L1 using the `CommonBridge` contract.
///
/// # Arguments
///
/// * `l1_from` - The address of the sender on L1.
/// * `l1_value` - The value to send from L1.
/// * `l1_gas_limit` - The gas limit for the transaction on L1.
/// * `l1_to_l2_tx_data` - The data for the transaction on L2.
/// * `sender_private_key` - The private key of the sender on L1.
/// * `bridge_address` - The address of the `CommonBridge` contract.
/// * `eth_client` - The Ethereum client to use.
#[allow(clippy::too_many_arguments)]
pub async fn send_l1_to_l2_tx(
l1_from: Address,
l1_value: Option<impl Into<U256>>,
l1_gas_limit: Option<u64>,
l1_to_l2_tx_data: L1ToL2TransactionData,
sender_private_key: &SecretKey,
bridge_address: Address,
eth_client: &EthClient,
) -> Result<H256, EthClientError> {
let l1_calldata = l1_to_l2_tx_data.to_calldata()?;

let l1_gas_price = eth_client.get_gas_price().await?.try_into().map_err(|_| {
EthClientError::InternalError("Failed to convert gas_price to a u64".to_owned())
})?;

let l1_tx_overrides = Overrides {
value: l1_value.map(Into::into),
from: Some(l1_from),
gas_limit: l1_gas_limit.or(Some(21000 * 5)),
max_fee_per_gas: Some(l1_gas_price),
max_priority_fee_per_gas: Some(l1_gas_price),
..Overrides::default()
};

let l1_to_l2_tx = eth_client
.build_eip1559_transaction(bridge_address, l1_from, l1_calldata.into(), l1_tx_overrides)
.await?;

eth_client
.send_eip1559_transaction(&l1_to_l2_tx, sender_private_key)
.await
}
34 changes: 30 additions & 4 deletions crates/l2/sdk/src/sdk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ use ethrex_rpc::types::receipt::RpcReceipt;
use keccak_hash::keccak;
use secp256k1::SecretKey;
use serde::{Deserialize, Deserializer, Serialize, Serializer};

pub mod calldata;
pub mod l1_to_l2_tx_data;
pub mod merkle_tree;

pub use l1_to_l2_tx_data::{send_l1_to_l2_tx, L1ToL2TransactionData};

// 0x554a14cd047c485b3ac3edbd9fbb373d6f84ad3f
pub const DEFAULT_BRIDGE_ADDRESS: Address = H160([
0x55, 0x4a, 0x14, 0xcd, 0x04, 0x7c, 0x48, 0x5b, 0x3a, 0xc3, 0xed, 0xbd, 0x9f, 0xbb, 0x37, 0x3d,
Expand Down Expand Up @@ -70,7 +74,7 @@ pub async fn transfer(
amount: U256,
from: Address,
to: Address,
private_key: SecretKey,
private_key: &SecretKey,
client: &EthClient,
) -> Result<H256, EthClientError> {
println!(
Expand Down Expand Up @@ -105,13 +109,13 @@ pub async fn transfer(
tx_generic.from = from;
let gas_limit = client.estimate_gas(tx_generic).await?;
tx.gas_limit = gas_limit;
client.send_eip1559_transaction(&tx, &private_key).await
client.send_eip1559_transaction(&tx, private_key).await
}

pub async fn deposit(
pub async fn deposit_through_transfer(
amount: U256,
from: Address,
from_pk: SecretKey,
from_pk: &SecretKey,
eth_client: &EthClient,
) -> Result<H256, EthClientError> {
println!("Depositing {amount} from {from:#x} to bridge");
Expand All @@ -125,6 +129,28 @@ pub async fn deposit(
.await
}

pub async fn deposit_through_contract_call(
amount: impl Into<U256>,
to: Address,
l1_gas_limit: u64,
l2_gas_limit: u64,
depositor_private_key: &SecretKey,
bridge_address: Address,
eth_client: &EthClient,
) -> Result<H256, EthClientError> {
let l1_from = get_address_from_secret_key(depositor_private_key)?;
send_l1_to_l2_tx(
l1_from,
Some(amount),
Some(l1_gas_limit),
L1ToL2TransactionData::new_deposit_data(to, l2_gas_limit),
depositor_private_key,
bridge_address,
eth_client,
)
.await
}

pub async fn withdraw(
amount: U256,
from: Address,
Expand Down
Loading