From f7736998c2ce6f5aa13f1c138307db0403d17707 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 12 May 2023 11:43:15 +0100 Subject: [PATCH 01/27] Cherry picking changes from #1669 --- crates/e2e/src/builders.rs | 132 ------------------------- crates/e2e/src/client.rs | 118 +++++++++++++++++----- crates/e2e/src/lib.rs | 5 - crates/e2e/src/xts.rs | 8 +- crates/env/src/call/call_builder.rs | 2 + crates/env/src/call/execution_input.rs | 8 +- 6 files changed, 105 insertions(+), 168 deletions(-) diff --git a/crates/e2e/src/builders.rs b/crates/e2e/src/builders.rs index 3f8c80b9d77..ce51971148c 100644 --- a/crates/e2e/src/builders.rs +++ b/crates/e2e/src/builders.rs @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -use ink::codegen::TraitCallBuilder; use ink_env::{ call::{ utils::{ @@ -20,11 +19,8 @@ use ink_env::{ Set, Unset, }, - Call, - CallBuilder, CreateBuilder, ExecutionInput, - FromAccountId, }, Environment, }; @@ -59,131 +55,3 @@ where .exec_input() .encode() } - -/// Captures the encoded input for an `ink!` message call, together with the account id of -/// the contract being called. -#[derive(Debug, Clone)] -pub struct Message { - account_id: E::AccountId, - exec_input: Vec, - _return_type: std::marker::PhantomData, -} - -impl Message -where - E: Environment, -{ - /// Create a new message from the given account id and encoded message data. - pub fn new(account_id: E::AccountId, exec_input: Vec) -> Self { - Self { - account_id, - exec_input, - _return_type: Default::default(), - } - } - - /// The account id of the contract being called to invoke the message. - pub fn account_id(&self) -> &E::AccountId { - &self.account_id - } - - /// The encoded message data, comprised of the selector and the message arguments. - pub fn exec_input(&self) -> &[u8] { - &self.exec_input - } -} - -/// Convenience method for building messages for the default environment. -/// -/// # Note -/// -/// This is hardcoded to [`ink_env::DefaultEnvironment`] so the user does not have to -/// specify this generic parameter, which currently is hardcoded in the E2E testing suite. -pub fn build_message( - account_id: ::AccountId, -) -> MessageBuilder -where - Ref: TraitCallBuilder + FromAccountId, -{ - MessageBuilder::from_account_id(account_id) -} - -/// Build messages using a contract ref. -pub struct MessageBuilder { - account_id: E::AccountId, - contract_ref: Ref, -} - -impl MessageBuilder -where - E: Environment, - Ref: TraitCallBuilder + FromAccountId, -{ - /// Create a new [`MessageBuilder`] to invoke a message on the given contract. - pub fn from_account_id(account_id: E::AccountId) -> Self { - let contract_ref = >::from_account_id(account_id.clone()); - Self { - account_id, - contract_ref, - } - } - - /// Build an encoded call for a message from a [`CallBuilder`] instance returned from - /// a contract ref method. - /// - /// This utilizes the generated message inherent methods on the contract ref - /// implementation, which returns a [`CallBuilder`] initialized with the selector - /// and message arguments. - /// - /// # Example - /// ``` - /// # #[ink::contract] - /// # pub mod my_contract { - /// # - /// # #[ink(storage)] - /// # pub struct MyContract { } - /// # - /// # impl MyContract { - /// # #[ink(constructor)] - /// # pub fn new() -> Self { - /// # Self {} - /// # } - /// # - /// # #[ink(message)] - /// # pub fn message(&self) {} - /// # } - /// # } - /// # - /// # fn message_builder_doc_test() { - /// # use my_contract::MyContractRef; - /// # let contract_acc_id = ink_primitives::AccountId::from([0x00; 32]); - /// ink_e2e::MessageBuilder::::from_account_id( - /// contract_acc_id, - /// ) - /// .call(|contract| contract.message()); - /// # } - /// ``` - - pub fn call(mut self, mut message: F) -> Message - where - F: FnMut( - &mut ::Builder, - ) -> CallBuilder< - E, - Set>, - Set>, - Set>, - >, - Args: scale::Encode, - RetType: scale::Decode, - { - let call_builder = ::call_mut(&mut self.contract_ref); - let builder = message(call_builder); - let exec_input = builder.params().exec_input().encode(); - Message { - account_id: self.account_id.clone(), - exec_input, - _return_type: Default::default(), - } - } -} diff --git a/crates/e2e/src/client.rs b/crates/e2e/src/client.rs index 8165f7f6a7a..e501d8d0bd7 100644 --- a/crates/e2e/src/client.rs +++ b/crates/e2e/src/client.rs @@ -16,7 +16,6 @@ use super::{ builders::{ constructor_exec_input, CreateBuilderPartial, - Message, }, log_error, log_info, @@ -27,7 +26,21 @@ use super::{ ContractsApi, Signer, }; -use ink_env::Environment; +use ink::codegen::ContractCallBuilder; +use ink_env::{ + call::{ + utils::{ + ReturnType, + Set, + }, + Call, + CallBuilder, + ExecutionInput, + FromAccountId, + }, + ContractReference, + Environment, +}; use ink_primitives::MessageResult; use pallet_contracts_primitives::ExecReturnValue; use sp_core::Pair; @@ -56,9 +69,15 @@ use subxt::{ }; /// Result of a contract instantiation. -pub struct InstantiationResult { +pub struct InstantiationResult< + C: subxt::Config, + E: Environment, + Contract: ContractCallBuilder, +> { /// The account id at which the contract was instantiated. pub account_id: E::AccountId, + /// Call builder for constructing calls, + pub call_builder: ::Type, /// The result of the dry run, contains debug messages /// if there were any. pub dry_run: ContractInstantiateResult, @@ -66,6 +85,17 @@ pub struct InstantiationResult { pub events: ExtrinsicEvents, } +impl InstantiationResult +where + C: subxt::Config, + E: Environment, + Contract: ContractCallBuilder, +{ + pub fn call(&mut self) -> &mut ::Type { + &mut self.call_builder + } +} + /// Result of a contract upload. pub struct UploadResult { /// The hash with which the contract can be instantiated. @@ -97,13 +127,14 @@ where /// We implement a custom `Debug` here, as to avoid requiring the trait /// bound `Debug` for `E`. -impl core::fmt::Debug for InstantiationResult +impl core::fmt::Debug for InstantiationResult where C: subxt::Config, C::AccountId: Debug, E: Environment, ::AccountId: Debug, ::Balance: Debug, + Contract: ContractCallBuilder, { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { f.debug_struct("InstantiationResult") @@ -465,15 +496,22 @@ where /// Calling this function multiple times is idempotent, the contract is /// newly instantiated each time using a unique salt. No existing contract /// instance is reused! - pub async fn instantiate( + pub async fn instantiate( &mut self, contract_name: &str, signer: &Signer, - constructor: CreateBuilderPartial, + constructor: CreateBuilderPartial< + E, + ::Type, + Args, + R, + >, value: E::Balance, storage_deposit_limit: Option, - ) -> Result, Error> + ) -> Result, Error> where + Contract: ContractCallBuilder + ContractReference, + ::Type: FromAccountId, Args: scale::Encode, { let code = self.load_code(contract_name); @@ -485,11 +523,11 @@ where } /// Dry run contract instantiation using the given constructor. - pub async fn instantiate_dry_run( + pub async fn instantiate_dry_run( &mut self, contract_name: &str, signer: &Signer, - constructor: CreateBuilderPartial, + constructor: CreateBuilderPartial, value: E::Balance, storage_deposit_limit: Option, ) -> ContractInstantiateResult @@ -533,15 +571,22 @@ where } /// Executes an `instantiate_with_code` call and captures the resulting events. - async fn exec_instantiate( + async fn exec_instantiate( &mut self, signer: &Signer, code: Vec, - constructor: CreateBuilderPartial, + constructor: CreateBuilderPartial< + E, + ::Type, + Args, + R, + >, value: E::Balance, storage_deposit_limit: Option, - ) -> Result, Error> + ) -> Result, Error> where + Contract: ContractCallBuilder + ContractReference, + ::Type: FromAccountId, Args: scale::Encode, { let salt = Self::salt(); @@ -613,12 +658,17 @@ where return Err(Error::InstantiateExtrinsic(dispatch_error)) } } + let account_id = account_id.expect("cannot extract `account_id` from events"); + let call_builder = <::Type as FromAccountId< + E, + >>::from_account_id(account_id.clone()); Ok(InstantiationResult { dry_run, + call_builder, // The `account_id` must exist at this point. If the instantiation fails // the dry-run must already return that. - account_id: account_id.expect("cannot extract `account_id` from events"), + account_id, events: tx_events, }) } @@ -729,19 +779,29 @@ where /// /// Returns when the transaction is included in a block. The return value /// contains all events that are associated with this transaction. - pub async fn call( + pub async fn call( &mut self, signer: &Signer, - message: Message, + message: &CallBuilder< + E, + Set>, + Set>, + Set>, + >, value: E::Balance, storage_deposit_limit: Option, ) -> Result, Error> where + Args: scale::Encode, RetType: scale::Decode, + CallBuilder>, Set>, Set>>: + Clone, { - log_info(&format!("call: {:02X?}", message.exec_input())); + let account_id = message.clone().params().callee().clone(); + let exec_input = scale::Encode::encode(message.clone().params().exec_input()); + log_info(&format!("call: {:02X?}", exec_input)); - let dry_run = self.call_dry_run(signer, &message, value, None).await; + let dry_run = self.call_dry_run(signer, message, value, None).await; if dry_run.exec_result.result.is_err() { return Err(Error::CallDryRun(dry_run.exec_result)) @@ -750,11 +810,11 @@ where let tx_events = self .api .call( - subxt::utils::MultiAddress::Id(message.account_id().clone()), + subxt::utils::MultiAddress::Id(account_id.clone()), value, dry_run.exec_result.gas_required.into(), storage_deposit_limit, - message.exec_input().to_vec(), + exec_input, signer, ) .await; @@ -826,21 +886,33 @@ where /// /// Returns the result of the dry run, together with the decoded return value of the /// invoked message. - pub async fn call_dry_run( + pub async fn call_dry_run( &mut self, signer: &Signer, - message: &Message, + message: &CallBuilder< + E, + Set>, + Set>, + Set>, + >, value: E::Balance, storage_deposit_limit: Option, ) -> CallDryRunResult where + Args: scale::Encode, RetType: scale::Decode, + CallBuilder>, Set>, Set>>: + Clone, { + let dest = message.clone().params().callee().clone(); + let exec_input = scale::Encode::encode(message.clone().params().exec_input()); + let exec_result = self .api - .call_dry_run( + .call_dry_run::( Signer::account_id(signer).clone(), - message, + dest, + exec_input, value, storage_deposit_limit, ) diff --git a/crates/e2e/src/lib.rs b/crates/e2e/src/lib.rs index f451f61e784..d6732b39a0a 100644 --- a/crates/e2e/src/lib.rs +++ b/crates/e2e/src/lib.rs @@ -25,11 +25,6 @@ mod default_accounts; mod node_proc; mod xts; -pub use builders::{ - build_message, - Message, - MessageBuilder, -}; pub use client::{ CallDryRunResult, CallResult, diff --git a/crates/e2e/src/xts.rs b/crates/e2e/src/xts.rs index ffccdb344c1..9a2db5428d7 100644 --- a/crates/e2e/src/xts.rs +++ b/crates/e2e/src/xts.rs @@ -13,7 +13,6 @@ // limitations under the License. use super::{ - builders::Message, log_info, sr25519, ContractExecResult, @@ -416,17 +415,18 @@ where pub async fn call_dry_run( &self, origin: C::AccountId, - message: &Message, + dest: E::AccountId, + input_data: Vec, value: E::Balance, storage_deposit_limit: Option, ) -> ContractExecResult { let call_request = RpcCallRequest:: { origin, - dest: message.account_id().clone(), + dest, value, gas_limit: None, storage_deposit_limit, - input_data: message.exec_input().to_vec(), + input_data, }; let func = "ContractsApi_call"; let params = rpc_params![func, Bytes(scale::Encode::encode(&call_request))]; diff --git a/crates/env/src/call/call_builder.rs b/crates/env/src/call/call_builder.rs index c0c5114f7ff..50875acc703 100644 --- a/crates/env/src/call/call_builder.rs +++ b/crates/env/src/call/call_builder.rs @@ -332,6 +332,7 @@ where /// The default call type for cross-contract calls. Performs a cross-contract call to /// `callee` with gas limit `gas_limit`, transferring `transferred_value` of currency. +#[derive(Clone)] pub struct Call { callee: E::AccountId, gas_limit: Gas, @@ -392,6 +393,7 @@ impl DelegateCall { } /// Builds up a cross contract call. +#[derive(Clone)] pub struct CallBuilder where E: Environment, diff --git a/crates/env/src/call/execution_input.rs b/crates/env/src/call/execution_input.rs index fb491468522..9ed23c53039 100644 --- a/crates/env/src/call/execution_input.rs +++ b/crates/env/src/call/execution_input.rs @@ -15,7 +15,7 @@ use crate::call::Selector; /// The input data for a smart contract execution. -#[derive(Default, Debug)] +#[derive(Clone, Default, Debug)] pub struct ExecutionInput { /// The selector for the smart contract execution. selector: Selector, @@ -80,7 +80,7 @@ impl ExecutionInput { /// arguments. The potentially heap allocating encoding is done right at the end /// where we can leverage the static environmental buffer instead of allocating /// heap memory. -#[derive(Default, Debug)] +#[derive(Clone, Default, Debug)] pub struct ArgumentList { /// The first argument of the argument list. head: Head, @@ -92,7 +92,7 @@ pub struct ArgumentList { pub type ArgsList = ArgumentList, Rest>; /// A single argument and its reference to a known value. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct Argument { /// The reference to the known value. /// @@ -109,7 +109,7 @@ impl Argument { } /// The end of an argument list. -#[derive(Default, Debug)] +#[derive(Clone, Default, Debug)] pub struct ArgumentListEnd; /// An empty argument list. From 46931327350a310f39e12333c9d2693560c71630 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 12 May 2023 12:06:54 +0100 Subject: [PATCH 02/27] Don't display verbose Debug message for module error. --- crates/e2e/src/client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/e2e/src/client.rs b/crates/e2e/src/client.rs index e501d8d0bd7..e26a2fcb74d 100644 --- a/crates/e2e/src/client.rs +++ b/crates/e2e/src/client.rs @@ -829,7 +829,7 @@ where let dispatch_error = subxt::error::DispatchError::decode_from(evt.field_bytes(), metadata) .map_err(Error::Decoding)?; - log_error(&format!("extrinsic for call failed: {dispatch_error:?}")); + log_error(&format!("extrinsic for call failed: {dispatch_error}")); return Err(Error::CallExtrinsic(dispatch_error)) } } From ad372d180c0d18452cfcc7c45dec5030b3e8426b Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 12 May 2023 12:07:39 +0100 Subject: [PATCH 03/27] Initial conversion of erc20 to use new call --- crates/e2e/src/client.rs | 2 +- integration-tests/erc20/lib.rs | 84 ++++++++++++++++------------------ 2 files changed, 41 insertions(+), 45 deletions(-) diff --git a/crates/e2e/src/client.rs b/crates/e2e/src/client.rs index e26a2fcb74d..6bec0b209ff 100644 --- a/crates/e2e/src/client.rs +++ b/crates/e2e/src/client.rs @@ -496,7 +496,7 @@ where /// Calling this function multiple times is idempotent, the contract is /// newly instantiated each time using a unique salt. No existing contract /// instance is reused! - pub async fn instantiate( + pub async fn instantiate( &mut self, contract_name: &str, signer: &Signer, diff --git a/integration-tests/erc20/lib.rs b/integration-tests/erc20/lib.rs index 4a26e5ed30f..15e9f2db2e6 100644 --- a/integration-tests/erc20/lib.rs +++ b/integration-tests/erc20/lib.rs @@ -537,7 +537,6 @@ mod erc20 { #[cfg(all(test, feature = "e2e-tests"))] mod e2e_tests { use super::*; - use ink_e2e::build_message; type E2EResult = std::result::Result>; #[ink_e2e::test] @@ -545,30 +544,27 @@ mod erc20 { // given let total_supply = 1_000_000_000; let constructor = Erc20Ref::new(total_supply); - let contract_acc_id = client - .instantiate("erc20", &ink_e2e::alice(), constructor, 0, None) + let mut erc20 = client + // todo: would be nice to not require type param hint here. + .instantiate::("erc20", &ink_e2e::alice(), constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); // when - let total_supply_msg = build_message::(contract_acc_id.clone()) - .call(|erc20| erc20.total_supply()); + let total_supply_msg = erc20.call().total_supply(); let total_supply_res = client .call_dry_run(&ink_e2e::bob(), &total_supply_msg, 0, None) .await; let bob_account = ink_e2e::account_id(ink_e2e::AccountKeyring::Bob); let transfer_to_bob = 500_000_000u128; - let transfer = build_message::(contract_acc_id.clone()) - .call(|erc20| erc20.transfer(bob_account.clone(), transfer_to_bob)); + let transfer = erc20.call().transfer(bob_account.clone(), transfer_to_bob); let _transfer_res = client - .call(&ink_e2e::alice(), transfer, 0, None) + .call(&ink_e2e::alice(), &transfer, 0, None) .await .expect("transfer failed"); - let balance_of = build_message::(contract_acc_id.clone()) - .call(|erc20| erc20.balance_of(bob_account)); + let balance_of = erc20.call().balance_of(bob_account); let balance_of_res = client .call_dry_run(&ink_e2e::alice(), &balance_of, 0, None) .await; @@ -589,11 +585,16 @@ mod erc20 { // given let total_supply = 1_000_000_000; let constructor = Erc20Ref::new(total_supply); - let contract_acc_id = client - .instantiate("erc20", &ink_e2e::bob(), constructor, 0, None) + let mut erc20 = client + .instantiate::( + "erc20", + &ink_e2e::bob(), + constructor, + 0, + None, + ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); // when @@ -601,16 +602,13 @@ mod erc20 { let charlie_account = ink_e2e::account_id(ink_e2e::AccountKeyring::Charlie); let amount = 500_000_000u128; - let transfer_from = - build_message::(contract_acc_id.clone()).call(|erc20| { - erc20.transfer_from( - bob_account.clone(), - charlie_account.clone(), - amount, - ) - }); + let transfer_from = erc20.call().transfer_from( + bob_account.clone(), + charlie_account.clone(), + amount, + ); let transfer_from_result = client - .call(&ink_e2e::charlie(), transfer_from, 0, None) + .call(&ink_e2e::charlie(), &transfer_from, 0, None) .await; assert!( @@ -620,43 +618,41 @@ mod erc20 { // Bob approves Charlie to transfer up to amount on his behalf let approved_value = 1_000u128; - let approve_call = build_message::(contract_acc_id.clone()) - .call(|erc20| erc20.approve(charlie_account.clone(), approved_value)); + let approve_call = erc20 + .call() + .approve(charlie_account.clone(), approved_value); client - .call(&ink_e2e::bob(), approve_call, 0, None) + .call(&ink_e2e::bob(), &approve_call, 0, None) .await .expect("approve failed"); // `transfer_from` the approved amount - let transfer_from = - build_message::(contract_acc_id.clone()).call(|erc20| { - erc20.transfer_from( - bob_account.clone(), - charlie_account.clone(), - approved_value, - ) - }); + let transfer_from = erc20.call().transfer_from( + bob_account.clone(), + charlie_account.clone(), + approved_value, + ); let transfer_from_result = client - .call(&ink_e2e::charlie(), transfer_from, 0, None) + .call(&ink_e2e::charlie(), &transfer_from, 0, None) .await; assert!( transfer_from_result.is_ok(), "approved transfer_from should succeed" ); - let balance_of = build_message::(contract_acc_id.clone()) - .call(|erc20| erc20.balance_of(bob_account)); + let balance_of = erc20.call().balance_of(bob_account); let balance_of_res = client .call_dry_run(&ink_e2e::alice(), &balance_of, 0, None) .await; // `transfer_from` again, this time exceeding the approved amount - let transfer_from = - build_message::(contract_acc_id.clone()).call(|erc20| { - erc20.transfer_from(bob_account.clone(), charlie_account.clone(), 1) - }); + let transfer_from = erc20.call().transfer_from( + bob_account.clone(), + charlie_account.clone(), + 1, + ); let transfer_from_result = client - .call(&ink_e2e::charlie(), transfer_from, 0, None) + .call(&ink_e2e::charlie(), &transfer_from, 0, None) .await; assert!( transfer_from_result.is_err(), From d4c95705006a3c48dd0927c2e80a98739f5e94ae Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 12 May 2023 12:16:33 +0100 Subject: [PATCH 04/27] Remove constraint from InstantiationResult --- crates/e2e/src/client.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/crates/e2e/src/client.rs b/crates/e2e/src/client.rs index 6bec0b209ff..fce3f0886ba 100644 --- a/crates/e2e/src/client.rs +++ b/crates/e2e/src/client.rs @@ -72,12 +72,12 @@ use subxt::{ pub struct InstantiationResult< C: subxt::Config, E: Environment, - Contract: ContractCallBuilder, + CallBuilder, > { /// The account id at which the contract was instantiated. pub account_id: E::AccountId, /// Call builder for constructing calls, - pub call_builder: ::Type, + pub call_builder: CallBuilder, /// The result of the dry run, contains debug messages /// if there were any. pub dry_run: ContractInstantiateResult, @@ -85,13 +85,12 @@ pub struct InstantiationResult< pub events: ExtrinsicEvents, } -impl InstantiationResult +impl InstantiationResult where C: subxt::Config, E: Environment, - Contract: ContractCallBuilder, { - pub fn call(&mut self) -> &mut ::Type { + pub fn call(&mut self) -> &mut CallBuilder { &mut self.call_builder } } @@ -508,7 +507,7 @@ where >, value: E::Balance, storage_deposit_limit: Option, - ) -> Result, Error> + ) -> Result::Type>, Error> where Contract: ContractCallBuilder + ContractReference, ::Type: FromAccountId, @@ -516,7 +515,7 @@ where { let code = self.load_code(contract_name); let ret = self - .exec_instantiate(signer, code, constructor, value, storage_deposit_limit) + .exec_instantiate::(signer, code, constructor, value, storage_deposit_limit) .await?; log_info(&format!("instantiated contract at {:?}", ret.account_id)); Ok(ret) @@ -583,7 +582,7 @@ where >, value: E::Balance, storage_deposit_limit: Option, - ) -> Result, Error> + ) -> Result::Type>, Error> where Contract: ContractCallBuilder + ContractReference, ::Type: FromAccountId, From e733996aa2623b63fca71c3c44bc8ce2b124aa98 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 17 May 2023 14:12:53 +0100 Subject: [PATCH 05/27] Use 3.0.0 release --- crates/e2e/macro/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/e2e/macro/Cargo.toml b/crates/e2e/macro/Cargo.toml index f3a95164976..2cace41bab1 100644 --- a/crates/e2e/macro/Cargo.toml +++ b/crates/e2e/macro/Cargo.toml @@ -21,7 +21,7 @@ proc-macro = true [dependencies] ink_ir = { version = "4.2.0", path = "../../ink/ir" } cargo_metadata = "0.15.3" -contract-build = "2.0.2" +contract-build = "3.0.0" derive_more = "0.99.17" tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } serde_json = "1.0.89" From ffc218f1ab06cc8b8638792f436ad65ab27b9050 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 17 May 2023 14:13:16 +0100 Subject: [PATCH 06/27] Revert "Use 3.0.0 release" This reverts commit e733996aa2623b63fca71c3c44bc8ce2b124aa98. --- crates/e2e/macro/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/e2e/macro/Cargo.toml b/crates/e2e/macro/Cargo.toml index 2cace41bab1..f3a95164976 100644 --- a/crates/e2e/macro/Cargo.toml +++ b/crates/e2e/macro/Cargo.toml @@ -21,7 +21,7 @@ proc-macro = true [dependencies] ink_ir = { version = "4.2.0", path = "../../ink/ir" } cargo_metadata = "0.15.3" -contract-build = "3.0.0" +contract-build = "2.0.2" derive_more = "0.99.17" tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } serde_json = "1.0.89" From feaa89b38b2be8b464b275d0b084dcc6ffc1e126 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 17 May 2023 15:37:35 +0100 Subject: [PATCH 07/27] Move instantiate generic parameter --- crates/e2e/src/client.rs | 58 +++++++++++++--------------------- integration-tests/erc20/lib.rs | 45 ++++++++++---------------- 2 files changed, 38 insertions(+), 65 deletions(-) diff --git a/crates/e2e/src/client.rs b/crates/e2e/src/client.rs index fce3f0886ba..926ddd99ae1 100644 --- a/crates/e2e/src/client.rs +++ b/crates/e2e/src/client.rs @@ -38,7 +38,6 @@ use ink_env::{ ExecutionInput, FromAccountId, }, - ContractReference, Environment, }; use ink_primitives::MessageResult; @@ -69,15 +68,9 @@ use subxt::{ }; /// Result of a contract instantiation. -pub struct InstantiationResult< - C: subxt::Config, - E: Environment, - CallBuilder, -> { +pub struct InstantiationResult { /// The account id at which the contract was instantiated. pub account_id: E::AccountId, - /// Call builder for constructing calls, - pub call_builder: CallBuilder, /// The result of the dry run, contains debug messages /// if there were any. pub dry_run: ContractInstantiateResult, @@ -85,13 +78,19 @@ pub struct InstantiationResult< pub events: ExtrinsicEvents, } -impl InstantiationResult +impl InstantiationResult where C: subxt::Config, E: Environment, { - pub fn call(&mut self) -> &mut CallBuilder { - &mut self.call_builder + pub fn call(&self) -> ::Type + where + Contract: ContractCallBuilder, + ::Type: FromAccountId, + { + <::Type as FromAccountId>::from_account_id( + self.account_id.clone(), + ) } } @@ -126,14 +125,13 @@ where /// We implement a custom `Debug` here, as to avoid requiring the trait /// bound `Debug` for `E`. -impl core::fmt::Debug for InstantiationResult +impl core::fmt::Debug for InstantiationResult where C: subxt::Config, C::AccountId: Debug, E: Environment, ::AccountId: Debug, ::Balance: Debug, - Contract: ContractCallBuilder, { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { f.debug_struct("InstantiationResult") @@ -499,23 +497,22 @@ where &mut self, contract_name: &str, signer: &Signer, - constructor: CreateBuilderPartial< - E, - ::Type, - Args, - R, - >, + constructor: CreateBuilderPartial, value: E::Balance, storage_deposit_limit: Option, - ) -> Result::Type>, Error> + ) -> Result, Error> where - Contract: ContractCallBuilder + ContractReference, - ::Type: FromAccountId, Args: scale::Encode, { let code = self.load_code(contract_name); let ret = self - .exec_instantiate::(signer, code, constructor, value, storage_deposit_limit) + .exec_instantiate::( + signer, + code, + constructor, + value, + storage_deposit_limit, + ) .await?; log_info(&format!("instantiated contract at {:?}", ret.account_id)); Ok(ret) @@ -574,18 +571,11 @@ where &mut self, signer: &Signer, code: Vec, - constructor: CreateBuilderPartial< - E, - ::Type, - Args, - R, - >, + constructor: CreateBuilderPartial, value: E::Balance, storage_deposit_limit: Option, - ) -> Result::Type>, Error> + ) -> Result, Error> where - Contract: ContractCallBuilder + ContractReference, - ::Type: FromAccountId, Args: scale::Encode, { let salt = Self::salt(); @@ -658,13 +648,9 @@ where } } let account_id = account_id.expect("cannot extract `account_id` from events"); - let call_builder = <::Type as FromAccountId< - E, - >>::from_account_id(account_id.clone()); Ok(InstantiationResult { dry_run, - call_builder, // The `account_id` must exist at this point. If the instantiation fails // the dry-run must already return that. account_id, diff --git a/integration-tests/erc20/lib.rs b/integration-tests/erc20/lib.rs index 15e9f2db2e6..dda45cd9b85 100644 --- a/integration-tests/erc20/lib.rs +++ b/integration-tests/erc20/lib.rs @@ -544,27 +544,27 @@ mod erc20 { // given let total_supply = 1_000_000_000; let constructor = Erc20Ref::new(total_supply); - let mut erc20 = client - // todo: would be nice to not require type param hint here. - .instantiate::("erc20", &ink_e2e::alice(), constructor, 0, None) + let erc20 = client + .instantiate("erc20", &ink_e2e::alice(), constructor, 0, None) .await .expect("instantiate failed"); + let mut call = erc20.call::(); // when - let total_supply_msg = erc20.call().total_supply(); + let total_supply_msg = call.total_supply(); let total_supply_res = client .call_dry_run(&ink_e2e::bob(), &total_supply_msg, 0, None) .await; let bob_account = ink_e2e::account_id(ink_e2e::AccountKeyring::Bob); let transfer_to_bob = 500_000_000u128; - let transfer = erc20.call().transfer(bob_account.clone(), transfer_to_bob); + let transfer = call.transfer(bob_account.clone(), transfer_to_bob); let _transfer_res = client .call(&ink_e2e::alice(), &transfer, 0, None) .await .expect("transfer failed"); - let balance_of = erc20.call().balance_of(bob_account); + let balance_of = call.balance_of(bob_account); let balance_of_res = client .call_dry_run(&ink_e2e::alice(), &balance_of, 0, None) .await; @@ -585,16 +585,11 @@ mod erc20 { // given let total_supply = 1_000_000_000; let constructor = Erc20Ref::new(total_supply); - let mut erc20 = client - .instantiate::( - "erc20", - &ink_e2e::bob(), - constructor, - 0, - None, - ) + let erc20 = client + .instantiate("erc20", &ink_e2e::bob(), constructor, 0, None) .await .expect("instantiate failed"); + let mut call = erc20.call::(); // when @@ -602,11 +597,8 @@ mod erc20 { let charlie_account = ink_e2e::account_id(ink_e2e::AccountKeyring::Charlie); let amount = 500_000_000u128; - let transfer_from = erc20.call().transfer_from( - bob_account.clone(), - charlie_account.clone(), - amount, - ); + let transfer_from = + call.transfer_from(bob_account.clone(), charlie_account.clone(), amount); let transfer_from_result = client .call(&ink_e2e::charlie(), &transfer_from, 0, None) .await; @@ -618,16 +610,14 @@ mod erc20 { // Bob approves Charlie to transfer up to amount on his behalf let approved_value = 1_000u128; - let approve_call = erc20 - .call() - .approve(charlie_account.clone(), approved_value); + let approve_call = call.approve(charlie_account.clone(), approved_value); client .call(&ink_e2e::bob(), &approve_call, 0, None) .await .expect("approve failed"); // `transfer_from` the approved amount - let transfer_from = erc20.call().transfer_from( + let transfer_from = call.transfer_from( bob_account.clone(), charlie_account.clone(), approved_value, @@ -640,17 +630,14 @@ mod erc20 { "approved transfer_from should succeed" ); - let balance_of = erc20.call().balance_of(bob_account); + let balance_of = call.balance_of(bob_account); let balance_of_res = client .call_dry_run(&ink_e2e::alice(), &balance_of, 0, None) .await; // `transfer_from` again, this time exceeding the approved amount - let transfer_from = erc20.call().transfer_from( - bob_account.clone(), - charlie_account.clone(), - 1, - ); + let transfer_from = + call.transfer_from(bob_account.clone(), charlie_account.clone(), 1); let transfer_from_result = client .call(&ink_e2e::charlie(), &transfer_from, 0, None) .await; From d752a4d5a4e352acfa29b859b6b6186d267de3d9 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 17 May 2023 17:56:25 +0100 Subject: [PATCH 08/27] Update call-runtime example --- integration-tests/call-runtime/lib.rs | 46 ++++++++++++--------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/integration-tests/call-runtime/lib.rs b/integration-tests/call-runtime/lib.rs index 7bf35e12507..fd6c6903240 100644 --- a/integration-tests/call-runtime/lib.rs +++ b/integration-tests/call-runtime/lib.rs @@ -124,7 +124,6 @@ mod runtime_call { }, primitives::AccountId, }; - use ink_e2e::build_message; type E2EResult = Result>; @@ -159,7 +158,7 @@ mod runtime_call { ) -> E2EResult<()> { // given let constructor = RuntimeCallerRef::new(); - let contract_acc_id = client + let contract = client .instantiate( "call-runtime", &ink_e2e::alice(), @@ -168,8 +167,8 @@ mod runtime_call { None, ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); let receiver: AccountId = default_accounts::().bob; @@ -183,11 +182,11 @@ mod runtime_call { .expect("Failed to get account balance"); // when - let transfer_message = build_message::(contract_acc_id) - .call(|caller| caller.transfer_through_runtime(receiver, TRANSFER_VALUE)); + let transfer_message = + call.transfer_through_runtime(receiver, TRANSFER_VALUE); let call_res = client - .call(&ink_e2e::alice(), transfer_message, 0, None) + .call(&ink_e2e::alice(), &transfer_message, 0, None) .await .expect("call failed"); @@ -226,7 +225,7 @@ mod runtime_call { ) -> E2EResult<()> { // given let constructor = RuntimeCallerRef::new(); - let contract_acc_id = client + let contract = client .instantiate( "call-runtime", &ink_e2e::alice(), @@ -235,16 +234,14 @@ mod runtime_call { None, ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); let receiver: AccountId = default_accounts::().bob; // when - let transfer_message = build_message::(contract_acc_id) - .call(|caller| { - caller.transfer_through_runtime(receiver, INSUFFICIENT_TRANSFER_VALUE) - }); + let transfer_message = + call.transfer_through_runtime(receiver, INSUFFICIENT_TRANSFER_VALUE); let call_res = client .call_dry_run(&ink_e2e::alice(), &transfer_message, 0, None) @@ -267,7 +264,7 @@ mod runtime_call { ) -> E2EResult<()> { // given let constructor = RuntimeCallerRef::new(); - let contract_acc_id = client + let contract = client .instantiate( "call-runtime", &ink_e2e::alice(), @@ -276,12 +273,11 @@ mod runtime_call { None, ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); // when - let transfer_message = build_message::(contract_acc_id) - .call(|caller| caller.call_nonexistent_extrinsic()); + let transfer_message = call.call_nonexistent_extrinsic(); let call_res = client .call_dry_run(&ink_e2e::alice(), &transfer_message, 0, None) @@ -302,20 +298,20 @@ mod runtime_call { ) -> E2EResult<()> { // given let constructor = RuntimeCallerRef::new(); - let contract_acc_id = client + let contract = client .instantiate("call-runtime", &ink_e2e::alice(), constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); let receiver: AccountId = default_accounts::().bob; - let transfer_message = build_message::(contract_acc_id) - .call(|caller| caller.transfer_through_runtime(receiver, TRANSFER_VALUE)); + let transfer_message = + call.transfer_through_runtime(receiver, TRANSFER_VALUE); // when let call_res = client - .call(&ink_e2e::alice(), transfer_message, 0, None) + .call(&ink_e2e::alice(), &transfer_message, 0, None) .await; // then From 107217585a4f3c52c78b2cb56e237ccf31551175 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 17 May 2023 18:05:03 +0100 Subject: [PATCH 09/27] Update contract-terminate tests --- integration-tests/contract-terminate/lib.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/integration-tests/contract-terminate/lib.rs b/integration-tests/contract-terminate/lib.rs index 53263df6479..fe19dfcae0d 100644 --- a/integration-tests/contract-terminate/lib.rs +++ b/integration-tests/contract-terminate/lib.rs @@ -55,7 +55,7 @@ pub mod just_terminates { #[cfg(all(test, feature = "e2e-tests"))] mod e2e_tests { - use super::JustTerminateRef; + use super::*; type E2EResult = std::result::Result>; #[ink_e2e::test] @@ -64,7 +64,7 @@ pub mod just_terminates { ) -> E2EResult<()> { // given let constructor = JustTerminateRef::new(); - let contract_acc_id = client + let contract = client .instantiate( "contract_terminate", &ink_e2e::alice(), @@ -73,15 +73,13 @@ pub mod just_terminates { None, ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); // when - let terminate_me = - ink_e2e::build_message::(contract_acc_id) - .call(|contract| contract.terminate_me()); + let terminate_me = call.terminate_me(); let call_res = client - .call(&ink_e2e::alice(), terminate_me, 0, None) + .call(&ink_e2e::alice(), &terminate_me, 0, None) .await .expect("terminate_me messages failed"); From 580141a12c54b59a066ef1f23e996e004713e24c Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 17 May 2023 18:11:15 +0100 Subject: [PATCH 10/27] Update contract-transfer tests --- integration-tests/contract-transfer/lib.rs | 27 +++++++++++----------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/integration-tests/contract-transfer/lib.rs b/integration-tests/contract-transfer/lib.rs index a1de05672d0..1e403697a25 100644 --- a/integration-tests/contract-transfer/lib.rs +++ b/integration-tests/contract-transfer/lib.rs @@ -190,7 +190,7 @@ pub mod give_me { ) -> E2EResult<()> { // given let constructor = GiveMeRef::new(); - let contract_acc_id = client + let contract = client .instantiate( "contract_transfer", &ink_e2e::alice(), @@ -199,14 +199,13 @@ pub mod give_me { None, ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); // when - let transfer = ink_e2e::build_message::(contract_acc_id) - .call(|contract| contract.give_me(120)); + let transfer = call.give_me(120); - let call_res = client.call(&ink_e2e::bob(), transfer, 10, None).await; + let call_res = client.call(&ink_e2e::bob(), &transfer, 10, None).await; // then if let Err(ink_e2e::Error::CallDryRun(dry_run)) = call_res { @@ -224,7 +223,7 @@ pub mod give_me { ) -> E2EResult<()> { // given let constructor = GiveMeRef::new(); - let contract_acc_id = client + let contract = client .instantiate( "contract_transfer", &ink_e2e::bob(), @@ -233,19 +232,19 @@ pub mod give_me { None, ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); + let balance_before: Balance = client - .balance(contract_acc_id.clone()) + .balance(contract.account_id.clone()) .await .expect("getting balance failed"); // when - let transfer = ink_e2e::build_message::(contract_acc_id) - .call(|contract| contract.give_me(120)); + let transfer = call.give_me(120); let call_res = client - .call(&ink_e2e::eve(), transfer, 0, None) + .call(&ink_e2e::eve(), &transfer, 0, None) .await .expect("call failed"); @@ -253,7 +252,7 @@ pub mod give_me { assert!(call_res.debug_message().contains("requested value: 120\n")); let balance_after: Balance = client - .balance(contract_acc_id) + .balance(contract.account_id.clone()) .await .expect("getting balance failed"); assert_eq!(balance_before - balance_after, 120); From 1bab0c75c0f281aaad8ca3f7da2ce86408be5a02 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 18 May 2023 11:06:18 +0100 Subject: [PATCH 11/27] Custom allocator --- integration-tests/custom-allocator/lib.rs | 28 +++++++++-------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/integration-tests/custom-allocator/lib.rs b/integration-tests/custom-allocator/lib.rs index 831809a66f9..55629ff505d 100755 --- a/integration-tests/custom-allocator/lib.rs +++ b/integration-tests/custom-allocator/lib.rs @@ -108,8 +108,6 @@ mod custom_allocator { mod e2e_tests { use super::*; - use ink_e2e::build_message; - type E2EResult = std::result::Result>; /// We test that we can upload and instantiate the contract using its default @@ -120,15 +118,14 @@ mod custom_allocator { let constructor = CustomAllocatorRef::default(); // When - let contract_account_id = client + let contract = client .instantiate("custom_allocator", &ink_e2e::alice(), constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let call = contract.call::(); // Then - let get = build_message::(contract_account_id.clone()) - .call(|custom_allocator| custom_allocator.get()); + let get = call.get(); let get_result = client.call_dry_run(&ink_e2e::alice(), &get, 0, None).await; assert!(matches!(get_result.return_value(), false)); @@ -141,28 +138,25 @@ mod custom_allocator { async fn it_works(mut client: ink_e2e::Client) -> E2EResult<()> { // Given let constructor = CustomAllocatorRef::new(false); - let contract_account_id = client + let contract = client .instantiate("custom_allocator", &ink_e2e::bob(), constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); - let get = build_message::(contract_account_id.clone()) - .call(|custom_allocator| custom_allocator.get()); + let get = call.get(); let get_result = client.call_dry_run(&ink_e2e::bob(), &get, 0, None).await; assert!(matches!(get_result.return_value(), false)); // When - let flip = build_message::(contract_account_id.clone()) - .call(|custom_allocator| custom_allocator.flip()); + let flip = call.flip(); let _flip_result = client - .call(&ink_e2e::bob(), flip, 0, None) + .call(&ink_e2e::bob(), &flip, 0, None) .await .expect("flip failed"); // Then - let get = build_message::(contract_account_id.clone()) - .call(|custom_allocator| custom_allocator.get()); + let get = call.get(); let get_result = client.call_dry_run(&ink_e2e::bob(), &get, 0, None).await; assert!(matches!(get_result.return_value(), true)); From 604053aeed659231e956af4e4665937d8c201b37 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 18 May 2023 11:45:16 +0100 Subject: [PATCH 12/27] Custom environment --- integration-tests/custom-environment/lib.rs | 28 +++++++-------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/integration-tests/custom-environment/lib.rs b/integration-tests/custom-environment/lib.rs index b83fcfd70a8..971485a993d 100644 --- a/integration-tests/custom-environment/lib.rs +++ b/integration-tests/custom-environment/lib.rs @@ -92,8 +92,6 @@ mod runtime_call { mod e2e_tests { use super::*; - use ink_e2e::MessageBuilder; - type E2EResult = Result>; #[cfg(feature = "permissive-node")] @@ -103,7 +101,7 @@ mod runtime_call { ) -> E2EResult<()> { // given let constructor = TopicsRef::new(); - let contract_acc_id = client + let contract = client .instantiate( "custom-environment", &ink_e2e::alice(), @@ -112,18 +110,14 @@ mod runtime_call { None, ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let call = contract.call::(); // when - let message = - MessageBuilder::::from_account_id( - contract_acc_id, - ) - .call(|caller| caller.trigger()); + let message = call.trigger(); let call_res = client - .call(&ink_e2e::alice(), message, 0, None) + .call(&ink_e2e::alice(), &message, 0, None) .await .expect("call failed"); @@ -140,7 +134,7 @@ mod runtime_call { ) -> E2EResult<()> { // given let constructor = TopicsRef::new(); - let contract_acc_id = client + let contract = client .instantiate( "custom-environment", &ink_e2e::alice(), @@ -149,14 +143,10 @@ mod runtime_call { None, ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); - let message = - MessageBuilder::::from_account_id( - contract_acc_id, - ) - .call(|caller| caller.trigger()); + let message = call.trigger(); // when let call_res = client From 57347295ada67b452d0db0c4a378e08d310e96b8 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 18 May 2023 11:51:14 +0100 Subject: [PATCH 13/27] e2e-call-runtime --- integration-tests/e2e-call-runtime/lib.rs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/integration-tests/e2e-call-runtime/lib.rs b/integration-tests/e2e-call-runtime/lib.rs index 5b64d93b2d3..16a899feb4e 100644 --- a/integration-tests/e2e-call-runtime/lib.rs +++ b/integration-tests/e2e-call-runtime/lib.rs @@ -21,10 +21,7 @@ pub mod e2e_call_runtime { #[cfg(all(test, feature = "e2e-tests"))] mod e2e_tests { use super::*; - use ink_e2e::{ - build_message, - subxt::dynamic::Value, - }; + use ink_e2e::subxt::dynamic::Value; type E2EResult = std::result::Result>; @@ -32,11 +29,11 @@ pub mod e2e_call_runtime { async fn call_runtime_works(mut client: ink_e2e::Client) -> E2EResult<()> { // given let constructor = ContractRef::new(); - let contract_acc_id = client + let contract = client .instantiate("e2e_call_runtime", &ink_e2e::alice(), constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let call = contract.call::(); let transfer_amount = 100_000_000_000u128; @@ -45,13 +42,12 @@ pub mod e2e_call_runtime { // A value representing a `MultiAddress`. We want the // "Id" variant, and that will ultimately contain the // bytes for our destination address - Value::unnamed_variant("Id", [Value::from_bytes(&contract_acc_id)]), + Value::unnamed_variant("Id", [Value::from_bytes(&contract.account_id)]), // A value representing the amount we'd like to transfer. Value::u128(transfer_amount), ]; - let get_balance = build_message::(contract_acc_id.clone()) - .call(|contract| contract.get_contract_balance()); + let get_balance = call.get_contract_balance(); let pre_balance = client .call_dry_run(&ink_e2e::alice(), &get_balance, 0, None) .await @@ -64,8 +60,7 @@ pub mod e2e_call_runtime { .expect("runtime call failed"); // then - let get_balance = build_message::(contract_acc_id.clone()) - .call(|contract| contract.get_contract_balance()); + let get_balance = call.get_contract_balance(); let get_balance_res = client .call_dry_run(&ink_e2e::alice(), &get_balance, 0, None) .await; From 4d8da7f4bf274f66bd828fff02b181280b072a49 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 18 May 2023 12:15:09 +0100 Subject: [PATCH 14/27] flipper --- integration-tests/flipper/lib.rs | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/integration-tests/flipper/lib.rs b/integration-tests/flipper/lib.rs index 1803644b394..e0e96e86fcb 100644 --- a/integration-tests/flipper/lib.rs +++ b/integration-tests/flipper/lib.rs @@ -55,7 +55,6 @@ pub mod flipper { #[cfg(all(test, feature = "e2e-tests"))] mod e2e_tests { use super::*; - use ink_e2e::build_message; type E2EResult = std::result::Result>; @@ -63,28 +62,25 @@ pub mod flipper { async fn it_works(mut client: ink_e2e::Client) -> E2EResult<()> { // given let constructor = FlipperRef::new(false); - let contract_acc_id = client + let contract = client .instantiate("flipper", &ink_e2e::alice(), constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); - let get = build_message::(contract_acc_id.clone()) - .call(|flipper| flipper.get()); + let get = call.get(); let get_res = client.call_dry_run(&ink_e2e::bob(), &get, 0, None).await; assert!(matches!(get_res.return_value(), false)); // when - let flip = build_message::(contract_acc_id.clone()) - .call(|flipper| flipper.flip()); + let flip = call.flip(); let _flip_res = client - .call(&ink_e2e::bob(), flip, 0, None) + .call(&ink_e2e::bob(), &flip, 0, None) .await .expect("flip failed"); // then - let get = build_message::(contract_acc_id.clone()) - .call(|flipper| flipper.get()); + let get = call.get(); let get_res = client.call_dry_run(&ink_e2e::bob(), &get, 0, None).await; assert!(matches!(get_res.return_value(), true)); @@ -97,15 +93,14 @@ pub mod flipper { let constructor = FlipperRef::new_default(); // when - let contract_acc_id = client + let contract = client .instantiate("flipper", &ink_e2e::bob(), constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let call = contract.call::(); // then - let get = build_message::(contract_acc_id.clone()) - .call(|flipper| flipper.get()); + let get = call.get(); let get_res = client.call_dry_run(&ink_e2e::bob(), &get, 0, None).await; assert!(matches!(get_res.return_value(), false)); From 97ac9f86e9ad22d9cf4e181027f2c1caec55424a Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 18 May 2023 12:34:12 +0100 Subject: [PATCH 15/27] lang-err-integration-tests, compiles but fails --- .../call-builder/lib.rs | 133 ++++++++---------- 1 file changed, 58 insertions(+), 75 deletions(-) diff --git a/integration-tests/lang-err-integration-tests/call-builder/lib.rs b/integration-tests/lang-err-integration-tests/call-builder/lib.rs index 4007e2a3916..1d0d52cc795 100755 --- a/integration-tests/lang-err-integration-tests/call-builder/lib.rs +++ b/integration-tests/lang-err-integration-tests/call-builder/lib.rs @@ -165,9 +165,11 @@ mod call_builder { #[cfg(all(test, feature = "e2e-tests"))] mod e2e_tests { - use super::CallBuilderTestRef; - use ink_e2e::build_message; - use integration_flipper::FlipperRef; + use super::*; + use integration_flipper::{ + Flipper, + FlipperRef, + }; type E2EResult = std::result::Result>; @@ -180,30 +182,28 @@ mod call_builder { .await; let constructor = CallBuilderTestRef::new(); - let contract_acc_id = client + let call_builder_contract = client .instantiate("call_builder", &origin, constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call_builder_call = call_builder_contract.call::(); let flipper_constructor = FlipperRef::new_default(); - let flipper_acc_id = client + let flipper = client .instantiate("integration_flipper", &origin, flipper_constructor, 0, None) .await - .expect("instantiate `flipper` failed") - .account_id; + .expect("instantiate `flipper` failed"); + let flipper_call = flipper.call::(); - let flipper_get = build_message::(flipper_acc_id) - .call(|contract| contract.get()); + let flipper_get = flipper_call.get(); let get_call_result = client.call_dry_run(&origin, &flipper_get, 0, None).await; let initial_value = get_call_result.return_value(); let selector = ink::selector_bytes!("invalid_selector"); - let call = build_message::(contract_acc_id) - .call(|contract| contract.call(flipper_acc_id, selector)); + let call = call_builder_call.call(flipper.account_id, selector); let call_result = client - .call(&origin, call, 0, None) + .call(&origin, &call, 0, None) .await .expect("Calling `call_builder::call` failed"); @@ -214,8 +214,7 @@ mod call_builder { Some(ink::LangError::CouldNotReadInput) )); - let flipper_get = build_message::(flipper_acc_id) - .call(|contract| contract.get()); + let flipper_get = flipper_call.get(); let get_call_result = client.call_dry_run(&origin, &flipper_get, 0, None).await; let flipped_value = get_call_result.return_value(); @@ -233,24 +232,22 @@ mod call_builder { .await; let constructor = CallBuilderTestRef::new(); - let contract_acc_id = client + let call_builder = client .instantiate("call_builder", &origin, constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call_builder_call = call_builder.call::(); let flipper_constructor = FlipperRef::new_default(); - let flipper_acc_id = client + let flipper = client .instantiate("integration_flipper", &origin, flipper_constructor, 0, None) .await - .expect("instantiate `flipper` failed") - .account_id; + .expect("instantiate `flipper` failed"); // Since `LangError`s can't be handled by the `CallBuilder::invoke()` method // we expect this to panic. let invalid_selector = [0x00, 0x00, 0x00, 0x00]; - let call = build_message::(contract_acc_id) - .call(|contract| contract.invoke(flipper_acc_id, invalid_selector)); + let call = call_builder_call.invoke(flipper.account_id, invalid_selector); let call_result = client.call_dry_run(&origin, &call, 0, None).await; assert!(call_result.is_err()); @@ -270,11 +267,11 @@ mod call_builder { .await; let constructor = CallBuilderTestRef::new(); - let contract_acc_id = client + let call_builder = client .instantiate("call_builder", &origin, constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call_builder_call = call_builder.call::(); let code_hash = client .upload("constructors_return_value", &origin, None) @@ -285,11 +282,9 @@ mod call_builder { let selector = ink::selector_bytes!("new"); let init_value = true; let call = - build_message::(contract_acc_id).call(|contract| { - contract.call_instantiate(code_hash, selector, init_value) - }); + call_builder_call.call_instantiate(code_hash, selector, init_value); let call_result = client - .call(&origin, call, 0, None) + .call(&origin, &call, 0, None) .await .expect("Client failed to call `call_builder::call_instantiate`.") .return_value(); @@ -311,11 +306,11 @@ mod call_builder { .await; let constructor = CallBuilderTestRef::new(); - let contract_acc_id = client + let call_builder = client .instantiate("call_builder", &origin, constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call_builder_call = call_builder.call::(); let code_hash = client .upload("constructors_return_value", &origin, None) @@ -326,11 +321,9 @@ mod call_builder { let selector = ink::selector_bytes!("invalid_selector"); let init_value = true; let call = - build_message::(contract_acc_id).call(|contract| { - contract.call_instantiate(code_hash, selector, init_value) - }); + call_builder_call.call_instantiate(code_hash, selector, init_value); let call_result = client - .call(&origin, call, 0, None) + .call(&origin, &call, 0, None) .await .expect("Client failed to call `call_builder::call_instantiate`.") .return_value(); @@ -352,11 +345,11 @@ mod call_builder { .await; let constructor = CallBuilderTestRef::new(); - let contract_acc_id = client + let call_builder = client .instantiate("call_builder", &origin, constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call_builder_call = call_builder.call::(); let code_hash = client .upload("constructors_return_value", &origin, None) @@ -367,9 +360,7 @@ mod call_builder { let selector = ink::selector_bytes!("revert_new"); let init_value = false; let call = - build_message::(contract_acc_id).call(|contract| { - contract.call_instantiate(code_hash, selector, init_value) - }); + call_builder_call.call_instantiate(code_hash, selector, init_value); let call_result = client.call_dry_run(&origin, &call, 0, None).await; assert!( @@ -397,11 +388,11 @@ mod call_builder { .await; let constructor = CallBuilderTestRef::new(); - let contract_acc_id = client + let call_builder = client .instantiate("call_builder", &origin, constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call_builder_call = call_builder.call::(); let code_hash = client .upload("constructors_return_value", &origin, None) @@ -411,12 +402,10 @@ mod call_builder { let selector = ink::selector_bytes!("try_new"); let init_value = true; - let call = - build_message::(contract_acc_id).call(|contract| { - contract.call_instantiate_fallible(code_hash, selector, init_value) - }); + let call = call_builder_call + .call_instantiate_fallible(code_hash, selector, init_value); let call_result = client - .call(&origin, call, 0, None) + .call(&origin, &call, 0, None) .await .expect("Calling `call_builder::call_instantiate_fallible` failed") .return_value(); @@ -438,11 +427,11 @@ mod call_builder { .await; let constructor = CallBuilderTestRef::new(); - let contract_acc_id = client + let call_builder = client .instantiate("call_builder", &origin, constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call_builder_call = call_builder.call::(); let code_hash = client .upload("constructors_return_value", &origin, None) @@ -452,12 +441,10 @@ mod call_builder { let selector = ink::selector_bytes!("try_new"); let init_value = false; - let call = - build_message::(contract_acc_id).call(|contract| { - contract.call_instantiate_fallible(code_hash, selector, init_value) - }); + let call = call_builder_call + .call_instantiate_fallible(code_hash, selector, init_value); let call_result = client - .call(&origin, call, 0, None) + .call(&origin, &call, 0, None) .await .expect("Calling `call_builder::call_instantiate_fallible` failed") .return_value(); @@ -486,11 +473,11 @@ mod call_builder { .await; let constructor = CallBuilderTestRef::new(); - let contract_acc_id = client + let call_builder = client .instantiate("call_builder", &origin, constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call_builder_call = call_builder.call::(); let code_hash = client .upload("constructors_return_value", &origin, None) @@ -500,10 +487,8 @@ mod call_builder { let selector = ink::selector_bytes!("try_revert_new"); let init_value = true; - let call = - build_message::(contract_acc_id).call(|contract| { - contract.call_instantiate_fallible(code_hash, selector, init_value) - }); + let call = call_builder_call + .call_instantiate_fallible(code_hash, selector, init_value); let call_result = client.call_dry_run(&origin, &call, 0, None).await; assert!( @@ -531,11 +516,11 @@ mod call_builder { .await; let constructor = CallBuilderTestRef::new(); - let contract_acc_id = client + let call_builder = client .instantiate("call_builder", &origin, constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call_builder_call = call_builder.call::(); let code_hash = client .upload("constructors_return_value", &origin, None) @@ -545,12 +530,10 @@ mod call_builder { let selector = ink::selector_bytes!("try_revert_new"); let init_value = false; - let call = - build_message::(contract_acc_id).call(|contract| { - contract.call_instantiate_fallible(code_hash, selector, init_value) - }); + let call = call_builder_call + .call_instantiate_fallible(code_hash, selector, init_value); let call_result = client - .call(&origin, call, 0, None) + .call(&origin, &call, 0, None) .await .expect( "Client failed to call `call_builder::call_instantiate_fallible`.", From 748103f2e1ecbf1dcf8ae6ed3868c656412f050c Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 18 May 2023 13:21:36 +0100 Subject: [PATCH 16/27] Don't debug log the entire dispatch error --- crates/e2e/src/client.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/e2e/src/client.rs b/crates/e2e/src/client.rs index 926ddd99ae1..58272fb47a3 100644 --- a/crates/e2e/src/client.rs +++ b/crates/e2e/src/client.rs @@ -642,7 +642,7 @@ where subxt::error::DispatchError::decode_from(evt.field_bytes(), metadata) .map_err(Error::Decoding)?; log_error(&format!( - "extrinsic for instantiate failed: {dispatch_error:?}" + "extrinsic for instantiate failed: {dispatch_error}" )); return Err(Error::InstantiateExtrinsic(dispatch_error)) } @@ -734,7 +734,7 @@ where subxt::error::DispatchError::decode_from(evt.field_bytes(), metadata) .map_err(Error::Decoding)?; - log_error(&format!("extrinsic for upload failed: {dispatch_error:?}")); + log_error(&format!("extrinsic for upload failed: {dispatch_error}")); return Err(Error::UploadExtrinsic(dispatch_error)) } } @@ -859,7 +859,7 @@ where subxt::error::DispatchError::decode_from(evt.field_bytes(), metadata) .map_err(Error::Decoding)?; - log_error(&format!("extrinsic for call failed: {dispatch_error:?}")); + log_error(&format!("extrinsic for call failed: {dispatch_error}")); return Err(Error::CallExtrinsic(dispatch_error)) } } From 21b898b7f932f62a8ba06fa9db85a9dc29570eca Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 18 May 2023 13:22:17 +0100 Subject: [PATCH 17/27] constructor-return-value --- .../constructors-return-value/lib.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/integration-tests/lang-err-integration-tests/constructors-return-value/lib.rs b/integration-tests/lang-err-integration-tests/constructors-return-value/lib.rs index d3da6398999..0242694b625 100644 --- a/integration-tests/lang-err-integration-tests/constructors-return-value/lib.rs +++ b/integration-tests/lang-err-integration-tests/constructors-return-value/lib.rs @@ -106,7 +106,7 @@ pub mod constructors_return_value { #[cfg(all(test, feature = "e2e-tests"))] mod e2e_tests { - use super::ConstructorsReturnValueRef; + use super::*; use scale::Decode as _; type E2EResult = std::result::Result>; @@ -187,7 +187,7 @@ pub mod constructors_return_value { ); let constructor = ConstructorsReturnValueRef::try_new(true); - let contract_acc_id = client + let contract = client .instantiate( "constructors_return_value", &ink_e2e::bob(), @@ -196,12 +196,10 @@ pub mod constructors_return_value { None, ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); - let get = - ink_e2e::build_message::(contract_acc_id) - .call(|contract| contract.get_value()); + let get = call.get_value(); let value = client .call_dry_run(&ink_e2e::bob(), &get, 0, None) .await From 5569857e3fea0e9eef9a3caf058dbfda5988da35 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 18 May 2023 13:27:55 +0100 Subject: [PATCH 18/27] contract-ref --- .../contract-ref/lib.rs | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/integration-tests/lang-err-integration-tests/contract-ref/lib.rs b/integration-tests/lang-err-integration-tests/contract-ref/lib.rs index cd88d62e740..55c6a4652e2 100755 --- a/integration-tests/lang-err-integration-tests/contract-ref/lib.rs +++ b/integration-tests/lang-err-integration-tests/contract-ref/lib.rs @@ -67,8 +67,7 @@ mod contract_ref { #[cfg(all(test, feature = "e2e-tests"))] mod e2e_tests { - use super::ContractRefRef; - use ink_e2e::build_message; + use super::*; type E2EResult = std::result::Result>; @@ -83,24 +82,22 @@ mod contract_ref { .code_hash; let constructor = ContractRefRef::new(0, flipper_hash); - let contract_acc_id = client + let contract_ref = client .instantiate("contract_ref", &ink_e2e::alice(), constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract_ref.call::(); - let get_check = build_message::(contract_acc_id.clone()) - .call(|contract| contract.get_check()); + let get_check = call.get_check(); let get_call_result = client .call_dry_run(&ink_e2e::alice(), &get_check, 0, None) .await; let initial_value = get_call_result.return_value(); - let flip_check = build_message::(contract_acc_id.clone()) - .call(|contract| contract.flip_check()); + let flip_check = call.flip_check(); let flip_call_result = client - .call(&ink_e2e::alice(), flip_check, 0, None) + .call(&ink_e2e::alice(), &flip_check, 0, None) .await .expect("Calling `flip` failed"); assert!( @@ -129,14 +126,13 @@ mod contract_ref { let succeed = true; let constructor = ContractRefRef::try_new(0, flipper_hash, succeed); - let contract_acc_id = client + let contract_ref = client .instantiate("contract_ref", &ink_e2e::bob(), constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract_ref.call::(); - let get_check = build_message::(contract_acc_id.clone()) - .call(|contract| contract.get_check()); + let get_check = call.get_check(); let get_call_result = client .call_dry_run(&ink_e2e::bob(), &get_check, 0, None) .await; From 036dd5ff682a4f690b12eddce4bba069df916d8c Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 18 May 2023 16:42:55 +0100 Subject: [PATCH 19/27] integration-flipper --- .../integration-flipper/lib.rs | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/integration-tests/lang-err-integration-tests/integration-flipper/lib.rs b/integration-tests/lang-err-integration-tests/integration-flipper/lib.rs index c48163808e9..9d05434c555 100644 --- a/integration-tests/lang-err-integration-tests/integration-flipper/lib.rs +++ b/integration-tests/lang-err-integration-tests/integration-flipper/lib.rs @@ -66,8 +66,7 @@ pub mod integration_flipper { #[cfg(all(test, feature = "e2e-tests"))] mod e2e_tests { - use super::FlipperRef; - use ink_e2e::build_message; + use super::*; type E2EResult = std::result::Result>; #[ink_e2e::test] @@ -75,7 +74,7 @@ pub mod integration_flipper { mut client: ink_e2e::Client, ) -> E2EResult<()> { let constructor = FlipperRef::new_default(); - let contract_acc_id = client + let flipper = client .instantiate( "integration_flipper", &ink_e2e::alice(), @@ -84,20 +83,18 @@ pub mod integration_flipper { None, ) .await - .expect("Instantiate `integration_flipper` failed") - .account_id; + .expect("Instantiate `integration_flipper` failed"); + let mut call = flipper.call::(); - let get = build_message::(contract_acc_id.clone()) - .call(|contract| contract.get()); + let get = call.get(); let initial_value = client .call_dry_run(&ink_e2e::alice(), &get, 0, None) .await .return_value(); - let flip = build_message::(contract_acc_id) - .call(|contract| contract.flip()); + let flip = call.flip(); let flip_call_result = client - .call(&ink_e2e::alice(), flip, 0, None) + .call(&ink_e2e::alice(), &flip, 0, None) .await .expect("Calling `flip` failed"); assert!( @@ -119,23 +116,21 @@ pub mod integration_flipper { mut client: ink_e2e::Client, ) -> E2EResult<()> { let constructor = FlipperRef::new_default(); - let contract_acc_id = client + let flipper = client .instantiate("integration_flipper", &ink_e2e::bob(), constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = flipper.call::(); - let get = build_message::(contract_acc_id.clone()) - .call(|contract| contract.get()); + let get = call.get(); let initial_value = client .call_dry_run(&ink_e2e::bob(), &get, 0, None) .await .return_value(); - let err_flip = build_message::(contract_acc_id) - .call(|contract| contract.err_flip()); + let err_flip = call.err_flip(); let err_flip_call_result = - client.call(&ink_e2e::bob(), err_flip, 0, None).await; + client.call(&ink_e2e::bob(), &err_flip, 0, None).await; assert!(matches!( err_flip_call_result, From f5c14962a7e8eb06006a116c6ccdd59726546027 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 18 May 2023 16:50:43 +0100 Subject: [PATCH 20/27] mapping-integration-tests --- .../mapping-integration-tests/lib.rs | 85 ++++++++----------- 1 file changed, 36 insertions(+), 49 deletions(-) diff --git a/integration-tests/mapping-integration-tests/lib.rs b/integration-tests/mapping-integration-tests/lib.rs index 5c1b11d3d55..64e32ac3088 100755 --- a/integration-tests/mapping-integration-tests/lib.rs +++ b/integration-tests/mapping-integration-tests/lib.rs @@ -97,7 +97,7 @@ mod mapping_integration_tests { ) -> E2EResult<()> { // given let constructor = MappingsRef::new(); - let contract_id = client + let contract = client .instantiate( "mapping-integration-tests", &ink_e2e::alice(), @@ -106,21 +106,19 @@ mod mapping_integration_tests { None, ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); // when - let insert = ink_e2e::build_message::(contract_id) - .call(|contract| contract.insert_balance(1_000)); + let insert = call.insert_balance(1_000); let size = client - .call(&ink_e2e::alice(), insert, 0, None) + .call(&ink_e2e::alice(), &insert, 0, None) .await .expect("Calling `insert_balance` failed") .return_value(); // then - let get = ink_e2e::build_message::(contract_id) - .call(|contract| contract.get_balance()); + let get = call.get_balance(); let balance = client .call_dry_run(&ink_e2e::alice(), &get, 0, None) .await @@ -138,7 +136,7 @@ mod mapping_integration_tests { ) -> E2EResult<()> { // given let constructor = MappingsRef::new(); - let contract_id = client + let contract = client .instantiate( "mapping-integration-tests", &ink_e2e::bob(), @@ -147,21 +145,19 @@ mod mapping_integration_tests { None, ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); // when - let insert = ink_e2e::build_message::(contract_id) - .call(|contract| contract.insert_balance(1_000)); + let insert = call.insert_balance(1_000); let _ = client - .call(&ink_e2e::bob(), insert, 0, None) + .call(&ink_e2e::bob(), &insert, 0, None) .await .expect("Calling `insert_balance` failed") .return_value(); // then - let contains = ink_e2e::build_message::(contract_id) - .call(|contract| contract.contains_balance()); + let contains = call.contains_balance(); let is_there = client .call_dry_run(&ink_e2e::bob(), &contains, 0, None) .await @@ -176,7 +172,7 @@ mod mapping_integration_tests { async fn reinsert_works(mut client: ink_e2e::Client) -> E2EResult<()> { // given let constructor = MappingsRef::new(); - let contract_id = client + let contract = client .instantiate( "mapping-integration-tests", &ink_e2e::charlie(), @@ -185,22 +181,20 @@ mod mapping_integration_tests { None, ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); // when - let first_insert = ink_e2e::build_message::(contract_id) - .call(|contract| contract.insert_balance(1_000)); + let first_insert = call.insert_balance(1_000); let _ = client - .call(&ink_e2e::charlie(), first_insert, 0, None) + .call(&ink_e2e::charlie(), &first_insert, 0, None) .await .expect("Calling `insert_balance` failed") .return_value(); - let insert = ink_e2e::build_message::(contract_id) - .call(|contract| contract.insert_balance(10_000)); + let insert = call.insert_balance(10_000); let size = client - .call(&ink_e2e::charlie(), insert, 0, None) + .call(&ink_e2e::charlie(), &insert, 0, None) .await .expect("Calling `insert_balance` failed") .return_value(); @@ -208,8 +202,7 @@ mod mapping_integration_tests { // then assert!(size.is_some()); - let get = ink_e2e::build_message::(contract_id) - .call(|contract| contract.get_balance()); + let get = call.get_balance(); let balance = client .call_dry_run(&ink_e2e::charlie(), &get, 0, None) .await @@ -226,7 +219,7 @@ mod mapping_integration_tests { ) -> E2EResult<()> { // given let constructor = MappingsRef::new(); - let contract_id = client + let contract = client .instantiate( "mapping-integration-tests", &ink_e2e::dave(), @@ -235,28 +228,25 @@ mod mapping_integration_tests { None, ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); // when - let insert = ink_e2e::build_message::(contract_id) - .call(|contract| contract.insert_balance(3_000)); + let insert = call.insert_balance(3_000); let _ = client - .call(&ink_e2e::dave(), insert, 0, None) + .call(&ink_e2e::dave(), &insert, 0, None) .await .expect("Calling `insert_balance` failed") .return_value(); - let remove = ink_e2e::build_message::(contract_id) - .call(|contract| contract.remove_balance()); + let remove = call.remove_balance(); let _ = client - .call(&ink_e2e::dave(), remove, 0, None) + .call(&ink_e2e::dave(), &remove, 0, None) .await .expect("Calling `remove_balance` failed"); // then - let get = ink_e2e::build_message::(contract_id) - .call(|contract| contract.get_balance()); + let get = call.get_balance(); let balance = client .call_dry_run(&ink_e2e::dave(), &get, 0, None) .await @@ -273,7 +263,7 @@ mod mapping_integration_tests { ) -> E2EResult<()> { // given let constructor = MappingsRef::new(); - let contract_id = client + let contract = client .instantiate( "mapping-integration-tests", &ink_e2e::eve(), @@ -282,22 +272,20 @@ mod mapping_integration_tests { None, ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); // when - let insert = ink_e2e::build_message::(contract_id) - .call(|contract| contract.insert_balance(4_000)); + let insert = call.insert_balance(4_000); let _ = client - .call(&ink_e2e::eve(), insert, 0, None) + .call(&ink_e2e::eve(), &insert, 0, None) .await .expect("Calling `insert_balance` failed") .return_value(); - let take = ink_e2e::build_message::(contract_id) - .call(|contract| contract.take_balance()); + let take = call.take_balance(); let balance = client - .call(&ink_e2e::eve(), take, 0, None) + .call(&ink_e2e::eve(), &take, 0, None) .await .expect("Calling `take_balance` failed") .return_value(); @@ -305,8 +293,7 @@ mod mapping_integration_tests { // then assert_eq!(balance, Some(4_000)); - let contains = ink_e2e::build_message::(contract_id) - .call(|contract| contract.contains_balance()); + let contains = call.contains_balance(); let is_there = client .call_dry_run(&ink_e2e::eve(), &contains, 0, None) .await From 9b181d3747753e5388df85863a0cab367658ece5 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 18 May 2023 17:06:58 +0100 Subject: [PATCH 21/27] multi-contract-caller --- .../multi-contract-caller/lib.rs | 45 ++++++------------- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/integration-tests/multi-contract-caller/lib.rs b/integration-tests/multi-contract-caller/lib.rs index be4318f8f97..c8353e99653 100644 --- a/integration-tests/multi-contract-caller/lib.rs +++ b/integration-tests/multi-contract-caller/lib.rs @@ -114,8 +114,7 @@ mod multi_contract_caller { #[cfg(all(test, feature = "e2e-tests"))] mod e2e_tests { - use super::MultiContractCallerRef; - use ink_e2e::build_message; + use super::*; type E2EResult = std::result::Result>; @@ -150,7 +149,7 @@ mod multi_contract_caller { subber_hash, ); - let multi_contract_caller_acc_id = client + let multi_contract_caller = client .instantiate( "multi_contract_caller", &ink_e2e::alice(), @@ -159,33 +158,24 @@ mod multi_contract_caller { None, ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = multi_contract_caller.call::(); // when - let get = build_message::( - multi_contract_caller_acc_id.clone(), - ) - .call(|contract| contract.get()); + let get = call.get(); let value = client .call_dry_run(&ink_e2e::bob(), &get, 0, None) .await .return_value(); assert_eq!(value, 1234); - let change = build_message::( - multi_contract_caller_acc_id.clone(), - ) - .call(|contract| contract.change(6)); + let change = call.change(6); let _ = client - .call(&ink_e2e::bob(), change, 0, None) + .call(&ink_e2e::bob(), &change, 0, None) .await .expect("calling `change` failed"); // then - let get = build_message::( - multi_contract_caller_acc_id.clone(), - ) - .call(|contract| contract.get()); + let get = call.get(); let value = client .call_dry_run(&ink_e2e::bob(), &get, 0, None) .await @@ -193,28 +183,19 @@ mod multi_contract_caller { assert_eq!(value, 1234 + 6); // when - let switch = build_message::( - multi_contract_caller_acc_id.clone(), - ) - .call(|contract| contract.switch()); + let switch = call.switch(); let _ = client - .call(&ink_e2e::bob(), switch, 0, None) + .call(&ink_e2e::bob(), &switch, 0, None) .await .expect("calling `switch` failed"); - let change = build_message::( - multi_contract_caller_acc_id.clone(), - ) - .call(|contract| contract.change(3)); + let change = call.change(3); let _ = client - .call(&ink_e2e::bob(), change, 0, None) + .call(&ink_e2e::bob(), &change, 0, None) .await .expect("calling `change` failed"); // then - let get = build_message::( - multi_contract_caller_acc_id.clone(), - ) - .call(|contract| contract.get()); + let get = call.get(); let value = client .call_dry_run(&ink_e2e::bob(), &get, 0, None) .await From 019736371b2cbd604863a91e1cb8418616fe1e54 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 18 May 2023 17:11:57 +0100 Subject: [PATCH 22/27] set-code-hash --- integration-tests/set-code-hash/lib.rs | 31 ++++++++++---------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/integration-tests/set-code-hash/lib.rs b/integration-tests/set-code-hash/lib.rs index 99574e86127..dd632d35920 100644 --- a/integration-tests/set-code-hash/lib.rs +++ b/integration-tests/set-code-hash/lib.rs @@ -68,7 +68,6 @@ pub mod incrementer { #[cfg(all(test, feature = "e2e-tests"))] mod e2e_tests { use super::*; - use ink_e2e::build_message; type E2EResult = std::result::Result>; @@ -76,26 +75,23 @@ pub mod incrementer { async fn set_code_works(mut client: ink_e2e::Client) -> E2EResult<()> { // Given let constructor = IncrementerRef::new(); - let contract_acc_id = client + let contract = client .instantiate("incrementer", &ink_e2e::alice(), constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut call = contract.call::(); - let get = build_message::(contract_acc_id.clone()) - .call(|incrementer| incrementer.get()); + let get = call.get(); let get_res = client.call_dry_run(&ink_e2e::alice(), &get, 0, None).await; assert!(matches!(get_res.return_value(), 0)); - let inc = build_message::(contract_acc_id.clone()) - .call(|incrementer| incrementer.inc()); + let inc = call.inc(); let _inc_result = client - .call(&ink_e2e::alice(), inc, 0, None) + .call(&ink_e2e::alice(), &inc, 0, None) .await .expect("`inc` failed"); - let get = build_message::(contract_acc_id.clone()) - .call(|incrementer| incrementer.get()); + let get = call.get(); let get_res = client.call_dry_run(&ink_e2e::alice(), &get, 0, None).await; assert!(matches!(get_res.return_value(), 1)); @@ -107,27 +103,24 @@ pub mod incrementer { .code_hash; let new_code_hash = new_code_hash.as_ref().try_into().unwrap(); - let set_code = build_message::(contract_acc_id.clone()) - .call(|incrementer| incrementer.set_code(new_code_hash)); + let set_code = call.set_code(new_code_hash); let _set_code_result = client - .call(&ink_e2e::alice(), set_code, 0, None) + .call(&ink_e2e::alice(), &set_code, 0, None) .await .expect("`set_code` failed"); // Then // Note that our contract's `AccountId` (so `contract_acc_id`) has stayed the // same between updates! - let inc = build_message::(contract_acc_id.clone()) - .call(|incrementer| incrementer.inc()); + let inc = call.inc(); let _inc_result = client - .call(&ink_e2e::alice(), inc, 0, None) + .call(&ink_e2e::alice(), &inc, 0, None) .await .expect("`inc` failed"); - let get = build_message::(contract_acc_id.clone()) - .call(|incrementer| incrementer.get()); + let get = call.get(); let get_res = client.call_dry_run(&ink_e2e::alice(), &get, 0, None).await; // Remember, we updated our incrementer contract to increment by `4`. From 46a5c025cfa5f76e0f79e24ae942a79617b554da Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 18 May 2023 17:54:15 +0100 Subject: [PATCH 23/27] wildcard-selector --- integration-tests/wildcard-selector/lib.rs | 34 +++++++++++++++------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/integration-tests/wildcard-selector/lib.rs b/integration-tests/wildcard-selector/lib.rs index c6d96f534bc..362dba43ce3 100644 --- a/integration-tests/wildcard-selector/lib.rs +++ b/integration-tests/wildcard-selector/lib.rs @@ -37,8 +37,19 @@ pub mod wildcard_selector { #[cfg(all(test, feature = "e2e-tests"))] mod e2e_tests { use super::*; - use ink_e2e::Message; - use scale::Encode as _; + + use ink::env::call::{ + utils::{ + Argument, + ArgumentList, + EmptyArgumentList, + ReturnType, + Set, + }, + Call, + CallBuilder, + ExecutionInput, + }; type E2EResult = std::result::Result>; type Environment = ::Env; @@ -47,8 +58,13 @@ pub mod wildcard_selector { account_id: AccountId, selector: [u8; 4], message: String, - ) -> Message { - let call_builder = ink::env::call::build_call::() + ) -> CallBuilder< + Environment, + Set>, + Set, EmptyArgumentList>>>, + Set>, + > { + ink::env::call::build_call::() .call(account_id) .exec_input( ink::env::call::ExecutionInput::new(ink::env::call::Selector::new( @@ -56,9 +72,7 @@ pub mod wildcard_selector { )) .push_arg(message), ) - .returns::<()>(); - let exec_input = call_builder.params().exec_input().encode(); - Message::::new(account_id, exec_input) + .returns::<()>() } #[ink_e2e::test] @@ -83,7 +97,7 @@ pub mod wildcard_selector { ); let result = client - .call(&ink_e2e::bob(), wildcard, 0, None) + .call(&ink_e2e::bob(), &wildcard, 0, None) .await .expect("wildcard failed"); @@ -96,7 +110,7 @@ pub mod wildcard_selector { ); let result2 = client - .call(&ink_e2e::bob(), wildcard2, 0, None) + .call(&ink_e2e::bob(), &wildcard2, 0, None) .await .expect("wildcard failed"); @@ -135,7 +149,7 @@ pub mod wildcard_selector { ); let result = client - .call(&ink_e2e::bob(), wildcard, 0, None) + .call(&ink_e2e::bob(), &wildcard, 0, None) .await .expect("wildcard failed"); From 867da3bb22507498616e07853ab094c4af1bce5b Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 18 May 2023 18:03:26 +0100 Subject: [PATCH 24/27] trait-dyn-cross-contract-calls --- .../trait-dyn-cross-contract-calls/lib.rs | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/integration-tests/trait-dyn-cross-contract-calls/lib.rs b/integration-tests/trait-dyn-cross-contract-calls/lib.rs index 12695ed78fa..9d8f8309ffc 100644 --- a/integration-tests/trait-dyn-cross-contract-calls/lib.rs +++ b/integration-tests/trait-dyn-cross-contract-calls/lib.rs @@ -43,14 +43,15 @@ pub mod caller { #[cfg(all(test, feature = "e2e-tests"))] mod e2e_tests { - use super::caller::CallerRef; + use super::caller::{ + Caller, + CallerRef, + }; use dyn_traits::Increment; - use ink::{ - contract_ref, - env::DefaultEnvironment, + use trait_incrementer::incrementer::{ + Incrementer, + IncrementerRef, }; - use ink_e2e::build_message; - use trait_incrementer::incrementer::IncrementerRef; type E2EResult = Result>; @@ -78,15 +79,15 @@ mod e2e_tests { let constructor = IncrementerRef::new(); - let incrementer_account_id = client + let incrementer = client .instantiate("trait-incrementer", &ink_e2e::alice(), constructor, 0, None) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let incrementer_call = incrementer.call::(); - let constructor = CallerRef::new(incrementer_account_id.clone()); + let constructor = CallerRef::new(incrementer.account_id.clone()); - let caller_account_id = client + let caller = client .instantiate( "trait-incrementer-caller", &ink_e2e::alice(), @@ -95,12 +96,11 @@ mod e2e_tests { None, ) .await - .expect("instantiate failed") - .account_id; + .expect("instantiate failed"); + let mut caller_call = caller.call::(); // Check through the caller that the value of the incrementer is zero - let get = build_message::(caller_account_id.clone()) - .call(|contract| contract.get()); + let get = caller_call.get(); let value = client .call_dry_run(&ink_e2e::alice(), &get, 0, None) .await @@ -108,20 +108,16 @@ mod e2e_tests { assert_eq!(value, 0); // Increment the value of the incrementer via the caller - let inc = build_message::(caller_account_id.clone()) - .call(|contract| contract.inc()); + let inc = caller_call.inc(); let _ = client - .call(&ink_e2e::alice(), inc, 0, None) + .call(&ink_e2e::alice(), &inc, 0, None) .await .expect("calling `inc` failed"); // Ask the `trait-increment` about a value. It should be updated by the caller. // Also use `contract_ref!(Increment)` instead of `IncrementerRef` // to check that it also works with e2e testing. - let get = build_message::( - incrementer_account_id.clone(), - ) - .call(|contract| contract.get()); + let get = incrementer_call.get(); let value = client .call_dry_run(&ink_e2e::alice(), &get, 0, None) .await From 4570150e66bb083e05b88d8171b2ea671319069a Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 18 May 2023 18:19:37 +0100 Subject: [PATCH 25/27] Clippy --- crates/e2e/src/client.rs | 30 ++++++++++++------------------ crates/e2e/src/xts.rs | 2 +- integration-tests/erc20/lib.rs | 1 + 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/crates/e2e/src/client.rs b/crates/e2e/src/client.rs index 58272fb47a3..951f0141673 100644 --- a/crates/e2e/src/client.rs +++ b/crates/e2e/src/client.rs @@ -34,7 +34,6 @@ use ink_env::{ Set, }, Call, - CallBuilder, ExecutionInput, FromAccountId, }, @@ -67,6 +66,13 @@ use subxt::{ tx::PairSigner, }; +type CallBuilder = ink_env::call::CallBuilder< + E, + Set>, + Set>, + Set>, +>; + /// Result of a contract instantiation. pub struct InstantiationResult { /// The account id at which the contract was instantiated. @@ -767,20 +773,14 @@ where pub async fn call( &mut self, signer: &Signer, - message: &CallBuilder< - E, - Set>, - Set>, - Set>, - >, + message: &CallBuilder, value: E::Balance, storage_deposit_limit: Option, ) -> Result, Error> where Args: scale::Encode, RetType: scale::Decode, - CallBuilder>, Set>, Set>>: - Clone, + CallBuilder: Clone, { let account_id = message.clone().params().callee().clone(); let exec_input = scale::Encode::encode(message.clone().params().exec_input()); @@ -874,27 +874,21 @@ where pub async fn call_dry_run( &mut self, signer: &Signer, - message: &CallBuilder< - E, - Set>, - Set>, - Set>, - >, + message: &CallBuilder, value: E::Balance, storage_deposit_limit: Option, ) -> CallDryRunResult where Args: scale::Encode, RetType: scale::Decode, - CallBuilder>, Set>, Set>>: - Clone, + CallBuilder: Clone, { let dest = message.clone().params().callee().clone(); let exec_input = scale::Encode::encode(message.clone().params().exec_input()); let exec_result = self .api - .call_dry_run::( + .call_dry_run( Signer::account_id(signer).clone(), dest, exec_input, diff --git a/crates/e2e/src/xts.rs b/crates/e2e/src/xts.rs index a3d38f27a57..9a8e8e831f2 100644 --- a/crates/e2e/src/xts.rs +++ b/crates/e2e/src/xts.rs @@ -412,7 +412,7 @@ where } /// Dry runs a call of the contract at `contract` with the given parameters. - pub async fn call_dry_run( + pub async fn call_dry_run( &self, origin: C::AccountId, dest: E::AccountId, diff --git a/integration-tests/erc20/lib.rs b/integration-tests/erc20/lib.rs index dda45cd9b85..f00c2eb25e7 100644 --- a/integration-tests/erc20/lib.rs +++ b/integration-tests/erc20/lib.rs @@ -597,6 +597,7 @@ mod erc20 { let charlie_account = ink_e2e::account_id(ink_e2e::AccountKeyring::Charlie); let amount = 500_000_000u128; + // tx let transfer_from = call.transfer_from(bob_account.clone(), charlie_account.clone(), amount); let transfer_from_result = client From 061114169f3e84dfbaede85451cf2649010b8a0c Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 19 May 2023 10:25:14 +0100 Subject: [PATCH 26/27] Export CallBuilderFinal type alias --- crates/e2e/src/client.rs | 11 ++++++----- crates/e2e/src/lib.rs | 1 + integration-tests/wildcard-selector/lib.rs | 22 +++++++--------------- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/crates/e2e/src/client.rs b/crates/e2e/src/client.rs index 951f0141673..088ad922b89 100644 --- a/crates/e2e/src/client.rs +++ b/crates/e2e/src/client.rs @@ -66,7 +66,8 @@ use subxt::{ tx::PairSigner, }; -type CallBuilder = ink_env::call::CallBuilder< +/// Represents an initialized contract message builder. +pub type CallBuilderFinal = ink_env::call::CallBuilder< E, Set>, Set>, @@ -773,14 +774,14 @@ where pub async fn call( &mut self, signer: &Signer, - message: &CallBuilder, + message: &CallBuilderFinal, value: E::Balance, storage_deposit_limit: Option, ) -> Result, Error> where Args: scale::Encode, RetType: scale::Decode, - CallBuilder: Clone, + CallBuilderFinal: Clone, { let account_id = message.clone().params().callee().clone(); let exec_input = scale::Encode::encode(message.clone().params().exec_input()); @@ -874,14 +875,14 @@ where pub async fn call_dry_run( &mut self, signer: &Signer, - message: &CallBuilder, + message: &CallBuilderFinal, value: E::Balance, storage_deposit_limit: Option, ) -> CallDryRunResult where Args: scale::Encode, RetType: scale::Decode, - CallBuilder: Clone, + CallBuilderFinal: Clone, { let dest = message.clone().params().callee().clone(); let exec_input = scale::Encode::encode(message.clone().params().exec_input()); diff --git a/crates/e2e/src/lib.rs b/crates/e2e/src/lib.rs index d6732b39a0a..343361934b1 100644 --- a/crates/e2e/src/lib.rs +++ b/crates/e2e/src/lib.rs @@ -26,6 +26,7 @@ mod node_proc; mod xts; pub use client::{ + CallBuilderFinal, CallDryRunResult, CallResult, Client, diff --git a/integration-tests/wildcard-selector/lib.rs b/integration-tests/wildcard-selector/lib.rs index 362dba43ce3..729bd56c3d1 100644 --- a/integration-tests/wildcard-selector/lib.rs +++ b/integration-tests/wildcard-selector/lib.rs @@ -38,17 +38,10 @@ pub mod wildcard_selector { mod e2e_tests { use super::*; - use ink::env::call::{ - utils::{ - Argument, - ArgumentList, - EmptyArgumentList, - ReturnType, - Set, - }, - Call, - CallBuilder, - ExecutionInput, + use ink::env::call::utils::{ + Argument, + ArgumentList, + EmptyArgumentList, }; type E2EResult = std::result::Result>; @@ -58,11 +51,10 @@ pub mod wildcard_selector { account_id: AccountId, selector: [u8; 4], message: String, - ) -> CallBuilder< + ) -> ink_e2e::CallBuilderFinal< Environment, - Set>, - Set, EmptyArgumentList>>>, - Set>, + ArgumentList, EmptyArgumentList>, + (), > { ink::env::call::build_call::() .call(account_id) From 5087d302eb87774794ef64b59669508ad28cd8ec Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 19 May 2023 10:26:33 +0100 Subject: [PATCH 27/27] CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 895b68d6bb4..15925026f73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Schema generation - [#1765](https://github.com/paritytech/ink/pull/1765) +### Changed +- E2E: improve call API, remove `build_message` + callback - [#1782](https://github.com/paritytech/ink/pull/1782) + ## Version 4.2.0 ### Added