From 4061385ee263d5ac514b92464853deb7cc471539 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:28:43 +0200 Subject: [PATCH] add transaction relayer to Kakarot EOA for tests (#1382) * add transaction relayer to Kakarot EOA for tests * Update kakarot submodule to commit +4b2139dcf7ab33ee94680275f77cd944524a0477 * wip * fix tests * clean up * add file back * add file back * fmt * fix some tests * add asdf to ci * fix clippy * fix test dirty * fix tests with katana_empty * fix send raw transaction test * fix comments * Update kakarot submodule to tag v0.8.9 --- .github/workflows/rust_test.yml | 8 +- Cargo.lock | 16 +-- lib/kakarot | 2 +- src/bin/hive_chain.rs | 13 ++- src/models/transaction.rs | 2 +- src/pool/mempool.rs | 45 ++++++-- .../eth_provider/starknet/relayer.rs | 32 +++--- src/test_utils/eoa.rs | 106 ++++++++++++++---- src/test_utils/fixtures.rs | 18 +-- src/test_utils/katana/mod.rs | 13 ++- tests/tests/alchemy_api.rs | 3 - tests/tests/eth_provider.rs | 48 ++++++-- 12 files changed, 222 insertions(+), 84 deletions(-) diff --git a/.github/workflows/rust_test.yml b/.github/workflows/rust_test.yml index 254805efc..792f84b72 100644 --- a/.github/workflows/rust_test.yml +++ b/.github/workflows/rust_test.yml @@ -48,6 +48,13 @@ jobs: with: path: .venv key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} + - name: Install asdf & tools + uses: asdf-vm/actions/setup@v3 + - name: install scarb + run: | + asdf plugin add scarb + asdf install scarb 2.6.5 + asdf install scarb 0.7.0 - name: Setup the Kakarot submodule run: make setup # Create dump @@ -55,7 +62,6 @@ jobs: run: ./scripts/make_with_env.sh katana-genesis - name: Test code run: make test - # We skip the hive tests for now, will be fixed in the next PR. # # Inspired by Reth CI. diff --git a/Cargo.lock b/Cargo.lock index 49d0115aa..c629c716b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -859,9 +859,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" @@ -2900,9 +2900,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.9" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", "clap_derive", @@ -2910,9 +2910,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.9" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstream", "anstyle", @@ -2931,9 +2931,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.8" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck 0.5.0", "proc-macro2", diff --git a/lib/kakarot b/lib/kakarot index b70fcf8b4..4b2139dcf 160000 --- a/lib/kakarot +++ b/lib/kakarot @@ -1 +1 @@ -Subproject commit b70fcf8b49fdad8ebb11e5e8db522e45e7e88508 +Subproject commit 4b2139dcf7ab33ee94680275f77cd944524a0477 diff --git a/src/bin/hive_chain.rs b/src/bin/hive_chain.rs index 14c06c45e..e84feeffc 100644 --- a/src/bin/hive_chain.rs +++ b/src/bin/hive_chain.rs @@ -3,7 +3,10 @@ use alloy_rlp::Decodable; use kakarot_rpc::{ into_via_try_wrapper, - providers::{eth_provider::starknet::relayer::LockedRelayer, sn_provider::StarknetProvider}, + providers::{ + eth_provider::{constant::RPC_CONFIG, starknet::relayer::LockedRelayer}, + sn_provider::StarknetProvider, + }, }; use reth_primitives::{bytes::Buf, Block, BlockBody, BytesMut}; use starknet::{ @@ -62,7 +65,13 @@ async fn main() -> eyre::Result<()> { let relayer_balance = into_via_try_wrapper!(relayer_balance)?; let current_nonce = Mutex::new(Felt::ZERO); - let mut relayer = LockedRelayer::new(current_nonce.lock().await, relayer_address, relayer_balance); + let mut relayer = LockedRelayer::new( + current_nonce.lock().await, + relayer_address, + relayer_balance, + JsonRpcClient::new(HttpTransport::new(RPC_CONFIG.network_url.clone())), + starknet_provider.chain_id().await.expect("failed to fetch chain id"), + ); for (block_number, body) in bodies.into_iter().enumerate() { while starknet_provider.block_number().await? < block_number as u64 { diff --git a/src/models/transaction.rs b/src/models/transaction.rs index ecb236d80..b5cc833c9 100644 --- a/src/models/transaction.rs +++ b/src/models/transaction.rs @@ -71,7 +71,7 @@ pub fn transaction_data_to_starknet_calldata( relayer_address, // OutsideExecution caller Felt::ZERO, // OutsideExecution nonce Felt::ZERO, // OutsideExecution execute_after - Felt::MAX, // OutsideExecution execute_before + Felt::from(u32::MAX), // OutsideExecution execute_before Felt::ONE, // call_array_len *KAKAROT_ADDRESS, // CallArray to *ETH_SEND_TRANSACTION, // CallArray selector diff --git a/src/pool/mempool.rs b/src/pool/mempool.rs index cfb0d1ad3..18d8acb96 100644 --- a/src/pool/mempool.rs +++ b/src/pool/mempool.rs @@ -1,14 +1,21 @@ #![allow(clippy::significant_drop_tightening)] use super::validate::KakarotTransactionValidator; -use crate::{client::EthClient, into_via_try_wrapper, providers::eth_provider::starknet::relayer::LockedRelayer}; +use crate::{ + client::EthClient, + into_via_try_wrapper, + providers::eth_provider::{constant::RPC_CONFIG, starknet::relayer::LockedRelayer}, +}; use futures::future::select_all; use reth_primitives::{BlockId, IntoRecoveredTransaction, U256}; use reth_transaction_pool::{ blobstore::NoopBlobStore, CoinbaseTipOrdering, EthPooledTransaction, Pool, TransactionOrigin, TransactionPool, }; use serde_json::Value; -use starknet::core::types::{BlockTag, Felt}; +use starknet::{ + core::types::{BlockTag, Felt}, + providers::{jsonrpc::HttpTransport, JsonRpcClient}, +}; use std::{collections::HashMap, fs::File, io::Read, str::FromStr, sync::Arc, time::Duration}; use tokio::{runtime::Handle, sync::Mutex}; @@ -96,7 +103,7 @@ impl AccountM let transaction = self.eth_client.mempool().get(best_hash); if transaction.is_none() { // Probably a race condition here - continue + continue; } let transaction = transaction.expect("not None"); @@ -110,23 +117,31 @@ impl AccountM if maybe_relayer.is_err() { // If we fail to fetch a relayer, we need to re-insert the transaction in the pool tracing::error!(target: "account_manager", err = ?maybe_relayer.unwrap(), "failed to fetch relayer"); - let _ = self.eth_client.mempool().add_transaction(TransactionOrigin::Local, transaction.transaction.clone()).await; - return + let _ = self + .eth_client + .mempool() + .add_transaction(TransactionOrigin::Local, transaction.transaction.clone()) + .await; + return; } let mut relayer = maybe_relayer.expect("maybe_lock is not error"); // Send the Ethereum transaction using the relayer - let transaction_signed = transaction.to_recovered_transaction().into_signed(); + let transaction_signed = transaction.to_recovered_transaction().into_signed(); let res = relayer.relay_transaction(&transaction_signed).await; if res.is_err() { -// If the relayer failed to relay the transaction, we need to reposition it in the mempool - let _ = self.eth_client.mempool().add_transaction(TransactionOrigin::Local, transaction.transaction.clone()).await; - return + // If the relayer failed to relay the transaction, we need to reposition it in the mempool + let _ = self + .eth_client + .mempool() + .add_transaction(TransactionOrigin::Local, transaction.transaction.clone()) + .await; + return; } // Increment account_nonce after sending a transaction let nonce = relayer.nonce_mut(); - *nonce= *nonce + 1; + *nonce = *nonce + 1; }); } @@ -136,7 +151,7 @@ impl AccountM } /// Returns the next available account from the manager. - async fn lock_account(&self) -> eyre::Result> + pub async fn lock_account(&self) -> eyre::Result>> where SP: starknet::providers::Provider + Send + Sync + Clone + 'static, { @@ -166,7 +181,13 @@ impl AccountM } let balance = into_via_try_wrapper!(balance)?; - let account = LockedRelayer::new(guard, *account_address, balance); + let account = LockedRelayer::new( + guard, + *account_address, + balance, + JsonRpcClient::new(HttpTransport::new(RPC_CONFIG.network_url.clone())), + self.eth_client.starknet_provider().chain_id().await.expect("Failed to get chain id"), + ); // Return the account address and the guard on the nonce return Ok(account); diff --git a/src/providers/eth_provider/starknet/relayer.rs b/src/providers/eth_provider/starknet/relayer.rs index eeb6be7e5..e7297a3e8 100644 --- a/src/providers/eth_provider/starknet/relayer.rs +++ b/src/providers/eth_provider/starknet/relayer.rs @@ -1,7 +1,6 @@ use crate::{ models::transaction::transaction_data_to_starknet_calldata, providers::eth_provider::{ - constant::{CHAIN_ID, RPC_CONFIG}, error::{SignatureError, TransactionError}, provider::EthApiResult, starknet::kakarot_core::{starknet_address, EXECUTE_FROM_OUTSIDE}, @@ -11,7 +10,7 @@ use reth_primitives::TransactionSigned; use starknet::{ accounts::{Account, ExecutionEncoding, ExecutionV1, SingleOwnerAccount}, core::types::Felt, - providers::{jsonrpc::HttpTransport, JsonRpcClient}, + providers::Provider, signers::{LocalWallet, SigningKey}, }; use std::{env::var, ops::Deref, str::FromStr, sync::LazyLock}; @@ -28,24 +27,24 @@ static RELAYER_SIGNER: LazyLock = LazyLock::new(|| { /// A relayer holding a lock on a mutex on an account and connected to the Starknet network. /// The relayer is used to sign transactions and broadcast them on the network. #[derive(Debug)] -pub struct LockedRelayer<'a> { +pub struct LockedRelayer<'a, SP: Provider + Send + Sync> { /// The account used to sign and broadcast the transaction - account: SingleOwnerAccount, LocalWallet>, + account: SingleOwnerAccount, /// The balance of the relayer balance: Felt, /// The locked nonce held by the relayer nonce: MutexGuard<'a, Felt>, } -impl<'a> LockedRelayer<'a> { - pub fn new(lock: MutexGuard<'a, Felt>, address: Felt, balance: Felt) -> Self { - let relayer = SingleOwnerAccount::new( - JsonRpcClient::new(HttpTransport::new(RPC_CONFIG.network_url.clone())), - RELAYER_SIGNER.clone(), - address, - *CHAIN_ID.get().expect("Failed to get chain id"), - ExecutionEncoding::Legacy, - ); +impl<'a, SP> LockedRelayer<'a, SP> +where + SP: Provider + Send + Sync, +{ + /// Create a new relayer with the provided Starknet provider, address, balance and nonce. + pub fn new(lock: MutexGuard<'a, Felt>, address: Felt, balance: Felt, provider: SP, chain_id: Felt) -> Self { + let relayer = + SingleOwnerAccount::new(provider, RELAYER_SIGNER.clone(), address, chain_id, ExecutionEncoding::New); + Self { account: relayer, balance, nonce: lock } } @@ -84,8 +83,11 @@ impl<'a> LockedRelayer<'a> { } } -impl<'a> Deref for LockedRelayer<'a> { - type Target = SingleOwnerAccount, LocalWallet>; +impl<'a, SP> Deref for LockedRelayer<'a, SP> +where + SP: Provider + Send + Sync, +{ + type Target = SingleOwnerAccount; fn deref(&self) -> &Self::Target { &self.account diff --git a/src/test_utils/eoa.rs b/src/test_utils/eoa.rs index e35bbd462..beba53ac3 100644 --- a/src/test_utils/eoa.rs +++ b/src/test_utils/eoa.rs @@ -1,7 +1,10 @@ use crate::{ client::{EthClient, KakarotTransactions}, - models::felt::Felt252Wrapper, - providers::eth_provider::{starknet::kakarot_core::starknet_address, ChainProvider, TransactionProvider}, + into_via_try_wrapper, + providers::eth_provider::{ + starknet::{kakarot_core::starknet_address, relayer::LockedRelayer}, + ChainProvider, TransactionProvider, + }, test_utils::{ evm_contract::{EvmContract, KakarotEvmContract, TransactionInfo, TxCommonInfo, TxFeeMarketInfo}, tx_waiter::watch_tx, @@ -16,13 +19,16 @@ use reth_primitives::{ }; use reth_rpc_types_compat::transaction::from_recovered; use starknet::{ + accounts::{Account, SingleOwnerAccount}, core::{ - types::{Felt, TransactionReceipt}, + types::{BlockId, BlockTag, Felt, TransactionReceipt}, utils::get_selector_from_name, }, - providers::Provider, + providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}, + signers::LocalWallet, }; use std::sync::Arc; +use tokio::sync::Mutex; pub const TX_GAS_LIMIT: u64 = 5_000_000; pub const TX_GAS_PRICE: u128 = 10; @@ -69,15 +75,20 @@ pub trait Eoa { } } -#[derive(Clone, Debug)] -pub struct KakarotEOA { +#[derive(Debug)] +pub struct KakarotEOA { pub private_key: B256, pub eth_client: Arc>, + pub relayer: SingleOwnerAccount, LocalWallet>, } impl KakarotEOA

{ - pub const fn new(private_key: B256, eth_client: Arc>) -> Self { - Self { private_key, eth_client } + pub const fn new( + private_key: B256, + eth_client: Arc>, + relayer: SingleOwnerAccount, LocalWallet>, + ) -> Self { + Self { private_key, eth_client, relayer } } } @@ -106,7 +117,7 @@ impl KakarotEOA

{ ) -> Result { let nonce = self.nonce().await?; let nonce: u64 = nonce.try_into()?; - let chain_id = self.eth_client.eth_provider().chain_id().await?.unwrap_or_default(); + let chain_id: u64 = self.eth_client.eth_provider().chain_id().await?.unwrap_or_default().try_into()?; // Empty bytecode if contract_name is None let bytecode = if let Some(name) = contract_name { @@ -122,7 +133,7 @@ impl KakarotEOA

{ let tx = if contract_name.is_none() { Transaction::Eip1559(TxEip1559 { - chain_id: chain_id.try_into()?, + chain_id, nonce, gas_limit: TX_GAS_LIMIT, max_fee_per_gas: TX_GAS_PRICE, @@ -132,16 +143,44 @@ impl KakarotEOA

{ ::prepare_create_transaction( &bytecode, constructor_args, - &TxCommonInfo { nonce, chain_id: Some(chain_id.try_into()?), ..Default::default() }, + &TxCommonInfo { nonce, chain_id: Some(chain_id), ..Default::default() }, )? }; let tx_signed = self.sign_transaction(tx)?; - let tx_hash = self.send_transaction(tx_signed).await?; - let tx_hash: Felt252Wrapper = tx_hash.into(); + let _ = self.send_transaction(tx_signed.clone()).await?; + + // Prepare the relayer + let relayer_balance = self + .eth_client + .starknet_provider() + .balance_at(self.relayer.address(), BlockId::Tag(BlockTag::Latest)) + .await?; + let relayer_balance = into_via_try_wrapper!(relayer_balance)?; + + let nonce = self + .eth_client + .starknet_provider() + .get_nonce(BlockId::Tag(BlockTag::Latest), self.relayer.address()) + .await + .unwrap_or_default(); + + let current_nonce = Mutex::new(nonce); + + // Relay the transaction + let starknet_transaction_hash = LockedRelayer::new( + current_nonce.lock().await, + self.relayer.address(), + relayer_balance, + self.starknet_provider(), + self.starknet_provider().chain_id().await.expect("Failed to get chain id"), + ) + .relay_transaction(&tx_signed) + .await + .expect("Failed to relay transaction"); watch_tx( self.eth_client.eth_provider().starknet_provider_inner(), - tx_hash.clone().into(), + starknet_transaction_hash, std::time::Duration::from_millis(300), 60, ) @@ -150,7 +189,7 @@ impl KakarotEOA

{ let maybe_receipt = self .starknet_provider() - .get_transaction_receipt(Felt::from(tx_hash)) + .get_transaction_receipt(starknet_transaction_hash) .await .expect("Failed to get transaction receipt after retries"); @@ -187,18 +226,45 @@ impl KakarotEOA

{ args, &TransactionInfo::FeeMarketInfo(TxFeeMarketInfo { common: TxCommonInfo { chain_id: Some(chain_id), nonce, value }, - ..Default::default() + max_fee_per_gas: 1000, + max_priority_fee_per_gas: 1000, }), )?; let tx_signed = self.sign_transaction(tx.clone())?; - let tx_hash = self.send_transaction(tx_signed).await?; + let _ = self.send_transaction(tx_signed.clone()).await?; + + // Prepare the relayer + let relayer_balance = self + .eth_client + .starknet_provider() + .balance_at(self.relayer.address(), BlockId::Tag(BlockTag::Latest)) + .await?; + let relayer_balance = into_via_try_wrapper!(relayer_balance)?; + + let nonce = self + .eth_client + .starknet_provider() + .get_nonce(BlockId::Tag(BlockTag::Latest), self.relayer.address()) + .await + .unwrap_or_default(); + + let current_nonce = Mutex::new(nonce); - let bytes = tx_hash.0; - let starknet_tx_hash = Felt::from_bytes_be(&bytes); + // Relay the transaction + let starknet_transaction_hash = LockedRelayer::new( + current_nonce.lock().await, + self.relayer.address(), + relayer_balance, + self.starknet_provider(), + self.starknet_provider().chain_id().await.expect("Failed to get chain id"), + ) + .relay_transaction(&tx_signed) + .await + .expect("Failed to relay transaction"); watch_tx( self.eth_client.eth_provider().starknet_provider_inner(), - starknet_tx_hash, + starknet_transaction_hash, std::time::Duration::from_millis(300), 60, ) diff --git a/src/test_utils/fixtures.rs b/src/test_utils/fixtures.rs index 775de0af2..ae3af126b 100644 --- a/src/test_utils/fixtures.rs +++ b/src/test_utils/fixtures.rs @@ -13,28 +13,28 @@ use { #[cfg(any(test, feature = "arbitrary", feature = "testing"))] #[fixture] #[awt] -pub async fn counter(#[future] katana: Katana) -> (Katana, KakarotEvmContract) { - let eoa = katana.eoa(); +pub async fn counter(#[future] katana_empty: Katana) -> (Katana, KakarotEvmContract) { + let eoa = katana_empty.eoa(); let contract = eoa.deploy_evm_contract(Some("Counter"), &[]).await.expect("Failed to deploy Counter contract"); - (katana, contract) + (katana_empty, contract) } /// This fixture deploys an empty contract on Katana. #[cfg(any(test, feature = "arbitrary", feature = "testing"))] #[fixture] #[awt] -pub async fn contract_empty(#[future] katana: Katana) -> (Katana, KakarotEvmContract) { - let eoa = katana.eoa(); +pub async fn contract_empty(#[future] katana_empty: Katana) -> (Katana, KakarotEvmContract) { + let eoa = katana_empty.eoa(); let contract = eoa.deploy_evm_contract(None, &[]).await.expect("Failed to deploy empty contract"); - (katana, contract) + (katana_empty, contract) } /// This fixture deploys an ERC20 contract on Katana. #[cfg(any(test, feature = "arbitrary", feature = "testing"))] #[fixture] #[awt] -pub async fn erc20(#[future] katana: Katana) -> (Katana, KakarotEvmContract) { - let eoa = katana.eoa(); +pub async fn erc20(#[future] katana_empty: Katana) -> (Katana, KakarotEvmContract) { + let eoa = katana_empty.eoa(); let contract = eoa .deploy_evm_contract( @@ -47,7 +47,7 @@ pub async fn erc20(#[future] katana: Katana) -> (Katana, KakarotEvmContract) { ) .await .expect("Failed to deploy ERC20 contract"); - (katana, contract) + (katana_empty, contract) } /// This fixture deploys the plain opcodes contract on Katana. diff --git a/src/test_utils/katana/mod.rs b/src/test_utils/katana/mod.rs index 4465c0c27..daf1fb546 100644 --- a/src/test_utils/katana/mod.rs +++ b/src/test_utils/katana/mod.rs @@ -57,7 +57,7 @@ pub fn katana_config() -> StarknetConfig { disable_fee: true, env: Environment { // Since kaka_test > u32::MAX, we should return the last 4 bytes of the chain_id: test - chain_id: ChainId::parse("kaka_test").unwrap(), + chain_id: ChainId::parse("test").unwrap(), invoke_max_steps: max_steps, validate_max_steps: max_steps, }, @@ -144,7 +144,7 @@ impl<'a> Katana { let eth_client = EthClient::try_new(starknet_provider, database).await.expect("failed to start eth client"); // Create a new Kakarot EOA instance with the private key and EthDataProvider instance. - let eoa = KakarotEOA::new(pk, Arc::new(eth_client.clone())); + let eoa = KakarotEOA::new(pk, Arc::new(eth_client.clone()), sequencer.account()); // Return a new instance of Katana with initialized fields. Self { @@ -171,6 +171,9 @@ impl<'a> Katana { let pk = std::env::var("EVM_PRIVATE_KEY").expect("Failed to get EVM private key"); let pk = B256::from_str(&pk).expect("Failed to parse EVM private key"); + // Set the relayer private key in the environment variables. + std::env::set_var("RELAYER_PRIVATE_KEY", format!("0x{:x}", sequencer.raw_account().private_key)); + // Initialize a MongoFuzzer instance with the specified random bytes size. let mut mongo_fuzzer = MongoFuzzer::new(rnd_bytes_size).await; @@ -185,7 +188,7 @@ impl<'a> Katana { let eth_client = EthClient::try_new(starknet_provider, database).await.expect("failed to start eth client"); // Create a new Kakarot EOA instance with the private key and EthDataProvider instance. - let eoa = KakarotEOA::new(pk, Arc::new(eth_client.clone())); + let eoa = KakarotEOA::new(pk, Arc::new(eth_client.clone()), sequencer.account()); // Return a new instance of Katana with initialized fields. Self { @@ -212,8 +215,8 @@ impl<'a> Katana { self.eoa.eth_client.eth_provider().starknet_provider_inner().clone() } - pub fn eoa(&self) -> KakarotEOA>> { - self.eoa.clone() + pub const fn eoa(&self) -> &KakarotEOA>> { + &self.eoa } #[allow(dead_code)] diff --git a/tests/tests/alchemy_api.rs b/tests/tests/alchemy_api.rs index ec6050480..badc582c8 100644 --- a/tests/tests/alchemy_api.rs +++ b/tests/tests/alchemy_api.rs @@ -23,7 +23,6 @@ use serde_json::Value; #[rstest] #[awt] #[tokio::test(flavor = "multi_thread")] -#[ignore = "failing because of relayer change"] async fn test_token_balances(#[future] erc20: (Katana, KakarotEvmContract), _setup: ()) { // Given let katana = erc20.0; @@ -83,7 +82,6 @@ async fn test_token_balances(#[future] erc20: (Katana, KakarotEvmContract), _set #[rstest] #[awt] #[tokio::test(flavor = "multi_thread")] -#[ignore = "failing because of relayer change"] async fn test_token_metadata(#[future] erc20: (Katana, KakarotEvmContract), _setup: ()) { // Obtain the Katana instance let katana = erc20.0; @@ -133,7 +131,6 @@ async fn test_token_metadata(#[future] erc20: (Katana, KakarotEvmContract), _set #[rstest] #[awt] #[tokio::test(flavor = "multi_thread")] -#[ignore = "failing because of relayer change"] async fn test_token_allowance(#[future] erc20: (Katana, KakarotEvmContract), _setup: ()) { // Obtain the Katana instance let katana = erc20.0; diff --git a/tests/tests/eth_provider.rs b/tests/tests/eth_provider.rs index e61a2b741..6688bd086 100644 --- a/tests/tests/eth_provider.rs +++ b/tests/tests/eth_provider.rs @@ -4,16 +4,18 @@ use alloy_primitives::{address, bytes}; use alloy_sol_types::{sol, SolCall}; use kakarot_rpc::{ client::KakarotTransactions, + into_via_try_wrapper, models::felt::Felt252Wrapper, providers::eth_provider::{ constant::{MAX_LOGS, STARKNET_MODULUS}, provider::EthereumProvider, + starknet::relayer::LockedRelayer, BlockProvider, ChainProvider, GasProvider, LogProvider, ReceiptProvider, StateProvider, TransactionProvider, }, test_utils::{ eoa::Eoa, evm_contract::{EvmContract, KakarotEvmContract}, - fixtures::{contract_empty, counter, katana, plain_opcodes, setup}, + fixtures::{contract_empty, counter, katana, katana_empty, plain_opcodes, setup}, katana::Katana, tx_waiter::watch_tx, }, @@ -28,8 +30,13 @@ use reth_rpc_types::{ }; use reth_transaction_pool::TransactionPool; use rstest::*; -use starknet::core::types::{BlockTag, Felt}; +use starknet::{ + accounts::Account, + core::types::{BlockId, BlockTag, Felt}, + providers::Provider, +}; use std::{collections::HashMap, sync::Arc}; +use tokio::sync::Mutex; #[rstest] #[awt] @@ -248,7 +255,6 @@ async fn test_nonce_contract_account(#[future] counter: (Katana, KakarotEvmContr #[rstest] #[awt] #[tokio::test(flavor = "multi_thread")] -#[ignore = "failing because of relayer change"] async fn test_nonce(#[future] counter: (Katana, KakarotEvmContract), _setup: ()) { // Given let katana: Katana = counter.0; @@ -477,7 +483,6 @@ async fn test_get_logs_block_hash(#[future] katana: Katana, _setup: ()) { #[rstest] #[awt] #[tokio::test(flavor = "multi_thread")] -#[ignore = "failing because of relayer change"] async fn test_get_code_empty(#[future] contract_empty: (Katana, KakarotEvmContract), _setup: ()) { // Given let katana: Katana = contract_empty.0; @@ -511,7 +516,6 @@ async fn test_get_code_no_contract(#[future] katana: Katana, _setup: ()) { #[rstest] #[awt] #[tokio::test(flavor = "multi_thread")] -#[ignore = "failing because of relayer change"] async fn test_estimate_gas(#[future] counter: (Katana, KakarotEvmContract), _setup: ()) { // Given let eoa = counter.0.eoa(); @@ -589,10 +593,12 @@ async fn test_predeploy_eoa(#[future] katana: Katana, _setup: ()) { let other_eoa_1 = KakarotEOA::new( b256!("00000000000000012330000000000000000000000000000000000000000abde1"), Arc::new(eth_client.clone()), + katana.sequencer.account(), ); let other_eoa_2 = KakarotEOA::new( b256!("00000000000000123123456000000000000000000000000000000000000abde2"), Arc::new(eth_client), + katana.sequencer.account(), ); let chain_id = starknet_provider.chain_id().await.unwrap(); CHAIN_ID.set(chain_id).expect("Failed to set chain id"); @@ -711,9 +717,9 @@ async fn test_to_starknet_block_id(#[future] katana: Katana, _setup: ()) { #[rstest] #[awt] #[tokio::test(flavor = "multi_thread")] -#[ignore = "failing because of relayer change"] -async fn test_send_raw_transaction(#[future] katana: Katana, _setup: ()) { +async fn test_send_raw_transaction(#[future] katana_empty: Katana, _setup: ()) { // Given + let katana = katana_empty; let eth_provider = katana.eth_provider(); let eth_client = katana.eth_client(); let chain_id = eth_provider.chain_id().await.unwrap_or_default().unwrap_or_default().to(); @@ -747,6 +753,34 @@ async fn test_send_raw_transaction(#[future] katana: Katana, _setup: ()) { .await .expect("failed to send transaction"); + // Prepare the relayer + let relayer_balance = eth_client + .starknet_provider() + .balance_at(katana.eoa.relayer.address(), BlockId::Tag(BlockTag::Latest)) + .await + .expect("Failed to get relayer balance"); + let relayer_balance = into_via_try_wrapper!(relayer_balance).expect("Failed to convert balance"); + + let nonce = eth_client + .starknet_provider() + .get_nonce(BlockId::Tag(BlockTag::Latest), katana.eoa.relayer.address()) + .await + .unwrap_or_default(); + + let current_nonce = Mutex::new(nonce); + + // Relay the transaction + let _ = LockedRelayer::new( + current_nonce.lock().await, + katana.eoa.relayer.address(), + relayer_balance, + &(*(*eth_client.starknet_provider())), + eth_client.starknet_provider().chain_id().await.expect("Failed to get chain id"), + ) + .relay_transaction(&transaction_signed) + .await + .expect("Failed to relay transaction"); + // Retrieve the current size of the mempool let mempool_size_after_send = eth_client.mempool().pool_size(); // Assert that the number of pending transactions in the mempool is 1