From 58535515e20bd91cca0a53f52ec8746ea1c043b5 Mon Sep 17 00:00:00 2001 From: Rodrigo Araujo Date: Wed, 24 Nov 2021 08:46:05 -0800 Subject: [PATCH] Require fuel_client for contract setup --- fuels-abigen-macro/Cargo.toml | 2 + fuels-abigen-macro/tests/harness.rs | 115 +++++++++++------- .../tests/test_projects/script_test/Forc.toml | 7 -- fuels-rs/Cargo.toml | 2 +- fuels-rs/src/code_gen/abigen.rs | 8 +- fuels-rs/src/code_gen/functions_gen.rs | 2 +- fuels-rs/src/contract.rs | 23 ++-- 7 files changed, 98 insertions(+), 61 deletions(-) diff --git a/fuels-abigen-macro/Cargo.toml b/fuels-abigen-macro/Cargo.toml index b41bddce1..ee94449c1 100644 --- a/fuels-abigen-macro/Cargo.toml +++ b/fuels-abigen-macro/Cargo.toml @@ -14,6 +14,8 @@ anyhow = "1" bytes = { version = "1.0.1", features = ["serde"] } forc = { git = "ssh://git@github.com/FuelLabs/sway.git", features = ["test", "util"], default-features = false } fuel-asm = { git = "ssh://git@github.com/FuelLabs/fuel-asm.git", features = ["serde-types"] } +fuel-client = { git = "ssh://git@github.com/FuelLabs/fuel-core", default-features = false} +fuel-core = { git = "ssh://git@github.com/FuelLabs/fuel-core", default-features = false} fuel-types = {git = "ssh://git@github.com/FuelLabs/fuel-types.git"} fuels-rs = {path = "../fuels-rs"} fuel-tx = { git = "ssh://git@github.com/FuelLabs/fuel-tx.git" } diff --git a/fuels-abigen-macro/tests/harness.rs b/fuels-abigen-macro/tests/harness.rs index 35ec55112..e2079ac3a 100644 --- a/fuels-abigen-macro/tests/harness.rs +++ b/fuels-abigen-macro/tests/harness.rs @@ -1,3 +1,5 @@ +use fuel_client::client::FuelClient; +use fuel_core::service::{Config, FuelService}; use fuel_tx::Salt; use fuels_abigen_macro::abigen; use fuels_rs::contract::Contract; @@ -6,8 +8,13 @@ use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; use sha2::{Digest, Sha256}; -#[test] -fn compile_bindings_from_contract_file() { +async fn setup_local_node() -> FuelClient { + let srv = FuelService::new_node(Config::local_node()).await.unwrap(); + FuelClient::from(srv.bound_address) +} + +#[tokio::test] +async fn compile_bindings_from_contract_file() { // Generates the bindings from an ABI definition in a JSON file // The generated bindings can be accessed through `SimpleContract`. abigen!( @@ -15,8 +22,10 @@ fn compile_bindings_from_contract_file() { "fuels-abigen-macro/tests/takes_ints_returns_bool.json" ); + let fuel_client = setup_local_node().await; + // `SimpleContract` is the name of the contract - let contract_instance = SimpleContract::new(Default::default()); + let contract_instance = SimpleContract::new(Default::default(), fuel_client); // Calls the function defined in the JSON ABI. // Note that this is type-safe, if the function does exist @@ -39,8 +48,8 @@ fn compile_bindings_from_contract_file() { assert_eq!("0000000003b568d4000000000000002a000000000000000a", encoded); } -#[test] -fn compile_bindings_from_inline_contract() { +#[tokio::test] +async fn compile_bindings_from_inline_contract() { // Generates the bindings from the an ABI definition inline. // The generated bindings can be accessed through `SimpleContract`. abigen!( @@ -71,7 +80,9 @@ fn compile_bindings_from_inline_contract() { "# ); - let contract_instance = SimpleContract::new(Default::default()); + let fuel_client = setup_local_node().await; + + let contract_instance = SimpleContract::new(Default::default(), fuel_client); let contract_call = contract_instance.takes_ints_returns_bool(42 as u32, 10 as u16); @@ -83,8 +94,8 @@ fn compile_bindings_from_inline_contract() { assert_eq!("0000000003b568d4000000000000002a000000000000000a", encoded); } -#[test] -fn compile_bindings_single_param() { +#[tokio::test] +async fn compile_bindings_single_param() { // Generates the bindings from the an ABI definition inline. // The generated bindings can be accessed through `SimpleContract`. abigen!( @@ -111,7 +122,9 @@ fn compile_bindings_single_param() { "# ); - let contract_instance = SimpleContract::new(Default::default()); + let fuel_client = setup_local_node().await; + + let contract_instance = SimpleContract::new(Default::default(), fuel_client); let contract_call = contract_instance.takes_ints_returns_bool(42 as u32); @@ -123,8 +136,8 @@ fn compile_bindings_single_param() { assert_eq!("000000009593586c000000000000002a", encoded); } -#[test] -fn compile_bindings_array_input() { +#[tokio::test] +async fn compile_bindings_array_input() { // Generates the bindings from the an ABI definition inline. // The generated bindings can be accessed through `SimpleContract`. abigen!( @@ -148,7 +161,9 @@ fn compile_bindings_array_input() { "# ); - let contract_instance = SimpleContract::new(Default::default()); + let fuel_client = setup_local_node().await; + + let contract_instance = SimpleContract::new(Default::default(), fuel_client); let input: Vec = vec![1, 2, 3, 4]; let contract_call = contract_instance.takes_array(input); @@ -164,8 +179,8 @@ fn compile_bindings_array_input() { ); } -#[test] -fn compile_bindings_bool_array_input() { +#[tokio::test] +async fn compile_bindings_bool_array_input() { // Generates the bindings from the an ABI definition inline. // The generated bindings can be accessed through `SimpleContract`. abigen!( @@ -189,7 +204,9 @@ fn compile_bindings_bool_array_input() { "# ); - let contract_instance = SimpleContract::new(Default::default()); + let fuel_client = setup_local_node().await; + + let contract_instance = SimpleContract::new(Default::default(), fuel_client); let input: Vec = vec![true, false, true]; let contract_call = contract_instance.takes_array(input); @@ -205,8 +222,8 @@ fn compile_bindings_bool_array_input() { ); } -#[test] -fn compile_bindings_byte_input() { +#[tokio::test] +async fn compile_bindings_byte_input() { // Generates the bindings from the an ABI definition inline. // The generated bindings can be accessed through `SimpleContract`. abigen!( @@ -230,7 +247,9 @@ fn compile_bindings_byte_input() { "# ); - let contract_instance = SimpleContract::new(Default::default()); + let fuel_client = setup_local_node().await; + + let contract_instance = SimpleContract::new(Default::default(), fuel_client); let contract_call = contract_instance.takes_byte(10 as u8); @@ -242,8 +261,8 @@ fn compile_bindings_byte_input() { assert_eq!("00000000a4bd3861000000000000000a", encoded); } -#[test] -fn compile_bindings_string_input() { +#[tokio::test] +async fn compile_bindings_string_input() { // Generates the bindings from the an ABI definition inline. // The generated bindings can be accessed through `SimpleContract`. abigen!( @@ -267,7 +286,9 @@ fn compile_bindings_string_input() { "# ); - let contract_instance = SimpleContract::new(Default::default()); + let fuel_client = setup_local_node().await; + + let contract_instance = SimpleContract::new(Default::default(), fuel_client); let contract_call = contract_instance.takes_string("This is a full sentence".into()); @@ -282,8 +303,8 @@ fn compile_bindings_string_input() { ); } -#[test] -fn compile_bindings_b256_input() { +#[tokio::test] +async fn compile_bindings_b256_input() { // Generates the bindings from the an ABI definition inline. // The generated bindings can be accessed through `SimpleContract`. abigen!( @@ -307,7 +328,9 @@ fn compile_bindings_b256_input() { "# ); - let contract_instance = SimpleContract::new(Default::default()); + let fuel_client = setup_local_node().await; + + let contract_instance = SimpleContract::new(Default::default(), fuel_client); let mut hasher = Sha256::new(); hasher.update("test string".as_bytes()); @@ -327,8 +350,8 @@ fn compile_bindings_b256_input() { ); } -#[test] -fn compile_bindings_struct_input() { +#[tokio::test] +async fn compile_bindings_struct_input() { // Generates the bindings from the an ABI definition inline. // The generated bindings can be accessed through `SimpleContract`. abigen!( @@ -360,6 +383,8 @@ fn compile_bindings_struct_input() { "# ); + let fuel_client = setup_local_node().await; + // Because of the abigen! macro, `MyStruct` is now in scope // and can be used! let input = MyStruct { @@ -367,7 +392,7 @@ fn compile_bindings_struct_input() { bar: true, }; - let contract_instance = SimpleContract::new(Default::default()); + let contract_instance = SimpleContract::new(Default::default(), fuel_client); let contract_call = contract_instance.takes_struct(input); @@ -379,8 +404,8 @@ fn compile_bindings_struct_input() { assert_eq!("00000000f5957fce000000000000000a0000000000000001", encoded); } -#[test] -fn compile_bindings_nested_struct_input() { +#[tokio::test] +async fn compile_bindings_nested_struct_input() { // Generates the bindings from the an ABI definition inline. // The generated bindings can be accessed through `SimpleContract`. abigen!( @@ -425,7 +450,9 @@ fn compile_bindings_nested_struct_input() { inner_struct, }; - let contract_instance = SimpleContract::new(Default::default()); + let fuel_client = setup_local_node().await; + + let contract_instance = SimpleContract::new(Default::default(), fuel_client); let contract_call = contract_instance.takes_nested_struct(input); @@ -437,8 +464,8 @@ fn compile_bindings_nested_struct_input() { assert_eq!("00000000e8a04d9c000000000000000a0000000000000001", encoded); } -#[test] -fn compile_bindings_enum_input() { +#[tokio::test] +async fn compile_bindings_enum_input() { // Generates the bindings from the an ABI definition inline. // The generated bindings can be accessed through `SimpleContract`. abigen!( @@ -472,7 +499,9 @@ fn compile_bindings_enum_input() { let variant = MyEnum::X(42); - let contract_instance = SimpleContract::new(Default::default()); + let fuel_client = setup_local_node().await; + + let contract_instance = SimpleContract::new(Default::default(), fuel_client); let contract_call = contract_instance.takes_enum(variant); @@ -484,8 +513,8 @@ fn compile_bindings_enum_input() { assert_eq!("000000009542a3c90000000000000000000000000000002a", encoded); } -#[test] -fn create_struct_from_decoded_tokens() { +#[tokio::test] +async fn create_struct_from_decoded_tokens() { // Generates the bindings from the an ABI definition inline. // The generated bindings can be accessed through `SimpleContract`. abigen!( @@ -528,7 +557,9 @@ fn create_struct_from_decoded_tokens() { assert_eq!(10 as u8, struct_from_tokens.foo); assert_eq!(true, struct_from_tokens.bar); - let contract_instance = SimpleContract::new(Default::default()); + let fuel_client = setup_local_node().await; + + let contract_instance = SimpleContract::new(Default::default(), fuel_client); let contract_call = contract_instance.takes_struct(struct_from_tokens); @@ -540,8 +571,8 @@ fn create_struct_from_decoded_tokens() { assert_eq!("00000000f5957fce000000000000000a0000000000000001", encoded); } -#[test] -fn create_nested_struct_from_decoded_tokens() { +#[tokio::test] +async fn create_nested_struct_from_decoded_tokens() { // Generates the bindings from the an ABI definition inline. // The generated bindings can be accessed through `SimpleContract`. abigen!( @@ -595,7 +626,9 @@ fn create_nested_struct_from_decoded_tokens() { assert_eq!(10 as u16, nested_struct_from_tokens.x); assert_eq!(true, nested_struct_from_tokens.inner_struct.a); - let contract_instance = SimpleContract::new(Default::default()); + let fuel_client = setup_local_node().await; + + let contract_instance = SimpleContract::new(Default::default(), fuel_client); let contract_call = contract_instance.takes_nested_struct(nested_struct_from_tokens); @@ -672,7 +705,7 @@ async fn example_workflow() { println!("Contract deployed @ {:x}", contract_id); - let contract_instance = MyContract::new(compiled); + let contract_instance = MyContract::new(compiled, fuel_client); let contract_call = contract_instance.initialize(42); @@ -680,6 +713,6 @@ async fn example_workflow() { // Soon it will be able to generate/craft the // `script_data` on the fly and dynamically call a // contract's function. - let res = contract_call.call(&fuel_client).await.unwrap(); + let res = contract_call.call().await.unwrap(); println!("res: {:?}\n", res); } diff --git a/fuels-abigen-macro/tests/test_projects/script_test/Forc.toml b/fuels-abigen-macro/tests/test_projects/script_test/Forc.toml index f4831e1f1..f88af91da 100644 --- a/fuels-abigen-macro/tests/test_projects/script_test/Forc.toml +++ b/fuels-abigen-macro/tests/test_projects/script_test/Forc.toml @@ -8,10 +8,3 @@ entry = "main.sw" [dependencies] std = { path = "../stdlib" } increment_abi = { path = "../library_test" } - -[[tx-input]] -type = "Contract" -contract-id = "0xe50103684750e4916cd9825b14cf7e6763ffcc6523a9e0af63de93dbd6e3d736" -utxo-id = "0xeeb578f9e1ebfb5b78f8ff74352370c120bc8cacead1f5e4f9c74aafe0ca6bfd" -balance-root = "0xeeb578f9e1ebfb5b78f8ff74352370c120bc8cacead1f5e4f9c74aafe0ca6bfd" -state-root = "0xeeb578f9e1ebfb5b78f8ff74352370c120bc8cacead1f5e4f9c74aafe0ca6bfd" diff --git a/fuels-rs/Cargo.toml b/fuels-rs/Cargo.toml index a1b05231d..9211a0ac9 100644 --- a/fuels-rs/Cargo.toml +++ b/fuels-rs/Cargo.toml @@ -37,4 +37,4 @@ url = "2.1" [[test]] name = "integration_tests" path = "tests/lib.rs" -harness = true \ No newline at end of file +harness = true diff --git a/fuels-rs/src/code_gen/abigen.rs b/fuels-rs/src/code_gen/abigen.rs index 79a668a7f..8dba4567e 100644 --- a/fuels-rs/src/code_gen/abigen.rs +++ b/fuels-rs/src/code_gen/abigen.rs @@ -92,14 +92,16 @@ impl Abigen { use fuels_rs::contract::{Contract, ContractCall, CompiledContract}; use fuels_rs::tokens::{Tokenizable, Token}; use fuels_rs::types::{EnumSelector}; + use fuel_client::client::FuelClient; pub struct #name { - compiled: CompiledContract + compiled: CompiledContract, + fuel_client: FuelClient } impl #name { - pub fn new(compiled: CompiledContract) -> Self { - Self{ compiled } + pub fn new(compiled: CompiledContract, fuel_client: FuelClient) -> Self { + Self{ compiled, fuel_client } } #contract_functions diff --git a/fuels-rs/src/code_gen/functions_gen.rs b/fuels-rs/src/code_gen/functions_gen.rs index 39691a675..fe0cef301 100644 --- a/fuels-rs/src/code_gen/functions_gen.rs +++ b/fuels-rs/src/code_gen/functions_gen.rs @@ -49,7 +49,7 @@ pub fn expand_function( Ok(quote! { #doc pub fn #name(&self #input) -> #result { - Contract::method_hash(&self.compiled, + Contract::method_hash(&self.fuel_client, &self.compiled, #tokenized_signature, #arg).expect("method not found (this should never happen)") } }) diff --git a/fuels-rs/src/contract.rs b/fuels-rs/src/contract.rs index 915ec81a9..52019cdb1 100644 --- a/fuels-rs/src/contract.rs +++ b/fuels-rs/src/contract.rs @@ -31,16 +31,12 @@ pub struct CompiledContract { /// Contract is a struct to interface with a contract. That includes things such as /// compiling, deploying, and running transactions against a contract. pub struct Contract { - pub contract_id: String, pub compiled_contract: CompiledContract, } impl Contract { - pub fn new(contract_id: String, compiled_contract: CompiledContract) -> Self { - Self { - contract_id, - compiled_contract, - } + pub fn new(compiled_contract: CompiledContract) -> Self { + Self { compiled_contract } } pub fn compute_contract_id(compiled_contract: &CompiledContract) -> ContractId { @@ -73,6 +69,13 @@ impl Contract { Opcode::RET(0x30), ]; + // @todo continue from here. + // Try deploying a contract with proper functions + // Then, try crafting `script_data` to contain + // the function selector and the arguments. + // Do it manually at first to validate that it works + // Then try and generalize it. + let script = script_ops.iter().copied().collect(); // To call a contract, `script_data` should be @@ -133,6 +136,7 @@ impl Contract { /// } /// For more details see `code_gen/functions_gen.rs`. pub fn method_hash( + fuel_client: &FuelClient, compiled_contract: &CompiledContract, signature: Selector, args: &[Token], @@ -171,6 +175,7 @@ impl Contract { compiled_contract: compiled_contract.clone(), encoded_params, encoded_selector, + fuel_client: fuel_client.clone(), // cheap clone behind the Arc tx, function: None, datatype: PhantomData, @@ -292,6 +297,8 @@ pub struct ContractCall { /// The raw transaction object pub tx: Transaction, + pub fuel_client: FuelClient, + pub compiled_contract: CompiledContract, /// The ABI of the function being called pub function: Option, // Temporarily an option @@ -306,9 +313,9 @@ impl ContractCall where D: Detokenize, { - pub async fn call(self, fuel_client: &FuelClient) -> Result, Error> { + pub async fn call(self) -> Result, Error> { let script = Script::new(self.tx); - Ok(script.call(fuel_client).await.unwrap()) + Ok(script.call(&self.fuel_client).await.unwrap()) } }