From a14870e078e5dadcbd268df458b781ca74f1e9b0 Mon Sep 17 00:00:00 2001 From: hal3e Date: Tue, 2 Jul 2024 13:59:49 +0200 Subject: [PATCH] feat: finalize support for `raw_slice` and `string_slice` (#1448) closes: https://github.com/FuelLabs/fuels-rs/issues/1152, https://github.com/FuelLabs/fuels-rs/issues/1158 --- .github/workflows/ci.yml | 4 +- e2e/Forc.toml | 6 +- .../types/contracts/string_slice/src/main.sw | 6 +- .../predicate_string_slice/Forc.toml | 5 ++ .../predicate_string_slice/src/main.sw | 5 ++ .../scripts/script_raw_slice/src/main.sw | 17 ++-- .../scripts/script_std_lib_string/src/main.sw | 6 +- .../scripts/script_string_slice/Forc.toml | 5 ++ .../scripts/script_string_slice/src/main.sw | 7 ++ e2e/tests/providers.rs | 2 +- e2e/tests/storage.rs | 44 +++++----- e2e/tests/types_contracts.rs | 18 ++-- e2e/tests/types_predicates.rs | 13 +++ e2e/tests/types_scripts.rs | 87 ++++++++++++------- examples/contracts/src/lib.rs | 4 +- 15 files changed, 148 insertions(+), 81 deletions(-) create mode 100644 e2e/sway/types/predicates/predicate_string_slice/Forc.toml create mode 100644 e2e/sway/types/predicates/predicate_string_slice/src/main.sw create mode 100644 e2e/sway/types/scripts/script_string_slice/Forc.toml create mode 100644 e2e/sway/types/scripts/script_string_slice/src/main.sw diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8aa223eec7..6c171e3246 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,8 +19,8 @@ env: FUEL_CORE_VERSION: 0.30.0 FUEL_CORE_PATCH_BRANCH: RUST_VERSION: 1.76.0 - FORC_VERSION: 0.60.0 - FORC_PATCH_BRANCH: "" + FORC_VERSION: 0.61.0 + FORC_PATCH_BRANCH: "xunilrj/fix-vec-memoverflow" FORC_PATCH_REVISION: "" NEXTEST_HIDE_PROGRESS_BAR: "true" NEXTEST_STATUS_LEVEL: "fail" diff --git a/e2e/Forc.toml b/e2e/Forc.toml index 663157f2e8..55fba74f15 100644 --- a/e2e/Forc.toml +++ b/e2e/Forc.toml @@ -89,6 +89,7 @@ members = [ 'sway/types/predicates/predicate_generics', 'sway/types/predicates/predicate_raw_slice', 'sway/types/predicates/predicate_std_lib_string', + 'sway/types/predicates/predicate_string_slice', 'sway/types/predicates/predicate_tuples', 'sway/types/predicates/predicate_u128', 'sway/types/predicates/predicate_u256', @@ -101,10 +102,9 @@ members = [ 'sway/types/scripts/script_bytes', 'sway/types/scripts/script_generics', 'sway/types/scripts/script_heap_types', - #TODO: Decide what to do with this test project once - # https://github.com/FuelLabs/sway/issues/5727 is resolved - # 'sway/types/scripts/script_raw_slice', + 'sway/types/scripts/script_raw_slice', 'sway/types/scripts/script_std_lib_string', + 'sway/types/scripts/script_string_slice', 'sway/types/scripts/script_tuples', 'sway/types/scripts/script_u128', 'sway/types/scripts/script_u256', diff --git a/e2e/sway/types/contracts/string_slice/src/main.sw b/e2e/sway/types/contracts/string_slice/src/main.sw index 3271275c7e..99919da2d9 100644 --- a/e2e/sway/types/contracts/string_slice/src/main.sw +++ b/e2e/sway/types/contracts/string_slice/src/main.sw @@ -1,11 +1,13 @@ contract; abi RawSliceContract { - fn return_str() -> str; + fn handles_str(input: str) -> str; } impl RawSliceContract for Contract { - fn return_str() -> str { + fn handles_str(input: str) -> str { + assert_eq(input, "contract-input"); + "contract-return" } } diff --git a/e2e/sway/types/predicates/predicate_string_slice/Forc.toml b/e2e/sway/types/predicates/predicate_string_slice/Forc.toml new file mode 100644 index 0000000000..74eb342b07 --- /dev/null +++ b/e2e/sway/types/predicates/predicate_string_slice/Forc.toml @@ -0,0 +1,5 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "predicate_string_slice" diff --git a/e2e/sway/types/predicates/predicate_string_slice/src/main.sw b/e2e/sway/types/predicates/predicate_string_slice/src/main.sw new file mode 100644 index 0000000000..29d0c4866c --- /dev/null +++ b/e2e/sway/types/predicates/predicate_string_slice/src/main.sw @@ -0,0 +1,5 @@ +predicate; + +fn main(input: str) -> bool { + input == "predicate-input" +} diff --git a/e2e/sway/types/scripts/script_raw_slice/src/main.sw b/e2e/sway/types/scripts/script_raw_slice/src/main.sw index 2d888eeb5a..d1752335ab 100644 --- a/e2e/sway/types/scripts/script_raw_slice/src/main.sw +++ b/e2e/sway/types/scripts/script_raw_slice/src/main.sw @@ -12,7 +12,7 @@ struct Wrapper { } fn validate_raw_slice(input: raw_slice) { - let vec: Vec = Vec::from(input); + let vec: Vec = Vec::from(input); require(vec.len() == 3, "raw slice len is not 3"); require( vec @@ -40,7 +40,7 @@ fn validate_vec(vec: Vec) { validate_raw_slice(vec.get(1).unwrap()); } -fn main(_arg: u64, wrapper: Wrapper>) -> raw_slice { +fn main(length: u8, wrapper: Wrapper>) -> raw_slice { if let SomeEnum::Second(enum_raw_slice) = wrapper.inner_enum { validate_raw_slice(enum_raw_slice); @@ -50,10 +50,11 @@ fn main(_arg: u64, wrapper: Wrapper>) -> raw_slice { validate_vec(wrapper.inner); - let mut rtn: Vec = Vec::new(); - rtn.push(1); - rtn.push(2); - rtn.push(3); - - rtn.as_raw_slice() + let mut vec = Vec::new(); + let mut counter = 0u8; + while counter < length { + vec.push(counter); + counter = counter + 1; + } + vec.as_raw_slice() } diff --git a/e2e/sway/types/scripts/script_std_lib_string/src/main.sw b/e2e/sway/types/scripts/script_std_lib_string/src/main.sw index 0f79560e31..577ea7fbf9 100644 --- a/e2e/sway/types/scripts/script_std_lib_string/src/main.sw +++ b/e2e/sway/types/scripts/script_std_lib_string/src/main.sw @@ -2,6 +2,8 @@ script; use std::string::String; -fn main(string: String) { - assert_eq(string, String::from_ascii_str("Hello World")); +fn main(string: String) -> String { + assert_eq(string, String::from_ascii_str("script-input")); + + String::from_ascii_str("script-return") } diff --git a/e2e/sway/types/scripts/script_string_slice/Forc.toml b/e2e/sway/types/scripts/script_string_slice/Forc.toml new file mode 100644 index 0000000000..61e215c0dd --- /dev/null +++ b/e2e/sway/types/scripts/script_string_slice/Forc.toml @@ -0,0 +1,5 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "script_string_slice" diff --git a/e2e/sway/types/scripts/script_string_slice/src/main.sw b/e2e/sway/types/scripts/script_string_slice/src/main.sw new file mode 100644 index 0000000000..f9d31cb712 --- /dev/null +++ b/e2e/sway/types/scripts/script_string_slice/src/main.sw @@ -0,0 +1,7 @@ +script; + +fn main(input: str) -> str { + assert_eq(input, "script-input"); + + "script-return" +} diff --git a/e2e/tests/providers.rs b/e2e/tests/providers.rs index 1174e7da02..d79bd21357 100644 --- a/e2e/tests/providers.rs +++ b/e2e/tests/providers.rs @@ -331,7 +331,7 @@ async fn test_gas_forwarded_defaults_to_tx_limit() -> Result<()> { ); // The gas used by the script to call a contract and forward remaining gas limit. - let gas_used_by_script = 255; + let gas_used_by_script = 249; let gas_limit = 225_883; let response = contract_instance .methods() diff --git a/e2e/tests/storage.rs b/e2e/tests/storage.rs index 290ebdd0bb..8f2d1bf6ef 100644 --- a/e2e/tests/storage.rs +++ b/e2e/tests/storage.rs @@ -1,5 +1,3 @@ -use std::str::FromStr; - use fuels::{ prelude::*, tx::StorageSlot, @@ -57,28 +55,32 @@ async fn test_init_storage_automatically() -> Result<()> { .deploy(&wallet, TxPolicies::default()) .await?; - let key1 = - Bytes32::from_str("de9090cb50e71c2588c773487d1da7066d0c719849a7e58dc8b6397a25c567c0") - .unwrap(); - let key2 = - Bytes32::from_str("f383b0ce51358be57daa3b725fe44acdb2d880604e367199080b4379c41bb6ed") - .unwrap(); - let contract_methods = MyContract::new(contract_id, wallet.clone()).methods(); + { + let key: Bytes32 = + "d95f4c8d717d52323d34c1118b3f0598a5ec3cabae386887507cabd6dd546a43".parse()?; - let value = contract_methods - .get_value_b256(Bits256(*key1)) - .call() - .await? - .value; - assert_eq!(value.0, [1u8; 32]); + let value = contract_methods + .get_value_b256(Bits256(*key)) + .call() + .await? + .value; + + assert_eq!(value.0, [1u8; 32]); + } + { + let key: Bytes32 = + "c979570128d5f52725e9a343a7f4992d8ed386d7c8cfd25f1c646c51c2ac6b4b".parse()?; + + let value = contract_methods + .get_value_u64(Bits256(*key)) + .call() + .await? + .value; + + assert_eq!(value, 64); + } - let value = contract_methods - .get_value_u64(Bits256(*key2)) - .call() - .await? - .value; - assert_eq!(value, 64); Ok(()) } diff --git a/e2e/tests/types_contracts.rs b/e2e/tests/types_contracts.rs index 6f1673eda2..7696ce16f4 100644 --- a/e2e/tests/types_contracts.rs +++ b/e2e/tests/types_contracts.rs @@ -1539,7 +1539,6 @@ async fn generics_test() -> Result<()> { 10u32, )], }; - contract_methods.complex_test(arg1.clone()).call().await?; } @@ -1547,7 +1546,7 @@ async fn generics_test() -> Result<()> { } #[tokio::test] -async fn test_vector() -> Result<()> { +async fn contract_vectors() -> Result<()> { setup_program_test!( Wallets("wallet"), Abigen(Contract( @@ -1976,7 +1975,7 @@ async fn test_bytes_as_input() -> Result<()> { } #[tokio::test] -async fn test_contract_raw_slice() -> Result<()> { +async fn contract_raw_slice() -> Result<()> { setup_program_test!( Wallets("wallet"), Abigen(Contract( @@ -2021,7 +2020,7 @@ async fn test_contract_raw_slice() -> Result<()> { } #[tokio::test] -async fn test_contract_returning_string_slice() -> Result<()> { +async fn contract_string_slice() -> Result<()> { setup_program_test!( Wallets("wallet"), Abigen(Contract( @@ -2037,16 +2036,17 @@ async fn test_contract_returning_string_slice() -> Result<()> { let contract_methods = contract_instance.methods(); - { - let response = contract_methods.return_str().call().await?; - assert_eq!(response.value, "contract-return"); - } + let response = contract_methods + .handles_str("contract-input".try_into()?) + .call() + .await?; + assert_eq!(response.value, "contract-return"); Ok(()) } #[tokio::test] -async fn test_contract_std_lib_string() -> Result<()> { +async fn contract_std_lib_string() -> Result<()> { setup_program_test!( Wallets("wallet"), Abigen(Contract( diff --git a/e2e/tests/types_predicates.rs b/e2e/tests/types_predicates.rs index fd18c6bb6a..6cca7dc44a 100644 --- a/e2e/tests/types_predicates.rs +++ b/e2e/tests/types_predicates.rs @@ -422,3 +422,16 @@ async fn predicate_handles_std_string() -> Result<()> { Ok(()) } + +#[tokio::test] +async fn predicate_string_slice() -> Result<()> { + abigen!(Predicate( + name = "MyPredicate", + abi = "e2e/sway/types/predicates/predicate_string_slice/out/release/predicate_string_slice-abi.json" + )); + + let data = MyPredicateEncoder::default().encode_data("predicate-input".try_into()?)?; + assert_predicate_spendable(data, "sway/types/predicates/predicate_string_slice").await?; + + Ok(()) +} diff --git a/e2e/tests/types_scripts.rs b/e2e/tests/types_scripts.rs index dcb00797c4..3a6585aa13 100644 --- a/e2e/tests/types_scripts.rs +++ b/e2e/tests/types_scripts.rs @@ -206,34 +206,32 @@ async fn main_function_vector_arguments() -> Result<()> { Ok(()) } -// TODO: Decide what to do with this test once -// https://github.com/FuelLabs/sway/issues/5727 is resolved -// #[tokio::test] -// async fn test_script_raw_slice() -> Result<()> { -// setup_program_test!( -// Wallets("wallet"), -// Abigen(Script( -// name = "BimBamScript", -// project = "e2e/sway/types/scripts/script_raw_slice", -// )), -// LoadScript( -// name = "script_instance", -// script = "BimBamScript", -// wallet = "wallet" -// ) -// ); - -// let raw_slice = RawSlice(vec![40, 41, 42]); -// let wrapper = Wrapper { -// inner: vec![raw_slice.clone(), raw_slice.clone()], -// inner_enum: SomeEnum::Second(raw_slice), -// }; - -// let rtn = script_instance.main(10, wrapper).call().await?.value; -// assert_eq!(rtn, RawSlice(vec![1, 2, 3])); - -// Ok(()) -// } +#[tokio::test] +async fn script_raw_slice() -> Result<()> { + setup_program_test!( + Wallets("wallet"), + Abigen(Script( + name = "BimBamScript", + project = "e2e/sway/types/scripts/script_raw_slice", + )), + LoadScript( + name = "script_instance", + script = "BimBamScript", + wallet = "wallet" + ) + ); + + let raw_slice = RawSlice(vec![40, 41, 42]); + let wrapper = Wrapper { + inner: vec![raw_slice.clone(), raw_slice.clone()], + inner_enum: SomeEnum::Second(raw_slice), + }; + + let rtn = script_instance.main(6, wrapper).call().await?.value; + assert_eq!(rtn, RawSlice(vec![0, 1, 2, 3, 4, 5])); + + Ok(()) +} #[tokio::test] async fn main_function_bytes_arguments() -> Result<()> { @@ -331,7 +329,7 @@ async fn script_handles_u256() -> Result<()> { } #[tokio::test] -async fn script_handles_std_string() -> Result<()> { +async fn script_std_string() -> Result<()> { setup_program_test!( Wallets("wallet"), Abigen(Script( @@ -345,8 +343,35 @@ async fn script_handles_std_string() -> Result<()> { ) ); - let arg = String::from("Hello World"); - script_instance.main(arg).call().await?; + let response = script_instance + .main("script-input".to_string()) + .call() + .await?; + assert_eq!(response.value, "script-return".to_string()); + + Ok(()) +} + +#[tokio::test] +async fn script_string_slice() -> Result<()> { + setup_program_test!( + Wallets("wallet"), + Abigen(Script( + name = "MyScript", + project = "e2e/sway/types/scripts/script_string_slice", + )), + LoadScript( + name = "script_instance", + script = "MyScript", + wallet = "wallet" + ) + ); + + let response = script_instance + .main("script-input".try_into()?) + .call() + .await?; + assert_eq!(response.value, "script-return"); Ok(()) } diff --git a/examples/contracts/src/lib.rs b/examples/contracts/src/lib.rs index ad2b8449c8..e722731f95 100644 --- a/examples/contracts/src/lib.rs +++ b/examples/contracts/src/lib.rs @@ -113,7 +113,7 @@ mod tests { .await?; // ANCHOR_END: contract_call_cost_estimation - let expected_gas = 2692; + let expected_gas = 2609; assert_eq!(transaction_cost.gas_used, expected_gas); @@ -610,7 +610,7 @@ mod tests { .await?; // ANCHOR_END: multi_call_cost_estimation - let expected_gas = 4191; + let expected_gas = 4076; assert_eq!(transaction_cost.gas_used, expected_gas);