From b1bd1d20335faef548479365612657902cfe0a0a Mon Sep 17 00:00:00 2001 From: hal3e Date: Mon, 25 Nov 2024 11:45:07 +0100 Subject: [PATCH] feat: add `assert_ne` and `revert_with_log` revert signals --- .github/workflows/ci.yml | 2 +- Cargo.toml | 3 + e2e/Forc.toml | 4 +- e2e/sway/contracts/asserts/src/main.sw | 17 +- .../{require => revert_logs}/Forc.toml | 2 +- .../{require => revert_logs}/src/main.sw | 28 ++ e2e/sway/scripts/script_asserts/src/main.sw | 11 + .../Forc.toml | 2 +- .../src/main.sw | 21 ++ e2e/sway/types/contracts/vectors/src/main.sw | 2 +- .../types/scripts/script_vectors/src/main.sw | 2 +- e2e/tests/logs.rs | 265 ++++++++++++++---- packages/fuels-core/src/types/tx_status.rs | 17 +- 13 files changed, 303 insertions(+), 73 deletions(-) rename e2e/sway/contracts/{require => revert_logs}/Forc.toml (81%) rename e2e/sway/contracts/{require => revert_logs}/src/main.sw (63%) rename e2e/sway/scripts/{script_require => script_revert_logs}/Forc.toml (76%) rename e2e/sway/scripts/{script_require => script_revert_logs}/src/main.sw (63%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 52cad62d49..f367656a3f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ env: FUEL_CORE_PATCH_BRANCH: "" FUEL_CORE_PATCH_REVISION: "" RUST_VERSION: 1.79.0 - FORC_VERSION: 0.66.4 + FORC_VERSION: 0.66.5 FORC_PATCH_BRANCH: "" FORC_PATCH_REVISION: "" NEXTEST_HIDE_PROGRESS_BAR: "true" diff --git a/Cargo.toml b/Cargo.toml index 5360aeb629..3dc853b0c8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -113,3 +113,6 @@ fuels-macros = { version = "0.66.10", path = "./packages/fuels-macros", default- fuels-programs = { version = "0.66.10", path = "./packages/fuels-programs", default-features = false } fuels-test-helpers = { version = "0.66.10", path = "./packages/fuels-test-helpers", default-features = false } versions-replacer = { version = "0.66.10", path = "./scripts/versions-replacer", default-features = false } + +[patch.crates-io] +fuel-abi-types = { git = "https://github.com/FuelLabs/fuel-abi-types", branch = "hal3e/add-require-with-log-signal", package = "fuel-abi-types"} diff --git a/e2e/Forc.toml b/e2e/Forc.toml index 530e385130..365dc9e567 100644 --- a/e2e/Forc.toml +++ b/e2e/Forc.toml @@ -24,7 +24,7 @@ members = [ 'sway/contracts/needs_custom_decoder', 'sway/contracts/payable_annotation', 'sway/contracts/proxy', - 'sway/contracts/require', + 'sway/contracts/revert_logs', 'sway/contracts/revert_transaction_error', 'sway/contracts/storage', 'sway/contracts/token_ops', @@ -55,7 +55,7 @@ members = [ 'sway/scripts/script_enum', 'sway/scripts/script_needs_custom_decoder', 'sway/scripts/script_proxy', - 'sway/scripts/script_require', + 'sway/scripts/script_revert_logs', 'sway/scripts/script_struct', 'sway/scripts/transfer_script', 'sway/types/contracts/b256', diff --git a/e2e/sway/contracts/asserts/src/main.sw b/e2e/sway/contracts/asserts/src/main.sw index a35e061e9a..63ec8546ab 100644 --- a/e2e/sway/contracts/asserts/src/main.sw +++ b/e2e/sway/contracts/asserts/src/main.sw @@ -29,9 +29,14 @@ impl Eq for TestEnum { abi TestContract { fn assert_primitive(a: u64, b: u64); + fn assert_eq_primitive(a: u64, b: u64); fn assert_eq_struct(test_struct: TestStruct, test_struct2: TestStruct); fn assert_eq_enum(test_enum: TestEnum, test_enum2: TestEnum); + + fn assert_ne_primitive(a: u64, b: u64); + fn assert_ne_struct(test_struct: TestStruct, test_struct2: TestStruct); + fn assert_ne_enum(test_enum: TestEnum, test_enum2: TestEnum); } impl TestContract for Contract { @@ -42,12 +47,20 @@ impl TestContract for Contract { fn assert_eq_primitive(a: u64, b: u64) { assert_eq(a, b); } - fn assert_eq_struct(test_struct: TestStruct, test_struct2: TestStruct) { assert_eq(test_struct, test_struct2); } - fn assert_eq_enum(test_enum: TestEnum, test_enum2: TestEnum) { assert_eq(test_enum, test_enum2); } + + fn assert_ne_primitive(a: u64, b: u64) { + assert_ne(a, b); + } + fn assert_ne_struct(test_struct: TestStruct, test_struct2: TestStruct) { + assert_ne(test_struct, test_struct2); + } + fn assert_ne_enum(test_enum: TestEnum, test_enum2: TestEnum) { + assert_ne(test_enum, test_enum2); + } } diff --git a/e2e/sway/contracts/require/Forc.toml b/e2e/sway/contracts/revert_logs/Forc.toml similarity index 81% rename from e2e/sway/contracts/require/Forc.toml rename to e2e/sway/contracts/revert_logs/Forc.toml index e69f6bab05..5845d86cfb 100644 --- a/e2e/sway/contracts/require/Forc.toml +++ b/e2e/sway/contracts/revert_logs/Forc.toml @@ -2,4 +2,4 @@ authors = ["Fuel Labs "] entry = "main.sw" license = "Apache-2.0" -name = "require" +name = "revert_logs" diff --git a/e2e/sway/contracts/require/src/main.sw b/e2e/sway/contracts/revert_logs/src/main.sw similarity index 63% rename from e2e/sway/contracts/require/src/main.sw rename to e2e/sway/contracts/revert_logs/src/main.sw index 6f33644caf..5f6d096086 100644 --- a/e2e/sway/contracts/require/src/main.sw +++ b/e2e/sway/contracts/revert_logs/src/main.sw @@ -25,6 +25,10 @@ abi TestContract { fn require_string(); fn require_custom_generic(); fn require_with_additional_logs(); + + fn rev_w_log_primitive(); + fn rev_w_log_string(); + fn rev_w_log_custom_generic(); } impl TestContract for Contract { @@ -57,4 +61,28 @@ impl TestContract for Contract { log(__to_str_array("fuel")); require(false, 64); } + + fn rev_w_log_primitive() { + revert_with_log(42); + } + + fn rev_w_log_string() { + revert_with_log(__to_str_array("fuel")); + } + + fn rev_w_log_custom_generic() { + let l: [u8; 3] = [1u8, 2u8, 3u8]; + + let test_enum = EnumWithGeneric::VariantOne(l); + let test_struct_nested = StructWithNestedGeneric { + field_1: test_enum, + field_2: 64, + }; + let test_deeply_nested_generic = StructDeeplyNestedGeneric { + field_1: test_struct_nested, + field_2: 64, + }; + + revert_with_log(test_deeply_nested_generic); + } } diff --git a/e2e/sway/scripts/script_asserts/src/main.sw b/e2e/sway/scripts/script_asserts/src/main.sw index 8ab0c8ad06..898ece135a 100644 --- a/e2e/sway/scripts/script_asserts/src/main.sw +++ b/e2e/sway/scripts/script_asserts/src/main.sw @@ -33,6 +33,9 @@ enum MatchEnum { AssertEqPrimitive: (u64, u64), AssertEqStruct: (TestStruct, TestStruct), AssertEqEnum: (TestEnum, TestEnum), + AssertNePrimitive: (u64, u64), + AssertNeStruct: (TestStruct, TestStruct), + AssertNeEnum: (TestEnum, TestEnum), } fn main(match_enum: MatchEnum) { @@ -46,5 +49,13 @@ fn main(match_enum: MatchEnum) { } else if let MatchEnum::AssertEqEnum((test_enum, test_enum2)) = match_enum { assert_eq(test_enum, test_enum2); + } else if let MatchEnum::AssertNePrimitive((a, b)) = match_enum { + assert_ne(a, b); + } else if let MatchEnum::AssertNeStruct((test_struct, test_struct2)) = match_enum + { + assert_ne(test_struct, test_struct2); + } else if let MatchEnum::AssertNeEnum((test_enum, test_enum2)) = match_enum + { + assert_ne(test_enum, test_enum2); } } diff --git a/e2e/sway/scripts/script_require/Forc.toml b/e2e/sway/scripts/script_revert_logs/Forc.toml similarity index 76% rename from e2e/sway/scripts/script_require/Forc.toml rename to e2e/sway/scripts/script_revert_logs/Forc.toml index 2cfce30dde..fb2c6d9289 100644 --- a/e2e/sway/scripts/script_require/Forc.toml +++ b/e2e/sway/scripts/script_revert_logs/Forc.toml @@ -2,4 +2,4 @@ authors = ["Fuel Labs "] entry = "main.sw" license = "Apache-2.0" -name = "script_require" +name = "script_revert_logs" diff --git a/e2e/sway/scripts/script_require/src/main.sw b/e2e/sway/scripts/script_revert_logs/src/main.sw similarity index 63% rename from e2e/sway/scripts/script_require/src/main.sw rename to e2e/sway/scripts/script_revert_logs/src/main.sw index 62afeb88ae..4cea809dc1 100644 --- a/e2e/sway/scripts/script_require/src/main.sw +++ b/e2e/sway/scripts/script_revert_logs/src/main.sw @@ -26,6 +26,9 @@ enum MatchEnum { RequireString: (), RequireCustomGeneric: (), RequireWithAdditionalLogs: (), + RevWLogPrimitive: (), + RevWLogString: (), + RevWLogCustomGeneric: (), } fn main(match_enum: MatchEnum) { @@ -51,5 +54,23 @@ fn main(match_enum: MatchEnum) { log(42); log(__to_str_array("fuel")); require(false, 64); + } else if let MatchEnum::RevWLogPrimitive = match_enum { + revert_with_log(42); + } else if let MatchEnum::RevWLogString = match_enum { + revert_with_log(__to_str_array("fuel")); + } else if let MatchEnum::RevWLogCustomGeneric = match_enum { + let l: [u8; 3] = [1u8, 2u8, 3u8]; + + let test_enum = EnumWithGeneric::VariantOne(l); + let test_struct_nested = StructWithNestedGeneric { + field_1: test_enum, + field_2: 64, + }; + let test_deeply_nested_generic = StructDeeplyNestedGeneric { + field_1: test_struct_nested, + field_2: 64, + }; + + revert_with_log(test_deeply_nested_generic); } } diff --git a/e2e/sway/types/contracts/vectors/src/main.sw b/e2e/sway/types/contracts/vectors/src/main.sw index a42ed5c7a4..6ea807bbf8 100644 --- a/e2e/sway/types/contracts/vectors/src/main.sw +++ b/e2e/sway/types/contracts/vectors/src/main.sw @@ -1,6 +1,6 @@ contract; -mod data_structures; +pub mod data_structures; mod eq_impls; mod utils; diff --git a/e2e/sway/types/scripts/script_vectors/src/main.sw b/e2e/sway/types/scripts/script_vectors/src/main.sw index fa19a2f3e3..a277fce3da 100644 --- a/e2e/sway/types/scripts/script_vectors/src/main.sw +++ b/e2e/sway/types/scripts/script_vectors/src/main.sw @@ -1,6 +1,6 @@ script; -mod data_structures; +pub mod data_structures; mod eq_impls; mod utils; diff --git a/e2e/tests/logs.rs b/e2e/tests/logs.rs index f9dc89dabd..664333c0a9 100644 --- a/e2e/tests/logs.rs +++ b/e2e/tests/logs.rs @@ -434,16 +434,16 @@ fn assert_revert_containing_msg(msg: &str, error: Error) { } #[tokio::test] -async fn test_require_log() -> Result<()> { +async fn test_revert_logs() -> Result<()> { setup_program_test!( Wallets("wallet"), Abigen(Contract( - name = "RequireContract", - project = "e2e/sway/contracts/require" + name = "RevertLogsContract", + project = "e2e/sway/contracts/revert_logs" )), Deploy( name = "contract_instance", - contract = "RequireContract", + contract = "RevertLogsContract", wallet = "wallet", random_salt = false, ), @@ -472,36 +472,52 @@ async fn test_require_log() -> Result<()> { }; } - reverts_with_msg!(require_primitive, call, "42"); - reverts_with_msg!(require_primitive, simulate, "42"); + { + reverts_with_msg!(require_primitive, call, "42"); + reverts_with_msg!(require_primitive, simulate, "42"); - reverts_with_msg!(require_string, call, "fuel"); - reverts_with_msg!(require_string, simulate, "fuel"); + reverts_with_msg!(require_string, call, "fuel"); + reverts_with_msg!(require_string, simulate, "fuel"); - reverts_with_msg!(require_custom_generic, call, "StructDeeplyNestedGeneric"); - reverts_with_msg!( - require_custom_generic, - simulate, - "StructDeeplyNestedGeneric" - ); + reverts_with_msg!(require_custom_generic, call, "StructDeeplyNestedGeneric"); + reverts_with_msg!( + require_custom_generic, + simulate, + "StructDeeplyNestedGeneric" + ); + + reverts_with_msg!(require_with_additional_logs, call, "64"); + reverts_with_msg!(require_with_additional_logs, simulate, "64"); + } + { + reverts_with_msg!(rev_w_log_primitive, call, "42"); + reverts_with_msg!(rev_w_log_primitive, simulate, "42"); - reverts_with_msg!(require_with_additional_logs, call, "64"); - reverts_with_msg!(require_with_additional_logs, simulate, "64"); + reverts_with_msg!(rev_w_log_string, call, "fuel"); + reverts_with_msg!(rev_w_log_string, simulate, "fuel"); + + reverts_with_msg!(rev_w_log_custom_generic, call, "StructDeeplyNestedGeneric"); + reverts_with_msg!( + rev_w_log_custom_generic, + simulate, + "StructDeeplyNestedGeneric" + ); + } Ok(()) } #[tokio::test] -async fn test_multi_call_require_log_single_contract() -> Result<()> { +async fn test_multi_call_revert_logs_single_contract() -> Result<()> { setup_program_test!( Wallets("wallet"), Abigen(Contract( - name = "RequireContract", - project = "e2e/sway/contracts/require" + name = "RevertLogsContract", + project = "e2e/sway/contracts/revert_logs" )), Deploy( name = "contract_instance", - contract = "RequireContract", + contract = "RevertLogsContract", wallet = "wallet", random_salt = false, ), @@ -513,7 +529,7 @@ async fn test_multi_call_require_log_single_contract() -> Result<()> { // handlers as the script returns the first revert it finds. { let call_handler_1 = contract_methods.require_string(); - let call_handler_2 = contract_methods.require_custom_generic(); + let call_handler_2 = contract_methods.rev_w_log_custom_generic(); let mut multi_call_handler = CallHandler::new_multi_call(wallet.clone()) .add_call(call_handler_1) @@ -535,7 +551,7 @@ async fn test_multi_call_require_log_single_contract() -> Result<()> { } { let call_handler_1 = contract_methods.require_custom_generic(); - let call_handler_2 = contract_methods.require_string(); + let call_handler_2 = contract_methods.rev_w_log_string(); let mut multi_call_handler = CallHandler::new_multi_call(wallet.clone()) .add_call(call_handler_1) @@ -560,22 +576,22 @@ async fn test_multi_call_require_log_single_contract() -> Result<()> { } #[tokio::test] -async fn test_multi_call_require_log_multi_contract() -> Result<()> { +async fn test_multi_call_revert_logs_multi_contract() -> Result<()> { setup_program_test!( Wallets("wallet"), Abigen(Contract( - name = "RequireContract", - project = "e2e/sway/contracts/require" + name = "RevertLogsContract", + project = "e2e/sway/contracts/revert_logs" )), Deploy( name = "contract_instance", - contract = "RequireContract", + contract = "RevertLogsContract", wallet = "wallet", random_salt = false, ), Deploy( name = "contract_instance2", - contract = "RequireContract", + contract = "RevertLogsContract", wallet = "wallet", random_salt = false, ), @@ -588,7 +604,7 @@ async fn test_multi_call_require_log_multi_contract() -> Result<()> { // handlers as the script returns the first revert it finds. { let call_handler_1 = contract_methods.require_string(); - let call_handler_2 = contract_methods2.require_custom_generic(); + let call_handler_2 = contract_methods2.rev_w_log_custom_generic(); let mut multi_call_handler = CallHandler::new_multi_call(wallet.clone()) .add_call(call_handler_1) @@ -610,7 +626,7 @@ async fn test_multi_call_require_log_multi_contract() -> Result<()> { } { let call_handler_1 = contract_methods2.require_custom_generic(); - let call_handler_2 = contract_methods.require_string(); + let call_handler_2 = contract_methods.rev_w_log_string(); let mut multi_call_handler = CallHandler::new_multi_call(wallet.clone()) .add_call(call_handler_1) @@ -639,13 +655,13 @@ async fn test_multi_call_require_log_multi_contract() -> Result<()> { async fn test_script_decode_logs() -> Result<()> { // ANCHOR: script_logs abigen!(Script( - name = "log_script", + name = "LogScript", abi = "e2e/sway/logs/script_logs/out/release/script_logs-abi.json" )); let wallet = launch_provider_and_get_wallet().await?; let bin_path = "sway/logs/script_logs/out/release/script_logs.bin"; - let instance = log_script::new(wallet.clone(), bin_path); + let instance = LogScript::new(wallet.clone(), bin_path); let response = instance.main().call().await?; @@ -911,7 +927,7 @@ async fn test_script_require_log() -> Result<()> { Wallets("wallet"), Abigen(Script( name = "LogScript", - project = "e2e/sway/scripts/script_require" + project = "e2e/sway/scripts/script_revert_logs" )), LoadScript( name = "script_instance", @@ -939,25 +955,45 @@ async fn test_script_require_log() -> Result<()> { }; } - reverts_with_msg!(MatchEnum::RequirePrimitive, call, "42"); - reverts_with_msg!(MatchEnum::RequirePrimitive, simulate, "42"); + { + reverts_with_msg!(MatchEnum::RequirePrimitive, call, "42"); + reverts_with_msg!(MatchEnum::RequirePrimitive, simulate, "42"); - reverts_with_msg!(MatchEnum::RequireString, call, "fuel"); - reverts_with_msg!(MatchEnum::RequireString, simulate, "fuel"); + reverts_with_msg!(MatchEnum::RequireString, call, "fuel"); + reverts_with_msg!(MatchEnum::RequireString, simulate, "fuel"); - reverts_with_msg!( - MatchEnum::RequireCustomGeneric, - call, - "StructDeeplyNestedGeneric" - ); - reverts_with_msg!( - MatchEnum::RequireCustomGeneric, - simulate, - "StructDeeplyNestedGeneric" - ); + reverts_with_msg!( + MatchEnum::RequireCustomGeneric, + call, + "StructDeeplyNestedGeneric" + ); + reverts_with_msg!( + MatchEnum::RequireCustomGeneric, + simulate, + "StructDeeplyNestedGeneric" + ); - reverts_with_msg!(MatchEnum::RequireWithAdditionalLogs, call, "64"); - reverts_with_msg!(MatchEnum::RequireWithAdditionalLogs, simulate, "64"); + reverts_with_msg!(MatchEnum::RequireWithAdditionalLogs, call, "64"); + reverts_with_msg!(MatchEnum::RequireWithAdditionalLogs, simulate, "64"); + } + { + reverts_with_msg!(MatchEnum::RevWLogPrimitive, call, "42"); + reverts_with_msg!(MatchEnum::RevWLogPrimitive, simulate, "42"); + + reverts_with_msg!(MatchEnum::RevWLogString, call, "fuel"); + reverts_with_msg!(MatchEnum::RevWLogString, simulate, "fuel"); + + reverts_with_msg!( + MatchEnum::RevWLogCustomGeneric, + call, + "StructDeeplyNestedGeneric" + ); + reverts_with_msg!( + MatchEnum::RevWLogCustomGeneric, + simulate, + "StructDeeplyNestedGeneric" + ); + } Ok(()) } @@ -1152,7 +1188,16 @@ async fn test_loader_script_require_from_loader_contract() -> Result<()> { } fn assert_assert_eq_containing_msg(left: T, right: T, error: Error) { - let msg = format!("left: `\"{left:?}\"`\n right: `\"{right:?}\"`"); + let msg = format!( + "assertion failed: `(left == right)`\n left: `\"{left:?}\"`\n right: `\"{right:?}\"`" + ); + assert_revert_containing_msg(&msg, error) +} + +fn assert_assert_ne_containing_msg(left: T, right: T, error: Error) { + let msg = format!( + "assertion failed: `(left != right)`\n left: `\"{left:?}\"`\n right: `\"{right:?}\"`" + ); assert_revert_containing_msg(&msg, error) } @@ -1256,6 +1301,59 @@ async fn test_contract_asserts_log() -> Result<()> { ); } + macro_rules! reverts_with_assert_ne_msg { + (($($arg: expr,)*), $method:ident, $execution: ident, $msg:expr) => { + let error = contract_instance + .methods() + .$method($($arg,)*) + .call() + .await + .expect_err("should return a revert error"); + assert_assert_ne_containing_msg($($arg,)* error); + } + } + + { + reverts_with_assert_ne_msg!((32, 32,), assert_ne_primitive, call, "assertion failed"); + reverts_with_assert_ne_msg!((32, 32,), assert_ne_primitive, simulate, "assertion failed"); + } + { + let test_struct = TestStruct { + field_1: true, + field_2: 64, + }; + + reverts_with_assert_ne_msg!( + (test_struct.clone(), test_struct.clone(),), + assert_ne_struct, + call, + "assertion failed" + ); + + reverts_with_assert_ne_msg!( + (test_struct.clone(), test_struct.clone(),), + assert_ne_struct, + simulate, + "assertion failed" + ); + } + { + let test_enum = TestEnum::VariantOne; + reverts_with_assert_ne_msg!( + (test_enum.clone(), test_enum.clone(),), + assert_ne_enum, + call, + "assertion failed" + ); + + reverts_with_assert_ne_msg!( + (test_enum.clone(), test_enum.clone(),), + assert_ne_enum, + simulate, + "assertion failed" + ); + } + Ok(()) } @@ -1292,7 +1390,7 @@ async fn test_script_asserts_log() -> Result<()> { }; } - macro_rules! reverts_with_assert_eq_msg { + macro_rules! reverts_with_assert_eq_ne_msg { ($arg:expr, call, $msg:expr) => { let error = script_instance .main($arg) @@ -1323,15 +1421,15 @@ async fn test_script_asserts_log() -> Result<()> { ); } { - reverts_with_assert_eq_msg!( + reverts_with_assert_eq_ne_msg!( MatchEnum::AssertEqPrimitive((32, 64)), call, - "assertion failed" + "assertion failed: `(left == right)`" ); - reverts_with_assert_eq_msg!( + reverts_with_assert_eq_ne_msg!( MatchEnum::AssertEqPrimitive((32, 64)), simulate, - "assertion failed" + "assertion failed: `(left == right)`" ); } { @@ -1344,30 +1442,73 @@ async fn test_script_asserts_log() -> Result<()> { field_1: false, field_2: 32, }; - reverts_with_assert_eq_msg!( + reverts_with_assert_eq_ne_msg!( MatchEnum::AssertEqStruct((test_struct.clone(), test_struct2.clone(),)), call, - "assertion failed" + "assertion failed: `(left == right)`" ); - reverts_with_assert_eq_msg!( + reverts_with_assert_eq_ne_msg!( MatchEnum::AssertEqStruct((test_struct.clone(), test_struct2.clone(),)), simulate, - "assertion failed" + "assertion failed: `(left == right)`" ); } { let test_enum = TestEnum::VariantOne; let test_enum2 = TestEnum::VariantTwo; - reverts_with_assert_eq_msg!( + reverts_with_assert_eq_ne_msg!( MatchEnum::AssertEqEnum((test_enum.clone(), test_enum2.clone(),)), call, - "assertion failed" + "assertion failed: `(left == right)`" ); - reverts_with_assert_eq_msg!( + reverts_with_assert_eq_ne_msg!( MatchEnum::AssertEqEnum((test_enum.clone(), test_enum2.clone(),)), simulate, - "assertion failed" + "assertion failed: `(left == right)`" + ); + } + + { + reverts_with_assert_eq_ne_msg!( + MatchEnum::AssertNePrimitive((32, 32)), + call, + "assertion failed: `(left != right)`" + ); + reverts_with_assert_eq_ne_msg!( + MatchEnum::AssertNePrimitive((32, 32)), + simulate, + "assertion failed: `(left != right)`" + ); + } + { + let test_struct = TestStruct { + field_1: true, + field_2: 64, + }; + reverts_with_assert_eq_ne_msg!( + MatchEnum::AssertNeStruct((test_struct.clone(), test_struct.clone(),)), + call, + "assertion failed: `(left != right)`" + ); + reverts_with_assert_eq_ne_msg!( + MatchEnum::AssertNeStruct((test_struct.clone(), test_struct.clone(),)), + simulate, + "assertion failed: `(left != right)`" + ); + } + { + let test_enum = TestEnum::VariantOne; + + reverts_with_assert_eq_ne_msg!( + MatchEnum::AssertNeEnum((test_enum.clone(), test_enum.clone(),)), + call, + "assertion failed: `(left != right)`" + ); + reverts_with_assert_eq_ne_msg!( + MatchEnum::AssertNeEnum((test_enum.clone(), test_enum.clone(),)), + simulate, + "assertion failed: `(left != right)`" ); } diff --git a/packages/fuels-core/src/types/tx_status.rs b/packages/fuels-core/src/types/tx_status.rs index 7f90ac478d..c5dff11402 100644 --- a/packages/fuels-core/src/types/tx_status.rs +++ b/packages/fuels-core/src/types/tx_status.rs @@ -1,6 +1,6 @@ use fuel_abi_types::error_codes::{ - FAILED_ASSERT_EQ_SIGNAL, FAILED_ASSERT_SIGNAL, FAILED_REQUIRE_SIGNAL, - FAILED_SEND_MESSAGE_SIGNAL, FAILED_TRANSFER_TO_ADDRESS_SIGNAL, + FAILED_ASSERT_EQ_SIGNAL, FAILED_ASSERT_NE_SIGNAL, FAILED_ASSERT_SIGNAL, FAILED_REQUIRE_SIGNAL, + FAILED_SEND_MESSAGE_SIGNAL, FAILED_TRANSFER_TO_ADDRESS_SIGNAL, REVERT_WITH_LOG_SIGNAL, }; #[cfg(feature = "std")] use fuel_core_client::client::types::TransactionStatus as ClientTransactionStatus; @@ -56,6 +56,9 @@ impl TxStatus { (FAILED_REQUIRE_SIGNAL, Some(log_decoder)) => log_decoder .decode_last_log(receipts) .unwrap_or_else(|err| format!("failed to decode log from require revert: {err}")), + (REVERT_WITH_LOG_SIGNAL, Some(log_decoder)) => log_decoder + .decode_last_log(receipts) + .unwrap_or_else(|err| format!("failed to decode log from revert_with_log: {err}")), (FAILED_ASSERT_EQ_SIGNAL, Some(log_decoder)) => { match log_decoder.decode_last_two_logs(receipts) { Ok((lhs, rhs)) => format!( @@ -66,6 +69,16 @@ impl TxStatus { } } } + (FAILED_ASSERT_NE_SIGNAL, Some(log_decoder)) => { + match log_decoder.decode_last_two_logs(receipts) { + Ok((lhs, rhs)) => format!( + "assertion failed: `(left != right)`\n left: `{lhs:?}`\n right: `{rhs:?}`" + ), + Err(err) => { + format!("failed to decode log from assert_eq revert: {err}") + } + } + } (FAILED_ASSERT_SIGNAL, _) => "assertion failed".into(), (FAILED_SEND_MESSAGE_SIGNAL, _) => "failed to send message".into(), (FAILED_TRANSFER_TO_ADDRESS_SIGNAL, _) => "failed transfer to address".into(),