From 8f0de7d4d24de97b9ffd5eb1d4c2b33e63c5f809 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Tue, 15 Oct 2024 09:42:19 -0400 Subject: [PATCH] Update bench script for channel nonces commit-id:b181e62c --- packages/account_sdk/cmd/bench.rs | 206 ++++++++++-------- .../src/execute_from_outside_test.rs | 96 +++++++- packages/account_sdk/src/provider.rs | 6 + packages/account_sdk/src/tests/account/mod.rs | 2 - .../src/tests/runners/cartridge.rs | 3 - .../account_sdk/src/tests/runners/katana.rs | 7 +- packages/account_sdk/src/upgrade_test.rs | 3 +- 7 files changed, 226 insertions(+), 97 deletions(-) diff --git a/packages/account_sdk/cmd/bench.rs b/packages/account_sdk/cmd/bench.rs index ed001cfb7..4b13d8e15 100644 --- a/packages/account_sdk/cmd/bench.rs +++ b/packages/account_sdk/cmd/bench.rs @@ -1,16 +1,23 @@ -use account_sdk::abigen::controller; use account_sdk::abigen::controller::{Call, OutsideExecution}; use account_sdk::account::outside_execution::{OutsideExecutionAccount, OutsideExecutionCaller}; use account_sdk::account::session::hash::Policy; +use account_sdk::account::session::SessionAccount; use account_sdk::artifacts::{Version, CONTROLLERS}; use account_sdk::controller::Controller; -use account_sdk::provider::CartridgeProvider; +use account_sdk::factory::ControllerFactory; +use account_sdk::provider::{ + CartridgeJsonRpcProvider, CartridgeProvider, ExecuteFromOutsideError, + ExecuteFromOutsideResponse, +}; use account_sdk::signers::{Owner, Signer}; -use cainome::cairo_serde::CairoSerde; +use cainome::cairo_serde::ContractAddress; use rand::Rng as _; -use starknet::core::utils::get_selector_from_name; +use starknet::accounts::{Account, AccountFactory, AccountFactoryError}; +use starknet::core::types::StarknetError; +use starknet::core::utils::cairo_short_string_to_felt; use starknet::macros::{felt, selector}; +use starknet::providers::ProviderError; use starknet::signers::SigningKey; use starknet_crypto::Felt; use std::sync::Arc; @@ -18,49 +25,76 @@ use tokio::time::Duration; use url::Url; // Constants for TPS and duration -const TPS: usize = 150; +const TPS: usize = 1; const DURATION_SECS: u64 = 30 * 60; -const BENCH_ACCOUNT: Felt = - felt!("0x014679c1478a47f2fb378699f921517b0a4b412c9b7cec7348b1e0bb3efc42cf"); - #[tokio::main] async fn main() { - let rpc_url = Url::parse("https://api.cartridge.gg/x/starknet/sepolia").unwrap(); + let rpc_url = Url::parse("http://localhost:8001/x/starknet/sepolia").unwrap(); + // let rpc_url = Url::parse("https://api.cartridge.gg/x/starknet/sepolia").unwrap(); + let provider = CartridgeJsonRpcProvider::new(rpc_url.clone()); + let chain_id = felt!("0x534e5f5345504f4c4941"); // Hex for "SN_SEPOLIA" - let owner = Signer::Starknet(SigningKey::from_secret_scalar(felt!( + let signer = SigningKey::from_secret_scalar(felt!( "0x6b80fcafbecee2c7ddff50c9a09b529c8f65b2fdb457ea134e76ee17640d768" - ))); + )); + let owner = Owner::Signer(Signer::Starknet(signer.clone())); let username = "bench".to_owned(); - - let mut controller = { - let mut constructor_calldata = controller::Signer::cairo_serialize(&owner.clone().into()); - constructor_calldata.extend(Option::::cairo_serialize(&None)); - - Controller::new( - "app_id".to_string(), - username, - CONTROLLERS[&Version::LATEST].hash, - rpc_url, - Owner::Signer(owner.clone()), - BENCH_ACCOUNT, - chain_id, - ) - }; + let salt = cairo_short_string_to_felt(&username).unwrap(); + + let factory = ControllerFactory::new( + CONTROLLERS[&Version::LATEST].hash, + chain_id, + owner.clone(), + provider, + ); + + let address = factory.address(salt); + + let mut controller = Controller::new( + "app_id".to_string(), + username, + CONTROLLERS[&Version::LATEST].hash, + rpc_url, + owner.clone(), + address, + chain_id, + ); + + match factory + .deploy_v1(salt) + .fee_estimate_multiplier(1.5) + .send() + .await + { + Ok(_) => (), + Err(e) => { + if let AccountFactoryError::Provider(ProviderError::StarknetError( + StarknetError::TransactionExecutionError(ref error_data), + )) = e + { + if !error_data + .execution_error + .contains("is unavailable for deployment") + { + println!("Deployment failed: {:?}", e); + } + } else { + println!("Deployment failed: {:?}", e); + } + } + } let contract_address = - felt!("0x77d04bd307605c021a1def7987278475342f4ea2581f7c49930e9269bedf476"); + felt!("0x165a91f138a5c5f5016a0afe3412b551559b3de4d89357282fe145e3e3c404b"); let duration = Duration::from_secs(DURATION_SECS); let total_transactions = TPS * duration.as_secs() as usize; - let _ = controller + let session_account = controller .create_session( - vec![ - Policy::new(contract_address, selector!("flop")), - Policy::new(contract_address, selector!("flip")), - ], + vec![Policy::new(contract_address, selector!("flip"))], u32::MAX as u64, ) .await @@ -69,67 +103,65 @@ async fn main() { let controller = Arc::new(controller); let interval = Duration::from_secs_f64(1.0 / TPS as f64); - let mut handles = vec![]; + // let mut handles = vec![]; for i in 0..total_transactions { let controller = Arc::clone(&controller); - let handle = tokio::spawn(async move { - let flop = Call { - to: contract_address.into(), - selector: get_selector_from_name("flop").unwrap(), - calldata: vec![], - }; - - let x = rand::thread_rng().gen_range(0..=100); - let y = rand::thread_rng().gen_range(0..=100); - let flip = Call { - to: contract_address.into(), - selector: get_selector_from_name("flip").unwrap(), - calldata: vec![x.into(), y.into()], - }; - - let session_account = controller - .session_account(&[flop.clone().into(), flip.clone().into()]) - .unwrap(); - - // Execute flip - let flip_execution = OutsideExecution { - caller: OutsideExecutionCaller::Any.into(), - execute_after: u64::MIN, - execute_before: u32::MAX as u64, - calls: vec![flip], - nonce: (SigningKey::from_random().secret_scalar(), Felt::ZERO), - }; - - let flip_signed = session_account - .sign_outside_execution(flip_execution.clone()) - .await - .unwrap(); - - let flip_result = controller - .provider - .add_execute_outside_transaction( - flip_execution, - BENCH_ACCOUNT, - flip_signed.signature, - ) - .await; - - match flip_result { - Ok(_) => { - println!("Routine {}: Successfully executed flip function", i); - } - Err(err) => { - eprintln!("Routine {}: Failed to execute flip function: {:?}", i, err); - } + let x = rand::thread_rng().gen_range(0..=100); + let y = rand::thread_rng().gen_range(0..=100); + + match flip(&controller, &session_account, contract_address.into(), x, y).await { + Ok(_) => { + println!("Routine {}: Successfully executed flip function", i); + } + Err(err) => { + eprintln!("Routine {}: Failed to execute flip function: {:?}", i, err); } - }); + } + // }); - handles.push(handle); + // handles.push(handle); tokio::time::sleep(interval).await; + break; } - for handle in handles { - handle.await.unwrap(); - } + // for handle in handles { + // handle.await.unwrap(); + // } +} + +async fn flip( + controller: &Controller, + session_account: &SessionAccount, + contract_address: ContractAddress, + x: u64, + y: u64, +) -> Result { + let flip = Call { + to: contract_address, + selector: selector!("flip"), + calldata: vec![x.into(), y.into()], + }; + + let flip_execution = OutsideExecution { + caller: OutsideExecutionCaller::Any.into(), + execute_after: 0, + execute_before: u32::MAX as u64, + calls: vec![flip], + nonce: (Felt::ONE, Felt::ZERO), + }; + + let flip_signed = session_account + .sign_outside_execution(flip_execution.clone()) + .await + .unwrap(); + + controller + .provider + .add_execute_outside_transaction( + flip_execution, + controller.address(), + flip_signed.signature, + ) + .await } diff --git a/packages/account_sdk/src/execute_from_outside_test.rs b/packages/account_sdk/src/execute_from_outside_test.rs index 24c62035e..e2672d207 100644 --- a/packages/account_sdk/src/execute_from_outside_test.rs +++ b/packages/account_sdk/src/execute_from_outside_test.rs @@ -3,13 +3,22 @@ use std::time::Duration; use starknet::{ core::types::Call, macros::{felt, selector}, + signers::SigningKey, }; +use starknet_crypto::Felt; -use crate::tests::account::FEE_TOKEN_ADDRESS; use crate::tests::runners::katana::KatanaRunner; use crate::tests::transaction_waiter::TransactionWaiter; -use crate::{abigen::erc_20::Erc20, signers::Owner}; +use crate::{ + abigen::{controller::OutsideExecution, erc_20::Erc20}, + account::{ + outside_execution::{OutsideExecutionAccount, OutsideExecutionCaller}, + session::hash::Policy, + }, + provider::CartridgeProvider, +}; use crate::{artifacts::Version, signers::Signer}; +use crate::{signers::Owner, tests::account::FEE_TOKEN_ADDRESS}; use cainome::cairo_serde::{CairoSerde, ContractAddress, U256}; #[tokio::test] @@ -59,3 +68,86 @@ async fn test_execute_from_outside() { assert_eq!(balance, amount); } + +#[tokio::test] +async fn test_execute_from_outside_with_session() { + let owner_signer = Signer::new_starknet_random(); + let runner = KatanaRunner::load(); + let mut controller = runner + .deploy_controller( + "testuser".to_owned(), + Owner::Signer(owner_signer.clone()), + Version::LATEST, + ) + .await; + + // Create policies for the session + let policies = vec![ + Policy::new(*FEE_TOKEN_ADDRESS, selector!("transfer")), + Policy::new(*FEE_TOKEN_ADDRESS, selector!("approve")), + ]; + + // Create a session + let session_account = controller + .create_session(policies, u32::MAX as u64) + .await + .expect("Failed to create session"); + + let recipient = ContractAddress(felt!("0x18301129")); + let amount = U256 { + low: 0x10_u128, + high: 0, + }; + + let call = Call { + to: *FEE_TOKEN_ADDRESS, + selector: selector!("transfer"), + calldata: [ + ::cairo_serialize(&recipient), + ::cairo_serialize(&amount), + ] + .concat(), + }; + + // Create OutsideExecution + let outside_execution = OutsideExecution { + caller: OutsideExecutionCaller::Any.into(), + execute_after: 0, + execute_before: u32::MAX as u64, + calls: vec![call.into()], + nonce: (SigningKey::from_random().secret_scalar(), Felt::ZERO), + }; + + // Sign the outside execution with the session account + let signed_execution = session_account + .sign_outside_execution(outside_execution.clone()) + .await + .expect("Failed to sign outside execution"); + + // Execute from outside + let result = controller + .provider + .add_execute_outside_transaction( + outside_execution, + controller.address, + signed_execution.signature, + ) + .await + .expect("Failed to execute from outside"); + + TransactionWaiter::new(result.transaction_hash, runner.client()) + .with_timeout(Duration::from_secs(5)) + .wait() + .await + .unwrap(); + + // Verify the transfer + let contract_erc20 = Erc20::new(*FEE_TOKEN_ADDRESS, &controller); + let balance = contract_erc20 + .balanceOf(&recipient) + .call() + .await + .expect("Failed to call contract"); + + assert_eq!(balance, amount); +} diff --git a/packages/account_sdk/src/provider.rs b/packages/account_sdk/src/provider.rs index dec9a5287..c73a10b62 100644 --- a/packages/account_sdk/src/provider.rs +++ b/packages/account_sdk/src/provider.rs @@ -78,6 +78,11 @@ impl CartridgeProvider for CartridgeJsonRpcProvider { }, }; + println!( + "JSON-RPC request: {}", + serde_json::to_string_pretty(&request).unwrap() + ); + let client = Client::new(); let response = client .post(self.rpc_url.as_str()) @@ -87,6 +92,7 @@ impl CartridgeProvider for CartridgeJsonRpcProvider { .await?; let json_response: Value = response.json().await?; + println!("json_rpc_response: {:?}", json_response); let json_rpc_response: JsonRpcResponse = serde_json::from_value(json_response)?; diff --git a/packages/account_sdk/src/tests/account/mod.rs b/packages/account_sdk/src/tests/account/mod.rs index 90500599f..c38a2670f 100644 --- a/packages/account_sdk/src/tests/account/mod.rs +++ b/packages/account_sdk/src/tests/account/mod.rs @@ -14,6 +14,4 @@ lazy_static! { felt!("0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"); pub static ref ERC20_CONTRACT_CLASS_HASH: Felt = felt!("0x02a8846878b6ad1f54f6ba46f5f40e11cee755c677f130b2c4b60566c9003f1f"); - pub static ref CHAIN_ID: Felt = - felt!("0x00000000000000000000000000000000000000000000000000004b4154414e41"); } diff --git a/packages/account_sdk/src/tests/runners/cartridge.rs b/packages/account_sdk/src/tests/runners/cartridge.rs index fbe43c8ed..3cec64965 100644 --- a/packages/account_sdk/src/tests/runners/cartridge.rs +++ b/packages/account_sdk/src/tests/runners/cartridge.rs @@ -181,9 +181,6 @@ impl CartridgeProxy { } async fn add_guardian_authorization(&self, session_token: &mut RawSessionToken, address: Felt) { - println!("\n\n----\n\n"); - dbg!(&session_token.session_authorization); - println!("\n\n----\n\n"); if session_token.session_authorization.len() == 2 { // Authorization by registered return; diff --git a/packages/account_sdk/src/tests/runners/katana.rs b/packages/account_sdk/src/tests/runners/katana.rs index 56f6759cb..6d3c6caa4 100644 --- a/packages/account_sdk/src/tests/runners/katana.rs +++ b/packages/account_sdk/src/tests/runners/katana.rs @@ -153,7 +153,12 @@ impl KatanaRunner { ) -> Controller { let prefunded: SingleOwnerAccount<&JsonRpcClient, LocalWallet> = self.executor().await; - let class_hash = self.declare_controller(version).await; + + let class_hash = CONTROLLERS[&version].hash; + if version == Version::LATEST { + self.declare_controller(version).await; + } + let salt = cairo_short_string_to_felt(&username).unwrap(); let contract_factory = ContractFactory::new_with_udc(class_hash, prefunded, *UDC_ADDRESS); diff --git a/packages/account_sdk/src/upgrade_test.rs b/packages/account_sdk/src/upgrade_test.rs index 0a20b7ace..aea6ee680 100644 --- a/packages/account_sdk/src/upgrade_test.rs +++ b/packages/account_sdk/src/upgrade_test.rs @@ -22,8 +22,6 @@ async fn test_controller_upgrade() { ) .await; - runner.declare_controller(Version::LATEST).await; - let hash = controller .provider() .get_class_hash_at(BlockId::Tag(BlockTag::Pending), controller.address()) @@ -32,6 +30,7 @@ async fn test_controller_upgrade() { assert_eq!(hash, CONTROLLERS[&Version::V1_0_4].hash); + runner.declare_controller(Version::LATEST).await; ensure_txn( controller .contract()