diff --git a/tests/integration/common/errors.rs b/tests/integration/common/errors.rs index 4c6164647..51d0c55ba 100644 --- a/tests/integration/common/errors.rs +++ b/tests/integration/common/errors.rs @@ -54,3 +54,5 @@ impl fmt::Display for RpcError { write!(f, "{self:?}") } } + +impl std::error::Error for RpcError {} diff --git a/tests/integration/common/utils.rs b/tests/integration/common/utils.rs index 0177344a6..b8dfe2f22 100644 --- a/tests/integration/common/utils.rs +++ b/tests/integration/common/utils.rs @@ -1,4 +1,4 @@ -use std::fmt::LowerHex; +use std::fmt::{Debug, LowerHex}; use std::fs; use std::path::Path; use std::process::{Child, Command}; @@ -17,7 +17,7 @@ use starknet_rs_core::types::contract::{CompiledClass, SierraClass}; use starknet_rs_core::types::{ BlockId, BlockTag, ContractClass, ContractExecutionError, DeployAccountTransactionResult, ExecutionResult, FeeEstimate, Felt, FlattenedSierraClass, FunctionCall, - InnerContractExecutionError, ResourceBounds, ResourceBoundsMapping, + InnerContractExecutionError, ResourceBounds, ResourceBoundsMapping, TransactionReceipt, }; use starknet_rs_core::utils::{ UdcUniqueSettings, get_selector_from_name, get_udc_deployed_address, @@ -102,16 +102,20 @@ pub fn get_timestamp_asserter_contract_artifacts() -> SierraWithCasmHash { ) } -pub async fn assert_tx_succeeded_accepted(tx_hash: &Felt, client: &T) { - let receipt = client.get_transaction_receipt(tx_hash).await.unwrap().receipt; +pub async fn assert_tx_succeeded_accepted( + tx_hash: &Felt, + client: &T, +) -> Result<(), anyhow::Error> { + let receipt = client.get_transaction_receipt(tx_hash).await?.receipt; + match receipt.execution_result() { ExecutionResult::Succeeded => (), - other => panic!("Should have succeeded; got: {other:?}"), + other => anyhow::bail!("Tx {tx_hash:#x} should have succeeded; got: {other:?}"), } match receipt.finality_status() { - starknet_rs_core::types::TransactionFinalityStatus::AcceptedOnL2 => (), - other => panic!("Should have been accepted on L2; got: {other:?}"), + starknet_rs_core::types::TransactionFinalityStatus::AcceptedOnL2 => Ok(()), + other => anyhow::bail!("Tx {tx_hash:#x} should have been accepted on L2; got: {other:?}"), } } @@ -129,7 +133,10 @@ pub async fn assert_tx_succeeded_pre_confirmed(_tx_hash: &Felt, _cl // } } -pub async fn get_contract_balance(devnet: &BackgroundDevnet, contract_address: Felt) -> Felt { +pub async fn get_contract_balance( + devnet: &BackgroundDevnet, + contract_address: Felt, +) -> Result { get_contract_balance_by_block_id(devnet, contract_address, BlockId::Tag(BlockTag::Latest)).await } @@ -137,18 +144,15 @@ pub async fn get_contract_balance_by_block_id( devnet: &BackgroundDevnet, contract_address: Felt, block_id: BlockId, -) -> Felt { +) -> Result { let contract_call = FunctionCall { contract_address, entry_point_selector: get_selector_from_name("get_balance").unwrap(), calldata: vec![], }; match devnet.json_rpc_client.call(contract_call, block_id).await { - Ok(res) => { - assert_eq!(res.len(), 1); - res[0] - } - Err(e) => panic!("Call failed: {e}"), + Ok(res) if res.len() == 1 => Ok(res[0]), + other => anyhow::bail!("Expected a single-felt result; got: {other:?}"), } } @@ -156,15 +160,17 @@ pub async fn assert_tx_reverted( tx_hash: &Felt, client: &T, expected_failure_reasons: &[&str], -) { - let receipt = client.get_transaction_receipt(tx_hash).await.unwrap().receipt; +) -> Result<(), anyhow::Error> { + let receipt: TransactionReceipt = client.get_transaction_receipt(tx_hash).await?.receipt; + match receipt.execution_result() { ExecutionResult::Reverted { reason } => { for expected_reason in expected_failure_reasons { - assert_contains(reason, expected_reason); + assert_contains(reason, expected_reason)? } + Ok(()) } - other => panic!("Should have reverted; got: {other:?}; receipt: {receipt:?}"), + other => anyhow::bail!("Should have reverted; got: {other:?}; receipt: {receipt:?}"), } } @@ -215,7 +221,11 @@ async fn send_ctrl_c_signal(process: &Child) { fn take_abi_from_json(value: &mut serde_json::Value) -> Result { let abi_jsonified = value["abi"].take(); - assert_ne!(abi_jsonified, serde_json::json!(null)); + let json_null = serde_json::json!(null); + anyhow::ensure!( + abi_jsonified != json_null, + format!("assertion `left == right` failed, left: {abi_jsonified}, right: {json_null}") + ); Ok(serde_json::from_str(abi_jsonified.as_str().unwrap())?) } @@ -231,8 +241,16 @@ pub fn assert_cairo1_classes_equal( let abi_a = take_abi_from_json(&mut class_a_jsonified)?; let abi_b = take_abi_from_json(&mut class_b_jsonified)?; - assert_eq!(class_a_jsonified, class_b_jsonified); - assert_eq!(abi_a, abi_b); + anyhow::ensure!( + class_a_jsonified == class_b_jsonified, + format!( + "assertion `left == right` failed, left: {class_a_jsonified}, right: {class_b_jsonified}" + ) + ); + anyhow::ensure!( + abi_a == abi_b, + format!("assertion `left == right` failed, left: {abi_a}, right: {abi_b}") + ); Ok(()) } @@ -429,21 +447,26 @@ pub async fn deploy_argent_account( let account_address = deployment.address(); devnet.mint(account_address, u128::MAX).await; - let deployment_result = deployment.send().await.map_err(|e| anyhow::anyhow!("{e:?}"))?; + let deployment_result = deployment.send().await?; Ok((deployment_result, signer)) } /// Assert that the set of elements of `iterable1` is a subset of the elements of `iterable2` and /// vice versa. -pub fn assert_equal_elements(iterable1: &[T], iterable2: &[T]) +pub fn assert_equal_elements(iterable1: &[T], iterable2: &[T]) -> Result<(), anyhow::Error> where - T: PartialEq, + T: PartialEq + Debug, { - assert_eq!(iterable1.len(), iterable2.len()); + if iterable1.len() != iterable2.len() { + anyhow::bail!("Length mismatch: left = {}, right = {}", iterable1.len(), iterable2.len()); + } for e in iterable1 { - assert!(iterable2.contains(e)); + if !iterable2.contains(e) { + anyhow::bail!("Element {:?} from left not found in right", e); + } } + Ok(()) } pub fn felt_to_u256(f: Felt) -> U256 { @@ -474,23 +497,35 @@ pub fn extract_json_rpc_error(error: ProviderError) -> Result Result<(), anyhow::Error> { + anyhow::ensure!( + (e1.code, &e1.message, &e1.data) == (e2.code, &e2.message, &e2.data), + format!( + "assertion `left == right` failed, left: ({}, {}, {:?}), right: ({}, {}, {:?})", + e1.code, e1.message, e1.data, e2.code, e2.message, e2.data + ) + ); + Ok(()) } /// Extract the message that is encapsulated inside the provided error. -pub fn extract_message_error(error: &ContractExecutionError) -> &String { +pub fn extract_message_error(error: &ContractExecutionError) -> Result<&String, anyhow::Error> { match error { - ContractExecutionError::Message(msg) => msg, - other => panic!("Unexpected error: {other:?}"), + ContractExecutionError::Message(msg) => Ok(msg), + other => anyhow::bail!("Unexpected error: {other:?}"), } } /// Extract the error that is nested inside the provided `error`. -pub fn extract_nested_error(error: &ContractExecutionError) -> &InnerContractExecutionError { +pub fn extract_nested_error( + error: &ContractExecutionError, +) -> Result<&InnerContractExecutionError, anyhow::Error> { match error { - ContractExecutionError::Nested(nested) => nested, - other => panic!("Unexpected error: {other:?}"), + ContractExecutionError::Nested(nested) => Ok(nested), + other => anyhow::bail!("Unexpected error: {other:?}"), } } @@ -569,23 +604,41 @@ pub async fn receive_notification( expected_subscription_id: SubscriptionId, ) -> Result { let mut notification = receive_rpc_via_ws(ws).await?; - assert_eq!(notification["jsonrpc"], "2.0"); - assert_eq!(notification["method"], method); - assert_eq!( - notification["params"]["subscription_id"] - .as_str() - .ok_or(anyhow::Error::msg("No Subscription ID in notification"))? - .to_string(), - expected_subscription_id + anyhow::ensure!( + notification["jsonrpc"] == "2.0", + format!( + "assertion `left == right` failed, left: {}, right: {}", + notification["jsonrpc"], "2.0" + ) + ); + anyhow::ensure!( + notification["method"] == method, + format!( + "assertion `left == right` failed, left: {}, right: {method}", + notification["method"] + ) + ); + let subscription_id = notification["params"]["subscription_id"] + .as_str() + .ok_or(anyhow::Error::msg("No Subscription ID in notification"))? + .to_string(); + anyhow::ensure!( + subscription_id == expected_subscription_id, + format!( + "assertion `left == right` failed, left: {}, right: {expected_subscription_id}", + subscription_id + ) ); Ok(notification["params"]["result"].take()) } -pub async fn assert_no_notifications(ws: &mut WebSocketStream>) { +pub async fn assert_no_notifications( + ws: &mut WebSocketStream>, +) -> Result<(), anyhow::Error> { match receive_rpc_via_ws(ws).await { - Ok(resp) => panic!("Expected no notifications; found: {resp}"), - Err(e) if e.to_string().contains("deadline has elapsed") => { /* expected */ } - Err(e) => panic!("Expected to error out due to empty channel; found: {e}"), + Ok(resp) => anyhow::bail!("Expected no notifications; found: {resp}"), + Err(e) if e.to_string().contains("deadline has elapsed") => Ok(()), /* expected */ + Err(e) => anyhow::bail!("Expected to error out due to empty channel; found: {e}"), } } @@ -672,15 +725,16 @@ impl From for LocalFee { } /// Panics if `text` does not contain `pattern` -pub fn assert_contains(text: &str, pattern: &str) { +pub fn assert_contains(text: &str, pattern: &str) -> Result<(), anyhow::Error> { if !text.contains(pattern) { - panic!( + anyhow::bail!( "Failed content assertion! Pattern: '{pattern}' not present in Text: '{text}'" ); } + Ok(()) } /// Set time and generate a new block diff --git a/tests/integration/general_rpc_tests.rs b/tests/integration/general_rpc_tests.rs index be88b7e08..56a27aac2 100644 --- a/tests/integration/general_rpc_tests.rs +++ b/tests/integration/general_rpc_tests.rs @@ -88,7 +88,8 @@ async fn storage_proof_request_should_always_return_error() { Err(e) => assert_json_rpc_errors_equal( extract_json_rpc_error(e).unwrap(), JsonRpcError { code: 42, message: devnet_storage_proof_msg.into(), data: None }, - ), + ) + .unwrap(), other => panic!("Unexpected result: {other:?}"), } } diff --git a/tests/integration/get_transaction_by_hash.rs b/tests/integration/get_transaction_by_hash.rs index 47cc8ee8d..39b908f33 100644 --- a/tests/integration/get_transaction_by_hash.rs +++ b/tests/integration/get_transaction_by_hash.rs @@ -38,7 +38,9 @@ async fn get_declare_v3_transaction_by_hash_happy_path() { .await .unwrap(); - assert_tx_succeeded_accepted(&declare_result.transaction_hash, &devnet.json_rpc_client).await; + assert_tx_succeeded_accepted(&declare_result.transaction_hash, &devnet.json_rpc_client) + .await + .unwrap(); } #[tokio::test] @@ -67,7 +69,8 @@ async fn get_deploy_account_transaction_by_hash_happy_path() { let deploy_account_result = deployment.send().await.unwrap(); assert_tx_succeeded_accepted(&deploy_account_result.transaction_hash, &devnet.json_rpc_client) - .await; + .await + .unwrap(); } #[tokio::test] @@ -97,7 +100,9 @@ async fn get_invoke_v3_transaction_by_hash_happy_path() { .await .unwrap(); - assert_tx_succeeded_accepted(&invoke_tx_result.transaction_hash, &devnet.json_rpc_client).await; + assert_tx_succeeded_accepted(&invoke_tx_result.transaction_hash, &devnet.json_rpc_client) + .await + .unwrap(); } #[tokio::test] diff --git a/tests/integration/get_transaction_receipt_by_hash.rs b/tests/integration/get_transaction_receipt_by_hash.rs index f67229358..014ac4c07 100644 --- a/tests/integration/get_transaction_receipt_by_hash.rs +++ b/tests/integration/get_transaction_receipt_by_hash.rs @@ -242,7 +242,7 @@ async fn reverted_invoke_transaction_receipt() { TransactionReceipt::Invoke(receipt) => { match receipt.execution_result { starknet_rs_core::types::ExecutionResult::Reverted { reason } => { - assert_contains(&reason, "Insufficient max L2Gas"); + assert_contains(&reason, "Insufficient max L2Gas").unwrap(); } _ => panic!("Invalid receipt {:?}", receipt), } diff --git a/tests/integration/test_abort_blocks.rs b/tests/integration/test_abort_blocks.rs index b2c698a9a..60afb36a7 100644 --- a/tests/integration/test_abort_blocks.rs +++ b/tests/integration/test_abort_blocks.rs @@ -13,15 +13,18 @@ async fn abort_blocks_error( devnet: &BackgroundDevnet, starting_block_id: &BlockId, expected_message_substring: &str, -) { - let aborted_blocks_error = devnet +) -> Result<(), anyhow::Error> { + let aborted_blocks_error: RpcError = devnet .send_custom_rpc("devnet_abortBlocks", json!({ "starting_block_id" : starting_block_id })) .await .unwrap_err(); - assert_contains(&aborted_blocks_error.message, expected_message_substring); + assert_contains(&aborted_blocks_error.message, expected_message_substring) } -async fn assert_block_aborted(devnet: &BackgroundDevnet, block_hash: &Felt) { +async fn assert_block_aborted( + devnet: &BackgroundDevnet, + block_hash: &Felt, +) -> Result<(), anyhow::Error> { let err = devnet .send_custom_rpc( "starknet_getBlockWithTxHashes", @@ -30,16 +33,25 @@ async fn assert_block_aborted(devnet: &BackgroundDevnet, block_hash: &Felt) { .await .unwrap_err(); - assert_eq!(err, RpcError { code: 24, message: "Block not found".into(), data: None }) + let expected_error = RpcError { code: 24, message: "Block not found".into(), data: None }; + anyhow::ensure!( + err == expected_error, + format!("assertion `left == right` failed, left: {err}, right: {expected_error}") + ); + Ok(()) } -async fn assert_txs_aborted(devnet: &BackgroundDevnet, tx_hashes: &[Felt]) { +async fn assert_txs_aborted( + devnet: &BackgroundDevnet, + tx_hashes: &[Felt], +) -> Result<(), anyhow::Error> { for tx_hash in tx_hashes { match devnet.json_rpc_client.get_transaction_by_hash(tx_hash).await { Err(ProviderError::StarknetError(StarknetError::TransactionHashNotFound)) => (), - other => panic!("Unexpected tx response: {other:?}"), + other => anyhow::bail!("Unexpected tx response for {tx_hash:#x}: {other:?}"), } } + Ok(()) } #[tokio::test] @@ -65,14 +77,15 @@ async fn abort_latest_block_with_hash() { .unwrap(); assert_eq!(genesis_block_after_abort["status"], "ACCEPTED_ON_L2".to_string()); - assert_block_aborted(&devnet, &new_block_hash).await; + assert_block_aborted(&devnet, &new_block_hash).await.unwrap(); abort_blocks_error( &devnet, &BlockId::Hash(genesis_block_hash), "Genesis block can't be aborted", ) - .await; + .await + .unwrap(); } #[tokio::test] @@ -88,8 +101,8 @@ async fn abort_two_blocks() { let aborted_blocks = devnet.abort_blocks(&BlockId::Hash(first_block_hash)).await.unwrap(); assert_eq!(json!(aborted_blocks), json!([second_block_hash, first_block_hash])); - assert_block_aborted(&devnet, &first_block_hash).await; - assert_block_aborted(&devnet, &second_block_hash).await; + assert_block_aborted(&devnet, &first_block_hash).await.unwrap(); + assert_block_aborted(&devnet, &second_block_hash).await.unwrap(); } #[tokio::test] @@ -107,8 +120,8 @@ async fn abort_block_with_transaction() { devnet.abort_blocks(&BlockId::Hash(latest_block.block_hash)).await.unwrap(); assert_eq!(aborted_blocks, vec![latest_block.block_hash]); - assert_block_aborted(&devnet, &latest_block.block_hash).await; - assert_txs_aborted(&devnet, &[mint_hash]).await; + assert_block_aborted(&devnet, &latest_block.block_hash).await.unwrap(); + assert_txs_aborted(&devnet, &[mint_hash]).await.unwrap(); } #[tokio::test] @@ -121,7 +134,7 @@ async fn query_aborted_block_by_number_should_fail() { let new_block_hash = devnet.create_block().await.unwrap(); let aborted_blocks = devnet.abort_blocks(&BlockId::Hash(new_block_hash)).await.unwrap(); assert_eq!(aborted_blocks, vec![new_block_hash]); - assert_block_aborted(&devnet, &new_block_hash).await; + assert_block_aborted(&devnet, &new_block_hash).await.unwrap(); let rpc_error = devnet .send_custom_rpc( @@ -225,7 +238,8 @@ async fn abort_blocks_without_state_archive_capacity() { &BlockId::Hash(new_block_hash), "The abort blocks feature requires state-archive-capacity set to full", ) - .await; + .await + .unwrap(); } #[tokio::test] @@ -241,8 +255,8 @@ async fn abort_same_block_twice() { let aborted_blocks = devnet.abort_blocks(&BlockId::Hash(first_block_hash)).await.unwrap(); assert_eq!(aborted_blocks, vec![second_block_hash, first_block_hash]); - abort_blocks_error(&devnet, &BlockId::Hash(first_block_hash), "No block found").await; - abort_blocks_error(&devnet, &BlockId::Hash(second_block_hash), "No block found").await; + abort_blocks_error(&devnet, &BlockId::Hash(first_block_hash), "No block found").await.unwrap(); + abort_blocks_error(&devnet, &BlockId::Hash(second_block_hash), "No block found").await.unwrap(); } #[tokio::test] @@ -265,8 +279,8 @@ async fn abort_same_block_twice_if_blocks_aborted_on_two_occasions() { devnet.abort_blocks(&BlockId::Hash(first_block_hash)).await.unwrap(); assert_eq!(second_aborted_blocks, vec![first_block_hash]); - abort_blocks_error(&devnet, &BlockId::Hash(first_block_hash), "No block found").await; - abort_blocks_error(&devnet, &BlockId::Hash(second_block_hash), "No block found").await; + abort_blocks_error(&devnet, &BlockId::Hash(first_block_hash), "No block found").await.unwrap(); + abort_blocks_error(&devnet, &BlockId::Hash(second_block_hash), "No block found").await.unwrap(); } #[tokio::test] @@ -283,7 +297,9 @@ async fn abort_block_after_fork() { let aborted_blocks = fork_devnet.abort_blocks(&BlockId::Hash(fork_block_hash)).await.unwrap(); assert_eq!(aborted_blocks, vec![fork_block_hash]); - abort_blocks_error(&fork_devnet, &BlockId::Hash(fork_block_hash), "No block found").await; + abort_blocks_error(&fork_devnet, &BlockId::Hash(fork_block_hash), "No block found") + .await + .unwrap(); } #[tokio::test] @@ -300,7 +316,8 @@ async fn abort_latest_blocks() { devnet.abort_blocks(&BlockId::Tag(BlockTag::Latest)).await.unwrap(); } abort_blocks_error(&devnet, &BlockId::Tag(BlockTag::Latest), "Genesis block can't be aborted") - .await; + .await + .unwrap(); } #[tokio::test] diff --git a/tests/integration/test_accepting_blocks_on_l1.rs b/tests/integration/test_accepting_blocks_on_l1.rs index e2b20b111..828bdb204 100644 --- a/tests/integration/test_accepting_blocks_on_l1.rs +++ b/tests/integration/test_accepting_blocks_on_l1.rs @@ -18,30 +18,63 @@ async fn assert_accepted_on_l1( devnet: &BackgroundDevnet, block_hashes: &[Felt], tx_hashes: &[Felt], -) { +) -> Result<(), anyhow::Error> { for block_hash in block_hashes { match devnet.json_rpc_client.get_block_with_tx_hashes(BlockId::Hash(*block_hash)).await { Ok(MaybePreConfirmedBlockWithTxHashes::Block(block)) => { - assert_eq!(block.status, BlockStatus::AcceptedOnL1) + anyhow::ensure!( + block.status == BlockStatus::AcceptedOnL1, + format!( + "assertion `left == right` failed, left: {:?}, right: {:?}", + block.status, + BlockStatus::AcceptedOnL1 + ) + ) } - other => panic!("Unexpected block: {other:?}"), + other => anyhow::bail!("Unexpected block: {other:?}"), } } for tx_hash in tx_hashes { let tx_status = devnet.json_rpc_client.get_transaction_status(tx_hash).await.unwrap(); - assert_eq!(tx_status.finality_status(), SequencerTransactionStatus::AcceptedOnL1); + let tx_finality_status = tx_status.finality_status(); + anyhow::ensure!( + tx_finality_status == SequencerTransactionStatus::AcceptedOnL1, + format!( + "assertion `left == right` failed, left: {tx_finality_status:?}, right: {:?}", + SequencerTransactionStatus::AcceptedOnL1 + ) + ); } + + Ok(()) } -async fn assert_latest_accepted_on_l2(devnet: &BackgroundDevnet) { - let latest_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - assert_eq!(latest_block.status, BlockStatus::AcceptedOnL2,); +async fn assert_latest_accepted_on_l2(devnet: &BackgroundDevnet) -> Result<(), anyhow::Error> { + let latest_block = devnet.get_latest_block_with_tx_hashes().await?; + anyhow::ensure!( + latest_block.status == BlockStatus::AcceptedOnL2, + format!( + "assertion `left == right` failed, left: {:?}, right: {:?}", + latest_block.status, + BlockStatus::AcceptedOnL2 + ) + ); for tx_hash in latest_block.transactions { - let tx_status = devnet.json_rpc_client.get_transaction_status(tx_hash).await.unwrap(); - assert_eq!(tx_status.finality_status(), SequencerTransactionStatus::AcceptedOnL2) + let tx_status = devnet.json_rpc_client.get_transaction_status(tx_hash).await?; + let tx_finality_status = tx_status.finality_status(); + anyhow::ensure!( + tx_finality_status == SequencerTransactionStatus::AcceptedOnL2, + format!( + "assertion `left == right` failed, left: {:?}, right: {:?}", + tx_finality_status, + SequencerTransactionStatus::AcceptedOnL2 + ) + ) } + + Ok(()) } #[tokio::test] @@ -63,7 +96,7 @@ async fn should_convert_accepted_on_l2_with_id_latest() { let accepted_block_hashes = devnet.accept_on_l1(&BlockId::Tag(BlockTag::Latest)).await.unwrap(); assert_eq!(accepted_block_hashes, block_hashes); - assert_accepted_on_l1(&devnet, &block_hashes, &tx_hashes).await; + assert_accepted_on_l1(&devnet, &block_hashes, &tx_hashes).await.unwrap(); } #[tokio::test] @@ -85,7 +118,7 @@ async fn should_convert_all_txs_in_block_on_demand() { let accepted_block_hashes = devnet.accept_on_l1(&BlockId::Tag(BlockTag::Latest)).await.unwrap(); assert_eq!(accepted_block_hashes, block_hashes); - assert_accepted_on_l1(&devnet, &block_hashes, &tx_hashes).await; + assert_accepted_on_l1(&devnet, &block_hashes, &tx_hashes).await.unwrap(); } #[tokio::test] @@ -107,8 +140,8 @@ async fn should_convert_accepted_on_l2_with_numeric_id() { let accepted_block_hashes = devnet.accept_on_l1(&BlockId::Number(1)).await.unwrap(); assert_eq!(accepted_block_hashes, block_hashes); - assert_accepted_on_l1(&devnet, &block_hashes, &[tx_hash]).await; - assert_latest_accepted_on_l2(&devnet).await; + assert_accepted_on_l1(&devnet, &block_hashes, &[tx_hash]).await.unwrap(); + assert_latest_accepted_on_l2(&devnet).await.unwrap(); } #[tokio::test] @@ -130,8 +163,8 @@ async fn should_convert_accepted_on_l2_with_hash_id() { let accepted_block_hashes = devnet.accept_on_l1(&BlockId::Hash(block_hash)).await.unwrap(); assert_eq!(accepted_block_hashes, block_hashes); - assert_accepted_on_l1(&devnet, &block_hashes, &[tx_hash]).await; - assert_latest_accepted_on_l2(&devnet).await; + assert_accepted_on_l1(&devnet, &block_hashes, &[tx_hash]).await.unwrap(); + assert_latest_accepted_on_l2(&devnet).await.unwrap(); } #[tokio::test] diff --git a/tests/integration/test_account_impersonation.rs b/tests/integration/test_account_impersonation.rs index 6b14a4189..beda2a32d 100644 --- a/tests/integration/test_account_impersonation.rs +++ b/tests/integration/test_account_impersonation.rs @@ -199,7 +199,7 @@ async fn test_simulate_transaction() { account.execute_v3(invoke_calls.clone()).simulate(!do_validate, true).await; if let Some(error_msg) = expected_error_message { let simulation_err = simulation_result.expect_err("Expected simulation to fail"); - assert_contains(&format!("{:?}", simulation_err).to_lowercase(), error_msg); + assert_contains(&format!("{:?}", simulation_err).to_lowercase(), error_msg).unwrap(); } else { simulation_result.expect("Expected simulation to succeed"); } @@ -268,5 +268,5 @@ async fn test_invoke_transaction( fn assert_anyhow_error_contains_message(error: anyhow::Error, message: &str) { let error_string = format!("{:?}", error.root_cause()).to_lowercase(); - assert_contains(&error_string, message); + assert_contains(&error_string, message).unwrap(); } diff --git a/tests/integration/test_account_selection.rs b/tests/integration/test_account_selection.rs index 1bcbb1e6c..73f8e36ea 100644 --- a/tests/integration/test_account_selection.rs +++ b/tests/integration/test_account_selection.rs @@ -42,33 +42,49 @@ async fn spawnable_with_custom_account_cairo_1() { } /// Common body for tests defined below -async fn correct_artifact_test_body(devnet_args: &[&str], expected_hash_hex: &str) { - let devnet = BackgroundDevnet::spawn_with_additional_args(devnet_args).await.unwrap(); +async fn correct_artifact_test_body( + devnet_args: &[&str], + expected_hash_hex: &str, +) -> Result<(), anyhow::Error> { + let devnet = BackgroundDevnet::spawn_with_additional_args(devnet_args).await?; let (_, account_address) = devnet.get_first_predeployed_account().await; let retrieved_class_hash = devnet .json_rpc_client .get_class_hash_at(BlockId::Tag(BlockTag::Latest), account_address) - .await - .unwrap(); + .await?; let expected_hash = Felt::from_hex_unchecked(expected_hash_hex); - assert_eq!(retrieved_class_hash, expected_hash); + anyhow::ensure!( + retrieved_class_hash == expected_hash, + format!( + "assertion `left == right` failed, left: {retrieved_class_hash}, right: {expected_hash}" + ) + ); let config = devnet.get_config().await; - let config_class_hash_hex = config["account_contract_class_hash"].as_str().unwrap(); - assert_eq!(Felt::from_hex_unchecked(config_class_hash_hex), expected_hash); + let config_class_hash_hex = config["account_contract_class_hash"] + .as_str() + .ok_or(anyhow::anyhow!("contract class hash not found"))?; + let config_class_hash = Felt::from_hex_unchecked(config_class_hash_hex); + anyhow::ensure!( + config_class_hash == expected_hash, + format!( + "assertion `left == right` failed, left: {config_class_hash}, right: {expected_hash}" + ) + ); + Ok(()) } #[tokio::test] async fn correct_cairo1_artifact() { let cli_args = ["--account-class", "cairo1"]; - correct_artifact_test_body(&cli_args, CAIRO_1_ACCOUNT_CONTRACT_SIERRA_HASH).await; + correct_artifact_test_body(&cli_args, CAIRO_1_ACCOUNT_CONTRACT_SIERRA_HASH).await.unwrap(); } #[tokio::test] async fn correct_custom_artifact() { let cli_args = ["--account-class-custom", CAIRO_1_ACCOUNT_CONTRACT_SIERRA_PATH]; - correct_artifact_test_body(&cli_args, CAIRO_1_ACCOUNT_CONTRACT_SIERRA_HASH).await; + correct_artifact_test_body(&cli_args, CAIRO_1_ACCOUNT_CONTRACT_SIERRA_HASH).await.unwrap(); } #[tokio::test] @@ -78,7 +94,8 @@ async fn can_deploy_new_cairo1_oz_account() { let (account_deployment, signer) = deploy_oz_account(&devnet).await.unwrap(); assert_tx_succeeded_accepted(&account_deployment.transaction_hash, &devnet.json_rpc_client) - .await; + .await + .unwrap(); let account_address = account_deployment.contract_address; can_declare_deploy_invoke_cairo1_using_account(&devnet, &signer, account_address).await; @@ -91,7 +108,8 @@ async fn can_deploy_new_cairo1_oz_account_when_cairo0_selected() { let (account_deployment, signer) = deploy_oz_account(&devnet).await.unwrap(); assert_tx_succeeded_accepted(&account_deployment.transaction_hash, &devnet.json_rpc_client) - .await; + .await + .unwrap(); let account_address = account_deployment.contract_address; can_declare_deploy_invoke_cairo1_using_account(&devnet, &signer, account_address).await; @@ -104,7 +122,8 @@ async fn can_deploy_new_custom_oz_account() { let (account_deployment, signer) = deploy_oz_account(&devnet).await.unwrap(); assert_tx_succeeded_accepted(&account_deployment.transaction_hash, &devnet.json_rpc_client) - .await; + .await + .unwrap(); let account_address = account_deployment.contract_address; can_declare_deploy_invoke_cairo1_using_account(&devnet, &signer, account_address).await; @@ -119,7 +138,8 @@ async fn argent_account_undeployable_by_default() { assert_contains( &error.to_string(), &format!("Class with hash {ARGENT_ACCOUNT_CLASS_HASH} is not declared"), - ); + ) + .unwrap(); } #[tokio::test] @@ -131,7 +151,8 @@ async fn can_deploy_instance_of_argent_account_via_fork() { let account_hash = Felt::from_hex_unchecked(ARGENT_ACCOUNT_CLASS_HASH); let (account_deployment, signer) = deploy_argent_account(&devnet, account_hash).await.unwrap(); assert_tx_succeeded_accepted(&account_deployment.transaction_hash, &devnet.json_rpc_client) - .await; + .await + .unwrap(); let account_address = account_deployment.contract_address; can_declare_deploy_invoke_cairo1_using_account(&devnet, &signer, account_address).await; @@ -145,7 +166,8 @@ async fn can_deploy_new_argent_account_from_predeclared_class() { let account_hash = Felt::from_hex_unchecked(ARGENT_ACCOUNT_CLASS_HASH); let (account_deployment, signer) = deploy_argent_account(&devnet, account_hash).await.unwrap(); assert_tx_succeeded_accepted(&account_deployment.transaction_hash, &devnet.json_rpc_client) - .await; + .await + .unwrap(); let account_address = account_deployment.contract_address; can_declare_deploy_invoke_cairo1_using_account(&devnet, &signer, account_address).await; @@ -199,7 +221,9 @@ async fn can_declare_deploy_invoke_cairo1_using_account( let invoke_result = account.execute_v3(contract_invoke.clone()).send().await.unwrap(); - assert_tx_succeeded_accepted(&invoke_result.transaction_hash, &devnet.json_rpc_client).await; + assert_tx_succeeded_accepted(&invoke_result.transaction_hash, &devnet.json_rpc_client) + .await + .unwrap(); } #[tokio::test] diff --git a/tests/integration/test_advancing_time.rs b/tests/integration/test_advancing_time.rs index 62c33e11f..cd2072b4a 100644 --- a/tests/integration/test_advancing_time.rs +++ b/tests/integration/test_advancing_time.rs @@ -30,16 +30,18 @@ async fn sleep_until_new_timestamp() { tokio::time::sleep(time::Duration::from_millis(1500)).await } -pub fn assert_ge_with_buffer(val1: u64, val2: u64) { - assert!(val1 >= val2, "Failed inequation: {val1:?} >= {val2:?}"); +pub fn assert_ge_with_buffer(val1: u64, val2: u64) -> Result<(), anyhow::Error> { + anyhow::ensure!(val1 >= val2, "Failed inequation: {val1:?} >= {val2:?}"); let upper_limit = val2 + BUFFER_TIME_SECONDS; - assert!(val1 <= upper_limit, "Failed inequation: {val1:?} <= {upper_limit:?}"); + anyhow::ensure!(val1 <= upper_limit, "Failed inequation: {val1:?} <= {upper_limit:?}"); + Ok(()) } -pub fn assert_gt_with_buffer(val1: u64, val2: u64) { - assert!(val1 > val2, "Failed inequation: {val1:?} > {val2:?}"); +pub fn assert_gt_with_buffer(val1: u64, val2: u64) -> Result<(), anyhow::Error> { + anyhow::ensure!(val1 > val2, "Failed inequation: {val1:?} > {val2:?}"); let upper_limit = val2 + BUFFER_TIME_SECONDS; - assert!(val1 <= upper_limit, "Failed inequation: {val1:?} <= {upper_limit:?}"); + anyhow::ensure!(val1 <= upper_limit, "Failed inequation: {val1:?} <= {upper_limit:?}"); + Ok(()) } fn assert_eq_with_buffer(val1: u64, val2: u64) { @@ -114,7 +116,7 @@ async fn timestamp_syscall_set_in_past() { // check if timestamp is greater/equal let current_timestamp = get_current_timestamp(&devnet, timestamp_contract_address).await; - assert_ge_with_buffer(current_timestamp, past_time); + assert_ge_with_buffer(current_timestamp, past_time).unwrap(); } #[tokio::test] @@ -131,7 +133,7 @@ async fn timestamp_syscall_set_in_future() { // check if timestamp is greater/equal let current_timestamp = get_current_timestamp(&devnet, timestamp_contract_address).await; - assert_ge_with_buffer(current_timestamp, future_time); + assert_ge_with_buffer(current_timestamp, future_time).unwrap(); } #[tokio::test] @@ -147,7 +149,7 @@ async fn timestamp_syscall_increase_time() { // check if timestamp is greater/equal let current_timestamp = get_current_timestamp(&devnet, timestamp_contract_address).await; - assert_ge_with_buffer(current_timestamp, now + time_increment); + assert_ge_with_buffer(current_timestamp, now + time_increment).unwrap(); sleep_until_new_timestamp().await; devnet.create_block().await.unwrap(); @@ -155,8 +157,8 @@ async fn timestamp_syscall_increase_time() { // check if timestamp is greater let timestamp_after_new_block = get_current_timestamp(&devnet, timestamp_contract_address).await; - assert_gt_with_buffer(timestamp_after_new_block, now + time_increment); - assert_gt_with_buffer(timestamp_after_new_block, current_timestamp); + assert_gt_with_buffer(timestamp_after_new_block, now + time_increment).unwrap(); + assert_gt_with_buffer(timestamp_after_new_block, current_timestamp).unwrap(); } #[tokio::test] @@ -181,15 +183,15 @@ async fn timestamp_syscall_contract_constructor() { .to_string() .parse::() .unwrap(); - assert_gt_with_buffer(storage_timestamp, now); + assert_gt_with_buffer(storage_timestamp, now).unwrap(); sleep_until_new_timestamp().await; devnet.create_block().await.unwrap(); // check if current timestamp > storage timestamp and now let current_timestamp = get_current_timestamp(&devnet, timestamp_contract_address).await; - assert_gt_with_buffer(current_timestamp, now); - assert_gt_with_buffer(current_timestamp, storage_timestamp); + assert_gt_with_buffer(current_timestamp, now).unwrap(); + assert_gt_with_buffer(current_timestamp, storage_timestamp).unwrap(); } #[tokio::test] @@ -207,7 +209,7 @@ async fn start_time_in_past_syscall() { // check if timestamp is greater/equal let current_timestamp = get_current_timestamp(&devnet, timestamp_contract_address).await; - assert_ge_with_buffer(current_timestamp, past_time); + assert_ge_with_buffer(current_timestamp, past_time).unwrap(); } #[tokio::test] @@ -226,7 +228,7 @@ async fn start_time_in_future_syscall() { // check if timestamp is greater/equal let current_timestamp = get_current_timestamp(&devnet, timestamp_contract_address).await; - assert_ge_with_buffer(current_timestamp, future_time); + assert_ge_with_buffer(current_timestamp, future_time).unwrap(); } async fn set_time_in_past(devnet: &BackgroundDevnet) { @@ -235,21 +237,21 @@ async fn set_time_in_past(devnet: &BackgroundDevnet) { let block_timestamp = set_time(devnet, past_time).await; assert_eq!(block_timestamp, past_time); let set_time_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - assert_ge_with_buffer(set_time_block.timestamp, past_time); + assert_ge_with_buffer(set_time_block.timestamp, past_time).unwrap(); sleep_until_new_timestamp().await; // create block and check if block_timestamp > past_time, check if inside buffer limit devnet.create_block().await.unwrap(); let empty_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - assert_gt_with_buffer(empty_block.timestamp, past_time); + assert_gt_with_buffer(empty_block.timestamp, past_time).unwrap(); sleep_until_new_timestamp().await; // check if after create block timestamp > last block, check if inside buffer limit devnet.create_block().await.unwrap(); let latest_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - assert_gt_with_buffer(latest_block.timestamp, empty_block.timestamp); + assert_gt_with_buffer(latest_block.timestamp, empty_block.timestamp).unwrap(); } #[tokio::test] @@ -275,21 +277,21 @@ async fn set_time_in_future(devnet: &BackgroundDevnet) { let block_timestamp = set_time(devnet, future_time).await; assert_eq!(block_timestamp, future_time); let set_time_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - assert_ge_with_buffer(set_time_block.timestamp, future_time); + assert_ge_with_buffer(set_time_block.timestamp, future_time).unwrap(); sleep_until_new_timestamp().await; // create block and check if block_timestamp > future_time, check if inside buffer limit devnet.create_block().await.unwrap(); let empty_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - assert_gt_with_buffer(empty_block.timestamp, future_time); + assert_gt_with_buffer(empty_block.timestamp, future_time).unwrap(); sleep_until_new_timestamp().await; // check if after create block timestamp > last empty block, check if inside buffer limit devnet.create_block().await.unwrap(); let latest_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - assert_gt_with_buffer(latest_block.timestamp, future_time); + assert_gt_with_buffer(latest_block.timestamp, future_time).unwrap(); } #[tokio::test] @@ -335,7 +337,7 @@ async fn set_time_with_pre_confirmed_txs() { let mut latest_txs = latest_block.transactions.clone(); latest_txs.sort(); assert_eq!(latest_txs, sent_mint_txs); - assert_ge_with_buffer(latest_block.timestamp, future_time); + assert_ge_with_buffer(latest_block.timestamp, future_time).unwrap(); } #[tokio::test] @@ -369,7 +371,7 @@ async fn test_increase_time() { let first_increase_time: u64 = 10000; increase_time(&devnet, first_increase_time).await; let first_increase_time_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - assert_ge_with_buffer(first_increase_time_block.timestamp, now + first_increase_time); + assert_ge_with_buffer(first_increase_time_block.timestamp, now + first_increase_time).unwrap(); // second increase time, check if inside buffer limit let second_increase_time: u64 = 1000; @@ -378,7 +380,8 @@ async fn test_increase_time() { assert_ge_with_buffer( second_increase_time_block.timestamp, now + first_increase_time + second_increase_time, - ); + ) + .unwrap(); sleep_until_new_timestamp().await; @@ -386,14 +389,14 @@ async fn test_increase_time() { // inside buffer limit devnet.create_block().await.unwrap(); let empty_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - assert_gt_with_buffer(empty_block.timestamp, second_increase_time_block.timestamp); + assert_gt_with_buffer(empty_block.timestamp, second_increase_time_block.timestamp).unwrap(); sleep_until_new_timestamp().await; // check if after mint timestamp > last block, check if inside buffer limit devnet.mint(DUMMY_ADDRESS, DUMMY_AMOUNT).await; let last_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - assert_gt_with_buffer(last_block.timestamp, empty_block.timestamp); + assert_gt_with_buffer(last_block.timestamp, empty_block.timestamp).unwrap(); } #[tokio::test] @@ -430,7 +433,7 @@ async fn start_time_in_past() { // create block and check if block timestamp >= 1, check if inside buffer limit devnet.create_block().await.unwrap(); let empty_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - assert_ge_with_buffer(empty_block.timestamp, past_time); + assert_ge_with_buffer(empty_block.timestamp, past_time).unwrap(); } #[tokio::test] @@ -447,7 +450,7 @@ async fn start_time_in_future() { // create block and check if block timestamp > now, check if inside buffer limit devnet.create_block().await.unwrap(); let empty_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - assert_ge_with_buffer(empty_block.timestamp, future_time); + assert_ge_with_buffer(empty_block.timestamp, future_time).unwrap(); } #[tokio::test] @@ -471,7 +474,8 @@ async fn advance_time_combination_test_with_dump_and_load() { let first_increase_time: u64 = 1000; increase_time(&devnet, first_increase_time).await; let first_increase_time_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - assert_ge_with_buffer(first_increase_time_block.timestamp, past_time + first_increase_time); + assert_ge_with_buffer(first_increase_time_block.timestamp, past_time + first_increase_time) + .unwrap(); // increase the time a second time and assert if >= past_time + first_increase_time + // second_increase_time, check if inside buffer limit @@ -481,14 +485,15 @@ async fn advance_time_combination_test_with_dump_and_load() { assert_ge_with_buffer( second_increase_time_block.timestamp, past_time + first_increase_time + second_increase_time, - ); + ) + .unwrap(); // set time to be now and check if the latest block timestamp >= now, check if // it's inside buffer limit let block_timestamp = set_time(&devnet, now).await; assert_eq!(block_timestamp, now); let set_time_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - assert_ge_with_buffer(set_time_block.timestamp, now); + assert_ge_with_buffer(set_time_block.timestamp, now).unwrap(); sleep_until_new_timestamp().await; @@ -496,7 +501,7 @@ async fn advance_time_combination_test_with_dump_and_load() { // inside buffer limit devnet.create_block().await.unwrap(); let empty_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - assert_gt_with_buffer(empty_block.timestamp, set_time_block.timestamp); + assert_gt_with_buffer(empty_block.timestamp, set_time_block.timestamp).unwrap(); // increase the time a third time and assert >= last empty block timestamp + // third_increase_time, check if inside buffer limit @@ -506,14 +511,15 @@ async fn advance_time_combination_test_with_dump_and_load() { assert_ge_with_buffer( third_increase_time_block.timestamp, empty_block.timestamp + third_increase_time, - ); + ) + .unwrap(); sleep_until_new_timestamp().await; // check if the last block timestamp is > previous block, check if inside buffer limit devnet.create_block().await.unwrap(); let last_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - assert_ge_with_buffer(last_block.timestamp, third_increase_time_block.timestamp); + assert_ge_with_buffer(last_block.timestamp, third_increase_time_block.timestamp).unwrap(); send_ctrl_c_signal_and_wait(&devnet.process).await; @@ -593,7 +599,7 @@ async fn correct_pre_confirmed_block_timestamp_after_setting() { devnet.create_block().await.unwrap(); let block = devnet.get_pre_confirmed_block_with_txs().await.unwrap(); - assert_gt_with_buffer(block.timestamp, initial_time); + assert_gt_with_buffer(block.timestamp, initial_time).unwrap(); } #[tokio::test] @@ -628,18 +634,18 @@ async fn tx_resource_estimation_fails_unless_time_incremented() { )) => { assert_eq!(error_data.transaction_index, 0); - let root_error = extract_nested_error(&error_data.execution_error); + let root_error = extract_nested_error(&error_data.execution_error).unwrap(); assert_eq!(root_error.contract_address, account.address()); assert_eq!(root_error.selector, get_selector_from_name("__execute__").unwrap()); // Currently the root error is twice mentioned, so we extract twice - let inner_error = extract_nested_error(&root_error.error); - let inner_error = extract_nested_error(&inner_error.error); + let inner_error = extract_nested_error(&root_error.error).unwrap(); + let inner_error = extract_nested_error(&inner_error.error).unwrap(); assert_eq!(inner_error.contract_address, contract_address); assert_eq!(inner_error.selector, time_check_selector); - let message = extract_message_error(&inner_error.error); - assert_contains(message, "Wait a bit more"); + let message = extract_message_error(&inner_error.error).unwrap(); + assert_contains(message, "Wait a bit more").unwrap(); } other => panic!("Invalid error: {other:?}"), } @@ -686,7 +692,7 @@ async fn tx_execution_fails_unless_time_incremented() { match devnet.json_rpc_client.get_transaction_status(reverted_tx.transaction_hash).await { Ok(TransactionStatus::AcceptedOnL2(tx_details)) => { assert_eq!(tx_details.status(), TransactionExecutionStatus::Reverted); - assert_contains(tx_details.revert_reason().unwrap(), "Wait a bit more"); + assert_contains(tx_details.revert_reason().unwrap(), "Wait a bit more").unwrap(); } other => panic!("Unexpected tx: {other:?}"), } diff --git a/tests/integration/test_advancing_time_on_fork.rs b/tests/integration/test_advancing_time_on_fork.rs index 8b5873feb..386983c01 100644 --- a/tests/integration/test_advancing_time_on_fork.rs +++ b/tests/integration/test_advancing_time_on_fork.rs @@ -64,18 +64,18 @@ async fn tx_resource_estimation_fails_on_forked_devnet_with_impersonation_unless )) => { assert_eq!(error_data.transaction_index, 0); - let root_error = extract_nested_error(&error_data.execution_error); + let root_error = extract_nested_error(&error_data.execution_error).unwrap(); assert_eq!(root_error.contract_address, fork_account.address()); assert_eq!(root_error.selector, get_selector_from_name("__execute__").unwrap()); // Currently the root error is twice mentioned, so we extract twice - let inner_error = extract_nested_error(&root_error.error); - let inner_error = extract_nested_error(&inner_error.error); + let inner_error = extract_nested_error(&root_error.error).unwrap(); + let inner_error = extract_nested_error(&inner_error.error).unwrap(); assert_eq!(inner_error.contract_address, contract_address); assert_eq!(inner_error.selector, time_check_selector); - let message = extract_message_error(&inner_error.error); - assert_contains(message, "Wait a bit more"); + let message = extract_message_error(&inner_error.error).unwrap(); + assert_contains(message, "Wait a bit more").unwrap(); } other => panic!("Invalid error: {other:?}"), } @@ -139,7 +139,7 @@ async fn tx_execution_fails_on_forked_devnet_with_impersonation_unless_time_incr match forked_devnet.json_rpc_client.get_transaction_status(reverted_tx.transaction_hash).await { Ok(TransactionStatus::AcceptedOnL2(tx_details)) => { assert_eq!(tx_details.status(), TransactionExecutionStatus::Reverted); - assert_contains(tx_details.revert_reason().unwrap(), "Wait a bit more"); + assert_contains(tx_details.revert_reason().unwrap(), "Wait a bit more").unwrap(); } other => panic!("Unexpected tx: {other:?}"), } diff --git a/tests/integration/test_blocks_generation.rs b/tests/integration/test_blocks_generation.rs index 7ea348d39..41e64dbd9 100644 --- a/tests/integration/test_blocks_generation.rs +++ b/tests/integration/test_blocks_generation.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use std::time; +use anyhow::anyhow; use serde_json::json; use starknet_rs_accounts::{Account, ExecutionEncoding, SingleOwnerAccount}; use starknet_rs_contract::ContractFactory; @@ -25,181 +26,328 @@ use crate::common::utils::{ static DUMMY_ADDRESS: u128 = 1; static DUMMY_AMOUNT: u128 = 1; -async fn assert_pre_confirmed_state_update(devnet: &BackgroundDevnet) { - let pre_confirmed_state_update = &devnet - .json_rpc_client - .get_state_update(BlockId::Tag(BlockTag::PreConfirmed)) - .await - .unwrap(); +async fn assert_pre_confirmed_state_update(devnet: &BackgroundDevnet) -> Result<(), anyhow::Error> { + let pre_confirmed_state_update = + &devnet.json_rpc_client.get_state_update(BlockId::Tag(BlockTag::PreConfirmed)).await?; - assert!(matches!( - pre_confirmed_state_update, - MaybePreConfirmedStateUpdate::PreConfirmedUpdate(_) - )); + anyhow::ensure!( + matches!(pre_confirmed_state_update, MaybePreConfirmedStateUpdate::PreConfirmedUpdate(_)), + "Expected a pre-confirmed state update, but found: {:?}", + pre_confirmed_state_update + ); + Ok(()) } -async fn assert_latest_state_update(devnet: &BackgroundDevnet) { +async fn assert_latest_state_update(devnet: &BackgroundDevnet) -> Result<(), anyhow::Error> { let latest_state_update = - &devnet.json_rpc_client.get_state_update(BlockId::Tag(BlockTag::Latest)).await.unwrap(); + &devnet.json_rpc_client.get_state_update(BlockId::Tag(BlockTag::Latest)).await?; - assert!(matches!(latest_state_update, MaybePreConfirmedStateUpdate::Update(_))); + anyhow::ensure!( + matches!(latest_state_update, MaybePreConfirmedStateUpdate::Update(_)), + "Expected an update state update, but found: {:?}", + latest_state_update + ); + Ok(()) } async fn assert_latest_block_with_tx_hashes( devnet: &BackgroundDevnet, block_number: u64, transactions: Vec, -) { - let latest_block = devnet.get_latest_block_with_tx_hashes().await.unwrap(); - - assert_eq!(latest_block.block_number, block_number); - assert_eq!(transactions, latest_block.transactions); - assert_eq!(latest_block.status, BlockStatus::AcceptedOnL2); +) -> Result<(), anyhow::Error> { + let latest_block = devnet.get_latest_block_with_tx_hashes().await?; + + anyhow::ensure!( + latest_block.block_number == block_number, + format!( + "assertion `left == right` failed, left: {}, right: {block_number}", + latest_block.block_number + ) + ); + anyhow::ensure!( + transactions == latest_block.transactions, + format!( + "assertion `left == right` failed, left: {transactions:?}, right: {:?}", + latest_block.transactions + ) + ); + anyhow::ensure!( + latest_block.status == BlockStatus::AcceptedOnL2, + format!( + "assertion `left == right` failed, left: {:?}, right: {:?}", + latest_block.status, + BlockStatus::AcceptedOnL2 + ) + ); for tx_hash in latest_block.transactions { - assert_tx_succeeded_accepted(&tx_hash, &devnet.json_rpc_client).await; + assert_tx_succeeded_accepted(&tx_hash, &devnet.json_rpc_client).await?; } + Ok(()) } -async fn assert_pre_confirmed_block_with_tx_hashes(devnet: &BackgroundDevnet, tx_count: usize) { - let pre_confirmed_block = devnet.get_pre_confirmed_block_with_tx_hashes().await.unwrap(); - - assert_eq!(pre_confirmed_block.transactions.len(), tx_count); +async fn assert_pre_confirmed_block_with_tx_hashes( + devnet: &BackgroundDevnet, + tx_count: usize, +) -> Result<(), anyhow::Error> { + let pre_confirmed_block = devnet.get_pre_confirmed_block_with_tx_hashes().await?; + + let pre_confirmed_block_tx_count = pre_confirmed_block.transactions.len(); + anyhow::ensure!( + pre_confirmed_block_tx_count == tx_count, + format!( + "assertion `left == right` failed, left: {pre_confirmed_block_tx_count}, right: {tx_count}" + ) + ); for tx_hash in pre_confirmed_block.transactions { assert_tx_succeeded_pre_confirmed(&tx_hash, &devnet.json_rpc_client).await; } + + Ok(()) } async fn assert_latest_block_with_txs( devnet: &BackgroundDevnet, block_number: u64, tx_count: usize, -) { - let latest_block = devnet.get_latest_block_with_txs().await.unwrap(); - - assert_eq!(latest_block.block_number, block_number); - assert_eq!(latest_block.status, BlockStatus::AcceptedOnL2); - assert_eq!(latest_block.transactions.len(), tx_count); +) -> Result<(), anyhow::Error> { + let latest_block = devnet.get_latest_block_with_txs().await?; + + anyhow::ensure!( + latest_block.block_number == block_number, + format!( + "assertion `left == right` failed, left: {}, right: {}", + latest_block.block_number, block_number + ) + ); + anyhow::ensure!( + latest_block.status == BlockStatus::AcceptedOnL2, + format!( + "assertion `left == right` failed, left: {:?}, right: {:?}", + latest_block.status, + BlockStatus::AcceptedOnL2 + ) + ); + let latest_block_tx_count = latest_block.transactions.len(); + anyhow::ensure!( + latest_block_tx_count == tx_count, + format!( + "assertion `left == right` failed, left: {latest_block_tx_count}, right: {tx_count}" + ) + ); for tx in latest_block.transactions { - assert_tx_succeeded_accepted(tx.transaction_hash(), &devnet.json_rpc_client).await; + assert_tx_succeeded_accepted(tx.transaction_hash(), &devnet.json_rpc_client).await?; } -} -async fn assert_pre_confirmed_block_with_txs(devnet: &BackgroundDevnet, tx_count: usize) { - let pre_confirmed_block = devnet.get_pre_confirmed_block_with_txs().await.unwrap(); + Ok(()) +} - assert_eq!(pre_confirmed_block.transactions.len(), tx_count); +async fn assert_pre_confirmed_block_with_txs( + devnet: &BackgroundDevnet, + tx_count: usize, +) -> Result<(), anyhow::Error> { + let pre_confirmed_block = devnet.get_pre_confirmed_block_with_txs().await?; + + let pre_confirmed_block_tx_count = pre_confirmed_block.transactions.len(); + anyhow::ensure!( + pre_confirmed_block_tx_count == tx_count, + format!( + "assertion `left == right` failed, left: {pre_confirmed_block_tx_count}, right: {tx_count}" + ) + ); for tx in pre_confirmed_block.transactions { assert_tx_succeeded_pre_confirmed(tx.transaction_hash(), &devnet.json_rpc_client).await; } + + Ok(()) } async fn assert_latest_block_with_receipts( devnet: &BackgroundDevnet, block_number: u64, tx_count: usize, -) { +) -> Result<(), anyhow::Error> { let latest_block = &devnet .send_custom_rpc("starknet_getBlockWithReceipts", json!({ "block_id": "latest" })) - .await - .unwrap(); - - assert_eq!(latest_block["transactions"].as_array().unwrap().len(), tx_count); - assert_eq!(latest_block["block_number"], block_number); - assert_eq!(latest_block["status"], "ACCEPTED_ON_L2"); + .await?; + + let latest_block_tx_count = latest_block["transactions"] + .as_array() + .ok_or(anyhow!("cannot convert block txs to array"))? + .len(); + anyhow::ensure!( + latest_block_tx_count == tx_count, + format!( + "assertion `left == right` failed, left: {latest_block_tx_count}, right: {tx_count}" + ) + ); + anyhow::ensure!( + latest_block["block_number"] == block_number, + format!( + "assertion `left == right` failed, left: {}, right: {}", + latest_block["block_number"], block_number + ) + ); + anyhow::ensure!( + latest_block["status"] == "ACCEPTED_ON_L2", + format!( + "assertion `left == right` failed, left: {}, right: {}", + latest_block["status"], "ACCEPTED_ON_L2" + ) + ); for tx in latest_block["transactions"].as_array().unwrap() { assert_tx_succeeded_accepted( - &Felt::from_hex_unchecked(tx["receipt"]["transaction_hash"].as_str().unwrap()), + &Felt::from_hex_unchecked( + tx["receipt"]["transaction_hash"] + .as_str() + .ok_or(anyhow!("failed to parse transaction hash"))?, + ), &devnet.json_rpc_client, ) - .await; + .await?; } + + Ok(()) } -async fn assert_pre_confirmed_block_with_receipts(devnet: &BackgroundDevnet, tx_count: usize) { +async fn assert_pre_confirmed_block_with_receipts( + devnet: &BackgroundDevnet, + tx_count: usize, +) -> Result<(), anyhow::Error> { let pre_confirmed_block = &devnet .send_custom_rpc("starknet_getBlockWithReceipts", json!({ "block_id": "pre_confirmed" })) - .await - .unwrap(); + .await?; - assert!(pre_confirmed_block["status"].is_null()); - assert_eq!(pre_confirmed_block["transactions"].as_array().unwrap().len(), tx_count); + anyhow::ensure!( + pre_confirmed_block["status"].is_null(), + format!( + "assertion failed, expected preconfirmed block status to be null, got: {}", + pre_confirmed_block["status"] + ) + ); + let pre_confirmed_block_tx_count = pre_confirmed_block["transactions"] + .as_array() + .ok_or(anyhow!("failed to convert block transactions to array"))? + .len(); + anyhow::ensure!( + pre_confirmed_block_tx_count == tx_count, + format!( + "assertion `left == right` failed, left: {pre_confirmed_block_tx_count}, right: {tx_count}" + ) + ); for tx in pre_confirmed_block["transactions"].as_array().unwrap() { - let tx_hash = Felt::from_hex_unchecked(tx["receipt"]["transaction_hash"].as_str().unwrap()); + let tx_hash = Felt::from_hex_unchecked( + tx["receipt"]["transaction_hash"] + .as_str() + .ok_or(anyhow!("failed to parse transaction hash"))?, + ); assert_tx_succeeded_pre_confirmed(&tx_hash, &devnet.json_rpc_client).await; } + + Ok(()) } -async fn assert_balance(devnet: &BackgroundDevnet, expected: Felt, tag: BlockTag) { - let balance = - devnet.get_balance_by_tag(&Felt::from(DUMMY_ADDRESS), FeeUnit::Fri, tag).await.unwrap(); - assert_eq!(balance, expected); +async fn assert_balance( + devnet: &BackgroundDevnet, + expected: Felt, + tag: BlockTag, +) -> Result<(), anyhow::Error> { + let balance = devnet.get_balance_by_tag(&Felt::from(DUMMY_ADDRESS), FeeUnit::Fri, tag).await?; + anyhow::ensure!( + balance == expected, + format!("assertion `left == right` failed, left: {balance}, right: {expected}") + ); + Ok(()) } -async fn assert_get_nonce(devnet: &BackgroundDevnet) { +async fn assert_get_nonce(devnet: &BackgroundDevnet) -> Result<(), anyhow::Error> { let (_, account_address) = devnet.get_first_predeployed_account().await; let pre_confirmed_block_nonce = devnet .json_rpc_client .get_nonce(BlockId::Tag(BlockTag::PreConfirmed), account_address) - .await - .unwrap(); - assert_eq!(pre_confirmed_block_nonce, Felt::ZERO); + .await?; + anyhow::ensure!( + pre_confirmed_block_nonce == Felt::ZERO, + format!( + "assertion `left == right` failed, left: {pre_confirmed_block_nonce}, right: {}", + Felt::ZERO + ) + ); - let latest_block_nonce = devnet - .json_rpc_client - .get_nonce(BlockId::Tag(BlockTag::Latest), account_address) - .await - .unwrap(); - assert_eq!(latest_block_nonce, Felt::ZERO); + let latest_block_nonce = + devnet.json_rpc_client.get_nonce(BlockId::Tag(BlockTag::Latest), account_address).await?; + anyhow::ensure!( + latest_block_nonce == Felt::ZERO, + format!( + "assertion `left == right` failed, left: {latest_block_nonce}, right: {}", + Felt::ZERO + ) + ); + Ok(()) } -async fn assert_get_storage_at(devnet: &BackgroundDevnet) { +async fn assert_get_storage_at(devnet: &BackgroundDevnet) -> Result<(), anyhow::Error> { let (_, account_address) = devnet.get_first_predeployed_account().await; let key = Felt::ZERO; let pre_confirmed_block_storage = devnet .json_rpc_client .get_storage_at(account_address, key, BlockId::Tag(BlockTag::PreConfirmed)) - .await - .unwrap(); - assert_eq!(pre_confirmed_block_storage, Felt::ZERO); + .await?; + anyhow::ensure!( + pre_confirmed_block_storage == Felt::ZERO, + format!( + "assertion `left == right` failed, left: {pre_confirmed_block_storage}, right: {}", + Felt::ZERO + ) + ); let latest_block_storage = devnet .json_rpc_client .get_storage_at(account_address, key, BlockId::Tag(BlockTag::Latest)) - .await - .unwrap(); - assert_eq!(latest_block_storage, Felt::ZERO); + .await?; + anyhow::ensure!( + latest_block_storage == Felt::ZERO, + format!( + "assertion `left == right` failed, left: {latest_block_storage}, right: {}", + Felt::ZERO + ) + ); + Ok(()) } -async fn assert_get_class_hash_at(devnet: &BackgroundDevnet) { +async fn assert_get_class_hash_at(devnet: &BackgroundDevnet) -> Result<(), anyhow::Error> { let (_, account_address) = devnet.get_first_predeployed_account().await; let pre_confirmed_block_class_hash = devnet .json_rpc_client .get_class_hash_at(BlockId::Tag(BlockTag::PreConfirmed), account_address) - .await - .unwrap(); - assert_eq!( - pre_confirmed_block_class_hash, - Felt::from_hex_unchecked(CAIRO_1_ACCOUNT_CONTRACT_SIERRA_HASH) + .await?; + let sierra_hash = Felt::from_hex_unchecked(CAIRO_1_ACCOUNT_CONTRACT_SIERRA_HASH); + anyhow::ensure!( + pre_confirmed_block_class_hash == sierra_hash, + format!( + "assertion `left == right` failed, left: {pre_confirmed_block_class_hash}, right: {sierra_hash}" + ) ); let latest_block_class_hash = devnet .json_rpc_client .get_class_hash_at(BlockId::Tag(BlockTag::Latest), account_address) - .await - .unwrap(); - assert_eq!( - latest_block_class_hash, - Felt::from_hex_unchecked(CAIRO_1_ACCOUNT_CONTRACT_SIERRA_HASH) + .await?; + anyhow::ensure!( + latest_block_class_hash == sierra_hash, + format!( + "assertion `left == right` failed, left: {latest_block_class_hash}, right: {sierra_hash}" + ) ); + Ok(()) } #[tokio::test] @@ -213,18 +361,22 @@ async fn normal_mode_states_and_blocks() { tx_hashes.push(mint_hash); } - assert_balance(&devnet, Felt::from(tx_count * DUMMY_AMOUNT), BlockTag::PreConfirmed).await; - assert_balance(&devnet, Felt::from(tx_count * DUMMY_AMOUNT), BlockTag::Latest).await; + assert_balance(&devnet, Felt::from(tx_count * DUMMY_AMOUNT), BlockTag::PreConfirmed) + .await + .unwrap(); + assert_balance(&devnet, Felt::from(tx_count * DUMMY_AMOUNT), BlockTag::Latest).await.unwrap(); - assert_pre_confirmed_block_with_tx_hashes(&devnet, 0).await; - assert_pre_confirmed_block_with_txs(&devnet, 0).await; - assert_pre_confirmed_block_with_receipts(&devnet, 0).await; - assert_latest_block_with_tx_hashes(&devnet, 5, vec![tx_hashes.last().copied().unwrap()]).await; - assert_latest_block_with_txs(&devnet, 5, 1).await; - assert_latest_block_with_receipts(&devnet, 5, 1).await; + assert_pre_confirmed_block_with_tx_hashes(&devnet, 0).await.unwrap(); + assert_pre_confirmed_block_with_txs(&devnet, 0).await.unwrap(); + assert_pre_confirmed_block_with_receipts(&devnet, 0).await.unwrap(); + assert_latest_block_with_tx_hashes(&devnet, 5, vec![tx_hashes.last().copied().unwrap()]) + .await + .unwrap(); + assert_latest_block_with_txs(&devnet, 5, 1).await.unwrap(); + assert_latest_block_with_receipts(&devnet, 5, 1).await.unwrap(); - assert_pre_confirmed_state_update(&devnet).await; - assert_latest_state_update(&devnet).await; + assert_pre_confirmed_state_update(&devnet).await.unwrap(); + assert_latest_state_update(&devnet).await.unwrap(); } #[tokio::test] @@ -241,34 +393,38 @@ async fn blocks_on_demand_states_and_blocks() { } assert_balance(&devnet, Felt::from(tx_count * DUMMY_AMOUNT as usize), BlockTag::PreConfirmed) - .await; - assert_balance(&devnet, Felt::ZERO, BlockTag::Latest).await; + .await + .unwrap(); + assert_balance(&devnet, Felt::ZERO, BlockTag::Latest).await.unwrap(); - assert_pre_confirmed_block_with_tx_hashes(&devnet, tx_count).await; - assert_pre_confirmed_block_with_txs(&devnet, tx_count).await; - assert_pre_confirmed_block_with_receipts(&devnet, tx_count).await; + assert_pre_confirmed_block_with_tx_hashes(&devnet, tx_count).await.unwrap(); + assert_pre_confirmed_block_with_txs(&devnet, tx_count).await.unwrap(); + assert_pre_confirmed_block_with_receipts(&devnet, tx_count).await.unwrap(); - assert_latest_block_with_tx_hashes(&devnet, 0, vec![]).await; - assert_latest_block_with_txs(&devnet, 0, 0).await; - assert_latest_block_with_receipts(&devnet, 0, 0).await; + assert_latest_block_with_tx_hashes(&devnet, 0, vec![]).await.unwrap(); + assert_latest_block_with_txs(&devnet, 0, 0).await.unwrap(); + assert_latest_block_with_receipts(&devnet, 0, 0).await.unwrap(); // create new block from pre_confirmed block devnet.create_block().await.unwrap(); assert_balance(&devnet, Felt::from(tx_count * DUMMY_AMOUNT as usize), BlockTag::PreConfirmed) - .await; - assert_balance(&devnet, Felt::from(tx_count * DUMMY_AMOUNT as usize), BlockTag::Latest).await; + .await + .unwrap(); + assert_balance(&devnet, Felt::from(tx_count * DUMMY_AMOUNT as usize), BlockTag::Latest) + .await + .unwrap(); - assert_pre_confirmed_block_with_tx_hashes(&devnet, 0).await; - assert_pre_confirmed_block_with_txs(&devnet, 0).await; - assert_pre_confirmed_block_with_receipts(&devnet, 0).await; + assert_pre_confirmed_block_with_tx_hashes(&devnet, 0).await.unwrap(); + assert_pre_confirmed_block_with_txs(&devnet, 0).await.unwrap(); + assert_pre_confirmed_block_with_receipts(&devnet, 0).await.unwrap(); - assert_latest_block_with_tx_hashes(&devnet, 1, tx_hashes).await; - assert_latest_block_with_txs(&devnet, 1, tx_count).await; - assert_latest_block_with_receipts(&devnet, 1, tx_count).await; + assert_latest_block_with_tx_hashes(&devnet, 1, tx_hashes).await.unwrap(); + assert_latest_block_with_txs(&devnet, 1, tx_count).await.unwrap(); + assert_latest_block_with_receipts(&devnet, 1, tx_count).await.unwrap(); - assert_pre_confirmed_state_update(&devnet).await; - assert_latest_state_update(&devnet).await; + assert_pre_confirmed_state_update(&devnet).await.unwrap(); + assert_latest_state_update(&devnet).await.unwrap(); } #[tokio::test] @@ -345,8 +501,9 @@ async fn blocks_on_demand_declarations() { for block_id in [BlockId::Tag(BlockTag::Latest), BlockId::Hash(declaration_block_hash)] { match devnet.json_rpc_client.get_state_update(block_id).await { Ok(MaybePreConfirmedStateUpdate::Update(StateUpdate { state_diff, .. })) => { - assert_equal_elements(&state_diff.declared_classes, &expected_block_declarations); - assert_equal_elements(&state_diff.nonces, &expected_block_nonce_update) + assert_equal_elements(&state_diff.declared_classes, &expected_block_declarations) + .unwrap(); + assert_equal_elements(&state_diff.nonces, &expected_block_nonce_update).unwrap() } other => panic!("Unexpected response: {other:?}"), } @@ -427,16 +584,14 @@ async fn blocks_on_demand_invoke_and_call() { } let expected_balance = initial_value + (increment * Felt::from(increment_count)); - - assert_eq!( - get_contract_balance_by_block_id( - &devnet, - contract_address, - BlockId::Tag(BlockTag::PreConfirmed) - ) - .await, - expected_balance - ); + let contract_balance = get_contract_balance_by_block_id( + &devnet, + contract_address, + BlockId::Tag(BlockTag::PreConfirmed), + ) + .await + .unwrap(); + assert_eq!(contract_balance, expected_balance); let contract_call = FunctionCall { contract_address, @@ -449,17 +604,17 @@ async fn blocks_on_demand_invoke_and_call() { devnet.create_block().await.unwrap(); - assert_latest_block_with_tx_hashes(&devnet, 1, tx_hashes).await; - assert_eq!( - get_contract_balance_by_block_id( - &devnet, - contract_address, - BlockId::Tag(BlockTag::PreConfirmed) - ) - .await, - expected_balance - ); - assert_eq!(get_contract_balance(&devnet, contract_address).await, expected_balance); + assert_latest_block_with_tx_hashes(&devnet, 1, tx_hashes).await.unwrap(); + let contract_balance = get_contract_balance_by_block_id( + &devnet, + contract_address, + BlockId::Tag(BlockTag::PreConfirmed), + ) + .await + .unwrap(); + assert_eq!(contract_balance, expected_balance); + let contract_balance = get_contract_balance(&devnet, contract_address).await.unwrap(); + assert_eq!(contract_balance, expected_balance); } #[tokio::test] @@ -498,7 +653,7 @@ async fn blocks_on_interval_transactions() { tokio::time::sleep(time::Duration::from_secs(period * 3 / 2)).await; // first is genesis block, second block is generated after transactions - assert_latest_block_with_tx_hashes(&devnet, 1, tx_hashes).await; + assert_latest_block_with_tx_hashes(&devnet, 1, tx_hashes).await.unwrap(); } #[tokio::test] @@ -543,7 +698,7 @@ async fn blocks_on_interval_dump_and_load() { async fn get_nonce_of_first_predeployed_account_normal_mode() { let devnet = BackgroundDevnet::spawn().await.unwrap(); - assert_get_nonce(&devnet).await; + assert_get_nonce(&devnet).await.unwrap(); } #[tokio::test] @@ -552,14 +707,14 @@ async fn get_nonce_of_first_predeployed_account_block_on_demand() { .await .unwrap(); - assert_get_nonce(&devnet).await; + assert_get_nonce(&devnet).await.unwrap(); } #[tokio::test] async fn get_storage_at_normal_mode() { let devnet = BackgroundDevnet::spawn().await.unwrap(); - assert_get_storage_at(&devnet).await; + assert_get_storage_at(&devnet).await.unwrap(); } #[tokio::test] @@ -568,14 +723,14 @@ async fn get_storage_at_block_on_demand() { .await .unwrap(); - assert_get_storage_at(&devnet).await; + assert_get_storage_at(&devnet).await.unwrap(); } #[tokio::test] async fn get_class_hash_at_normal_mode() { let devnet = BackgroundDevnet::spawn().await.unwrap(); - assert_get_class_hash_at(&devnet).await; + assert_get_class_hash_at(&devnet).await.unwrap(); } #[tokio::test] @@ -584,7 +739,7 @@ async fn get_class_hash_at_block_on_demand() { .await .unwrap(); - assert_get_class_hash_at(&devnet).await; + assert_get_class_hash_at(&devnet).await.unwrap(); } #[tokio::test] diff --git a/tests/integration/test_call.rs b/tests/integration/test_call.rs index 25311ad88..60f34542a 100644 --- a/tests/integration/test_call.rs +++ b/tests/integration/test_call.rs @@ -139,18 +139,18 @@ async fn call_panicking_method() { ProviderError::StarknetError(StarknetError::ContractError(ContractErrorData { revert_error, })) => { - let root = extract_nested_error(&revert_error); + let root = extract_nested_error(&revert_error).unwrap(); assert_eq!(root.contract_address, contract_address); assert_eq!(root.class_hash, class_hash); assert_eq!(root.selector, top_selector); - let inner = extract_nested_error(&root.error); + let inner = extract_nested_error(&root.error).unwrap(); assert_eq!(inner.contract_address, other_contract_address); assert_eq!(inner.selector, get_selector_from_name("create_panic").unwrap()); assert_eq!(inner.class_hash, class_hash); - let error_msg = extract_message_error(&inner.error); - assert_contains(error_msg, &panic_message.to_hex_string()); + let error_msg = extract_message_error(&inner.error).unwrap(); + assert_contains(error_msg, &panic_message.to_hex_string()).unwrap(); } _ => panic!("Invalid error received {err:?}"), } diff --git a/tests/integration/test_deploy.rs b/tests/integration/test_deploy.rs index 184a50eb9..95fe7b166 100644 --- a/tests/integration/test_deploy.rs +++ b/tests/integration/test_deploy.rs @@ -68,17 +68,17 @@ async fn double_deployment_not_allowed() { ); assert_eq!(top_error.selector, get_selector_from_name("__execute__").unwrap()); - let udc_error = extract_nested_error(&top_error.error); + let udc_error = extract_nested_error(&top_error.error).unwrap(); assert_eq!(udc_error.contract_address, UDC_LEGACY_CONTRACT_ADDRESS); assert_eq!(udc_error.class_hash, UDC_LEGACY_CONTRACT_CLASS_HASH); assert_eq!(udc_error.selector, get_selector_from_name("deployContract").unwrap()); - let undeployed_contract_error = extract_nested_error(&udc_error.error); + let undeployed_contract_error = extract_nested_error(&udc_error.error).unwrap(); assert_eq!(undeployed_contract_error.class_hash, declaration_result.class_hash); assert_eq!(undeployed_contract_error.selector, Felt::ZERO); // constructor - let msg_error = extract_message_error(&undeployed_contract_error.error); - assert_contains(msg_error, "contract already deployed"); + let msg_error = extract_message_error(&undeployed_contract_error.error).unwrap(); + assert_contains(msg_error, "contract already deployed").unwrap(); } other => panic!("Unexpected result: {other:?}"), }; @@ -108,7 +108,7 @@ async fn cannot_deploy_undeclared_class() { // deployment should fail match contract_factory.deploy_v3(ctor_args, salt, unique).send().await { - Err(e) => assert_contains(&format!("{e:?}"), "not declared"), + Err(e) => assert_contains(&format!("{e:?}"), "not declared").unwrap(), other => panic!("Unexpected result: {other:?}"), }; } @@ -137,7 +137,8 @@ async fn test_all_udc_deployment_methods_supported() { .await .unwrap(); assert_tx_succeeded_accepted(&declaration_result.transaction_hash, &devnet.json_rpc_client) - .await; + .await + .unwrap(); let mut salt = Felt::ONE; let legacy_deployment_method = "deployContract"; @@ -162,6 +163,7 @@ async fn test_all_udc_deployment_methods_supported() { let invoke_result = account.execute_v3(contract_invoke.clone()).send().await.unwrap(); assert_tx_succeeded_accepted(&invoke_result.transaction_hash, &devnet.json_rpc_client) - .await; + .await + .unwrap(); } } diff --git a/tests/integration/test_dump_and_load.rs b/tests/integration/test_dump_and_load.rs index b2bd11f59..12e974539 100644 --- a/tests/integration/test_dump_and_load.rs +++ b/tests/integration/test_dump_and_load.rs @@ -19,7 +19,7 @@ use starknet_rs_core::types::{DeclareTransaction, Felt, InvokeTransaction, Trans use crate::common::utils::get_events_contract_artifacts; -async fn dump_load_dump_load(mode: &str) { +async fn dump_load_dump_load(mode: &str) -> Result<(), anyhow::Error> { let dump_file = UniqueAutoDeletableFile::new(("dump_load_dump_load_on_".to_owned() + mode).as_str()); @@ -30,8 +30,7 @@ async fn dump_load_dump_load(mode: &str) { "--dump-on", mode, ]) - .await - .expect("Could not start Devnet"); + .await?; devnet_dump.create_block().await.unwrap(); devnet_dump.mint(DUMMY_ADDRESS, DUMMY_AMOUNT).await; @@ -45,11 +44,17 @@ async fn dump_load_dump_load(mode: &str) { "--dump-on", mode, ]) - .await - .expect("Could not start Devnet"); - - let last_block = devnet_load.get_latest_block_with_tx_hashes().await.unwrap(); - assert_eq!(last_block.block_number, 4); + .await?; + + let last_block = devnet_load.get_latest_block_with_tx_hashes().await?; + anyhow::ensure!( + last_block.block_number == 4, + format!( + "assertion `left == right` failed, left: {}, right: {}", + last_block.block_number, 4 + ) + ); + Ok(()) } #[tokio::test] @@ -85,12 +90,12 @@ async fn dump_load_dump_load_without_path() { #[tokio::test] async fn dump_load_dump_load_on_exit() { - dump_load_dump_load("exit").await; + dump_load_dump_load("exit").await.unwrap(); } #[tokio::test] async fn dump_load_dump_load_on_transaction() { - dump_load_dump_load("block").await; + dump_load_dump_load("block").await.unwrap(); } #[tokio::test] diff --git a/tests/integration/test_estimate_fee.rs b/tests/integration/test_estimate_fee.rs index 682f196ac..0d100086a 100644 --- a/tests/integration/test_estimate_fee.rs +++ b/tests/integration/test_estimate_fee.rs @@ -99,7 +99,8 @@ async fn estimate_fee_of_deploy_account() { .await .expect("Should deploy with sufficient fee"); assert_tx_succeeded_accepted(&successful_deployment.transaction_hash, &devnet.json_rpc_client) - .await; + .await + .unwrap(); } #[tokio::test] @@ -129,7 +130,8 @@ async fn estimate_fee_of_invalid_deploy_account() { "Class with hash {} is not declared.", invalid_class_hash.to_fixed_hex_string() ), - ); + ) + .unwrap(); } other => panic!("Unexpected response: {other:?}"), } @@ -200,7 +202,8 @@ async fn estimate_fee_of_declare_v3() { .await .unwrap(); assert_tx_succeeded_accepted(&successful_declare_tx.transaction_hash, &devnet.json_rpc_client) - .await; + .await + .unwrap(); } #[tokio::test] @@ -278,7 +281,8 @@ async fn estimate_fee_of_invoke() { &devnet.json_rpc_client, &["Insufficient max L2Gas"], ) - .await; + .await + .unwrap(); // invoke with sufficient resource bounds let fee = LocalFee::from(fee_estimation); @@ -357,11 +361,11 @@ async fn message_available_if_estimation_reverts() { .. }), )) => { - let account_error = extract_nested_error(&execution_error); - let contract_error = extract_nested_error(&account_error.error); - let inner_error = extract_nested_error(&contract_error.error); - let error_msg = extract_message_error(&inner_error.error); - assert_contains(error_msg, &panic_reason.to_hex_string()); + let account_error = extract_nested_error(&execution_error).unwrap(); + let contract_error = extract_nested_error(&account_error.error).unwrap(); + let inner_error = extract_nested_error(&contract_error.error).unwrap(); + let error_msg = extract_message_error(&inner_error.error).unwrap(); + assert_contains(error_msg, &panic_reason.to_hex_string()).unwrap(); } other => panic!("Invalid err: {other:?}"), }; @@ -631,7 +635,8 @@ async fn estimate_fee_of_multiple_txs_with_second_failing() { assert_contains( &format!("{:?}", execution_error), &ENTRYPOINT_NOT_FOUND_ERROR_ENCODED.to_hex_string(), - ); + ) + .unwrap(); } _ => panic!("Unexpected error: {err}"), }; @@ -725,7 +730,7 @@ async fn estimate_fee_of_multiple_failing_txs_should_return_index_of_the_first_f TransactionExecutionErrorData { transaction_index, execution_error }, )) => { assert_eq!(transaction_index, 0); - assert_contains(&format!("{:?}", execution_error), "invalid signature"); + assert_contains(&format!("{:?}", execution_error), "invalid signature").unwrap(); } other => panic!("Unexpected error: {:?}", other), } diff --git a/tests/integration/test_fork.rs b/tests/integration/test_fork.rs index 4a53d7315..72fdff88e 100644 --- a/tests/integration/test_fork.rs +++ b/tests/integration/test_fork.rs @@ -260,11 +260,12 @@ async fn test_origin_declare_deploy_fork_invoke() { ); // assert correctly deployed - assert_eq!(get_contract_balance(&origin_devnet, contract_address).await, initial_value); + let origin_balance = get_contract_balance(&origin_devnet, contract_address).await.unwrap(); + assert_eq!(origin_balance, initial_value); let fork_devnet = origin_devnet.fork().await.unwrap(); - - assert_eq!(get_contract_balance(&fork_devnet, contract_address).await, initial_value); + let fork_balance = get_contract_balance(&fork_devnet, contract_address).await.unwrap(); + assert_eq!(fork_balance, initial_value); let fork_predeployed_account = SingleOwnerAccount::new( fork_devnet.clone_provider(), @@ -292,14 +293,14 @@ async fn test_origin_declare_deploy_fork_invoke() { .unwrap(); assert_tx_succeeded_accepted(&invoke_result.transaction_hash, &fork_devnet.json_rpc_client) - .await; + .await + .unwrap(); // assert origin intact and fork changed - assert_eq!(get_contract_balance(&origin_devnet, contract_address).await, initial_value); - assert_eq!( - get_contract_balance(&fork_devnet, contract_address).await, - initial_value + increment - ); + let origin_balance = get_contract_balance(&origin_devnet, contract_address).await.unwrap(); + assert_eq!(origin_balance, initial_value); + let fork_balance = get_contract_balance(&fork_devnet, contract_address).await.unwrap(); + assert_eq!(fork_balance, initial_value + increment); } #[tokio::test] @@ -520,7 +521,9 @@ async fn changes_in_origin_after_forking_block_should_not_affect_fork_state() { .unwrap(); assert_tx_succeeded_accepted(&invoke_result.transaction_hash, &origin_devnet.json_rpc_client) - .await; + .await + .unwrap(); + let latest_origin_block_number = origin_devnet.json_rpc_client.block_number().await.unwrap(); assert_eq!(latest_origin_block_number, 3); // declare, deploy, invoke @@ -535,11 +538,11 @@ async fn changes_in_origin_after_forking_block_should_not_affect_fork_state() { .unwrap(); // Assert fork intact and origin changed - assert_eq!(get_contract_balance(&fork_devnet, contract_address).await, initial_value); - assert_eq!( - get_contract_balance(&origin_devnet, contract_address).await, - initial_value + increment_value - ); + let fork_balance = get_contract_balance(&fork_devnet, contract_address).await.unwrap(); + assert_eq!(fork_balance, initial_value); + + let origin_balance = get_contract_balance(&origin_devnet, contract_address).await.unwrap(); + assert_eq!(origin_balance, initial_value + increment_value); } #[tokio::test] @@ -570,9 +573,11 @@ async fn test_fork_if_origin_dies() { assert_contains( &received_error.message, "Failed to read from state: Error in communication with forking origin", - ); - assert_contains(&received_error.message, "Connection refused"); - assert_contains(&received_error.message, &format!("url: \"{}/\"", origin_devnet.url)); + ) + .unwrap(); + assert_contains(&received_error.message, "Connection refused").unwrap(); + assert_contains(&received_error.message, &format!("url: \"{}/\"", origin_devnet.url)) + .unwrap(); assert_eq!(received_error.data, None); } unexpected => panic!("Got unexpected resp: {unexpected:?}"), diff --git a/tests/integration/test_gas_modification.rs b/tests/integration/test_gas_modification.rs index aa57b78f3..835294029 100644 --- a/tests/integration/test_gas_modification.rs +++ b/tests/integration/test_gas_modification.rs @@ -54,7 +54,10 @@ impl SetGasPrice for BackgroundDevnet { /// /// Note to test maintainer: the usual way of adapting this test to a new Starknet version is to /// repeatedly run it and hardcode new hex fee values. -async fn set_gas_scenario(devnet: BackgroundDevnet, expected_chain_id: Felt) { +async fn set_gas_scenario( + devnet: BackgroundDevnet, + expected_chain_id: Felt, +) -> Result<(), anyhow::Error> { // get account let (signer, account_address) = devnet.get_first_predeployed_account().await; let account = SingleOwnerAccount::new( @@ -80,9 +83,8 @@ async fn set_gas_scenario(devnet: BackgroundDevnet, expected_chain_id: Felt) { .l2_gas(0) .l2_gas_price(0) .nonce(nonce) - .prepared() - .unwrap(); - let signature = signer.sign_hash(&declaration.transaction_hash(false)).await.unwrap(); + .prepared()?; + let signature = signer.sign_hash(&declaration.transaction_hash(false)).await?; let zero_bounds = json!({ "max_amount": "0x0", "max_price_per_unit": "0x0" }); let sender_address_hex = to_hex_felt(&account_address); @@ -114,28 +116,60 @@ async fn set_gas_scenario(devnet: BackgroundDevnet, expected_chain_id: Felt) { }) }; - let chain_id = devnet.json_rpc_client.chain_id().await.unwrap(); - assert_eq!(chain_id, expected_chain_id); + let chain_id = devnet.json_rpc_client.chain_id().await?; + anyhow::ensure!( + chain_id == expected_chain_id, + format!( + "Chain ID mismatch: assertion `left == right` failed, left: {chain_id}, right: {expected_chain_id}" + ) + ); let params_skip_fee_charge = get_params(&["SKIP_FEE_CHARGE"]); let resp_no_flags = &devnet .send_custom_rpc("starknet_simulateTransactions", params_skip_fee_charge.clone()) .await - .unwrap()[0]; - assert_eq!( - resp_no_flags["fee_estimation"]["l1_gas_price"], - to_hex_felt(&DEVNET_DEFAULT_L1_GAS_PRICE) + .map_err(|err| anyhow::anyhow!("failed to simulate transactions {:?}", err))?[0]; + anyhow::ensure!( + resp_no_flags["fee_estimation"]["l1_gas_price"] + == to_hex_felt(&DEVNET_DEFAULT_L1_GAS_PRICE), + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_no_flags["fee_estimation"]["l1_gas_price"], + to_hex_felt(&DEVNET_DEFAULT_L1_GAS_PRICE) + ) ); - assert_eq!( - resp_no_flags["fee_estimation"]["l1_data_gas_price"], - to_hex_felt(&DEVNET_DEFAULT_L1_DATA_GAS_PRICE) + anyhow::ensure!( + resp_no_flags["fee_estimation"]["l1_data_gas_price"] + == to_hex_felt(&DEVNET_DEFAULT_L1_DATA_GAS_PRICE), + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_no_flags["fee_estimation"]["l1_data_gas_price"], + to_hex_felt(&DEVNET_DEFAULT_L1_DATA_GAS_PRICE) + ) ); - assert_eq!( - resp_no_flags["fee_estimation"]["l2_gas_price"], - to_hex_felt(&DEVNET_DEFAULT_L2_GAS_PRICE) + anyhow::ensure!( + resp_no_flags["fee_estimation"]["l2_gas_price"] + == to_hex_felt(&DEVNET_DEFAULT_L2_GAS_PRICE), + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_no_flags["fee_estimation"]["l2_gas_price"], + to_hex_felt(&DEVNET_DEFAULT_L2_GAS_PRICE) + ) + ); + anyhow::ensure!( + resp_no_flags["transaction_trace"]["execution_resources"]["l1_gas"] == 0, + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_no_flags["transaction_trace"]["execution_resources"]["l1_gas"], 0 + ) + ); + anyhow::ensure!( + resp_no_flags["fee_estimation"]["overall_fee"] == "0x99cb411f968000", + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_no_flags["fee_estimation"]["overall_fee"], "0x99cb411f968000" + ) ); - assert_eq!(resp_no_flags["transaction_trace"]["execution_resources"]["l1_gas"], 0); - assert_eq!(resp_no_flags["fee_estimation"]["overall_fee"], "0x99cb411f968000"); let params_skip_validation_and_fee_charge = get_params(&["SKIP_VALIDATE", "SKIP_FEE_CHARGE"]); let resp_skip_validation = &devnet @@ -144,22 +178,49 @@ async fn set_gas_scenario(devnet: BackgroundDevnet, expected_chain_id: Felt) { params_skip_validation_and_fee_charge.clone(), ) .await - .unwrap()[0]; - - assert_eq!( - resp_skip_validation["fee_estimation"]["l1_gas_price"], - to_hex_felt(&DEVNET_DEFAULT_L1_GAS_PRICE) + .map_err(|err| anyhow::anyhow!("failed to simulate transactions {:?}", err))?[0]; + + anyhow::ensure!( + resp_skip_validation["fee_estimation"]["l1_gas_price"] + == to_hex_felt(&DEVNET_DEFAULT_L1_GAS_PRICE), + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_skip_validation["fee_estimation"]["l1_gas_price"], + to_hex_felt(&DEVNET_DEFAULT_L1_GAS_PRICE) + ) ); - assert_eq!( - resp_skip_validation["fee_estimation"]["l1_data_gas_price"], - to_hex_felt(&DEVNET_DEFAULT_L1_DATA_GAS_PRICE) + anyhow::ensure!( + resp_skip_validation["fee_estimation"]["l1_data_gas_price"] + == to_hex_felt(&DEVNET_DEFAULT_L1_DATA_GAS_PRICE), + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_skip_validation["fee_estimation"]["l1_data_gas_price"], + to_hex_felt(&DEVNET_DEFAULT_L1_DATA_GAS_PRICE) + ) ); - assert_eq!( - resp_skip_validation["fee_estimation"]["l2_gas_price"], - to_hex_felt(&DEVNET_DEFAULT_L2_GAS_PRICE) + anyhow::ensure!( + resp_skip_validation["fee_estimation"]["l2_gas_price"] + == to_hex_felt(&DEVNET_DEFAULT_L2_GAS_PRICE), + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_skip_validation["fee_estimation"]["l2_gas_price"], + to_hex_felt(&DEVNET_DEFAULT_L2_GAS_PRICE) + ) + ); + anyhow::ensure!( + resp_no_flags["transaction_trace"]["execution_resources"]["l1_gas"] == 0, + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_no_flags["transaction_trace"]["execution_resources"]["l1_gas"], 0 + ) + ); + anyhow::ensure!( + resp_skip_validation["fee_estimation"]["overall_fee"] == "0x995e1d72370000", + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_skip_validation["fee_estimation"]["overall_fee"], "0x995e1d72370000" + ) ); - assert_eq!(resp_no_flags["transaction_trace"]["execution_resources"]["l1_gas"], 0); - assert_eq!(resp_skip_validation["fee_estimation"]["overall_fee"], "0x995e1d72370000"); let should_skip_fee_invocation = true; assert_difference_if_validation( @@ -180,37 +241,89 @@ async fn set_gas_scenario(devnet: BackgroundDevnet, expected_chain_id: Felt) { "l2_gas_price_wei": 7e18 as u128, "l2_gas_price_fri": l2_fri_price, }); - let gas_response = &devnet.set_gas_price(&gas_request, true).await.unwrap(); + let gas_response = &devnet.set_gas_price(&gas_request, true).await?; - assert_eq!(gas_response, &gas_request); + anyhow::ensure!( + gas_response == &gas_request, + format!("assertion `left == right` failed, left: {gas_response}, right: {}", &gas_request) + ); - let chain_id = devnet.json_rpc_client.chain_id().await.unwrap(); - assert_eq!(chain_id, expected_chain_id); + let chain_id = devnet.json_rpc_client.chain_id().await?; + anyhow::ensure!( + chain_id == expected_chain_id, + format!("assertion `left == right` failed, left: {chain_id}, right: {expected_chain_id}") + ); - let resp_no_flags = &devnet - .send_custom_rpc("starknet_simulateTransactions", params_skip_fee_charge) - .await - .unwrap()[0]; + let resp_no_flags = + &devnet.send_custom_rpc("starknet_simulateTransactions", params_skip_fee_charge).await?[0]; - assert_eq!(resp_no_flags["fee_estimation"]["l1_gas_price"], to_hex_felt(&l1_fri_price)); - assert_eq!( - resp_no_flags["fee_estimation"]["l1_data_gas_price"], - to_hex_felt(&l1_data_fri_price) + anyhow::ensure!( + resp_no_flags["fee_estimation"]["l1_gas_price"] == to_hex_felt(&l1_fri_price), + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_no_flags["fee_estimation"]["l1_gas_price"], + to_hex_felt(&l1_fri_price) + ) + ); + anyhow::ensure!( + resp_no_flags["fee_estimation"]["l1_data_gas_price"] == to_hex_felt(&l1_data_fri_price), + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_no_flags["fee_estimation"]["l1_data_gas_price"], + to_hex_felt(&l1_data_fri_price) + ) + ); + anyhow::ensure!( + resp_no_flags["fee_estimation"]["l2_gas_price"] == to_hex_felt(&l2_fri_price), + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_no_flags["fee_estimation"]["l2_gas_price"], + to_hex_felt(&l2_fri_price) + ) + ); + anyhow::ensure!( + resp_no_flags["fee_estimation"]["overall_fee"] == "0xe8c077047881faf1800000", + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_no_flags["fee_estimation"]["overall_fee"], "0xe8c077047881faf1800000" + ) ); - assert_eq!(resp_no_flags["fee_estimation"]["l2_gas_price"], to_hex_felt(&l2_fri_price)); - assert_eq!(resp_no_flags["fee_estimation"]["overall_fee"], "0xe8c077047881faf1800000"); let resp_skip_validation = &devnet .send_custom_rpc("starknet_simulateTransactions", params_skip_validation_and_fee_charge) - .await - .unwrap()[0]; - assert_eq!(resp_skip_validation["fee_estimation"]["l1_gas_price"], to_hex_felt(&l1_fri_price)); - assert_eq!( - resp_skip_validation["fee_estimation"]["l1_data_gas_price"], - to_hex_felt(&l1_data_fri_price) + .await?[0]; + anyhow::ensure!( + resp_skip_validation["fee_estimation"]["l1_gas_price"] == to_hex_felt(&l1_fri_price), + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_skip_validation["fee_estimation"]["l1_gas_price"], + to_hex_felt(&l1_fri_price) + ) + ); + anyhow::ensure!( + resp_skip_validation["fee_estimation"]["l1_data_gas_price"] + == to_hex_felt(&l1_data_fri_price), + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_skip_validation["fee_estimation"]["l1_data_gas_price"], + to_hex_felt(&l1_data_fri_price) + ) + ); + anyhow::ensure!( + resp_skip_validation["fee_estimation"]["l2_gas_price"] == to_hex_felt(&l2_fri_price), + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_skip_validation["fee_estimation"]["l2_gas_price"], + to_hex_felt(&l2_fri_price) + ) + ); + anyhow::ensure!( + resp_skip_validation["fee_estimation"]["overall_fee"] == "0xe81b4b21fb0b18a2000000", + format!( + "assertion `left == right` failed, left: {}, right: {}", + resp_skip_validation["fee_estimation"]["overall_fee"], "0xe81b4b21fb0b18a2000000" + ) ); - assert_eq!(resp_skip_validation["fee_estimation"]["l2_gas_price"], to_hex_felt(&l2_fri_price)); - assert_eq!(resp_skip_validation["fee_estimation"]["overall_fee"], "0xe81b4b21fb0b18a2000000"); assert_difference_if_validation( resp_no_flags, @@ -218,6 +331,8 @@ async fn set_gas_scenario(devnet: BackgroundDevnet, expected_chain_id: Felt) { &sender_address_hex, should_skip_fee_invocation, ); + + Ok(()) } #[tokio::test] @@ -225,7 +340,7 @@ async fn set_gas() { let devnet = BackgroundDevnet::spawn().await.expect("Could not start Devnet"); // Testnet gas modification test scenario - set_gas_scenario(devnet, SEPOLIA).await; + set_gas_scenario(devnet, SEPOLIA).await.unwrap(); } #[tokio::test] @@ -236,7 +351,8 @@ async fn set_gas_fork() { // Sepolia fork gas modification test scenario set_gas_scenario(fork_devnet, cairo_short_string_to_felt("SN_INTEGRATION_SEPOLIA").unwrap()) - .await; + .await + .unwrap(); } #[tokio::test] @@ -407,7 +523,8 @@ async fn unsuccessful_declare_set_gas_successful_declare() { .await .unwrap(); assert_tx_succeeded_accepted(&successful_declare_tx.transaction_hash, &devnet.json_rpc_client) - .await; + .await + .unwrap(); } #[tokio::test] diff --git a/tests/integration/test_messaging.rs b/tests/integration/test_messaging.rs index 90d101d3f..03df2a677 100644 --- a/tests/integration/test_messaging.rs +++ b/tests/integration/test_messaging.rs @@ -70,7 +70,7 @@ async fn increase_balance( contract_address: Felt, user: Felt, amount: Felt, -) { +) -> Result<(), anyhow::Error> { let invoke_calls = vec![Call { to: contract_address, selector: get_selector_from_name("increase_balance").unwrap(), @@ -84,18 +84,24 @@ async fn increase_balance( .l2_gas(5e7 as u64) .send() .await - .unwrap(); + .map_err(|err| anyhow::anyhow!("invoke error {:?}", err))?; + Ok(()) } /// Gets the balance for the given user. -async fn get_balance(devnet: &BackgroundDevnet, contract_address: Felt, user: Felt) -> Vec { +async fn get_balance( + devnet: &BackgroundDevnet, + contract_address: Felt, + user: Felt, +) -> Result, anyhow::Error> { let call = FunctionCall { contract_address, entry_point_selector: get_selector_from_name("get_balance").unwrap(), calldata: vec![user], }; - devnet.json_rpc_client.call(call, BlockId::Tag(BlockTag::PreConfirmed)).await.unwrap() + let result = devnet.json_rpc_client.call(call, BlockId::Tag(BlockTag::PreConfirmed)).await?; + Ok(result) } /// Withdraws the given amount from a user and send this amount in a l2->l1 message @@ -137,12 +143,7 @@ async fn deploy_l2_msg_contract( &UdcUniqueness::NotUnique, &constructor_calldata, ); - contract_factory - .deploy_v3(constructor_calldata, salt, false) - .nonce(Felt::ONE) - .send() - .await - .unwrap(); + contract_factory.deploy_v3(constructor_calldata, salt, false).nonce(Felt::ONE).send().await?; Ok(contract_address) } @@ -151,8 +152,11 @@ async fn deploy_l2_msg_contract( /// Returns (devnet instance, account used for deployment, l1-l2 contract address). async fn setup_devnet( devnet_args: &[&str], -) -> (BackgroundDevnet, Arc, LocalWallet>>, Felt) { - let devnet = BackgroundDevnet::spawn_with_additional_args(devnet_args).await.unwrap(); +) -> Result< + (BackgroundDevnet, Arc, LocalWallet>>, Felt), + anyhow::Error, +> { + let devnet = BackgroundDevnet::spawn_with_additional_args(devnet_args).await?; let (signer, account_address) = devnet.get_first_predeployed_account().await; @@ -164,22 +168,44 @@ async fn setup_devnet( ExecutionEncoding::New, )); - let contract_address = deploy_l2_msg_contract(account.clone()).await.unwrap(); + let contract_address = deploy_l2_msg_contract(account.clone()).await?; - (devnet, account, contract_address) + Ok((devnet, account, contract_address)) } -fn assert_accepted_l1_handler_trace(trace: &TransactionTrace) { +fn assert_accepted_l1_handler_trace(trace: &TransactionTrace) -> Result<(), anyhow::Error> { match trace { TransactionTrace::L1Handler(L1HandlerTransactionTrace { function_invocation: ExecuteInvocation::Success(invocation), .. }) => { - assert_eq!(invocation.contract_address.to_hex_string(), MESSAGING_L2_CONTRACT_ADDRESS); - assert_eq!(invocation.entry_point_selector.to_hex_string(), L1_HANDLER_SELECTOR); - assert_eq!(invocation.calldata[0].to_hex_string(), MESSAGING_L1_CONTRACT_ADDRESS); + anyhow::ensure!( + invocation.contract_address.to_hex_string() == MESSAGING_L2_CONTRACT_ADDRESS, + format!( + "assertion `left == right` failed, left: {}, right: {}", + invocation.contract_address.to_hex_string(), + MESSAGING_L2_CONTRACT_ADDRESS + ) + ); + anyhow::ensure!( + invocation.entry_point_selector.to_hex_string() == L1_HANDLER_SELECTOR, + format!( + "assertion `left == right` failed, left: {}, right: {}", + invocation.entry_point_selector.to_hex_string(), + L1_HANDLER_SELECTOR + ) + ); + anyhow::ensure!( + invocation.calldata[0].to_hex_string() == MESSAGING_L1_CONTRACT_ADDRESS, + format!( + "assertion `left == right` failed, left: {}, right: {}", + invocation.calldata[0].to_hex_string(), + MESSAGING_L1_CONTRACT_ADDRESS + ) + ); + Ok(()) } - other => panic!("Invalid trace: {other:?}"), + other => anyhow::bail!("Invalid trace: {other:?}"), } } @@ -190,26 +216,34 @@ async fn assert_withdrawn( to_address: Felt, user: Felt, amount: Felt, -) -> Result<(), RpcError> { - assert_eq!(get_balance(devnet, from_address, user).await, [Felt::ZERO]); +) -> Result<(), anyhow::Error> { + let balance = get_balance(devnet, from_address, user).await?; + anyhow::ensure!( + balance == [Felt::ZERO], + format!("assertion `left == right` failed, left: {:?}, right: {:?}", balance, [Felt::ZERO]) + ); let resp_body = devnet.send_custom_rpc("devnet_postmanFlush", json!({ "dry_run": true })).await?; - assert_eq!( - resp_body, - json!({ - "messages_to_l1": [ - { - "from_address": from_address, - "to_address": to_address, - "payload": [MESSAGE_WITHDRAW_OPCODE, user, amount] - } - ], - "messages_to_l2": [], - "generated_l2_transactions": [], - "l1_provider": "dry run" - }) + let expected_resp = json!({ + "messages_to_l1": [ + { + "from_address": from_address, + "to_address": to_address, + "payload": [MESSAGE_WITHDRAW_OPCODE, user, amount] + } + ], + "messages_to_l2": [], + "generated_l2_transactions": [], + "l1_provider": "dry run" + }); + anyhow::ensure!( + resp_body == expected_resp, + format!( + "assertion `left == right` failed, left: {:?}, right: {:?}", + resp_body, expected_resp + ) ); Ok(()) @@ -218,13 +252,13 @@ async fn assert_withdrawn( #[tokio::test] async fn can_send_message_to_l1() { let (devnet, account, l1l2_contract_address) = - setup_devnet(&["--account-class", "cairo1"]).await; + setup_devnet(&["--account-class", "cairo1"]).await.unwrap(); let user = Felt::ONE; // Set balance to 1 for user. let user_balance = Felt::ONE; - increase_balance(account.clone(), l1l2_contract_address, user, user_balance).await; - assert_eq!(get_balance(&devnet, l1l2_contract_address, user).await, [user_balance]); + increase_balance(account.clone(), l1l2_contract_address, user, user_balance).await.unwrap(); + assert_eq!(get_balance(&devnet, l1l2_contract_address, user).await.unwrap(), [user_balance]); // We don't actually send a message to L1 in this test. let l1_address = DUMMY_L1_ADDRESS; @@ -237,7 +271,7 @@ async fn can_send_message_to_l1() { #[tokio::test] async fn can_send_message_to_l1_from_library_syscall() { let (devnet, account, l1l2_contract_address) = - setup_devnet(&["--account-class", "cairo1"]).await; + setup_devnet(&["--account-class", "cairo1"]).await.unwrap(); // Declare l1l2 lib with only one function to send messages. // Its class hash can then be ignored, it's hardcoded in the contract. @@ -257,8 +291,10 @@ async fn can_send_message_to_l1_from_library_syscall() { // Set balance to 1 for user. let user_balance = Felt::ONE; - increase_balance(Arc::clone(&account), l1l2_contract_address, user, user_balance).await; - assert_eq!(get_balance(&devnet, l1l2_contract_address, user).await, [user_balance]); + increase_balance(Arc::clone(&account), l1l2_contract_address, user, user_balance) + .await + .unwrap(); + assert_eq!(get_balance(&devnet, l1l2_contract_address, user).await.unwrap(), [user_balance]); // We don't actually send a message to the L1 in this test. let l1_address = DUMMY_L1_ADDRESS; @@ -281,13 +317,13 @@ async fn can_send_message_to_l1_from_library_syscall() { #[tokio::test] async fn mock_message_to_l2_creates_a_tx_with_desired_effect() { let (devnet, account, l1l2_contract_address) = - setup_devnet(&["--account-class", "cairo1"]).await; + setup_devnet(&["--account-class", "cairo1"]).await.unwrap(); let user = Felt::ONE; // Set balance to 1 for user. let user_balance = Felt::ONE; - increase_balance(account, l1l2_contract_address, user, user_balance).await; - assert_eq!(get_balance(&devnet, l1l2_contract_address, user).await, [user_balance]); + increase_balance(account, l1l2_contract_address, user, user_balance).await.unwrap(); + assert_eq!(get_balance(&devnet, l1l2_contract_address, user).await.unwrap(), [user_balance]); // Use postman to send a message to l2 without l1 - the message increments user balance let increment_amount = Felt::from_hex_unchecked("0xff"); @@ -303,11 +339,11 @@ async fn mock_message_to_l2_creates_a_tx_with_desired_effect() { .await.unwrap(); let tx_hash_hex = body.get("transaction_hash").unwrap().as_str().unwrap(); let tx_hash = Felt::from_hex_unchecked(tx_hash_hex); - assert_tx_succeeded_accepted(&tx_hash, &devnet.json_rpc_client).await; + assert_tx_succeeded_accepted(&tx_hash, &devnet.json_rpc_client).await.unwrap(); // assert state changed assert_eq!( - get_balance(&devnet, l1l2_contract_address, user).await, + get_balance(&devnet, l1l2_contract_address, user).await.unwrap(), [user_balance + increment_amount] ); @@ -337,7 +373,7 @@ async fn mock_message_to_l2_creates_a_tx_with_desired_effect() { async fn can_deploy_l1_messaging_contract() { let anvil = BackgroundAnvil::spawn().await.unwrap(); - let (devnet, _, _) = setup_devnet(&["--account-class", "cairo1"]).await; + let (devnet, _, _) = setup_devnet(&["--account-class", "cairo1"]).await.unwrap(); let body = devnet .send_custom_rpc("devnet_postmanLoad", json!({ "network_url": anvil.url })) @@ -431,13 +467,13 @@ async fn setup_anvil_incorrect_eth_private_key() { .await .unwrap(); - let (devnet, _, _) = setup_devnet(&["--account-class", "cairo1"]).await; + let (devnet, _, _) = setup_devnet(&["--account-class", "cairo1"]).await.unwrap(); let body = devnet .send_custom_rpc("devnet_postmanLoad", json!({ "network_url": anvil.url })) .await .unwrap_err(); - assert_contains(&body.message, "CallGasCostMoreThanGasLimit"); + assert_contains(&body.message, "CallGasCostMoreThanGasLimit").unwrap(); let body = devnet .send_custom_rpc( @@ -449,7 +485,7 @@ async fn setup_anvil_incorrect_eth_private_key() { ) .await .unwrap_err(); - assert_contains(&body.message, "CallGasCostMoreThanGasLimit"); + assert_contains(&body.message, "CallGasCostMoreThanGasLimit").unwrap(); } #[tokio::test] @@ -462,7 +498,7 @@ async fn deploy_l1_messaging_contract_with_custom_key() { .await .unwrap(); - let (devnet, _, _) = setup_devnet(&["--account-class", "cairo1"]).await; + let (devnet, _, _) = setup_devnet(&["--account-class", "cairo1"]).await.unwrap(); let body = devnet .send_custom_rpc( @@ -484,20 +520,20 @@ async fn deploy_l1_messaging_contract_with_custom_key() { #[tokio::test] async fn can_consume_from_l2() { let (devnet, account, l1l2_contract_address) = - setup_devnet(&["--account-class", "cairo1"]).await; + setup_devnet(&["--account-class", "cairo1"]).await.unwrap(); let user = Felt::ONE; // Set balance to 1 for user. let user_balance = Felt::ONE; - increase_balance(account.clone(), l1l2_contract_address, user, user_balance).await; - assert_eq!(get_balance(&devnet, l1l2_contract_address, user).await, [user_balance]); + increase_balance(account.clone(), l1l2_contract_address, user, user_balance).await.unwrap(); + assert_eq!(get_balance(&devnet, l1l2_contract_address, user).await.unwrap(), [user_balance]); // We don't need valid l1 address as we don't use L1 node. let l1_address = DUMMY_L1_ADDRESS; // Withdraw the 1 amount in a l2->l1 message. withdraw(account, l1l2_contract_address, user, user_balance, l1_address).await.unwrap(); - assert_eq!(get_balance(&devnet, l1l2_contract_address, user).await, [Felt::ZERO]); + assert_eq!(get_balance(&devnet, l1l2_contract_address, user).await.unwrap(), [Felt::ZERO]); let body = devnet .send_custom_rpc( @@ -528,7 +564,8 @@ async fn can_interact_with_l1() { "--dump-on", "exit", ]) - .await; + .await + .unwrap(); // Load l1 messaging contract. let body: serde_json::Value = devnet @@ -552,14 +589,14 @@ async fn can_interact_with_l1() { // Set balance to 1 for the user 1 on L2. let user_balance = Felt::ONE; - increase_balance(sn_account.clone(), sn_l1l2_contract, user_sn, user_balance).await; - assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await, [user_balance]); + increase_balance(sn_account.clone(), sn_l1l2_contract, user_sn, user_balance).await.unwrap(); + assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await.unwrap(), [user_balance]); // Withdraw the amount 1 from user 1 balance on L2 to send it on L1 with a l2->l1 message. withdraw(sn_account, sn_l1l2_contract, user_sn, user_balance, eth_l1l2_address_felt) .await .unwrap(); - assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await, [Felt::ZERO]); + assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await.unwrap(), [Felt::ZERO]); // Flush to send the messages. devnet.send_custom_rpc("devnet_postmanFlush", json!({})).await.expect("flush failed"); @@ -583,7 +620,7 @@ async fn can_interact_with_l1() { // Balances on both layers is 0 at this point. assert_eq!(user_balance_eth, 0.into()); - assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await, [Felt::ZERO]); + assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await.unwrap(), [Felt::ZERO]); // Flush messages to have MessageToL2 executed. let flush_resp = devnet.send_custom_rpc("devnet_postmanFlush", json!({})).await.unwrap(); @@ -592,10 +629,10 @@ async fn can_interact_with_l1() { let generated_l2_tx = Felt::from_hex_unchecked(generated_l2_txs[0].as_str().unwrap()); // Ensure the balance is back to 1 on L2. - assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await, [Felt::ONE]); + assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await.unwrap(), [Felt::ONE]); let l1_handler_trace = devnet.json_rpc_client.trace_transaction(generated_l2_tx).await.unwrap(); - assert_accepted_l1_handler_trace(&l1_handler_trace); + assert_accepted_l1_handler_trace(&l1_handler_trace).unwrap(); send_ctrl_c_signal_and_wait(&devnet.process).await; @@ -611,7 +648,7 @@ async fn can_interact_with_l1() { let l1_handler_trace_loaded = loaded_devnet.json_rpc_client.trace_transaction(generated_l2_tx).await.unwrap(); - assert_accepted_l1_handler_trace(&l1_handler_trace_loaded); + assert_accepted_l1_handler_trace(&l1_handler_trace_loaded).unwrap(); } #[tokio::test] @@ -625,13 +662,19 @@ async fn assert_l1_handler_tx_can_be_dumped_and_loaded() { "--dump-path", &dump_file.path, ]) - .await; + .await + .unwrap(); // Set balance for user let user = Felt::ONE; let user_balance = Felt::ONE; - increase_balance(Arc::clone(&account), l1l2_contract_address, user, user_balance).await; - assert_eq!(get_balance(&dumping_devnet, l1l2_contract_address, user).await, [user_balance]); + increase_balance(Arc::clone(&account), l1l2_contract_address, user, user_balance) + .await + .unwrap(); + assert_eq!( + get_balance(&dumping_devnet, l1l2_contract_address, user).await.unwrap(), + [user_balance] + ); // Use postman to send a message to l2 without l1 - the message increments user balance let increment_amount = Felt::from(0xff); @@ -652,7 +695,7 @@ async fn assert_l1_handler_tx_can_be_dumped_and_loaded() { .unwrap(); assert_eq!( - get_balance(&dumping_devnet, l1l2_contract_address, user).await, + get_balance(&dumping_devnet, l1l2_contract_address, user).await.unwrap(), [user_balance + increment_amount] ); @@ -668,7 +711,7 @@ async fn assert_l1_handler_tx_can_be_dumped_and_loaded() { .unwrap(); assert_eq!( - get_balance(&loading_devnet, l1l2_contract_address, user).await, + get_balance(&loading_devnet, l1l2_contract_address, user).await.unwrap(), [user_balance + increment_amount] ); } @@ -676,7 +719,7 @@ async fn assert_l1_handler_tx_can_be_dumped_and_loaded() { #[tokio::test] async fn test_correct_message_order() { let anvil = BackgroundAnvil::spawn_with_additional_args(&["--block-time", "1"]).await.unwrap(); - let (devnet, sn_account, sn_l1l2_contract) = setup_devnet(&[]).await; + let (devnet, sn_account, sn_l1l2_contract) = setup_devnet(&[]).await.unwrap(); // Load l1 messaging contract. let load_resp: serde_json::Value = devnet @@ -700,7 +743,9 @@ async fn test_correct_message_order() { // Set balance for the user on L2. let init_balance = 5_u64; - increase_balance(sn_account.clone(), sn_l1l2_contract, user_sn, init_balance.into()).await; + increase_balance(sn_account.clone(), sn_l1l2_contract, user_sn, init_balance.into()) + .await + .unwrap(); // Withdraw the set amount from user 1 balance on L2 to send it on L1 with a l2->l1 message. withdraw(sn_account, sn_l1l2_contract, user_sn, init_balance.into(), eth_l1l2_address_felt) @@ -762,8 +807,8 @@ async fn test_dumpability_of_messaging_contract_loading() { send_ctrl_c_signal_and_wait(&anvil.process).await; match devnet.send_custom_rpc("devnet_load", json!({ "path": dump_file.path })).await { Err(RpcError { message, .. }) => { - assert_contains(&message, "error sending request for url"); - assert_contains(&message, &anvil.url); + assert_contains(&message, "error sending request for url").unwrap(); + assert_contains(&message, &anvil.url).unwrap(); } other => panic!("Unexpected response: {other:?}"), }; @@ -772,7 +817,7 @@ async fn test_dumpability_of_messaging_contract_loading() { #[tokio::test] async fn flushing_only_new_messages_after_restart() { let anvil = BackgroundAnvil::spawn().await.unwrap(); - let (devnet, sn_account, sn_l1l2_contract) = setup_devnet(&[]).await; + let (devnet, sn_account, sn_l1l2_contract) = setup_devnet(&[]).await.unwrap(); // Load l1 messaging contract. let load_resp = devnet @@ -796,14 +841,14 @@ async fn flushing_only_new_messages_after_restart() { // Set balance to for the user 1 on L2. let user_balance = Felt::TWO; - increase_balance(sn_account.clone(), sn_l1l2_contract, user_sn, user_balance).await; - assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await, [user_balance]); + increase_balance(sn_account.clone(), sn_l1l2_contract, user_sn, user_balance).await.unwrap(); + assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await.unwrap(), [user_balance]); // Withdraw on L2 to send it to L1 with a l2->l1 message. withdraw(sn_account.clone(), sn_l1l2_contract, user_sn, user_balance, eth_l1l2_address_felt) .await .unwrap(); - assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await, [Felt::ZERO]); + assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await.unwrap(), [Felt::ZERO]); // Flush to send the messages. devnet.send_custom_rpc("devnet_postmanFlush", json!({})).await.unwrap(); @@ -837,14 +882,14 @@ async fn flushing_only_new_messages_after_restart() { let user_balance_eth = anvil.get_balance_l1l2(eth_l1l2_address, user_eth).await.unwrap(); assert_eq!(user_balance_eth, 1.into()); // 2 - 1 - assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await, [Felt::ZERO]); + assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await.unwrap(), [Felt::ZERO]); // Flush messages to have MessageToL2 executed. devnet.send_custom_rpc("devnet_postmanFlush", json!({})).await.unwrap(); let user_balance_eth = anvil.get_balance_l1l2(eth_l1l2_address, user_eth).await.unwrap(); assert_eq!(user_balance_eth, deposit_amount.into()); - assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await, [Felt::ONE]); + assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await.unwrap(), [Felt::ONE]); // Restart Devnet, l1-l2 messaging should be intact devnet.restart().await; @@ -858,7 +903,7 @@ async fn flushing_only_new_messages_after_restart() { // Redeploy let sn_l1l2_contract = deploy_l2_msg_contract(sn_account).await.unwrap(); let sn_l1l2_contract_u256 = felt_to_u256(sn_l1l2_contract); - assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await, [Felt::ZERO]); + assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await.unwrap(), [Felt::ZERO]); // Trigger a new action to return funds to L2 anvil @@ -869,15 +914,15 @@ async fn flushing_only_new_messages_after_restart() { // After depositing, there should be no funds on L1; also no funds on L2 before flushing. let user_balance_eth = anvil.get_balance_l1l2(eth_l1l2_address, user_eth).await.unwrap(); assert_eq!(user_balance_eth, 0.into()); // 2 - 1 - 1 - assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await, [Felt::ZERO]); + assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await.unwrap(), [Felt::ZERO]); devnet.send_custom_rpc("devnet_postmanFlush", json!({})).await.unwrap(); - assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await, [Felt::ONE]); + assert_eq!(get_balance(&devnet, sn_l1l2_contract, user_sn).await.unwrap(), [Felt::ONE]); } #[tokio::test] async fn test_getting_status_of_mock_message() { - let (devnet, _, l1l2_contract_address) = setup_devnet(&[]).await; + let (devnet, _, l1l2_contract_address) = setup_devnet(&[]).await.unwrap(); // Use postman to send a message to l2 without l1 - the message increments user balance let increment_amount = Felt::from(0xff); @@ -896,7 +941,10 @@ async fn test_getting_status_of_mock_message() { let mock_msg_resp = devnet.send_custom_rpc("devnet_postmanSendMessageToL2", mock_msg_body).await.unwrap(); - assert_eq!(get_balance(&devnet, l1l2_contract_address, user).await, [increment_amount]); + assert_eq!( + get_balance(&devnet, l1l2_contract_address, user).await.unwrap(), + [increment_amount] + ); let messages_status = devnet .send_custom_rpc("starknet_getMessagesStatus", json!({ "transaction_hash": l1_tx_hash })) @@ -916,7 +964,7 @@ async fn test_getting_status_of_mock_message() { #[tokio::test] async fn test_getting_status_of_real_message() { let anvil = BackgroundAnvil::spawn().await.unwrap(); - let (devnet, sn_account, sn_l1l2_contract) = setup_devnet(&[]).await; + let (devnet, sn_account, sn_l1l2_contract) = setup_devnet(&[]).await.unwrap(); // Load l1 messaging contract. let body: serde_json::Value = devnet @@ -939,7 +987,7 @@ async fn test_getting_status_of_real_message() { // Set balance to 1 for the user 1 on L2 and withdraw to L1. let user_sn = Felt::ONE; let user_balance = Felt::ONE; - increase_balance(sn_account.clone(), sn_l1l2_contract, user_sn, user_balance).await; + increase_balance(sn_account.clone(), sn_l1l2_contract, user_sn, user_balance).await.unwrap(); withdraw(sn_account, sn_l1l2_contract, user_sn, user_balance, eth_l1l2_address_felt) .await .unwrap(); @@ -957,9 +1005,10 @@ async fn test_getting_status_of_real_message() { anvil.deposit_l1l2(eth_l1l2_address, sn_l1l2_contract_u256, user_eth, 1.into()).await.unwrap(); // Flush to trigger L2 transaction generation. - let generated_l2_txs_raw = - &devnet.send_custom_rpc("devnet_postmanFlush", json!({})).await.unwrap() - ["generated_l2_transactions"]; + let generated_l2_txs_raw = &devnet + .send_custom_rpc("devnet_postmanFlush", json!({})) + .await + .unwrap()["generated_l2_transactions"]; let generated_l2_txs = generated_l2_txs_raw.as_array().unwrap(); assert_eq!(generated_l2_txs.len(), 1); let generated_l2_tx = &generated_l2_txs[0]; @@ -994,13 +1043,13 @@ async fn test_getting_status_of_real_message() { #[tokio::test] async fn withdrawing_should_incur_l1_gas_cost() { let (devnet, account, l1l2_contract_address) = - setup_devnet(&["--account-class", "cairo1"]).await; + setup_devnet(&["--account-class", "cairo1"]).await.unwrap(); let user = Felt::ONE; // Set balance to 1 for user. let user_balance = Felt::ONE; - increase_balance(account.clone(), l1l2_contract_address, user, user_balance).await; - assert_eq!(get_balance(&devnet, l1l2_contract_address, user).await, [user_balance]); + increase_balance(account.clone(), l1l2_contract_address, user, user_balance).await.unwrap(); + assert_eq!(get_balance(&devnet, l1l2_contract_address, user).await.unwrap(), [user_balance]); // We don't actually send a message to L1 in this test. let l1_address = DUMMY_L1_ADDRESS; @@ -1036,7 +1085,7 @@ async fn withdrawing_should_incur_l1_gas_cost() { TransactionReceipt::Invoke(InvokeTransactionReceipt { execution_result: ExecutionResult::Reverted { reason }, .. - }) => assert_contains(&reason, "Insufficient max L1Gas"), + }) => assert_contains(&reason, "Insufficient max L1Gas").unwrap(), other => panic!("Unexpected receipt: {other:?}"), } } diff --git a/tests/integration/test_minting.rs b/tests/integration/test_minting.rs index f57df9a87..592f58dc6 100644 --- a/tests/integration/test_minting.rs +++ b/tests/integration/test_minting.rs @@ -1,3 +1,4 @@ +use anyhow::anyhow; use serde_json::json; use starknet_rs_core::types::Felt; @@ -13,7 +14,7 @@ async fn increase_balance_happy_path( init_amount: u128, mint_amount: u128, unit: FeeUnit, -) { +) -> Result<(), anyhow::Error> { let devnet = BackgroundDevnet::spawn().await.expect("Could not start Devnet"); let mut resp_body: serde_json::Value = devnet @@ -25,36 +26,44 @@ async fn increase_balance_happy_path( "unit": unit, }), ) - .await - .unwrap(); + .await?; // tx hash is not constant so we just assert its general form let tx_hash_value = resp_body["tx_hash"].take(); - assert!(tx_hash_value.as_str().unwrap().starts_with("0x")); + let tx_hash = tx_hash_value + .as_str() + .ok_or(anyhow!("failed to parse transaction hash"))? + .starts_with("0x"); + anyhow::ensure!(tx_hash, "Transaction hash does not start with '0x'"); let final_balance = Felt::from(init_amount) + Felt::from(mint_amount); - assert_eq!( - resp_body, - json!({ - "new_balance": final_balance.to_biguint().to_string(), - "unit": unit, - "tx_hash": null - }) + let expected_resp_body = json!({ + "new_balance": final_balance.to_biguint().to_string(), + "unit": unit, + "tx_hash": null + }); + anyhow::ensure!( + resp_body == expected_resp_body, + format!("assertion `left == right` failed, left: {resp_body}, right: {expected_resp_body}") ); let new_balance = devnet.get_balance_latest(&Felt::from_hex_unchecked(address), unit).await.unwrap(); - assert_eq!(final_balance, new_balance); + anyhow::ensure!( + final_balance == new_balance, + format!("assertion `left == right` failed, left: {final_balance}, right: {new_balance}") + ); + Ok(()) } #[tokio::test] async fn increase_balance_of_undeployed_address_wei() { - increase_balance_happy_path(DUMMY_ADDRESS, 0, DUMMY_AMOUNT, FeeUnit::Wei).await; + increase_balance_happy_path(DUMMY_ADDRESS, 0, DUMMY_AMOUNT, FeeUnit::Wei).await.unwrap(); } #[tokio::test] async fn increase_balance_of_undeployed_address_fri() { - increase_balance_happy_path(DUMMY_ADDRESS, 0, DUMMY_AMOUNT, FeeUnit::Fri).await; + increase_balance_happy_path(DUMMY_ADDRESS, 0, DUMMY_AMOUNT, FeeUnit::Fri).await.unwrap(); } #[tokio::test] @@ -89,6 +98,7 @@ async fn increase_balance_of_predeployed_account() { FeeUnit::Wei, ) .await + .unwrap() } #[tokio::test] @@ -100,6 +110,7 @@ async fn increase_balance_of_predeployed_account_u256() { FeeUnit::Wei, ) .await + .unwrap() } #[tokio::test] diff --git a/tests/integration/test_old_state.rs b/tests/integration/test_old_state.rs index b2d29cd0c..b0b47ea43 100644 --- a/tests/integration/test_old_state.rs +++ b/tests/integration/test_old_state.rs @@ -213,7 +213,7 @@ async fn fee_estimation_and_simulation_of_deployment_at_old_block_should_not_yie ProviderError::StarknetError(StarknetError::TransactionExecutionError( TransactionExecutionErrorData { execution_error, .. }, )) => { - let account_error = extract_nested_error(&execution_error); + let account_error = extract_nested_error(&execution_error).unwrap(); assert_eq!(account_error.selector, get_selector_from_name("__execute__").unwrap()); assert_eq!(account_error.contract_address, account.address()); @@ -225,16 +225,16 @@ async fn fee_estimation_and_simulation_of_deployment_at_old_block_should_not_yie .unwrap(); assert_eq!(account_error.class_hash, account_class_hash); - let udc_error = extract_nested_error(&account_error.error); + let udc_error = extract_nested_error(&account_error.error).unwrap(); assert_eq!(udc_error.contract_address, UDC_LEGACY_CONTRACT_ADDRESS); assert_eq!(udc_error.selector, udc_selector); assert_eq!(udc_error.class_hash, UDC_LEGACY_CONTRACT_CLASS_HASH); - let error_at_to_be_deployed_address = extract_nested_error(&udc_error.error); + let error_at_to_be_deployed_address = extract_nested_error(&udc_error.error).unwrap(); assert_eq!(error_at_to_be_deployed_address.class_hash, class_hash); assert_eq!(error_at_to_be_deployed_address.selector, Felt::ZERO); - let error_msg = extract_message_error(&error_at_to_be_deployed_address.error); + let error_msg = extract_message_error(&error_at_to_be_deployed_address.error).unwrap(); assert_eq!(error_msg.trim(), &expected_error_msg) } other => panic!("Unexpected error: {other:?}"), diff --git a/tests/integration/test_restart.rs b/tests/integration/test_restart.rs index ee966da09..d191151d4 100644 --- a/tests/integration/test_restart.rs +++ b/tests/integration/test_restart.rs @@ -93,7 +93,10 @@ async fn assert_account_deployment_reverted() { let deployment_tx = deployment.send().await.unwrap(); // assert deployment successful and class associated with deployment address is present - assert_tx_succeeded_accepted(&deployment_tx.transaction_hash, &devnet.json_rpc_client).await; + assert_tx_succeeded_accepted(&deployment_tx.transaction_hash, &devnet.json_rpc_client) + .await + .unwrap(); + devnet .json_rpc_client .get_class_at(BlockId::Tag(BlockTag::Latest), deployment_address) diff --git a/tests/integration/test_simulate_transactions.rs b/tests/integration/test_simulate_transactions.rs index 6d0cee7ac..0ebb845e7 100644 --- a/tests/integration/test_simulate_transactions.rs +++ b/tests/integration/test_simulate_transactions.rs @@ -485,7 +485,7 @@ async fn test_simulation_of_panicking_invoke() { execute_invocation: ExecuteInvocation::Reverted(reverted_invocation), .. }) => { - assert_contains(&reverted_invocation.revert_reason, panic_message_text); + assert_contains(&reverted_invocation.revert_reason, panic_message_text).unwrap(); } other_trace => panic!("Unexpected trace {other_trace:?}"), } @@ -577,7 +577,7 @@ async fn simulate_of_multiple_txs_shouldnt_return_an_error_if_invoke_transaction TransactionTrace::Invoke(InvokeTransactionTrace { execute_invocation: ExecuteInvocation::Reverted(reverted_invocation), .. - }) => assert_contains(&reverted_invocation.revert_reason, "ENTRYPOINT_NOT_FOUND"), + }) => assert_contains(&reverted_invocation.revert_reason, "ENTRYPOINT_NOT_FOUND").unwrap(), other_trace => panic!("Unexpected trace {:?}", other_trace), } } @@ -709,7 +709,7 @@ async fn simulate_with_gas_bounds_exceeding_balance_returns_error_if_charging_no execution_error, .. }), - )) => assert_contains(&format!("{:?}", execution_error), "exceed balance"), + )) => assert_contains(&format!("{:?}", execution_error), "exceed balance").unwrap(), other => panic!("Unexpected error {other:?}"), } @@ -936,7 +936,7 @@ async fn simulate_invoke_v3_with_fee_just_below_estimated_should_return_a_trace_ TransactionTrace::Invoke(InvokeTransactionTrace { execute_invocation: ExecuteInvocation::Reverted(reverted_invocation), .. - }) => assert_contains(&reverted_invocation.revert_reason, "Insufficient"), + }) => assert_contains(&reverted_invocation.revert_reason, "Insufficient").unwrap(), other => panic!("Unexpected trace {other:?}"), } } @@ -1117,7 +1117,7 @@ async fn simulate_invoke_v3_with_failing_execution_should_return_a_trace_of_reve TransactionTrace::Invoke(InvokeTransactionTrace { execute_invocation: ExecuteInvocation::Reverted(reverted_invocation), .. - }) => assert_contains(&reverted_invocation.revert_reason, panic_reason), + }) => assert_contains(&reverted_invocation.revert_reason, panic_reason).unwrap(), other => panic!("Unexpected trace {other:?}"), } } diff --git a/tests/integration/test_subscription_to_blocks.rs b/tests/integration/test_subscription_to_blocks.rs index 9d6184809..35831534b 100644 --- a/tests/integration/test_subscription_to_blocks.rs +++ b/tests/integration/test_subscription_to_blocks.rs @@ -43,7 +43,7 @@ async fn should_not_receive_block_notification_if_not_subscribed() { let (mut ws, _) = connect_async(devnet.ws_url()).await.unwrap(); devnet.create_block().await.unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -89,7 +89,7 @@ async fn subscription_to_an_old_block_by_number_should_notify_of_all_blocks_up_t assert_eq!(notification_block["block_number"], json!(block_i)); } - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -116,7 +116,7 @@ async fn subscription_to_an_old_block_by_hash_should_notify_of_all_blocks_up_to_ assert_eq!(notification_block["block_number"], json!(block_i)); } - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -137,11 +137,11 @@ async fn assert_latest_block_is_default() { let notification_block_latest = receive_block(&mut ws_latest, subscription_id_latest).await.unwrap(); - assert_no_notifications(&mut ws_latest).await; + assert_no_notifications(&mut ws_latest).await.unwrap(); let notification_block_default = receive_block(&mut ws_default, subscription_id_default).await.unwrap(); - assert_no_notifications(&mut ws_default).await; + assert_no_notifications(&mut ws_default).await.unwrap(); assert_eq!(notification_block_latest, notification_block_default); } @@ -177,7 +177,7 @@ async fn test_multiple_subscribers_one_unsubscribes() { assert_eq!(notification_block["block_hash"], json!(created_block_hash)); } - assert_no_notifications(&mut unsubscriber_ws).await; + assert_no_notifications(&mut unsubscriber_ws).await.unwrap(); } #[tokio::test] @@ -213,7 +213,7 @@ async fn read_only_methods_do_not_generate_notifications() { .await .unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -227,7 +227,7 @@ async fn test_notifications_in_block_on_demand_mode() { let dummy_address = 0x1; devnet.mint(dummy_address, 1).await; - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); let created_block_hash = devnet.create_block().await.unwrap(); diff --git a/tests/integration/test_subscription_to_events.rs b/tests/integration/test_subscription_to_events.rs index ff8d9963d..ef81542de 100644 --- a/tests/integration/test_subscription_to_events.rs +++ b/tests/integration/test_subscription_to_events.rs @@ -103,12 +103,12 @@ async fn event_subscription_with_no_params_until_unsubscription() { ); receive_rpc_via_ws(&mut ws).await.unwrap(); // erc20 - fee charge - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); unsubscribe(&mut ws, subscription_id).await.unwrap(); emit_static_event(&account, contract_address).await.unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -139,7 +139,7 @@ async fn should_notify_only_from_filtered_address() { }) ); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -170,7 +170,7 @@ async fn should_notify_of_new_events_only_from_filtered_key() { }) ); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -200,7 +200,7 @@ async fn should_notify_if_already_in_latest_block_in_on_tx_mode() { }) ); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -245,8 +245,8 @@ async fn should_notify_only_once_for_pre_confirmed_in_on_demand_mode() { // Should not re-notify on pre_confirmed->latest devnet.create_block().await.unwrap(); - assert_no_notifications(&mut ws_before).await; - assert_no_notifications(&mut ws_after).await; + assert_no_notifications(&mut ws_before).await.unwrap(); + assert_no_notifications(&mut ws_after).await.unwrap(); } #[tokio::test] @@ -311,8 +311,8 @@ async fn should_notify_only_once_for_accepted_on_l2_in_on_demand_mode( subscribe_events(&mut ws_after, subscription_request).await.unwrap(); // No notifications before block creation and conversion from pre-confirmed to accepted_on_l2 - assert_no_notifications(&mut ws_before).await; - assert_no_notifications(&mut ws_after).await; + assert_no_notifications(&mut ws_before).await.unwrap(); + assert_no_notifications(&mut ws_after).await.unwrap(); let created_block_hash = devnet.create_block().await.unwrap(); for (ws, subscription_id) in @@ -335,8 +335,8 @@ async fn should_notify_only_once_for_accepted_on_l2_in_on_demand_mode( // Should not re-notify on next block devnet.create_block().await.unwrap(); - assert_no_notifications(&mut ws_before).await; - assert_no_notifications(&mut ws_after).await; + assert_no_notifications(&mut ws_before).await.unwrap(); + assert_no_notifications(&mut ws_after).await.unwrap(); } #[tokio::test] @@ -389,7 +389,7 @@ async fn should_notify_of_events_in_old_blocks_with_no_filters() { assert_eq!(invocation_fee_event["block_number"], latest_block.block_number); assert_eq!(invocation_fee_event["from_address"], json!(STRK_ERC20_CONTRACT_ADDRESS)); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -422,7 +422,7 @@ async fn should_notify_of_old_and_new_events_with_address_filter() { "finality_status": TransactionFinalityStatus::AcceptedOnL2, }) ); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); // new event (after subscription) let new_invocation = emit_static_event(&account, contract_address).await.unwrap(); @@ -440,7 +440,7 @@ async fn should_notify_of_old_and_new_events_with_address_filter() { "finality_status": TransactionFinalityStatus::AcceptedOnL2, }) ); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -473,7 +473,7 @@ async fn should_notify_of_old_and_new_events_with_key_filter() { "finality_status": TransactionFinalityStatus::AcceptedOnL2, }) ); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); // new event (after subscription) let new_invocation = emit_static_event(&account, contract_address).await.unwrap(); @@ -491,7 +491,7 @@ async fn should_notify_of_old_and_new_events_with_key_filter() { "finality_status": TransactionFinalityStatus::AcceptedOnL2, }) ); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -507,7 +507,7 @@ async fn should_not_notify_of_events_in_too_old_blocks() { subscribe_events(&mut ws, json!({ "block_id": BlockId::Hash(last_block_hash) })).await.unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -550,5 +550,5 @@ async fn should_notify_of_events_in_old_blocks() { assert_eq!(received_tx_hashes_from_events, txs_with_invocation_events); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } diff --git a/tests/integration/test_subscription_to_new_tx_receipts.rs b/tests/integration/test_subscription_to_new_tx_receipts.rs index 72782f5cb..2b28d289c 100644 --- a/tests/integration/test_subscription_to_new_tx_receipts.rs +++ b/tests/integration/test_subscription_to_new_tx_receipts.rs @@ -48,7 +48,7 @@ async fn should_not_notify_in_block_on_demand_mode_if_default_subscription_param // No notifications because default finality_status is ACCEPTED_ON_L2 subscribe_new_tx_receipts(&mut ws, json!({})).await.unwrap(); send_dummy_mint_tx(&devnet).await; - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -69,7 +69,7 @@ async fn should_notify_of_pre_confirmed_txs_with_block_generation_on_demand() { assert_eq!(extracted_receipt.transaction_hash, tx_hash); assert_eq!(extracted_receipt.finality_status, finality_status); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -100,7 +100,7 @@ async fn should_notify_of_accepted_on_l2_with_block_generation_on_tx() { serde_json::from_value(receipt_notification).unwrap(); assert_eq!(extracted_receipt.transaction_hash, tx_hash); assert_eq!(extracted_receipt.finality_status, finality_status); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } } @@ -125,7 +125,7 @@ async fn should_notify_for_multiple_subscribers_with_default_params() { assert_eq!(extracted_receipt.transaction_hash, tx_hash); assert_eq!(extracted_receipt.finality_status, finality_status); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } } @@ -150,7 +150,7 @@ async fn should_stop_notifying_after_unsubscription() { send_dummy_mint_tx(&devnet).await; for (mut ws, _) in subscribers { - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } } @@ -174,7 +174,7 @@ async fn should_work_with_subscription_to_receipts_and_txs() { assert_eq!(receipt.transaction_hash(), &tx_hash); } - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -213,7 +213,7 @@ async fn should_notify_for_filtered_address() { serde_json::from_value(deployment_notification).unwrap(); assert_eq!(deployment_receipt.finality_status, TransactionFinalityStatus::AcceptedOnL2); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -227,7 +227,7 @@ async fn should_not_notify_if_filtered_address_not_matched() { send_dummy_mint_tx(&devnet).await; // nothing matched since minting is done via the Chargeable account - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -246,7 +246,7 @@ async fn should_not_notify_if_tx_by_filtered_address_already_in_pre_confirmed_bl ] { let (mut ws, _) = connect_async(devnet.ws_url()).await.unwrap(); subscribe_new_tx_receipts(&mut ws, subscription_params).await.unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } } @@ -268,7 +268,7 @@ async fn should_not_notify_if_tx_by_filtered_address_in_latest_block_in_on_deman .await .unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -289,7 +289,7 @@ async fn should_not_notify_if_tx_by_filtered_address_in_latest_block_in_on_tx_mo .await .unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -306,7 +306,7 @@ async fn should_not_notify_if_tx_already_in_latest_block_in_on_demand_mode() { subscribe_new_tx_receipts(&mut ws, json!({ "finality_status": [finality_status] })) .await .unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -324,7 +324,7 @@ async fn should_not_notify_if_tx_already_in_latest_block_in_on_tx_mode() { subscribe_new_tx_receipts(&mut ws, json!({ "finality_status": [finality_status] })) .await .unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } } @@ -347,7 +347,7 @@ async fn should_not_notify_on_read_request_if_txs_in_pre_confirmed_block() { let dummy_address = Felt::ONE; devnet.get_balance_latest(&dummy_address, FeeUnit::Wei).await.unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -373,11 +373,11 @@ async fn should_notify_twice_if_subscribed_to_both_finality_statuses() { assert_eq!(extracted_receipt.transaction_hash, tx_hash); assert_eq!(extracted_receipt.finality_status, finality_status); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); devnet.create_block().await.unwrap(); // On first loop iteration, this changes tx status } - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -400,5 +400,5 @@ async fn test_deploy_account_receipt_notification() { &deployment_result.transaction_hash ); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } diff --git a/tests/integration/test_subscription_to_new_txs.rs b/tests/integration/test_subscription_to_new_txs.rs index 6dd1c16b7..c4d632f46 100644 --- a/tests/integration/test_subscription_to_new_txs.rs +++ b/tests/integration/test_subscription_to_new_txs.rs @@ -24,7 +24,7 @@ async fn should_not_notify_in_block_on_demand_mode_if_default_subscription_param // No notifications because default finality_status is ACCEPTED_ON_L2 subscribe_new_txs(&mut ws, json!({})).await.unwrap(); send_dummy_mint_tx(&devnet).await; - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -44,7 +44,7 @@ async fn should_notify_of_pre_confirmed_txs_with_block_generation_on_demand() { let extracted_tx: Transaction = serde_json::from_value(notification_tx).unwrap(); assert_eq!(extracted_tx.transaction_hash(), &tx_hash); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -71,7 +71,7 @@ async fn should_notify_of_accepted_on_l2_with_block_generation_on_tx() { assert_eq!(notification_tx["finality_status"].take(), json!(finality_status)); let extracted_tx: Transaction = serde_json::from_value(notification_tx).unwrap(); assert_eq!(extracted_tx.transaction_hash(), &tx_hash); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } } @@ -95,7 +95,7 @@ async fn should_notify_for_multiple_subscribers_with_default_params() { let extracted_tx: Transaction = serde_json::from_value(notification_tx).unwrap(); assert_eq!(extracted_tx.transaction_hash(), &tx_hash); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } } @@ -120,7 +120,7 @@ async fn should_stop_notifying_after_unsubscription() { send_dummy_mint_tx(&devnet).await; for (mut ws, _) in subscribers { - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } } @@ -158,7 +158,7 @@ async fn should_notify_for_filtered_address() { serde_json::from_value(deployment_notification).unwrap(); assert_eq!(deployment_tx.nonce, Felt::ONE); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -172,7 +172,7 @@ async fn should_not_notify_if_filtered_address_not_matched() { send_dummy_mint_tx(&devnet).await; // nothing matched since minting is done via the Chargeable account - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -191,7 +191,7 @@ async fn should_not_notify_if_tx_by_filtered_address_already_in_pre_confirmed_bl ] { let (mut ws, _) = connect_async(devnet.ws_url()).await.unwrap(); subscribe_new_txs(&mut ws, subscription_params).await.unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } } @@ -213,7 +213,7 @@ async fn should_not_notify_if_tx_by_filtered_address_in_latest_block_in_on_deman .await .unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -234,7 +234,7 @@ async fn should_not_notify_if_tx_by_filtered_address_in_latest_block_in_on_tx_mo .await .unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -249,7 +249,7 @@ async fn should_not_notify_if_tx_already_in_latest_block_in_on_demand_mode() { // Subscribe AFTER the tx and block creation. let finality_status = TransactionFinalityStatus::PreConfirmed; subscribe_new_txs(&mut ws, json!({ "finality_status": [finality_status] })).await.unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -265,7 +265,7 @@ async fn should_not_notify_if_tx_already_in_latest_block_in_on_tx_mode() { [TransactionFinalityStatus::PreConfirmed, TransactionFinalityStatus::AcceptedOnL2] { subscribe_new_txs(&mut ws, json!({ "finality_status": [finality_status] })).await.unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } } @@ -286,7 +286,7 @@ async fn should_not_notify_on_read_request_if_txs_in_pre_confirmed_block() { let dummy_address = Felt::ONE; devnet.get_balance_latest(&dummy_address, FeeUnit::Wei).await.unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -308,11 +308,11 @@ async fn should_notify_twice_if_subscribed_to_both_finality_statuses() { let extracted_tx: Transaction = serde_json::from_value(notification_tx).unwrap(); assert_eq!(extracted_tx.transaction_hash(), &tx_hash); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); devnet.create_block().await.unwrap(); // On first loop iteration, this changes tx status } - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -331,5 +331,5 @@ async fn test_deploy_account_tx_notification() { // assert_eq!(tx.transaction_hash, deployment_result.transaction_hash); assert_eq!(notification["transaction_hash"], json!(deployment_result.transaction_hash)); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } diff --git a/tests/integration/test_subscription_to_reorg.rs b/tests/integration/test_subscription_to_reorg.rs index becf0579e..fb816c4e2 100644 --- a/tests/integration/test_subscription_to_reorg.rs +++ b/tests/integration/test_subscription_to_reorg.rs @@ -59,7 +59,7 @@ async fn reorg_notification_for_all_subscriptions() { let additional_block_hash = devnet.create_block().await.unwrap(); devnet.abort_blocks(&BlockId::Hash(additional_block_hash)).await.unwrap(); for (_, mut ws) in notifiable_subscribers { - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } } @@ -121,5 +121,5 @@ async fn socket_with_n_subscriptions_should_get_n_reorg_notifications() { assert_eq!(notification_ids, HashSet::from_iter(subscription_ids)); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } diff --git a/tests/integration/test_subscription_to_tx_status.rs b/tests/integration/test_subscription_to_tx_status.rs index 5ff4b7a33..978a119e5 100644 --- a/tests/integration/test_subscription_to_tx_status.rs +++ b/tests/integration/test_subscription_to_tx_status.rs @@ -31,25 +31,27 @@ fn assert_mint_notification_succeeded( tx_hash: Felt, subscription_id: SubscriptionId, expected_finality_status: &str, -) { - assert_eq!( - notification, - json!({ - "jsonrpc": "2.0", - "method": "starknet_subscriptionTransactionStatus", - "params": { - "result": { - "transaction_hash": tx_hash, - "status": { - "finality_status": expected_finality_status, - "failure_reason": null, - "execution_status": "SUCCEEDED", - }, +) -> Result<(), anyhow::Error> { + let expected_resp = json!({ + "jsonrpc": "2.0", + "method": "starknet_subscriptionTransactionStatus", + "params": { + "result": { + "transaction_hash": tx_hash, + "status": { + "finality_status": expected_finality_status, + "failure_reason": null, + "execution_status": "SUCCEEDED", }, - "subscription_id": subscription_id, - } - }) + }, + "subscription_id": subscription_id, + } + }); + anyhow::ensure!( + notification == expected_resp, + format!("assertion `left == right` failed, left: {notification}, right: {expected_resp}") ); + Ok(()) } #[tokio::test] @@ -65,7 +67,8 @@ async fn subscribe_to_new_tx_status_happy_path() { assert_eq!(tx_hash, expected_tx_hash); let notification = receive_rpc_via_ws(&mut ws).await.unwrap(); - assert_mint_notification_succeeded(notification, tx_hash, subscription_id, "ACCEPTED_ON_L2"); + assert_mint_notification_succeeded(notification, tx_hash, subscription_id, "ACCEPTED_ON_L2") + .unwrap(); } #[tokio::test] @@ -81,7 +84,7 @@ async fn should_stop_notifying_after_unsubscription() { assert_eq!(unsubscription, json!({ "jsonrpc": "2.0", "id": 0, "result": true })); devnet.mint(address, mint_amount).await; - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -90,7 +93,7 @@ async fn should_not_receive_notification_if_not_subscribed() { let (mut ws, _) = connect_async(devnet.ws_url()).await.unwrap(); devnet.mint(0x1, 1).await; - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -106,7 +109,7 @@ async fn should_not_receive_notification_if_subscribed_to_another_tx() { assert_eq!(tx_hash, expected_tx_hash); assert_ne!(tx_hash, dummy_tx_hash); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -121,7 +124,7 @@ async fn should_not_receive_tx_notification_if_subscribed_to_blocks() { // there should only be a single new block notification since minting is a block-adding tx let notification = receive_rpc_via_ws(&mut ws).await.unwrap(); assert_eq!(notification["method"], "starknet_subscriptionNewHeads"); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -132,7 +135,7 @@ async fn should_not_receive_block_notification_if_subscribed_to_tx() { subscribe_tx_status(&mut ws, &Felt::ONE).await.unwrap(); devnet.create_block().await.unwrap(); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } async fn should_notify_if_subscribed_before_and_after_tx( @@ -140,15 +143,14 @@ async fn should_notify_if_subscribed_before_and_after_tx( ws_before_tx: &mut WebSocketStream>, ws_after_tx: &mut WebSocketStream>, expected_finality_status: &str, -) -> (Felt, String, String) { +) -> Result<(Felt, String, String), anyhow::Error> { let (address, mint_amount, expected_tx_hash) = first_mint_data(); // should work if subscribing before sending the tx - let subscription_id_before = - subscribe_tx_status(ws_before_tx, &expected_tx_hash).await.unwrap(); + let subscription_id_before = subscribe_tx_status(ws_before_tx, &expected_tx_hash).await?; let tx_hash = devnet.mint(address, mint_amount).await; - assert_eq!(tx_hash, expected_tx_hash); + anyhow::ensure!(tx_hash == expected_tx_hash); { let notification = receive_rpc_via_ws(ws_before_tx).await.unwrap(); @@ -157,24 +159,24 @@ async fn should_notify_if_subscribed_before_and_after_tx( tx_hash, subscription_id_before.clone(), expected_finality_status, - ); - assert_no_notifications(ws_before_tx).await; + )?; + assert_no_notifications(ws_before_tx).await?; } // should work even if subscribing after the tx was sent - let subscription_id_after = subscribe_tx_status(ws_after_tx, &expected_tx_hash).await.unwrap(); + let subscription_id_after = subscribe_tx_status(ws_after_tx, &expected_tx_hash).await?; { - let notification = receive_rpc_via_ws(ws_after_tx).await.unwrap(); + let notification = receive_rpc_via_ws(ws_after_tx).await?; assert_mint_notification_succeeded( notification, tx_hash, subscription_id_after.clone(), expected_finality_status, - ); - assert_no_notifications(ws_after_tx).await; + )?; + assert_no_notifications(ws_after_tx).await?; } - (tx_hash, subscription_id_before, subscription_id_after) + Ok((tx_hash, subscription_id_before, subscription_id_after)) } #[tokio::test] @@ -192,7 +194,8 @@ async fn should_notify_in_on_demand_mode() { &mut ws_after_tx, "PRE_CONFIRMED", ) - .await; + .await + .unwrap(); // Creating a new block should make txs go: PRE_CONFIRMED->ACCEPTED_ON_L2 devnet.create_block().await.unwrap(); @@ -206,8 +209,9 @@ async fn should_notify_in_on_demand_mode() { mint_tx_hash, subscription_id, "ACCEPTED_ON_L2", - ); - assert_no_notifications(&mut ws).await; + ) + .unwrap(); + assert_no_notifications(&mut ws).await.unwrap(); } } @@ -225,12 +229,13 @@ async fn should_notify_only_once_in_on_demand_mode() { assert_eq!(tx_hash, expected_tx_hash); let notification = receive_rpc_via_ws(&mut ws).await.unwrap(); - assert_mint_notification_succeeded(notification, tx_hash, subscription_id, "PRE_CONFIRMED"); - assert_no_notifications(&mut ws).await; + assert_mint_notification_succeeded(notification, tx_hash, subscription_id, "PRE_CONFIRMED") + .unwrap(); + assert_no_notifications(&mut ws).await.unwrap(); let another_tx_hash = devnet.mint(address, mint_amount).await; assert_ne!(another_tx_hash, tx_hash); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -247,13 +252,14 @@ async fn should_notify_in_on_transaction_mode() { &mut ws_after_tx, "ACCEPTED_ON_L2", ) - .await; + .await + .unwrap(); // Expect no new notifications on creating a new empty block devnet.create_block().await.unwrap(); - assert_no_notifications(&mut ws_before_tx).await; - assert_no_notifications(&mut ws_after_tx).await; + assert_no_notifications(&mut ws_before_tx).await.unwrap(); + assert_no_notifications(&mut ws_after_tx).await.unwrap(); } #[tokio::test] @@ -269,10 +275,11 @@ async fn should_notify_if_already_in_latest() { let subscription_id = subscribe_tx_status(&mut ws, &tx_hash).await.unwrap(); let notification = receive_rpc_via_ws(&mut ws).await.unwrap(); - assert_mint_notification_succeeded(notification, tx_hash, subscription_id, "ACCEPTED_ON_L2"); + assert_mint_notification_succeeded(notification, tx_hash, subscription_id, "ACCEPTED_ON_L2") + .unwrap(); devnet.mint(address, mint_amount).await; - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -292,10 +299,11 @@ async fn should_notify_if_already_in_an_old_block() { let subscription_id = subscribe_tx_status(&mut ws, &tx_hash).await.unwrap(); let notification = receive_rpc_via_ws(&mut ws).await.unwrap(); - assert_mint_notification_succeeded(notification, tx_hash, subscription_id, "ACCEPTED_ON_L2"); + assert_mint_notification_succeeded(notification, tx_hash, subscription_id, "ACCEPTED_ON_L2") + .unwrap(); devnet.mint(address, mint_amount).await; - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -310,12 +318,13 @@ async fn should_not_notify_of_status_change_when_block_aborted() { // as expected, the actual tx accepted notification is first let notification = receive_rpc_via_ws(&mut ws).await.unwrap(); - assert_mint_notification_succeeded(notification, tx_hash, subscription_id, "ACCEPTED_ON_L2"); + assert_mint_notification_succeeded(notification, tx_hash, subscription_id, "ACCEPTED_ON_L2") + .unwrap(); devnet.abort_blocks(&BlockId::Number(1)).await.unwrap(); // only expect reorg subscription let notification = receive_rpc_via_ws(&mut ws).await.unwrap(); assert_eq!(notification["method"], "starknet_subscriptionReorg"); - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } diff --git a/tests/integration/test_subscription_with_invalid_block_id.rs b/tests/integration/test_subscription_with_invalid_block_id.rs index 10d5ca62e..9bcc02d64 100644 --- a/tests/integration/test_subscription_with_invalid_block_id.rs +++ b/tests/integration/test_subscription_with_invalid_block_id.rs @@ -34,7 +34,7 @@ async fn test_subscribing_to_non_existent_block() { } } - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] @@ -58,7 +58,7 @@ async fn test_aborted_blocks_not_subscribable() { } } - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test] diff --git a/tests/integration/test_trace.rs b/tests/integration/test_trace.rs index 3e19b8466..cd448cc58 100644 --- a/tests/integration/test_trace.rs +++ b/tests/integration/test_trace.rs @@ -21,7 +21,7 @@ use crate::common::utils::{get_deployable_account_signer, get_events_contract_ar static DUMMY_ADDRESS: Felt = Felt::from_hex_unchecked("0x7b"); static DUMMY_AMOUNT: u128 = 456; -fn assert_mint_invocation(trace: &TransactionTrace) { +fn assert_mint_invocation(trace: &TransactionTrace) -> Result<(), anyhow::Error> { match trace { TransactionTrace::Invoke(InvokeTransactionTrace { validate_invocation, @@ -31,43 +31,77 @@ fn assert_mint_invocation(trace: &TransactionTrace) { .. }) => { for invocation in [validate_invocation.as_ref().unwrap(), execute_invocation] { - assert_eq!( - invocation.contract_address, - Felt::from_hex_unchecked(CHARGEABLE_ACCOUNT_ADDRESS) + anyhow::ensure!( + invocation.contract_address + == Felt::from_hex_unchecked(CHARGEABLE_ACCOUNT_ADDRESS), + format!( + "assertion `left == right` failed, left: {}, right: {}", + invocation.contract_address, + Felt::from_hex_unchecked(CHARGEABLE_ACCOUNT_ADDRESS) + ) ); - assert_eq!( - invocation.calldata, - vec![ - Felt::ONE, // number of calls - STRK_ERC20_CONTRACT_ADDRESS, - get_selector_from_name("permissioned_mint").unwrap(), - Felt::THREE, // calldata length - DUMMY_ADDRESS, - Felt::from(DUMMY_AMOUNT), // low bytes - Felt::ZERO // high bytes - ] + let expected_calldata = vec![ + Felt::ONE, // number of calls + STRK_ERC20_CONTRACT_ADDRESS, + get_selector_from_name("permissioned_mint").unwrap(), + Felt::THREE, // calldata length + DUMMY_ADDRESS, + Felt::from(DUMMY_AMOUNT), // low bytes + Felt::ZERO, // high bytes + ]; + anyhow::ensure!( + invocation.calldata == expected_calldata, + format!( + "assertion `left == right` failed, left: {:?}, right: {:?}", + invocation.calldata, expected_calldata + ) ); } - assert_eq!( - fee_transfer_invocation.as_ref().unwrap().contract_address, - STRK_ERC20_CONTRACT_ADDRESS + let fee_transfer_contract_address = fee_transfer_invocation + .as_ref() + .ok_or(anyhow::anyhow!("failed to reference fee transfer invocation"))? + .contract_address; + anyhow::ensure!( + fee_transfer_contract_address == STRK_ERC20_CONTRACT_ADDRESS, + format!( + "assertion `left == right` failed, left: {fee_transfer_contract_address}, right: {STRK_ERC20_CONTRACT_ADDRESS}" + ) ); - assert_eq!(execution_resources.l1_gas, 0); - assert!(execution_resources.l1_data_gas > 0); - assert!(execution_resources.l2_gas > 0); + anyhow::ensure!( + execution_resources.l1_gas == 0, + format!( + "assertion `left == right` failed, left: {}, right: {}", + execution_resources.l1_gas, 0 + ) + ); + anyhow::ensure!( + execution_resources.l1_data_gas > 0, + format!( + "assertion `left == right` failed, left: {}, right: {}", + execution_resources.l1_data_gas, 0 + ) + ); + anyhow::ensure!( + execution_resources.l2_gas > 0, + format!( + "assertion `left == right` failed, left: {}, right: {}", + execution_resources.l2_gas, 0 + ) + ); } - other => panic!("Invalid trace: {other:?}"), + other => anyhow::bail!("Invalid trace: {other:?}"), }; + Ok(()) } -async fn get_invoke_trace(devnet: &BackgroundDevnet) { +async fn get_invoke_trace(devnet: &BackgroundDevnet) -> Result<(), anyhow::Error> { let mint_tx_hash = devnet.mint(DUMMY_ADDRESS, DUMMY_AMOUNT).await; - devnet.create_block().await.unwrap(); + devnet.create_block().await?; - let mint_tx_trace = devnet.json_rpc_client.trace_transaction(mint_tx_hash).await.unwrap(); - assert_mint_invocation(&mint_tx_trace); + let mint_tx_trace = devnet.json_rpc_client.trace_transaction(mint_tx_hash).await?; + assert_mint_invocation(&mint_tx_trace) } #[tokio::test] @@ -83,7 +117,7 @@ async fn get_trace_non_existing_transaction() { async fn get_invoke_trace_normal_mode() { let devnet = BackgroundDevnet::spawn().await.expect("Could not start Devnet"); - get_invoke_trace(&devnet).await + get_invoke_trace(&devnet).await.unwrap() } #[tokio::test] @@ -92,7 +126,7 @@ async fn get_invoke_trace_block_generation_on_demand() { .await .expect("Could not start Devnet"); - get_invoke_trace(&devnet).await + get_invoke_trace(&devnet).await.unwrap() } #[tokio::test] @@ -283,5 +317,5 @@ async fn get_traces_from_block() { let trace = &traces[0]; assert_eq!(trace.transaction_hash, mint_tx_hash); - assert_mint_invocation(&trace.trace_root); + assert_mint_invocation(&trace.trace_root).unwrap(); } diff --git a/tests/integration/test_transaction_handling.rs b/tests/integration/test_transaction_handling.rs index c1d7e5c56..66c18335f 100644 --- a/tests/integration/test_transaction_handling.rs +++ b/tests/integration/test_transaction_handling.rs @@ -45,7 +45,7 @@ async fn test_failed_validation_with_expected_message() { match declaration_result { Err(AccountError::Provider(ProviderError::StarknetError( StarknetError::ValidationFailure(message), - ))) => assert_contains(&message, "FAILED VALIDATE DECLARE"), + ))) => assert_contains(&message, "FAILED VALIDATE DECLARE").unwrap(), other => panic!("Unexpected result: {other:?}"), } } @@ -123,6 +123,7 @@ async fn test_tx_status_content_of_failed_invoke() { .unwrap(); assert_eq!(tx_status["finality_status"], "ACCEPTED_ON_L2"); - assert_contains(tx_status["failure_reason"].as_str().unwrap(), "Error in the called contract"); + assert_contains(tx_status["failure_reason"].as_str().unwrap(), "Error in the called contract") + .unwrap(); assert_eq!(tx_status["execution_status"], "REVERTED"); } diff --git a/tests/integration/test_v3_transactions.rs b/tests/integration/test_v3_transactions.rs index 898a7f3ee..04a4f0fed 100644 --- a/tests/integration/test_v3_transactions.rs +++ b/tests/integration/test_v3_transactions.rs @@ -72,7 +72,8 @@ async fn declare_deploy_happy_path() { account.declare_v3(Arc::new(sierra_artifact), casm_hash).send().await.unwrap(); assert_tx_succeeded_accepted(&declare_transaction.transaction_hash, &devnet.json_rpc_client) - .await; + .await + .unwrap(); devnet .json_rpc_client @@ -101,7 +102,8 @@ async fn declare_deploy_happy_path() { ); let deploy_transaction = account.execute_v3(deploy_call).send().await.unwrap(); assert_tx_succeeded_accepted(&deploy_transaction.transaction_hash, &devnet.json_rpc_client) - .await; + .await + .unwrap(); let class_hash_of_contract = devnet .json_rpc_client @@ -153,7 +155,8 @@ async fn declare_from_an_account_with_insufficient_strk_tokens_balance() { .unwrap(); assert_tx_succeeded_accepted(&invoke_txn_result.transaction_hash, &devnet.json_rpc_client) - .await; + .await + .unwrap(); let account_strk_balance = devnet.get_balance_by_tag(&account_address, FeeUnit::Fri, BlockTag::Latest).await.unwrap(); @@ -193,7 +196,7 @@ async fn invoke_with_insufficient_gas_price_and_or_gas_units_should_fail() { Some(&account), Option::<&OpenZeppelinAccountFactory>>::None, ) - .await; + .await.unwrap(); } #[tokio::test] @@ -218,7 +221,7 @@ async fn deploy_account_with_insufficient_gas_price_and_or_gas_units_should_fail Option::<&SingleOwnerAccount, LocalWallet>>::None, Some(&factory), ) - .await + .await.unwrap() } #[tokio::test] @@ -280,7 +283,7 @@ async fn declare_with_insufficient_gas_price_and_or_gas_units_should_fail() { Some(&account), Option::<&OpenZeppelinAccountFactory>>::None, ) - .await; + .await.unwrap(); } #[tokio::test] @@ -302,7 +305,7 @@ async fn deploy_account_happy_path() { devnet.mint_unit(account_address, 1e18 as u128, FeeUnit::Fri).await; let result = deploy_v3.send().await.unwrap(); - assert_tx_succeeded_accepted(&result.transaction_hash, &devnet.json_rpc_client).await; + assert_tx_succeeded_accepted(&result.transaction_hash, &devnet.json_rpc_client).await.unwrap(); } /// This function sets the gas price and/or gas units to a value that is less than the estimated @@ -315,19 +318,28 @@ async fn transaction_with_less_gas_units_and_or_less_gas_price_should_return_err transaction_action: Action, account: Option<&A>, account_factory: Option<&F>, -) { +) -> Result<(), anyhow::Error> { let estimate_fee = match &transaction_action { - Action::Declaration(sierra_class, casm_hash) => { - DeclarationV3::new(sierra_class.clone(), *casm_hash, account.unwrap()) + Action::Declaration(sierra_class, casm_hash) => DeclarationV3::new( + sierra_class.clone(), + *casm_hash, + account.ok_or(anyhow::anyhow!("Account not found"))?, + ) + .estimate_fee() + .await + .map_err(|e| anyhow::Error::msg(e.to_string()))?, + Action::AccountDeployment(salt) => AccountDeploymentV3::new( + *salt, + account_factory.ok_or(anyhow::anyhow!("Account Factory is None"))?, + ) + .estimate_fee() + .await + .map_err(|e| anyhow::Error::msg(e.to_string()))?, + Action::Execution(calls) => { + ExecutionV3::new(calls.clone(), account.ok_or(anyhow::anyhow!("Account not found"))?) .estimate_fee() .await - .unwrap() - } - Action::AccountDeployment(salt) => { - AccountDeploymentV3::new(*salt, account_factory.unwrap()).estimate_fee().await.unwrap() - } - Action::Execution(calls) => { - ExecutionV3::new(calls.clone(), account.unwrap()).estimate_fee().await.unwrap() + .map_err(|e| anyhow::Error::msg(e.to_string()))? } }; @@ -356,7 +368,7 @@ async fn transaction_with_less_gas_units_and_or_less_gas_price_should_return_err starknet_rs_accounts::AccountError::Provider(ProviderError::StarknetError( StarknetError::InsufficientResourcesForValidate, )) => {} - other => panic!("Unexpected error {:?}", other), + other => anyhow::bail!("Unexpected error {:?}", other), } } Action::AccountDeployment(salt) => { @@ -373,7 +385,7 @@ async fn transaction_with_less_gas_units_and_or_less_gas_price_should_return_err StarknetError::InsufficientResourcesForValidate, ), ) => {} - other => panic!("Unexpected error {:?}", other), + other => anyhow::bail!("Unexpected error {:?}", other), } } Action::Execution(calls) => { @@ -389,17 +401,16 @@ async fn transaction_with_less_gas_units_and_or_less_gas_price_should_return_err match transaction_result { Ok(InvokeTransactionResult { transaction_hash }) => { let receipt = account - .unwrap() + .ok_or(anyhow::anyhow!("Account not found"))? .provider() .get_transaction_receipt(transaction_hash) - .await - .unwrap(); + .await?; let execution_result = receipt.receipt.execution_result(); match execution_result { ExecutionResult::Reverted { reason } => { - assert_contains(reason.as_str(), "Insufficient max L2Gas"); + assert_contains(reason.as_str(), "Insufficient max L2Gas").unwrap(); } - other => panic!("Unexpected result: {:?}", other), + other => anyhow::bail!("Unexpected result: {:?}", other), } } Err(starknet_rs_accounts::AccountError::Provider( @@ -407,11 +418,13 @@ async fn transaction_with_less_gas_units_and_or_less_gas_price_should_return_err StarknetError::InsufficientResourcesForValidate, ), )) => {} - Err(error) => panic!("Unexpected error {:?}", error), + Err(error) => anyhow::bail!("Unexpected error {:?}", error), } } }; } + + Ok(()) } #[tokio::test] diff --git a/tests/integration/test_websocket.rs b/tests/integration/test_websocket.rs index 42beea348..59d293acc 100644 --- a/tests/integration/test_websocket.rs +++ b/tests/integration/test_websocket.rs @@ -106,7 +106,7 @@ async fn restarting_should_forget_all_websocket_subscriptions() { devnet.restart().await; - assert_no_notifications(&mut ws).await; + assert_no_notifications(&mut ws).await.unwrap(); } #[tokio::test]