From 08883cf36267577d7b36813f9f21a8703d7e1fdc Mon Sep 17 00:00:00 2001 From: 0xTrinityy Date: Thu, 11 Jan 2024 15:48:29 +0100 Subject: [PATCH 1/8] finishing simulate transaction test --- Cargo.lock | 1 + unit_tests/Cargo.toml | 1 + unit_tests/src/constants.rs | 6 + unit_tests/src/lib.rs | 20 + unit_tests/tests/test_simulate_transaction.rs | 428 ++++++++++++++++++ 5 files changed, 456 insertions(+) create mode 100644 unit_tests/tests/test_simulate_transaction.rs diff --git a/Cargo.lock b/Cargo.lock index 0e26508..0e6509d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2556,6 +2556,7 @@ dependencies = [ "serde", "serde_json", "starknet", + "starknet-accounts", "starknet-core", "starknet-providers", "tokio", diff --git a/unit_tests/Cargo.toml b/unit_tests/Cargo.toml index 50e5f04..8677c5e 100644 --- a/unit_tests/Cargo.toml +++ b/unit_tests/Cargo.toml @@ -15,6 +15,7 @@ url = "2.5.0" starknet = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "a35ce22", default-features = false } starknet-core = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "a35ce22", default-features = false } starknet-providers = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "a35ce22", default-features = false } +starknet-accounts = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "a35ce22", default-features = false } [dev-dependencies] jsonrpsee = { version = "0.21.0", features = ["client"] } diff --git a/unit_tests/src/constants.rs b/unit_tests/src/constants.rs index af56595..37dcb12 100644 --- a/unit_tests/src/constants.rs +++ b/unit_tests/src/constants.rs @@ -141,3 +141,9 @@ pub const TEST_CONTRACT_CLASS_HASH: &str = ""; pub const ETHEREUM_ADDRESS: &str = ""; pub const INVALID_ETHEREUM_ADDRESS: &str = ""; pub const SELECTOR_NAME: &str = ""; + +/// +/// Value to be used as a signer for simulate_transaction tests. +/// +pub const SIGNER_PRIVATE: &str = ""; +pub const ARGENT_CONTRACT_ADDRESS: &str = ""; \ No newline at end of file diff --git a/unit_tests/src/lib.rs b/unit_tests/src/lib.rs index b97e0b4..8251577 100644 --- a/unit_tests/src/lib.rs +++ b/unit_tests/src/lib.rs @@ -73,3 +73,23 @@ impl TransactionFactory for BadTransactionFactory { }) } } + +pub struct MaxFeeTransactionFactory; + +impl TransactionFactory for MaxFeeTransactionFactory { + fn build(_: Option) -> BroadcastedTransaction { + BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction { + max_fee: FieldElement::from_hex_be("0x100000000000000000000000000000000").unwrap(), + signature: vec![], + nonce: FieldElement::ZERO, + sender_address: FieldElement::from_hex_be(ACCOUNT_CONTRACT).unwrap(), + calldata: vec![ + FieldElement::from_hex_be(TEST_CONTRACT_ADDRESS).unwrap(), + get_selector_from_name("sqrt").unwrap(), + FieldElement::from_hex_be("1").unwrap(), + FieldElement::from(81u8), + ], + is_query: false, + }) + } +} diff --git a/unit_tests/tests/test_simulate_transaction.rs b/unit_tests/tests/test_simulate_transaction.rs new file mode 100644 index 0000000..bcd3daf --- /dev/null +++ b/unit_tests/tests/test_simulate_transaction.rs @@ -0,0 +1,428 @@ +#![feature(assert_matches)] + +mod common; +use common::*; + +use starknet::signers::{LocalWallet, SigningKey}; +use starknet_accounts::{Account, Call, ConnectedAccount, Execution, SingleOwnerAccount}; +use starknet_core::chain_id; +use starknet_core::types::{ + BlockId, BlockTag, BroadcastedInvokeTransaction, BroadcastedTransaction, FieldElement, + SimulationFlag, StarknetError, +}; +use starknet_core::utils::get_selector_from_name; +use starknet_providers::{ + jsonrpc::HttpTransport, JsonRpcClient, MaybeUnknownErrorCode, Provider, ProviderError, + StarknetErrorWithMessage, +}; +use std::assert_matches::assert_matches; +use std::collections::HashMap; +use unit_tests::{ + BadTransactionFactory, MaxFeeTransactionFactory, OkTransactionFactory, TransactionFactory, +}; + +/// Test for the `simulate transaction` Deoxys RPC Call +/// Simulate a given sequence of transactions on the requested state, and generate the execution traces. +/// Note that some of the transactions may revert, in which case no error is thrown, but revert details can be seen on the returned trace object. +/// Note that some of the transactions may revert, this will be reflected by the revert_error property in the trace. +/// +/// # Arguments +// * `transactions` - A sequence of transactions to simulate, running each transaction on the state resulting from applying all the previous ones +// * `block_id` - The hash of the requested block, or number (height) of the requested block, or a block tag, +// * `simulation_flags` - Describes what parts of the transaction should be executed +// +// # Returns +// * `simulated_transactions` - The execution trace and consuemd resources of the required transactions +// +// # Errors +// * `block_not_found` - If the block is not found or invalid +// * `transaction_execution_error` - If one of the transactions failed to execute + + + +type RpcAccount<'a> = SingleOwnerAccount<&'a JsonRpcClient, LocalWallet>; + +pub fn build_single_owner_account<'a>( + rpc: &'a JsonRpcClient, + private_key: &str, + account_address: &str, + is_legacy: bool, +) -> RpcAccount<'a> { + let signer = LocalWallet::from(SigningKey::from_secret_scalar( + FieldElement::from_hex_be(private_key).unwrap(), + )); + let account_address = + FieldElement::from_hex_be(account_address).expect("Invalid Contract Address"); + let execution_encoding = if is_legacy { + starknet_accounts::ExecutionEncoding::Legacy + } else { + starknet_accounts::ExecutionEncoding::New + }; + SingleOwnerAccount::new( + rpc, + signer, + account_address, + chain_id::TESTNET, + execution_encoding, + ) +} +trait PrepareInvoke { + async fn prepare_invoke( + &self, + calls: Vec, + nonce: FieldElement, + max_fee: FieldElement, + query_only: bool, + ) -> BroadcastedInvokeTransaction; +} + +impl PrepareInvoke for SingleOwnerAccount<&JsonRpcClient, LocalWallet> { + async fn prepare_invoke( + &self, + calls: Vec, + nonce: FieldElement, + max_fee: FieldElement, + query_only: bool, + ) -> BroadcastedInvokeTransaction + where + Self: Account + ConnectedAccount, + { + let prepared_execution = Execution::new(calls, self) + .nonce(nonce) + .max_fee(max_fee) + .prepared() + .unwrap(); + prepared_execution + .get_invoke_request(query_only) + .await + .unwrap() + } +} + +pub fn generate_call( + contract_address: &str, + function_name: &str, + calldata_values: Vec, +) -> Call { + let to = FieldElement::from_hex_be(contract_address).unwrap(); + let selector = get_selector_from_name(function_name).unwrap(); + let calldata = calldata_values + .into_iter() + .map(FieldElement::from) + .collect(); + + Call { + to, + selector, + calldata, + } +} + +#[rstest] +#[tokio::test] +async fn fail_non_existing_block(clients: HashMap>) { + let deoxys = &clients[DEOXYS]; + + let ok_invoke_transaction = OkTransactionFactory::build(Some(FieldElement::ZERO)); + + assert_matches!( + deoxys.simulate_transactions(BlockId::Hash(FieldElement::ZERO),&[ok_invoke_transaction], []).await, + Err(ProviderError::StarknetError(StarknetErrorWithMessage { code: MaybeUnknownErrorCode::Known(code), .. })) if code == StarknetError::BlockNotFound + ); +} + +#[rstest] +#[tokio::test] +async fn fail_max_fee_too_big(clients: HashMap>) { + let deoxys = &clients[DEOXYS]; + + let max_fee_transaction = MaxFeeTransactionFactory::build(Some(FieldElement::ZERO)); + + assert_matches!( + deoxys.simulate_transactions(BlockId::Tag(BlockTag::Latest), &[max_fee_transaction], []).await, + Err(ProviderError::StarknetError(StarknetErrorWithMessage { code: MaybeUnknownErrorCode::Unknown(500), message })) if message == "Internal server error" + ); +} + +#[rstest] +#[tokio::test] +async fn fail_if_one_txn_cannot_be_executed( + clients: HashMap>, +) { + let deoxys = &clients[DEOXYS]; + + let bad_invoke_transaction = BadTransactionFactory::build(None); + let ok_invoke_transaction = OkTransactionFactory::build(Some(FieldElement::ONE)); + + assert_matches!( + deoxys.simulate_transactions(BlockId::Tag(BlockTag::Latest),&[ + bad_invoke_transaction, + ok_invoke_transaction, + ],[] ).await, + Err(ProviderError::StarknetError(StarknetErrorWithMessage { code: MaybeUnknownErrorCode::Known(code), .. })) if code == StarknetError::ContractError + ); +} + +#[rstest] +#[tokio::test] +async fn works_ok_on_no_validate(clients: HashMap>) { + let deoxys = &clients[DEOXYS]; + let pathfinder = &clients[PATHFINDER]; + + let tx = BroadcastedInvokeTransaction { + max_fee: FieldElement::from(420u16), + signature: vec![], + nonce: FieldElement::ZERO, + sender_address: FieldElement::from_hex_be(ACCOUNT_CONTRACT).unwrap(), + calldata: vec![ + FieldElement::from_hex_be(TEST_CONTRACT_ADDRESS).unwrap(), + get_selector_from_name("sqrt").unwrap(), + FieldElement::from_hex_be("1").unwrap(), + FieldElement::from(81u8), + ], + is_query: false, + }; + + let invoke_transaction = BroadcastedTransaction::Invoke(tx.clone()); + let invoke_transaction_2 = invoke_transaction.clone(); + + let invoked_transaction = BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction { + nonce: FieldElement::ONE, + ..tx + }); + + let invoked_transaction_2 = invoked_transaction.clone(); + + let deoxys_simulations = deoxys + .simulate_transactions( + BlockId::Tag(BlockTag::Latest), + &[invoke_transaction, invoked_transaction], + [], + ) + .await + .unwrap(); + + let pathfinder_simulations = pathfinder + .simulate_transactions( + BlockId::Tag(BlockTag::Latest), + &[invoke_transaction_2, invoked_transaction_2], + [], + ) + .await + .unwrap(); + + assert_eq!(deoxys_simulations.len(), pathfinder_simulations.len()); + assert_eq!( + deoxys_simulations[0].fee_estimation.gas_consumed, + pathfinder_simulations[0].fee_estimation.gas_consumed + ); + assert_eq!( + deoxys_simulations[0].fee_estimation.overall_fee, + pathfinder_simulations[0].fee_estimation.overall_fee + ); + assert_eq!( + deoxys_simulations[0].fee_estimation.gas_price, + pathfinder_simulations[0].fee_estimation.gas_price + ); +} + +#[rstest] +#[tokio::test] +async fn works_ok_on_validate_with_signature( + clients: HashMap>, +) { + let deoxys = &clients[DEOXYS]; + let pathfinder = &clients[PATHFINDER]; + + let deoxys_funding_account = + build_single_owner_account(deoxys, SIGNER_PRIVATE, ARGENT_CONTRACT_ADDRESS, true); + let pathfinder_funding_account = + build_single_owner_account(pathfinder, SIGNER_PRIVATE, ARGENT_CONTRACT_ADDRESS, true); + let deoxys_nonce = deoxys_funding_account + .get_nonce() + .await + .expect("Failed to get deoxys nonce"); + let pathfinder_nonce = pathfinder_funding_account + .get_nonce() + .await + .expect("Failed to get pathfinder nonce"); + + let max_fee = FieldElement::from(1000u16); + + let deoxys_calls = vec![generate_call(TEST_CONTRACT_ADDRESS, "sqrt", vec![81u8])]; + let pathfinder_calls = vec![generate_call(TEST_CONTRACT_ADDRESS, "sqrt", vec![81u8])]; + + let tx_deoxys = deoxys_funding_account + .prepare_invoke(deoxys_calls, deoxys_nonce, max_fee, false) + .await; + let tx_pathfinder = pathfinder_funding_account + .prepare_invoke(pathfinder_calls, pathfinder_nonce, max_fee, false) + .await; + + let invoke_transaction_deoxys = BroadcastedTransaction::Invoke(tx_deoxys); + let invoke_transaction_pathfinder = BroadcastedTransaction::Invoke(tx_pathfinder); + + let deoxys_simulations = deoxys + .simulate_transactions( + BlockId::Tag(BlockTag::Latest), + &[invoke_transaction_deoxys], + [], + ) + .await + .unwrap(); + let pathfinder_simulations = pathfinder + .simulate_transactions( + BlockId::Tag(BlockTag::Latest), + &[invoke_transaction_pathfinder], + [], + ) + .await + .unwrap(); + + assert_eq!(deoxys_simulations.len(), pathfinder_simulations.len()); + assert_eq!( + deoxys_simulations[0].fee_estimation.gas_consumed, + pathfinder_simulations[0].fee_estimation.gas_consumed + ); + assert_eq!( + deoxys_simulations[0].fee_estimation.overall_fee, + pathfinder_simulations[0].fee_estimation.overall_fee + ); + assert_eq!( + deoxys_simulations[0].fee_estimation.gas_price, + pathfinder_simulations[0].fee_estimation.gas_price + ); +} + +#[rstest] +#[tokio::test] +async fn works_ok_on_validate_without_signature_with_skip_validate( + clients: HashMap>, +) { + let deoxys = &clients[DEOXYS]; + let pathfinder = &clients[PATHFINDER]; + + let deoxys_funding_account = + build_single_owner_account(&deoxys, SIGNER_PRIVATE, ARGENT_CONTRACT_ADDRESS, true); + let pathfinder_funding_account = + build_single_owner_account(&pathfinder, SIGNER_PRIVATE, ARGENT_CONTRACT_ADDRESS, true); + let deoxys_nonce = deoxys_funding_account + .get_nonce() + .await + .expect("Failed to get deoxys nonce"); + let pathfinder_nonce = pathfinder_funding_account + .get_nonce() + .await + .expect("Failed to get pathfinder nonce"); + + let max_fee = FieldElement::from(1000u16); + + let deoxys_calls = vec![generate_call(TEST_CONTRACT_ADDRESS, "sqrt", vec![81u8])]; + let pathfinder_calls = vec![generate_call(TEST_CONTRACT_ADDRESS, "sqrt", vec![81u8])]; + + let tx_deoxys = deoxys_funding_account + .prepare_invoke(deoxys_calls, deoxys_nonce, max_fee, false) + .await; + let tx_pathfinder = pathfinder_funding_account + .prepare_invoke(pathfinder_calls, pathfinder_nonce, max_fee, false) + .await; + + let invoke_transaction_deoxys = BroadcastedTransaction::Invoke(tx_deoxys); + let invoke_transaction_pathfinder = BroadcastedTransaction::Invoke(tx_pathfinder); + + let deoxys_simulations = deoxys + .simulate_transactions( + BlockId::Tag(BlockTag::Latest), + &[invoke_transaction_deoxys], + [SimulationFlag::SkipValidate], + ) + .await + .unwrap(); + + let pathfinder_simulations = pathfinder + .simulate_transactions( + BlockId::Tag(BlockTag::Latest), + &[invoke_transaction_pathfinder], + [SimulationFlag::SkipValidate], + ) + .await + .unwrap(); + + assert_eq!(deoxys_simulations.len(), pathfinder_simulations.len()); + assert_eq!( + deoxys_simulations[0].fee_estimation.gas_consumed, + pathfinder_simulations[0].fee_estimation.gas_consumed + ); + assert_eq!( + deoxys_simulations[0].fee_estimation.overall_fee, + pathfinder_simulations[0].fee_estimation.overall_fee + ); + assert_eq!( + deoxys_simulations[0].fee_estimation.gas_price, + pathfinder_simulations[0].fee_estimation.gas_price + ); +} + +#[rstest] +#[tokio::test] +async fn works_ok_without_max_fee_with_skip_fee_charge( + clients: HashMap>, +) { + let deoxys = &clients[DEOXYS]; + let pathfinder = &clients[PATHFINDER]; + + let tx = BroadcastedInvokeTransaction { + max_fee: FieldElement::from(0u8), + signature: vec![], + nonce: FieldElement::ZERO, + sender_address: FieldElement::from_hex_be(ACCOUNT_CONTRACT).unwrap(), + calldata: vec![ + FieldElement::from_hex_be(TEST_CONTRACT_ADDRESS).unwrap(), + get_selector_from_name("sqrt").unwrap(), + FieldElement::from_hex_be("1").unwrap(), + FieldElement::from(81u8), + ], + is_query: false, + }; + + let invoke_transaction = BroadcastedTransaction::Invoke(tx.clone()); + let invoke_transaction_2 = invoke_transaction.clone(); + + let invoked_transaction_deoxys = BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction { + nonce: FieldElement::ONE, + ..tx + }); + let invoked_transaction_pathfinder = invoked_transaction_deoxys.clone(); + + let deoxys_simulations = deoxys + .simulate_transactions( + BlockId::Tag(BlockTag::Latest), + &[invoke_transaction, invoked_transaction_deoxys], + [SimulationFlag::SkipFeeCharge], + ) + .await + .unwrap(); + + let pathfinder_simulations = pathfinder + .simulate_transactions( + BlockId::Tag(BlockTag::Latest), + &[invoke_transaction_2, invoked_transaction_pathfinder], + [SimulationFlag::SkipFeeCharge], + ) + .await + .unwrap(); + + assert_eq!(deoxys_simulations.len(), pathfinder_simulations.len()); + assert_eq!( + deoxys_simulations[0].fee_estimation.gas_consumed, + pathfinder_simulations[0].fee_estimation.gas_consumed + ); + assert_eq!( + deoxys_simulations[0].fee_estimation.overall_fee, + pathfinder_simulations[0].fee_estimation.overall_fee + ); + assert_eq!( + deoxys_simulations[0].fee_estimation.gas_price, + pathfinder_simulations[0].fee_estimation.gas_price + ); +} From 3ffc62ea50ca485a6c924e2a847d89caa5db93e2 Mon Sep 17 00:00:00 2001 From: 0xTrinityy Date: Thu, 11 Jan 2024 15:50:34 +0100 Subject: [PATCH 2/8] feat: :white_check_mark: Adding simulate transaction test Adding simulate transaction type for Ditto test, TODO : Add constant --- unit_tests/src/constants.rs | 2 +- unit_tests/tests/test_simulate_transaction.rs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/unit_tests/src/constants.rs b/unit_tests/src/constants.rs index 37dcb12..64b8811 100644 --- a/unit_tests/src/constants.rs +++ b/unit_tests/src/constants.rs @@ -146,4 +146,4 @@ pub const SELECTOR_NAME: &str = ""; /// Value to be used as a signer for simulate_transaction tests. /// pub const SIGNER_PRIVATE: &str = ""; -pub const ARGENT_CONTRACT_ADDRESS: &str = ""; \ No newline at end of file +pub const ARGENT_CONTRACT_ADDRESS: &str = ""; diff --git a/unit_tests/tests/test_simulate_transaction.rs b/unit_tests/tests/test_simulate_transaction.rs index bcd3daf..ddbbd58 100644 --- a/unit_tests/tests/test_simulate_transaction.rs +++ b/unit_tests/tests/test_simulate_transaction.rs @@ -22,10 +22,10 @@ use unit_tests::{ }; /// Test for the `simulate transaction` Deoxys RPC Call -/// Simulate a given sequence of transactions on the requested state, and generate the execution traces. +/// Simulate a given sequence of transactions on the requested state, and generate the execution traces. /// Note that some of the transactions may revert, in which case no error is thrown, but revert details can be seen on the returned trace object. /// Note that some of the transactions may revert, this will be reflected by the revert_error property in the trace. -/// +/// /// # Arguments // * `transactions` - A sequence of transactions to simulate, running each transaction on the state resulting from applying all the previous ones // * `block_id` - The hash of the requested block, or number (height) of the requested block, or a block tag, @@ -38,8 +38,6 @@ use unit_tests::{ // * `block_not_found` - If the block is not found or invalid // * `transaction_execution_error` - If one of the transactions failed to execute - - type RpcAccount<'a> = SingleOwnerAccount<&'a JsonRpcClient, LocalWallet>; pub fn build_single_owner_account<'a>( From c1b0fcc5253ec33c824f06ca0042c00d1306ac50 Mon Sep 17 00:00:00 2001 From: 0xTrinityy Date: Thu, 11 Jan 2024 18:10:54 +0100 Subject: [PATCH 3/8] style: :art: Transfert simulate_transactions utils from test_simulate_transactions.rs to lib.rs Transfert simulate_transactions utils from test_simulate_transactions.rs to lib.rs for a better code format --- unit_tests/src/lib.rs | 84 ++++++++++++++++++ unit_tests/tests/test_simulate_transaction.rs | 85 +------------------ 2 files changed, 87 insertions(+), 82 deletions(-) diff --git a/unit_tests/src/lib.rs b/unit_tests/src/lib.rs index daa2f86..91c623b 100644 --- a/unit_tests/src/lib.rs +++ b/unit_tests/src/lib.rs @@ -4,10 +4,14 @@ use std::{fs::File, io::Read}; use constants::*; use serde::Deserialize; +use starknet::signers::{LocalWallet, SigningKey}; +use starknet_accounts::{Account, Call, ConnectedAccount, Execution, SingleOwnerAccount}; +use starknet_core::chain_id; use starknet_core::{ types::{BroadcastedInvokeTransaction, BroadcastedTransaction, FieldElement}, utils::get_selector_from_name, }; +use starknet_providers::{jsonrpc::HttpTransport, JsonRpcClient}; pub mod constants; pub mod fixtures; @@ -90,3 +94,83 @@ impl TransactionFactory for MaxFeeTransactionFactory { }) } } + +type RpcAccount<'a> = SingleOwnerAccount<&'a JsonRpcClient, LocalWallet>; + +pub fn build_single_owner_account<'a>( + rpc: &'a JsonRpcClient, + private_key: &str, + account_address: &str, + is_legacy: bool, +) -> RpcAccount<'a> { + let signer = LocalWallet::from(SigningKey::from_secret_scalar( + FieldElement::from_hex_be(private_key).unwrap(), + )); + let account_address = + FieldElement::from_hex_be(account_address).expect("Invalid Contract Address"); + let execution_encoding = if is_legacy { + starknet_accounts::ExecutionEncoding::Legacy + } else { + starknet_accounts::ExecutionEncoding::New + }; + SingleOwnerAccount::new( + rpc, + signer, + account_address, + chain_id::TESTNET, + execution_encoding, + ) +} + +#[allow(async_fn_in_trait)] +pub trait PrepareInvoke { + async fn prepare_invoke( + &self, + calls: Vec, + nonce: FieldElement, + max_fee: FieldElement, + query_only: bool, + ) -> BroadcastedInvokeTransaction; +} + +impl PrepareInvoke for SingleOwnerAccount<&JsonRpcClient, LocalWallet> { + async fn prepare_invoke( + &self, + calls: Vec, + nonce: FieldElement, + max_fee: FieldElement, + query_only: bool, + ) -> BroadcastedInvokeTransaction + where + Self: Account + ConnectedAccount, + { + let prepared_execution = Execution::new(calls, self) + .nonce(nonce) + .max_fee(max_fee) + .prepared() + .unwrap(); + prepared_execution + .get_invoke_request(query_only) + .await + .unwrap() + } +} + +pub fn generate_call( + contract_address: &str, + function_name: &str, + calldata_values: Vec, +) -> Call { + let to = FieldElement::from_hex_be(contract_address).unwrap(); + let selector = get_selector_from_name(function_name).unwrap(); + let calldata = calldata_values + .into_iter() + .map(FieldElement::from) + .collect(); + + Call { + to, + selector, + calldata, + } +} diff --git a/unit_tests/tests/test_simulate_transaction.rs b/unit_tests/tests/test_simulate_transaction.rs index ddbbd58..2d5744c 100644 --- a/unit_tests/tests/test_simulate_transaction.rs +++ b/unit_tests/tests/test_simulate_transaction.rs @@ -3,9 +3,7 @@ mod common; use common::*; -use starknet::signers::{LocalWallet, SigningKey}; -use starknet_accounts::{Account, Call, ConnectedAccount, Execution, SingleOwnerAccount}; -use starknet_core::chain_id; +use starknet_accounts::ConnectedAccount; use starknet_core::types::{ BlockId, BlockTag, BroadcastedInvokeTransaction, BroadcastedTransaction, FieldElement, SimulationFlag, StarknetError, @@ -18,7 +16,8 @@ use starknet_providers::{ use std::assert_matches::assert_matches; use std::collections::HashMap; use unit_tests::{ - BadTransactionFactory, MaxFeeTransactionFactory, OkTransactionFactory, TransactionFactory, + build_single_owner_account, generate_call, BadTransactionFactory, MaxFeeTransactionFactory, + OkTransactionFactory, PrepareInvoke, TransactionFactory, }; /// Test for the `simulate transaction` Deoxys RPC Call @@ -38,84 +37,6 @@ use unit_tests::{ // * `block_not_found` - If the block is not found or invalid // * `transaction_execution_error` - If one of the transactions failed to execute -type RpcAccount<'a> = SingleOwnerAccount<&'a JsonRpcClient, LocalWallet>; - -pub fn build_single_owner_account<'a>( - rpc: &'a JsonRpcClient, - private_key: &str, - account_address: &str, - is_legacy: bool, -) -> RpcAccount<'a> { - let signer = LocalWallet::from(SigningKey::from_secret_scalar( - FieldElement::from_hex_be(private_key).unwrap(), - )); - let account_address = - FieldElement::from_hex_be(account_address).expect("Invalid Contract Address"); - let execution_encoding = if is_legacy { - starknet_accounts::ExecutionEncoding::Legacy - } else { - starknet_accounts::ExecutionEncoding::New - }; - SingleOwnerAccount::new( - rpc, - signer, - account_address, - chain_id::TESTNET, - execution_encoding, - ) -} -trait PrepareInvoke { - async fn prepare_invoke( - &self, - calls: Vec, - nonce: FieldElement, - max_fee: FieldElement, - query_only: bool, - ) -> BroadcastedInvokeTransaction; -} - -impl PrepareInvoke for SingleOwnerAccount<&JsonRpcClient, LocalWallet> { - async fn prepare_invoke( - &self, - calls: Vec, - nonce: FieldElement, - max_fee: FieldElement, - query_only: bool, - ) -> BroadcastedInvokeTransaction - where - Self: Account + ConnectedAccount, - { - let prepared_execution = Execution::new(calls, self) - .nonce(nonce) - .max_fee(max_fee) - .prepared() - .unwrap(); - prepared_execution - .get_invoke_request(query_only) - .await - .unwrap() - } -} - -pub fn generate_call( - contract_address: &str, - function_name: &str, - calldata_values: Vec, -) -> Call { - let to = FieldElement::from_hex_be(contract_address).unwrap(); - let selector = get_selector_from_name(function_name).unwrap(); - let calldata = calldata_values - .into_iter() - .map(FieldElement::from) - .collect(); - - Call { - to, - selector, - calldata, - } -} - #[rstest] #[tokio::test] async fn fail_non_existing_block(clients: HashMap>) { From 312c3139c357497e158488a6052c4d206483413e Mon Sep 17 00:00:00 2001 From: 0xTrinityy Date: Thu, 11 Jan 2024 18:16:40 +0100 Subject: [PATCH 4/8] refactor: :zap: Changing tests results for better reliability Changing tests results for better reliability --- unit_tests/tests/test_simulate_transaction.rs | 52 ++----------------- 1 file changed, 4 insertions(+), 48 deletions(-) diff --git a/unit_tests/tests/test_simulate_transaction.rs b/unit_tests/tests/test_simulate_transaction.rs index 2d5744c..2dd30fc 100644 --- a/unit_tests/tests/test_simulate_transaction.rs +++ b/unit_tests/tests/test_simulate_transaction.rs @@ -131,18 +131,7 @@ async fn works_ok_on_no_validate(clients: HashMap Date: Thu, 11 Jan 2024 22:57:34 +0100 Subject: [PATCH 5/8] feat: :building_construction: bump starknet.rs version to maintain compatibility with Deoxys bump starknet.rs version to maintain compatibility with Deoxys --- Cargo.lock | 36 +++++++++---------- unit_tests/Cargo.toml | 8 ++--- unit_tests/tests/test_call.rs | 29 ++++----------- unit_tests/tests/test_estimate_fee.rs | 4 +-- unit_tests/tests/test_estimate_message_fee.rs | 10 +++--- .../tests/test_get_block_transaction_count.rs | 7 ++-- .../tests/test_get_block_with_tx_hashes.rs | 7 ++-- unit_tests/tests/test_get_block_with_txs.rs | 7 ++-- unit_tests/tests/test_get_class.rs | 7 ++-- unit_tests/tests/test_get_class_at.rs | 13 ++----- unit_tests/tests/test_get_class_hash_at.rs | 13 ++----- unit_tests/tests/test_get_events.rs | 15 +++----- unit_tests/tests/test_get_nonce.rs | 13 ++----- unit_tests/tests/test_get_state_update.rs | 5 ++- unit_tests/tests/test_get_storage_at.rs | 13 ++----- ...t_get_transaction_by_block_id_and_index.rs | 13 ++----- .../tests/test_get_transaction_by_hash.rs | 8 ++--- .../tests/test_get_transaction_status.rs | 8 ++--- unit_tests/tests/test_simulate_transaction.rs | 9 +++-- 19 files changed, 72 insertions(+), 153 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 74703b4..a3f017c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2127,8 +2127,8 @@ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "starknet" -version = "0.7.0" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.8.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=96c6803#96c6803118773d9fd1d74fcf1465763f11a080a1" dependencies = [ "starknet-accounts", "starknet-contract", @@ -2142,8 +2142,8 @@ dependencies = [ [[package]] name = "starknet-accounts" -version = "0.6.1" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.7.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=96c6803#96c6803118773d9fd1d74fcf1465763f11a080a1" dependencies = [ "async-trait", "auto_impl", @@ -2155,8 +2155,8 @@ dependencies = [ [[package]] name = "starknet-contract" -version = "0.6.0" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.7.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=96c6803#96c6803118773d9fd1d74fcf1465763f11a080a1" dependencies = [ "serde", "serde_json", @@ -2169,8 +2169,8 @@ dependencies = [ [[package]] name = "starknet-core" -version = "0.7.2" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.8.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=96c6803#96c6803118773d9fd1d74fcf1465763f11a080a1" dependencies = [ "base64 0.21.6", "flate2", @@ -2187,7 +2187,7 @@ dependencies = [ [[package]] name = "starknet-crypto" version = "0.6.1" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=96c6803#96c6803118773d9fd1d74fcf1465763f11a080a1" dependencies = [ "crypto-bigint", "hex", @@ -2206,7 +2206,7 @@ dependencies = [ [[package]] name = "starknet-crypto-codegen" version = "0.3.2" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=96c6803#96c6803118773d9fd1d74fcf1465763f11a080a1" dependencies = [ "starknet-curve", "starknet-ff", @@ -2216,7 +2216,7 @@ dependencies = [ [[package]] name = "starknet-curve" version = "0.4.0" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=96c6803#96c6803118773d9fd1d74fcf1465763f11a080a1" dependencies = [ "starknet-ff", ] @@ -2224,7 +2224,7 @@ dependencies = [ [[package]] name = "starknet-ff" version = "0.3.5" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=96c6803#96c6803118773d9fd1d74fcf1465763f11a080a1" dependencies = [ "ark-ff", "bigdecimal", @@ -2236,8 +2236,8 @@ dependencies = [ [[package]] name = "starknet-macros" -version = "0.1.4" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.1.5" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=96c6803#96c6803118773d9fd1d74fcf1465763f11a080a1" dependencies = [ "starknet-core", "syn 2.0.48", @@ -2245,8 +2245,8 @@ dependencies = [ [[package]] name = "starknet-providers" -version = "0.7.0" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.8.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=96c6803#96c6803118773d9fd1d74fcf1465763f11a080a1" dependencies = [ "async-trait", "auto_impl", @@ -2264,8 +2264,8 @@ dependencies = [ [[package]] name = "starknet-signers" -version = "0.5.0" -source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=64ebc36#64ebc364c0c346e81b715c5b4a3b32ef37b055c8" +version = "0.6.0" +source = "git+https://github.com/xJonathanLEI/starknet-rs.git?rev=96c6803#96c6803118773d9fd1d74fcf1465763f11a080a1" dependencies = [ "async-trait", "auto_impl", diff --git a/unit_tests/Cargo.toml b/unit_tests/Cargo.toml index d8348cd..fd05b76 100644 --- a/unit_tests/Cargo.toml +++ b/unit_tests/Cargo.toml @@ -12,10 +12,10 @@ serde = "1.0.194" serde_json = "1.0.110" tokio = { version = "1", features = ["full"] } url = "2.5.0" -starknet = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "64ebc36", default-features = false } -starknet-core = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "64ebc36", default-features = false } -starknet-providers = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "64ebc36", default-features = false } -starknet-accounts = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "64ebc36", default-features = false } +starknet = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "96c6803", default-features = false } +starknet-core = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "96c6803", default-features = false } +starknet-providers = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "96c6803", default-features = false } +starknet-accounts = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "96c6803", default-features = false } env_logger = "0.10.1" [dev-dependencies] diff --git a/unit_tests/tests/test_call.rs b/unit_tests/tests/test_call.rs index 832ce3e..c0856c9 100644 --- a/unit_tests/tests/test_call.rs +++ b/unit_tests/tests/test_call.rs @@ -10,8 +10,7 @@ use starknet_core::{ utils::get_selector_from_name, }; use starknet_providers::{ - jsonrpc::HttpTransport, JsonRpcClient, MaybeUnknownErrorCode, Provider, ProviderError, - StarknetErrorWithMessage, + jsonrpc::HttpTransport, JsonRpcClient, Provider, ProviderError, }; /// @@ -39,11 +38,7 @@ async fn fail_non_existing_block(clients: HashMap) { assert_matches!( response_deoxys, - Some(ProviderError::StarknetError(StarknetErrorWithMessage { - message: _, - code: MaybeUnknownErrorCode::Unknown(-32602) - })) + Some(ProviderError::StarknetError(StarknetError::UnexpectedError(_))) //previous error : Unknown(-32602) ) } @@ -101,10 +97,7 @@ async fn fail_invalid_block_range(deoxys: JsonRpcClient) { // for some reason a block range of 0 results in an internal error assert_matches!( response_deoxys, - Some(ProviderError::StarknetError(StarknetErrorWithMessage { - message: _, - code: MaybeUnknownErrorCode::Unknown(-32603) - })) + Some(ProviderError::StarknetError(StarknetError::UnexpectedError(_))) //previous error : Unknown(-32603) ) } diff --git a/unit_tests/tests/test_get_nonce.rs b/unit_tests/tests/test_get_nonce.rs index bd42fa2..11319d2 100644 --- a/unit_tests/tests/test_get_nonce.rs +++ b/unit_tests/tests/test_get_nonce.rs @@ -6,8 +6,7 @@ use std::{assert_matches::assert_matches, collections::HashMap}; use common::*; use starknet_core::types::{BlockId, BlockTag, FieldElement, StarknetError}; use starknet_providers::{ - jsonrpc::HttpTransport, JsonRpcClient, MaybeUnknownErrorCode, Provider, ProviderError, - StarknetErrorWithMessage, + jsonrpc::HttpTransport, JsonRpcClient, Provider, ProviderError, }; /// @@ -47,10 +46,7 @@ async fn fail_non_existing_block(clients: HashMap Date: Thu, 11 Jan 2024 23:00:06 +0100 Subject: [PATCH 6/8] feat: :art: formated code formated code --- unit_tests/tests/test_call.rs | 19 ++++++---- unit_tests/tests/test_estimate_fee.rs | 11 ++++-- unit_tests/tests/test_estimate_message_fee.rs | 10 ++++-- unit_tests/tests/test_get_class.rs | 22 +++++------- unit_tests/tests/test_get_class_at.rs | 8 ++--- unit_tests/tests/test_get_class_hash_at.rs | 8 ++--- unit_tests/tests/test_get_events.rs | 12 ++++--- unit_tests/tests/test_get_nonce.rs | 8 ++--- unit_tests/tests/test_get_state_update.rs | 8 ++--- unit_tests/tests/test_get_storage_at.rs | 8 ++--- ...t_get_transaction_by_block_id_and_index.rs | 8 ++--- .../tests/test_get_transaction_by_hash.rs | 8 ++--- .../tests/test_get_transaction_status.rs | 8 ++--- unit_tests/tests/test_simulate_transaction.rs | 35 +++++++++++++------ 14 files changed, 98 insertions(+), 75 deletions(-) diff --git a/unit_tests/tests/test_call.rs b/unit_tests/tests/test_call.rs index c0856c9..cd70692 100644 --- a/unit_tests/tests/test_call.rs +++ b/unit_tests/tests/test_call.rs @@ -9,9 +9,7 @@ use starknet_core::{ types::{BlockId, BlockTag, FieldElement, FunctionCall, StarknetError}, utils::get_selector_from_name, }; -use starknet_providers::{ - jsonrpc::HttpTransport, JsonRpcClient, Provider, ProviderError, -}; +use starknet_providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider, ProviderError}; /// /// Unit test for `starknet_call` @@ -38,7 +36,8 @@ async fn fail_non_existing_block(clients: HashMap) { assert_matches!( response_deoxys, - Some(ProviderError::StarknetError(StarknetError::UnexpectedError(_))) //previous error : Unknown(-32602) + Some(ProviderError::StarknetError( + StarknetError::UnexpectedError(_) + )) //previous error : Unknown(-32602) ) } @@ -97,7 +97,9 @@ async fn fail_invalid_block_range(deoxys: JsonRpcClient) { // for some reason a block range of 0 results in an internal error assert_matches!( response_deoxys, - Some(ProviderError::StarknetError(StarknetError::UnexpectedError(_))) //previous error : Unknown(-32603) + Some(ProviderError::StarknetError( + StarknetError::UnexpectedError(_) + )) //previous error : Unknown(-32603) ) } diff --git a/unit_tests/tests/test_get_nonce.rs b/unit_tests/tests/test_get_nonce.rs index 11319d2..1914a86 100644 --- a/unit_tests/tests/test_get_nonce.rs +++ b/unit_tests/tests/test_get_nonce.rs @@ -5,9 +5,7 @@ use std::{assert_matches::assert_matches, collections::HashMap}; use common::*; use starknet_core::types::{BlockId, BlockTag, FieldElement, StarknetError}; -use starknet_providers::{ - jsonrpc::HttpTransport, JsonRpcClient, Provider, ProviderError, -}; +use starknet_providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider, ProviderError}; /// /// Test for RPC call starknet_getNonce. @@ -71,7 +69,9 @@ async fn fail_non_existing_contract(clients: HashMap Date: Fri, 12 Jan 2024 11:31:06 +0100 Subject: [PATCH 7/8] feat: :art: fmt fmt --- unit_tests/tests/test_get_transaction_receipt.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/unit_tests/tests/test_get_transaction_receipt.rs b/unit_tests/tests/test_get_transaction_receipt.rs index fe2286a..ec9e59e 100644 --- a/unit_tests/tests/test_get_transaction_receipt.rs +++ b/unit_tests/tests/test_get_transaction_receipt.rs @@ -24,7 +24,9 @@ async fn fail_invalid_transaction_hash(clients: HashMap Date: Fri, 12 Jan 2024 14:53:54 +0100 Subject: [PATCH 8/8] feat: :art: Improve code format Improve code format --- Cargo.lock | 1 + unit_tests/Cargo.toml | 1 + unit_tests/src/lib.rs | 2 +- unit_tests/tests/test_chain_id.rs | 5 +---- unit_tests/tests/test_syncing.rs | 9 ++------- 5 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4feab28..af017f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2811,6 +2811,7 @@ dependencies = [ "starknet-accounts 0.7.0", "starknet-core 0.8.0", "starknet-providers 0.8.0", + "starknet-signers 0.6.0", "tokio", "url", ] diff --git a/unit_tests/Cargo.toml b/unit_tests/Cargo.toml index 55b8752..fb95f28 100644 --- a/unit_tests/Cargo.toml +++ b/unit_tests/Cargo.toml @@ -14,6 +14,7 @@ starknet = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "96c starknet-core = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "96c6803", default-features = false } starknet-providers = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "96c6803", default-features = false } starknet-accounts = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "96c6803", default-features = false } +starknet-signers = { git = "https://github.com/xJonathanLEI/starknet-rs.git", rev = "96c6803", default-features = false } env_logger = "0.10.1" macro_utils = { path = "../macro_utils/" } diff --git a/unit_tests/src/lib.rs b/unit_tests/src/lib.rs index 7952cae..c948462 100644 --- a/unit_tests/src/lib.rs +++ b/unit_tests/src/lib.rs @@ -1,7 +1,6 @@ #![feature(assert_matches)] use constants::*; -use starknet::signers::{LocalWallet, SigningKey}; use starknet_accounts::{Account, Call, ConnectedAccount, Execution, SingleOwnerAccount}; use starknet_core::chain_id; use starknet_core::{ @@ -9,6 +8,7 @@ use starknet_core::{ utils::get_selector_from_name, }; use starknet_providers::{jsonrpc::HttpTransport, JsonRpcClient}; +use starknet_signers::{LocalWallet, SigningKey}; pub mod constants; pub mod fixtures; diff --git a/unit_tests/tests/test_chain_id.rs b/unit_tests/tests/test_chain_id.rs index 325e66f..f00230f 100644 --- a/unit_tests/tests/test_chain_id.rs +++ b/unit_tests/tests/test_chain_id.rs @@ -1,10 +1,7 @@ mod common; use common::*; -use starknet::providers::{ - jsonrpc::{HttpTransport, JsonRpcClient}, - Provider, -}; +use starknet_providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}; use std::collections::HashMap; /// diff --git a/unit_tests/tests/test_syncing.rs b/unit_tests/tests/test_syncing.rs index 9d51229..b03e8b6 100644 --- a/unit_tests/tests/test_syncing.rs +++ b/unit_tests/tests/test_syncing.rs @@ -1,13 +1,8 @@ mod common; use common::*; -use starknet::{ - core::types::SyncStatusType, - providers::{ - jsonrpc::{HttpTransport, JsonRpcClient}, - Provider, - }, -}; +use starknet_core::types::SyncStatusType; +use starknet_providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider}; use std::collections::HashMap; ///