diff --git a/tests/account.rs b/tests/account.rs index 973ca310..73950cda 100644 --- a/tests/account.rs +++ b/tests/account.rs @@ -2,18 +2,20 @@ use std::{thread, time}; use beerus::gen::{ client::Client, Address, BlockId, BlockTag, BroadcastedDeclareTxn, - BroadcastedTxn, Felt, Rpc, SimulationFlagForEstimateFee, + BroadcastedTxn, Felt, Rpc, SimulationFlagForEstimateFee, TxnHash, }; use common::{ constants::{ - dummy_transaction_v3, COMPILED_ACCOUNT_CONTRACT, DECLARE_ACCOUNT, + declare_transaction, deploy_transaction, estimate_fee_transaction, + invoke_transaction, COMPILED_ACCOUNT_CONTRACT, DECLARE_ACCOUNT, }, katana::Katana, matchers::StarknetMatcher::{ - AddDeclareTransaction, AddDeclareTransactionMalicious, ChainId, + self, AddDeclareTransaction, AddDeclareTransactionMalicious, + AddDeployAccountTransaction, AddInvokeTransaction, ChainId, ChainIdMalicious, ClassError, ClassMalicious, ClassSuccess, - EstimateFee, EstimateFeeMalicious, Nonce, NonceMalicious, SpecVersion, - SpecVersionMalicious, + EstimateFee, EstimateFeeMalicious, GetTransactionReceipt, Nonce, + NonceMalicious, SpecVersion, SpecVersionMalicious, }, node::setup_client_with_mock_starknet_node, }; @@ -139,36 +141,23 @@ async fn get_class_success() { #[tokio::test] async fn spec_version_estimate_fee() { - let declare_transaction = dummy_transaction_v3(); let (client, _starknet_node) = setup_client_with_mock_starknet_node(vec![SpecVersion, EstimateFee]) .await; + let tx = estimate_fee_transaction(); assert!(client.specVersion().await.is_ok()); let res = client - .estimateFee( - vec![BroadcastedTxn::BroadcastedDeclareTxn( - BroadcastedDeclareTxn::BroadcastedDeclareTxnV3( - declare_transaction, - ), - )], - vec![], - BlockId::BlockTag(BlockTag::Latest), - ) + .estimateFee(vec![tx], vec![], BlockId::BlockTag(BlockTag::Latest)) .await; assert!(res.is_ok()); } #[tokio::test] async fn add_declare_transaction() { - let declare_transaction = dummy_transaction_v3(); + let tx = declare_transaction(); let (client, _starknet_node) = setup_client_with_mock_starknet_node(vec![AddDeclareTransaction]).await; - assert!(client - .addDeclareTransaction(BroadcastedDeclareTxn::BroadcastedDeclareTxnV3( - declare_transaction - )) - .await - .is_ok()); + assert!(client.addDeclareTransaction(tx).await.is_ok()); } #[tokio::test] @@ -186,7 +175,8 @@ async fn declare_account_mock() { let block_id = BlockId::BlockTag(BlockTag::Latest); let class_hash = Felt::try_new("0x0").unwrap(); let contract_address = Address(class_hash.clone()); - let declare_transaction = dummy_transaction_v3(); + let estimate_tx = estimate_fee_transaction(); + let declare_tx = declare_transaction(); assert!(client.chainId().await.is_ok()); assert!(client.getClass(block_id.clone(), class_hash).await.is_err()); @@ -194,23 +184,10 @@ async fn declare_account_mock() { assert!(client.getNonce(block_id.clone(), contract_address).await.is_ok()); assert!(client.specVersion().await.is_ok()); assert!(client - .estimateFee( - vec![BroadcastedTxn::BroadcastedDeclareTxn( - BroadcastedDeclareTxn::BroadcastedDeclareTxnV3( - declare_transaction.clone(), - ), - )], - vec![], - block_id - ) - .await - .is_ok()); - assert!(client - .addDeclareTransaction(BroadcastedDeclareTxn::BroadcastedDeclareTxnV3( - declare_transaction - )) + .estimateFee(vec![estimate_tx], vec![], block_id) .await .is_ok()); + assert!(client.addDeclareTransaction(declare_tx).await.is_ok()); } #[tokio::test] @@ -227,28 +204,70 @@ async fn malicious_data_results_in_err() { let block_id = BlockId::BlockTag(BlockTag::Latest); let class_hash = Felt::try_new("0x0").unwrap(); let contract_address = Address(class_hash.clone()); - let declare_transaction = dummy_transaction_v3(); + let declare_tx = declare_transaction(); + let estimate_tx = estimate_fee_transaction(); - assert!(client - .addDeclareTransaction(BroadcastedDeclareTxn::BroadcastedDeclareTxnV3( - declare_transaction.clone() - )) - .await - .is_err()); + assert!(client.addDeclareTransaction(declare_tx).await.is_err()); assert!(client.chainId().await.is_err()); assert!(client - .estimateFee( - vec![BroadcastedTxn::BroadcastedDeclareTxn( - BroadcastedDeclareTxn::BroadcastedDeclareTxnV3( - declare_transaction.clone(), - ), - )], - vec![], - block_id.clone() - ) + .estimateFee(vec![estimate_tx], vec![], block_id.clone()) .await .is_err()); assert!(client.getClass(block_id.clone(), class_hash).await.is_err()); assert!(client.getNonce(block_id, contract_address).await.is_err()); assert!(client.specVersion().await.is_err()); } + +#[tokio::test] +async fn deploy_account_mock() { + let mut account_deploy: Vec = + vec![ChainId, Nonce, SpecVersion, EstimateFee]; + let mut invoke_eth_transfer: Vec = vec![ + ChainId, + ChainId, + Nonce, + SpecVersion, + EstimateFee, + AddInvokeTransaction, + ]; + let mut account_deploy_last: Vec = + vec![Nonce, AddDeployAccountTransaction, GetTransactionReceipt]; + account_deploy.append(&mut invoke_eth_transfer); + account_deploy.append(&mut account_deploy_last); + let (client, _starknet_node) = + setup_client_with_mock_starknet_node(account_deploy).await; + let block_id = BlockId::BlockTag(BlockTag::Latest); + let class_hash = Felt::try_new("0x0").unwrap(); + let contract_address = Address(class_hash.clone()); + let estimate_tx = estimate_fee_transaction(); + let invoke_tx = invoke_transaction(); + let deploy_tx = deploy_transaction(); + let tx_hash = TxnHash(class_hash); + + assert!(client.chainId().await.is_ok()); + assert!(client + .getNonce(block_id.clone(), contract_address.clone()) + .await + .is_ok()); + assert!(client.specVersion().await.is_ok()); + assert!(client + .estimateFee(vec![estimate_tx.clone()], vec![], block_id.clone()) + .await + .is_ok()); + + assert!(client.chainId().await.is_ok()); + assert!(client.chainId().await.is_ok()); + assert!(client + .getNonce(block_id.clone(), contract_address.clone()) + .await + .is_ok()); + assert!(client.specVersion().await.is_ok()); + assert!(client + .estimateFee(vec![estimate_tx], vec![], block_id.clone()) + .await + .is_ok()); + assert!(client.addInvokeTransaction(invoke_tx).await.is_ok()); + assert!(client.getNonce(block_id, contract_address).await.is_ok()); + assert!(client.addDeployAccountTransaction(deploy_tx).await.is_ok()); + assert!(client.getTransactionReceipt(tx_hash).await.is_ok()); +} diff --git a/tests/common/constants.rs b/tests/common/constants.rs index f8bb3930..cd75f8f6 100644 --- a/tests/common/constants.rs +++ b/tests/common/constants.rs @@ -1,8 +1,11 @@ use beerus::gen::{ - Address, BroadcastedDeclareTxnV3, BroadcastedDeclareTxnV3Type, - BroadcastedDeclareTxnV3Version, ContractClass, - ContractClassEntryPointsByType, DaMode, Felt, ResourceBounds, - ResourceBoundsMapping, SierraEntryPoint, U128, U64, + Address, BroadcastedDeclareTxn, BroadcastedDeclareTxnV3, + BroadcastedDeclareTxnV3Type, BroadcastedDeclareTxnV3Version, + BroadcastedDeployAccountTxn, BroadcastedInvokeTxn, BroadcastedTxn, + ContractClass, ContractClassEntryPointsByType, DaMode, DeployAccountTxn, + DeployAccountTxnV3, DeployAccountTxnV3Type, DeployAccountTxnV3Version, + Felt, InvokeTxn, InvokeTxnV3, InvokeTxnV3Type, InvokeTxnV3Version, + ResourceBounds, ResourceBoundsMapping, SierraEntryPoint, U128, U64, }; #[allow(dead_code)] @@ -12,7 +15,35 @@ pub const COMPILED_ACCOUNT_CONTRACT: &str = pub const DECLARE_ACCOUNT: &str = include_str!("../clob/declare_account.txt"); #[allow(dead_code)] -pub fn dummy_transaction_v3() -> BroadcastedDeclareTxnV3 { +pub fn declare_transaction() -> BroadcastedDeclareTxn { + BroadcastedDeclareTxn::BroadcastedDeclareTxnV3( + dummy_declare_transaction_v3(), + ) +} + +#[allow(dead_code)] +pub fn estimate_fee_transaction() -> BroadcastedTxn { + BroadcastedTxn::BroadcastedDeclareTxn( + BroadcastedDeclareTxn::BroadcastedDeclareTxnV3( + dummy_declare_transaction_v3(), + ), + ) +} + +#[allow(dead_code)] +pub fn invoke_transaction() -> BroadcastedInvokeTxn { + BroadcastedInvokeTxn(InvokeTxn::InvokeTxnV3(dummy_invoke_transaction_v3())) +} + +#[allow(dead_code)] +pub fn deploy_transaction() -> BroadcastedDeployAccountTxn { + BroadcastedDeployAccountTxn(DeployAccountTxn::DeployAccountTxnV3( + dummy_deploy_transaction_v3(), + )) +} + +#[allow(dead_code)] +fn dummy_declare_transaction_v3() -> BroadcastedDeclareTxnV3 { BroadcastedDeclareTxnV3 { account_deployment_data: vec![Felt::try_new("0x0").unwrap()], compiled_class_hash: Felt::try_new("0x0").unwrap(), @@ -60,3 +91,57 @@ pub fn dummy_transaction_v3() -> BroadcastedDeclareTxnV3 { tip: U64::try_new("0x0").unwrap(), } } + +#[allow(dead_code)] +fn dummy_invoke_transaction_v3() -> InvokeTxnV3 { + InvokeTxnV3 { + account_deployment_data: vec![Felt::try_new("0x0").unwrap()], + calldata: vec![Felt::try_new("0x1").unwrap()], + fee_data_availability_mode: DaMode::L1, + nonce: Felt::try_new("0x2").unwrap(), + nonce_data_availability_mode: DaMode::L1, + paymaster_data: vec![Felt::try_new("0x1").unwrap()], + r#type: InvokeTxnV3Type::Invoke, + resource_bounds: ResourceBoundsMapping { + l1_gas: ResourceBounds { + max_amount: U64::try_new("0x0").unwrap(), + max_price_per_unit: U128::try_new("0x0").unwrap(), + }, + l2_gas: ResourceBounds { + max_amount: U64::try_new("0x0").unwrap(), + max_price_per_unit: U128::try_new("0x0").unwrap(), + }, + }, + sender_address: Address(Felt::try_new("0x3").unwrap()), + signature: vec![Felt::try_new("0x4").unwrap()], + tip: U64::try_new("0x0").unwrap(), + version: InvokeTxnV3Version::V0x3, + } +} + +#[allow(dead_code)] +fn dummy_deploy_transaction_v3() -> DeployAccountTxnV3 { + DeployAccountTxnV3 { + class_hash: Felt::try_new("0x0").unwrap(), + constructor_calldata: vec![Felt::try_new("0x1").unwrap()], + contract_address_salt: Felt::try_new("0x2").unwrap(), + fee_data_availability_mode: DaMode::L1, + nonce: Felt::try_new("0x3").unwrap(), + nonce_data_availability_mode: DaMode::L1, + paymaster_data: vec![Felt::try_new("0x4").unwrap()], + r#type: DeployAccountTxnV3Type::DeployAccount, + resource_bounds: ResourceBoundsMapping { + l1_gas: ResourceBounds { + max_amount: U64::try_new("0x0").unwrap(), + max_price_per_unit: U128::try_new("0x0").unwrap(), + }, + l2_gas: ResourceBounds { + max_amount: U64::try_new("0x0").unwrap(), + max_price_per_unit: U128::try_new("0x0").unwrap(), + }, + }, + signature: vec![Felt::try_new("0x5").unwrap()], + tip: U64::try_new("0x0").unwrap(), + version: DeployAccountTxnV3Version::V0x3, + } +} diff --git a/tests/common/matchers.rs b/tests/common/matchers.rs index c737eaf0..724ec5af 100644 --- a/tests/common/matchers.rs +++ b/tests/common/matchers.rs @@ -7,6 +7,8 @@ use wiremock::{Match, Request}; pub enum StarknetMatcher { AddDeclareTransaction, AddDeclareTransactionMalicious, + AddDeployAccountTransaction, + AddInvokeTransaction, ChainId, ChainIdMalicious, ClassError, @@ -14,6 +16,7 @@ pub enum StarknetMatcher { ClassMalicious, EstimateFee, EstimateFeeMalicious, + GetTransactionReceipt, Nonce, NonceMalicious, SpecVersion, @@ -319,3 +322,137 @@ impl Response for AddDeclareTransactionMatcher { self.response.clone() } } + +pub struct AddInvokeTransactionMatcher { + pub response: Value, +} + +impl Default for AddInvokeTransactionMatcher { + fn default() -> Self { + Self { + response: serde_json::json!( + { + "jsonrpc": "2.0", + "id": 1, + "result": { + "transaction_hash": "0x0", + } + }), + } + } +} + +impl Match for AddInvokeTransactionMatcher { + fn matches(&self, request: &Request) -> bool { + let request = request.body_json::().unwrap(); + matches!(request.method.as_str(), "starknet_addInvokeTransaction") + } +} + +impl Response for AddInvokeTransactionMatcher { + fn response(&self) -> Value { + self.response.clone() + } +} + +pub struct AddDeployAccountTransactionMatcher { + pub response: Value, +} + +impl Default for AddDeployAccountTransactionMatcher { + fn default() -> Self { + Self { + response: serde_json::json!( + { + "jsonrpc": "2.0", + "id": 1, + "result": { + "contract_address": "0x0", + "transaction_hash": "0x0", + } + }), + } + } +} + +impl Match for AddDeployAccountTransactionMatcher { + fn matches(&self, request: &Request) -> bool { + let request = request.body_json::().unwrap(); + matches!( + request.method.as_str(), + "starknet_addDeployAccountTransaction" + ) + } +} + +impl Response for AddDeployAccountTransactionMatcher { + fn response(&self) -> Value { + self.response.clone() + } +} + +pub struct GetTransactionReceiptMatcher { + pub response: Value, +} + +impl Default for GetTransactionReceiptMatcher { + fn default() -> Self { + Self { + response: serde_json::json!( + { + "jsonrpc":"2.0", + "result": { + "transaction_hash":"0x1", + "actual_fee": { + "amount":"0x2", + "unit":"WEI" + }, + "finality_status":"ACCEPTED_ON_L2", + "messages_sent":[], + "events":[{ + "from_address":"0x3", + "keys":[ + "0x4" + ], + "data":[ + "0x5", + "0x6", + "0x7", + "0x8" + ] + }], + "execution_resources": { + "steps": 1, + "memory_holes": 2, + "range_check_builtin_applications": 3, + "pedersen_builtin_applications": 4, + "ec_op_builtin_applications": 5, + "data_availability": { + "l1_gas": 6, + "l1_data_gas": 7 + } + }, + "execution_status":"SUCCEEDED", + "type":"DEPLOY_ACCOUNT", + "contract_address":"0x9", + "block_hash":"0x10", + "block_number":8 + }, + "id":1 + }), + } + } +} + +impl Match for GetTransactionReceiptMatcher { + fn matches(&self, request: &Request) -> bool { + let request = request.body_json::().unwrap(); + matches!(request.method.as_str(), "starknet_getTransactionReceipt") + } +} + +impl Response for GetTransactionReceiptMatcher { + fn response(&self) -> Value { + self.response.clone() + } +} diff --git a/tests/common/node.rs b/tests/common/node.rs index 39d1b09d..9b216229 100644 --- a/tests/common/node.rs +++ b/tests/common/node.rs @@ -4,9 +4,10 @@ use beerus::gen::client::Client; use wiremock::{Match, Mock, MockGuard, MockServer, ResponseTemplate}; use super::matchers::{ - AddDeclareTransactionMatcher, ChainIdMatcher, ClassMatcher, - EstimateFeeMatcher, NonceMatcher, Response, SpecVersionMatcher, - StarknetMatcher, + AddDeclareTransactionMatcher, AddDeployAccountTransactionMatcher, + AddInvokeTransactionMatcher, ChainIdMatcher, ClassMatcher, + EstimateFeeMatcher, GetTransactionReceiptMatcher, NonceMatcher, Response, + SpecVersionMatcher, StarknetMatcher, }; #[allow(dead_code)] @@ -55,6 +56,20 @@ impl StarknetNode { ) .await } + StarknetMatcher::AddDeployAccountTransaction => { + self.create_mock_guard( + AddDeployAccountTransactionMatcher::default(), + num_request, + ) + .await + } + StarknetMatcher::AddInvokeTransaction => { + self.create_mock_guard( + AddInvokeTransactionMatcher::default(), + num_request, + ) + .await + } StarknetMatcher::ClassError => { self.create_mock_guard(ClassMatcher::error(), num_request) .await @@ -98,6 +113,13 @@ impl StarknetNode { ) .await } + StarknetMatcher::GetTransactionReceipt => { + self.create_mock_guard( + GetTransactionReceiptMatcher::default(), + num_request, + ) + .await + } StarknetMatcher::Nonce => { self.create_mock_guard(NonceMatcher::default(), num_request) .await