diff --git a/crates/e2e/src/backend.rs b/crates/e2e/src/backend.rs index dff4de39d68..fba042c129f 100644 --- a/crates/e2e/src/backend.rs +++ b/crates/e2e/src/backend.rs @@ -19,7 +19,10 @@ use ink_env::{ EncodeArgsWith, }, }; -use ink_primitives::H160; +use ink_primitives::{ + H160, + U256, +}; use ink_revive_types::evm::CallTrace; use jsonrpsee::core::async_trait; use sp_weights::Weight; @@ -65,14 +68,14 @@ pub trait ChainBackend { async fn create_and_fund_account( &mut self, origin: &Keypair, - amount: Self::Balance, + amount: U256, ) -> Keypair; /// Returns the free balance of `account`. async fn free_balance( &mut self, account: Self::AccountId, - ) -> Result; + ) -> Result; /// Executes a runtime call `call_name` for the `pallet_name`. /// The `call_data` is a `Vec`. @@ -104,8 +107,13 @@ pub trait ChainBackend { &mut self, origin: &Keypair, dest: Self::AccountId, - value: Self::Balance, + value: U256, ) -> Result<(), Self::Error>; + + /// Get the balance with EVM decimals of the given `address`. + /// + /// Returns the spendable balance excluding the existential deposit. + async fn evm_balance(&mut self, address: H160) -> U256; } /// Contract-specific operations. @@ -256,9 +264,9 @@ pub trait BuilderClient: ContractsBackend { &mut self, caller: &Keypair, message: &CallBuilderFinal, - value: E::Balance, + value: U256, gas_limit: Weight, - storage_deposit_limit: E::Balance, + storage_deposit_limit: U256, ) -> Result<(Self::EventLog, Option), Self::Error> where CallBuilderFinal: Clone; @@ -280,8 +288,8 @@ pub trait BuilderClient: ContractsBackend { &mut self, caller: &Keypair, message: &CallBuilderFinal, - value: E::Balance, - storage_deposit_limit: Option, + value: U256, + storage_deposit_limit: Option, ) -> Result, Self::Error> where CallBuilderFinal: Clone; @@ -332,8 +340,8 @@ pub trait BuilderClient: ContractsBackend { &mut self, contract_name: &str, caller: &Keypair, - storage_deposit_limit: Option, - ) -> Result, Self::Error>; + storage_deposit_limit: Option, + ) -> Result, Self::Error>; /// Removes the code of the contract at `code_hash`. async fn bare_remove_code( @@ -365,9 +373,9 @@ pub trait BuilderClient: ContractsBackend { code: Vec, caller: &Keypair, constructor: &mut CreateBuilderPartial, - value: E::Balance, + value: U256, gas_limit: Weight, - storage_deposit_limit: E::Balance, + storage_deposit_limit: U256, ) -> Result, Self::Error>; async fn raw_instantiate( @@ -394,9 +402,9 @@ pub trait BuilderClient: ContractsBackend { signer: &Keypair, contract_name: &str, data: Vec, - value: E::Balance, + value: U256, gas_limit: Weight, - storage_deposit_limit: E::Balance, + storage_deposit_limit: U256, ) -> Result, Self::Error>; /// Dry run contract instantiation. @@ -415,8 +423,8 @@ pub trait BuilderClient: ContractsBackend { contract_name: &str, caller: &Keypair, constructor: &mut CreateBuilderPartial, - value: E::Balance, - storage_deposit_limit: Option, + value: U256, + storage_deposit_limit: Option, ) -> Result, Self::Error>; /// Checks if `caller` was already mapped in `pallet-revive`. If not, it will do so diff --git a/crates/e2e/src/backend_calls.rs b/crates/e2e/src/backend_calls.rs index 8368fecc40b..e8244a45030 100644 --- a/crates/e2e/src/backend_calls.rs +++ b/crates/e2e/src/backend_calls.rs @@ -21,6 +21,7 @@ use ink_env::{ EncodeArgsWith, }, }; +use ink_primitives::U256; use sp_weights::Weight; use super::{ @@ -51,10 +52,10 @@ where client: &'a mut B, caller: &'a Keypair, message: &'a CallBuilderFinal, - value: E::Balance, + value: U256, extra_gas_portion: Option, gas_limit: Option, - storage_deposit_limit: Option, + storage_deposit_limit: Option, } impl<'a, E, Args, RetType, B, Abi> CallBuilder<'a, E, Args, RetType, B, Abi> @@ -70,15 +71,12 @@ where client: &'a mut B, caller: &'a Keypair, message: &'a CallBuilderFinal, - ) -> CallBuilder<'a, E, Args, RetType, B, Abi> - where - E::Balance: From, - { + ) -> CallBuilder<'a, E, Args, RetType, B, Abi> { Self { client, caller, message, - value: 0u32.into(), + value: U256::zero(), extra_gas_portion: None, gas_limit: None, storage_deposit_limit: None, @@ -86,7 +84,7 @@ where } /// Provide value with a call - pub fn value(&mut self, value: E::Balance) -> &mut Self { + pub fn value(&mut self, value: U256) -> &mut Self { self.value = value; self } @@ -124,10 +122,7 @@ where } /// Specify the max amount of funds that can be charged for storage. - pub fn storage_deposit_limit( - &mut self, - storage_deposit_limit: E::Balance, - ) -> &mut Self { + pub fn storage_deposit_limit(&mut self, storage_deposit_limit: U256) -> &mut Self { self.storage_deposit_limit = Some(storage_deposit_limit); self } @@ -168,7 +163,7 @@ where self.message, self.value, gas_limit, - dry_run.exec_result.storage_deposit.charge_or_zero(), + E::native_to_eth(dry_run.exec_result.storage_deposit.charge_or_zero()), ) .await?; @@ -207,10 +202,10 @@ where caller: &'a Keypair, contract_name: &'a str, constructor: &'a mut CreateBuilderPartial, - value: E::Balance, + value: U256, extra_gas_portion: Option, gas_limit: Option, - storage_deposit_limit: Option, + storage_deposit_limit: Option, } impl<'a, E, Contract, Args, R, B, Abi> @@ -228,16 +223,13 @@ where caller: &'a Keypair, contract_name: &'a str, constructor: &'a mut CreateBuilderPartial, - ) -> InstantiateBuilder<'a, E, Contract, Args, R, B, Abi> - where - E::Balance: From, - { + ) -> InstantiateBuilder<'a, E, Contract, Args, R, B, Abi> { Self { client, caller, contract_name, constructor, - value: 0u32.into(), + value: U256::zero(), extra_gas_portion: None, gas_limit: None, storage_deposit_limit: None, @@ -245,7 +237,7 @@ where } /// Provide value with a call - pub fn value(&mut self, value: E::Balance) -> &mut Self { + pub fn value(&mut self, value: U256) -> &mut Self { self.value = value; self } @@ -287,7 +279,7 @@ where /// *Important*: `None` means charging the maximum! pub fn storage_deposit_limit( &mut self, - storage_deposit_limit: Option, + storage_deposit_limit: Option, ) -> &mut Self { self.storage_deposit_limit = storage_deposit_limit; self @@ -329,7 +321,7 @@ where self.constructor, self.value, gas_limit, - dry_run.contract_result.storage_deposit.charge_or_zero(), + E::native_to_eth(dry_run.contract_result.storage_deposit.charge_or_zero()), ) .await?; @@ -366,7 +358,8 @@ where client: &'a mut B, contract_name: &'a str, caller: &'a Keypair, - storage_deposit_limit: Option, + storage_deposit_limit: Option, + _phantom: PhantomData, } impl<'a, E, B> UploadBuilder<'a, E, B> @@ -381,20 +374,21 @@ where contract_name, caller, storage_deposit_limit: None, + _phantom: Default::default(), } } /// Specify the max amount of funds that can be charged for storage. pub fn storage_deposit_limit( &mut self, - storage_deposit_limit: Option, + storage_deposit_limit: Option, ) -> &mut Self { self.storage_deposit_limit = storage_deposit_limit; self } /// Execute the upload. - pub async fn submit(&mut self) -> Result, B::Error> { + pub async fn submit(&mut self) -> Result, B::Error> { B::bare_upload( self.client, self.contract_name, diff --git a/crates/e2e/src/contract_results.rs b/crates/e2e/src/contract_results.rs index 8a070b1a74b..bccb50697a7 100644 --- a/crates/e2e/src/contract_results.rs +++ b/crates/e2e/src/contract_results.rs @@ -194,32 +194,15 @@ where } /// Result of a contract upload. -pub struct UploadResult { +pub struct UploadResult { /// The hash with which the contract can be instantiated. pub code_hash: H256, /// The result of the dry run, contains debug messages if there were any. - pub dry_run: CodeUploadResult, + pub dry_run: CodeUploadResult, /// Events that happened with the contract instantiation. pub events: EventLog, } -/// We implement a custom `Debug` here, to avoid requiring the trait bound `Debug` for -/// `E`. -impl Debug for UploadResult -where - E::Balance: Debug, - H256: Debug, - EventLog: Debug, -{ - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - f.debug_struct("UploadResult") - .field("code_hash", &self.code_hash) - .field("dry_run", &self.dry_run) - .field("events", &self.events) - .finish() - } -} - /// Result of a contract call. pub struct CallResult { /// The result of the dry run, contains debug messages if there were any. diff --git a/crates/e2e/src/subxt_client.rs b/crates/e2e/src/subxt_client.rs index 5bc4f171496..1f5784dc090 100644 --- a/crates/e2e/src/subxt_client.rs +++ b/crates/e2e/src/subxt_client.rs @@ -55,7 +55,10 @@ use crate::{ events, events::ContractInstantiatedEvent, }; -use ink::H160; +use ink::{ + H160, + U256, +}; use ink_env::{ Environment, call::{ @@ -130,7 +133,7 @@ where E: Environment, E::AccountId: Debug, E::EventRecord: Debug, - E::Balance: Debug + scale::HasCompact + serde::Serialize, + E::Balance: Debug + scale::HasCompact + serde::Serialize, // todo can be removed? H256: Debug + scale::Encode, { /// Creates a new [`Client`] instance using a `subxt` client. @@ -151,11 +154,15 @@ where &mut self, signer: &Keypair, code: Vec, - storage_deposit_limit: Option, - ) -> Result>, Error> { + storage_deposit_limit: Option, + ) -> Result>, Error> { let dry_run = self .api - .upload_dry_run(signer, code.clone(), storage_deposit_limit) + .upload_dry_run( + signer, + code.clone(), + storage_deposit_limit.map(E::eth_to_native), + ) .await; log_info(&format!("upload dry run: {dry_run:?}")); if let Err(err) = dry_run { @@ -173,8 +180,10 @@ where Some(limit) => limit, }; - let (tx_events, trace) = - self.api.upload(signer, code, storage_deposit_limit).await; + let (tx_events, trace) = self + .api + .upload(signer, code, E::eth_to_native(storage_deposit_limit)) + .await; let mut hash = None; for evt in tx_events.iter() { @@ -368,7 +377,7 @@ where async fn create_and_fund_account( &mut self, origin: &Keypair, - amount: Self::Balance, + amount: U256, ) -> Keypair { let (_, phrase, _) = ::generate_with_phrase(None); @@ -397,7 +406,7 @@ where async fn free_balance( &mut self, account: Self::AccountId, - ) -> Result { + ) -> Result { let account_addr = subxt::dynamic::storage( "System", "Account", @@ -435,7 +444,7 @@ where })?; log_info(&format!("balance of contract {account:?} is {balance:?}")); - Ok(balance) + Ok(E::native_to_eth(balance)) } async fn runtime_call<'a>( @@ -474,7 +483,7 @@ where &mut self, origin: &Keypair, dest: Self::AccountId, - value: Self::Balance, + value: U256, ) -> Result<(), Self::Error> { let dest = Encode::encode(&dest); let dest: C::AccountId = Decode::decode(&mut &dest[..]).unwrap(); @@ -483,6 +492,10 @@ where .await .map_err(|err| Error::Balance(format!("{err:?}"))) } + + async fn evm_balance(&mut self, _address: H160) -> U256 { + unimplemented!("todo") + } } #[async_trait] @@ -524,13 +537,20 @@ where code: Vec, caller: &Keypair, constructor: &mut CreateBuilderPartial, - value: E::Balance, + value: U256, gas_limit: Weight, - storage_deposit_limit: E::Balance, + storage_deposit_limit: U256, ) -> Result, Self::Error> { let data = constructor_exec_input(constructor.clone()); let ret = self - .raw_instantiate(code, caller, data, value, gas_limit, storage_deposit_limit) + .raw_instantiate( + code, + caller, + data, + E::eth_to_native(value), + gas_limit, + E::eth_to_native(storage_deposit_limit), + ) .await?; Ok(ret) } @@ -608,13 +628,20 @@ where signer: &Keypair, contract_name: &str, data: Vec, - value: E::Balance, + value: U256, gas_limit: Weight, - storage_deposit_limit: E::Balance, + storage_deposit_limit: U256, ) -> Result, Self::Error> { let code = self.contracts.load_code(contract_name); - self.raw_instantiate(code, signer, data, value, gas_limit, storage_deposit_limit) - .await + self.raw_instantiate( + code, + signer, + data, + E::eth_to_native(value), + gas_limit, + E::eth_to_native(storage_deposit_limit), + ) + .await } /// Important: For an uncomplicated UX of the E2E testing environment we @@ -631,13 +658,19 @@ where contract_name: &str, caller: &Keypair, constructor: &mut CreateBuilderPartial, - value: E::Balance, - storage_deposit_limit: Option, + value: U256, + storage_deposit_limit: Option, ) -> Result, Self::Error> { let code = self.contracts.load_code(contract_name); let data = constructor_exec_input(constructor.clone()); - self.raw_instantiate_dry_run(code, caller, data, value, storage_deposit_limit) - .await + self.raw_instantiate_dry_run( + code, + caller, + data, + E::eth_to_native(value), + storage_deposit_limit.map(|v| E::eth_to_native(v)), + ) + .await } /// Important: For an uncomplicated UX of the E2E testing environment we @@ -690,8 +723,8 @@ where &mut self, contract_name: &str, caller: &Keypair, - storage_deposit_limit: Option, - ) -> Result, Self::Error> { + storage_deposit_limit: Option, + ) -> Result, Self::Error> { let code = self.contracts.load_code(contract_name); let ret = self .exec_upload(caller, code, storage_deposit_limit) @@ -735,9 +768,9 @@ where &mut self, caller: &Keypair, message: &CallBuilderFinal, - value: E::Balance, + value: U256, gas_limit: Weight, - storage_deposit_limit: E::Balance, + storage_deposit_limit: U256, ) -> Result<(Self::EventLog, Option), Self::Error> where CallBuilderFinal: Clone, @@ -748,9 +781,9 @@ where self.raw_call( addr, exec_input, - value, + E::eth_to_native(value), gas_limit, - storage_deposit_limit, + E::eth_to_native(storage_deposit_limit), caller, ) .await @@ -815,8 +848,8 @@ where &mut self, caller: &Keypair, message: &CallBuilderFinal, - value: E::Balance, - storage_deposit_limit: Option, + value: U256, + storage_deposit_limit: Option, ) -> Result, Self::Error> where CallBuilderFinal: Clone, @@ -829,7 +862,13 @@ where let (exec_result, trace) = self .api - .call_dry_run(dest, exec_input, value, storage_deposit_limit, caller) + .call_dry_run( + dest, + exec_input, + E::eth_to_native(value), + storage_deposit_limit.map(|v| E::eth_to_native(v)), + caller, + ) .await; log_info(&format!("call dry run result: {:?}", &exec_result.result)); diff --git a/crates/e2e/src/xts.rs b/crates/e2e/src/xts.rs index 5a75b9b91c1..554dbe795cb 100644 --- a/crates/e2e/src/xts.rs +++ b/crates/e2e/src/xts.rs @@ -25,9 +25,13 @@ use crate::contract_results::{ }; use core::marker::PhantomData; use funty::Fundamental; -use ink_primitives::Address; +use ink_primitives::{ + Address, + U256, +}; use ink_revive_types::{ CodeUploadResult, + CodeUploadReturnValue, evm::{ CallTrace, CallTracerConfig, @@ -248,14 +252,14 @@ where &self, origin: &Keypair, dest: C::AccountId, - value: E::Balance, + value: U256, ) -> Result<(), subxt::Error> { let call = subxt::tx::DefaultPayload::new( "Balances", "transfer_allow_death", Transfer:: { dest: subxt::utils::Static(dest.into()), - value, + value: E::eth_to_native(value), }, ) .unvalidated(); @@ -544,7 +548,7 @@ where signer: &Keypair, code: Vec, storage_deposit_limit: Option, - ) -> CodeUploadResult { + ) -> CodeUploadResult { let call_request = RpcCodeUploadRequest:: { origin: Signer::::account_id(signer), code, @@ -559,8 +563,29 @@ where .unwrap_or_else(|err| { panic!("error on ws request `upload_code`: {err:?}"); }); - scale::Decode::decode(&mut bytes.as_ref()) - .unwrap_or_else(|err| panic!("decoding CodeUploadResult failed: {err}")) + + /// The result of successfully uploading a contract. + //#[derive(Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen, RuntimeDebug, + //#[derive(Clone, TypeInfo)] + #[derive(scale::Encode, scale::Decode)] + struct PrCodeUploadReturnValue { + /// The key under which the new code is stored. + pub code_hash: H256, + /// The deposit that was reserved at the caller. Is zero when the code + /// already existed. + pub deposit: Balance, + } + let res: Result, sp_runtime::DispatchError> = + scale::Decode::decode(&mut bytes.as_ref()) + .unwrap_or_else(|err| panic!("decoding CodeUploadResult failed: {err}")); + + let ret: CodeUploadResult = res.map(|c: PrCodeUploadReturnValue| { + CodeUploadReturnValue { + code_hash: c.code_hash, + deposit: E::native_to_eth(c.deposit), + } + }); + ret } /// Submits an extrinsic to upload a given code. diff --git a/crates/primitives/src/types.rs b/crates/primitives/src/types.rs index 86a890adb49..de3ad180654 100644 --- a/crates/primitives/src/types.rs +++ b/crates/primitives/src/types.rs @@ -328,6 +328,7 @@ pub trait Environment: Clone { + Eq + AtLeast32BitUnsigned + Into + + From + FromLittleEndian; /// The type of hash. @@ -383,6 +384,30 @@ pub trait Environment: Clone { .saturating_mul(Self::NATIVE_TO_ETH_RATIO.into()) .into() } + + /// Converts from the generic `Balance` type to the Ethereum native `U256`. + /// + /// # Developer Note + /// + /// `pallet-revive` uses both types, hence we have to convert in between them + /// for certain functions. Notice that precision loss might occur when converting + /// the other way (from `U256` to `Balance`). + /// + /// See for more details. + fn eth_to_native(value: U256) -> Self::Balance { + let (quotient, remainder) = value.div_mod(Self::NATIVE_TO_ETH_RATIO.into()); + let q = quotient.as_u128(); + let r = remainder.as_u128(); + assert_eq!( + r, + 0, + "oh no! remainder of '{} / {}' was not 0: {}", + value, + Self::NATIVE_TO_ETH_RATIO, + r + ); + q.into() + } } /// The fundamental types of the default configuration. diff --git a/crates/revive-types/src/primitives.rs b/crates/revive-types/src/primitives.rs index c435a067bfc..385c90da7c4 100644 --- a/crates/revive-types/src/primitives.rs +++ b/crates/revive-types/src/primitives.rs @@ -217,17 +217,16 @@ pub struct InstantiateReturnValue { /// The result of successfully uploading a contract. #[derive(Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen, RuntimeDebug, TypeInfo)] -pub struct CodeUploadReturnValue { +pub struct CodeUploadReturnValue { /// The key under which the new code is stored. pub code_hash: H256, /// The deposit that was reserved at the caller. Is zero when the code already /// existed. - pub deposit: Balance, + pub deposit: U256, } /// Result type of a `bare_code_upload` call. -pub type CodeUploadResult = - Result, DispatchError>; +pub type CodeUploadResult = Result; /// `Stack` wide configuration options. #[derive(Debug, Clone)] diff --git a/crates/sandbox/src/api/balance_api.rs b/crates/sandbox/src/api/balance_api.rs index 8bbc0f0a30d..eb58988fafc 100644 --- a/crates/sandbox/src/api/balance_api.rs +++ b/crates/sandbox/src/api/balance_api.rs @@ -7,6 +7,10 @@ use frame_support::{ sp_runtime::DispatchError, traits::fungible::Mutate, }; +use ink_e2e::subxt::{ + config::polkadot::U256, + utils::H160, +}; use pallet_revive::sp_runtime::traits::StaticLookup; type BalanceOf = ::Balance; diff --git a/crates/sandbox/src/api/revive_api.rs b/crates/sandbox/src/api/revive_api.rs index 8e84b86143d..bf92fc530aa 100644 --- a/crates/sandbox/src/api/revive_api.rs +++ b/crates/sandbox/src/api/revive_api.rs @@ -19,7 +19,10 @@ use frame_support::{ weights::Weight, }; use frame_system::pallet_prelude::OriginFor; -use ink_primitives::Address; +use ink_primitives::{ + Address, + H160, +}; use pallet_revive::{ Code, CodeUploadResult, @@ -148,7 +151,13 @@ pub trait ContractAPI { storage_deposit_limit: BalanceOf, ) -> ContractExecResultFor; + /// Build an EVM tracer from the given tracer type. fn evm_tracer(&mut self, tracer_type: TracerType) -> Tracer; + + /// Get the balance with EVM decimals of the given `address`. + /// + /// Returns the spendable balance excluding the existential deposit. + fn evm_balance(&mut self, address: H160) -> U256; } impl ContractAPI for T @@ -290,6 +299,10 @@ where fn evm_tracer(&mut self, tracer_type: TracerType) -> Tracer { self.execute_with(|| pallet_revive::Pallet::::evm_tracer(tracer_type)) } + + fn evm_balance(&mut self, address: H160) -> U256 { + self.execute_with(|| pallet_revive::Pallet::::evm_balance(&address)) + } } /// todo diff --git a/crates/sandbox/src/client.rs b/crates/sandbox/src/client.rs index 48e2b298a59..e10785a8576 100644 --- a/crates/sandbox/src/client.rs +++ b/crates/sandbox/src/client.rs @@ -92,12 +92,15 @@ use ink_revive_types::{ use jsonrpsee::core::async_trait; use scale::Decode; use sp_core::{ + Get, Pair as _, sr25519::Pair, }; use sp_runtime::traits::Bounded; use std::{ + fmt::Debug, marker::PhantomData, + ops::Div, path::PathBuf, }; @@ -165,8 +168,13 @@ where #[async_trait] impl + Send, S: Sandbox> ChainBackend for Client where - S::Runtime: pallet_balances::Config, + S::Runtime: pallet_balances::Config + pallet_revive::Config, AccountIdFor: From<[u8; 32]>, + BalanceOf: Into + TryFrom + Bounded, + as TryFrom>::Error: Debug, + MomentOf: Into, + <::Runtime as frame_system::Config>::Nonce: Into, + <::Runtime as frame_system::Config>::Hash: IsType, { type AccountId = AccountId; type Balance = BalanceOf; @@ -176,12 +184,15 @@ where async fn create_and_fund_account( &mut self, _origin: &Keypair, - amount: Self::Balance, + amount: U256, ) -> Keypair { let (pair, seed) = Pair::generate(); self.sandbox - .mint_into(&pair.public().0.into(), amount) + .mint_into( + &pair.public().0.into(), + amount.try_into().expect("conversion failed"), + ) .expect("Failed to mint tokens"); Keypair::from_secret_key(seed).expect("Failed to create keypair") @@ -190,9 +201,15 @@ where async fn free_balance( &mut self, account: Self::AccountId, - ) -> Result { + ) -> Result { + /* let account = AccountIdFor::::from(*account.as_ref()); - Ok(self.sandbox.free_balance(&account)) + let free: BalanceOf = self.sandbox.free_balance(&account); + let free_u: U256 = free.into(); + let free: E::Balance = free_u.try_into().unwrap(); + Ok(E::native_to_eth(free)) + */ + panic!("foo"); } async fn runtime_call<'a>( @@ -243,7 +260,7 @@ where &mut self, origin: &Keypair, dest: Self::AccountId, - value: Self::Balance, + value: U256, ) -> Result<(), Self::Error> { let caller = keypair_to_account(origin); let origin = RawOrigin::Signed(caller); @@ -252,12 +269,26 @@ where let dest = dest.as_ref(); let dest = Decode::decode(&mut dest.as_slice()).unwrap(); + let ratio = ::NativeToEthRatio::get(); + let value2 = value.div(ratio); + let value3: BalanceOf = value2.try_into().unwrap(); + /* + let value1: E::Balance = E::eth_to_native(value); + let value2: U256 = >::into(value1); + let value3: BalanceOf = value2.try_into().unwrap(); + //let value_u: u128 = value1.try_into().unwrap(); + */ + self.sandbox - .transfer_allow_death(&origin, &dest, value) + .transfer_allow_death(&origin, &dest, value3) .map_err(|err| { SandboxErr::new(format!("transfer_allow_death failed: {err:?}")) }) } + + async fn evm_balance(&mut self, addr: H160) -> U256 { + self.sandbox.evm_balance(addr) + } } #[async_trait] @@ -287,13 +318,20 @@ where signer: &Keypair, contract_name: &str, data: Vec, - value: E::Balance, + value: U256, gas_limit: Weight, - storage_deposit_limit: E::Balance, + storage_deposit_limit: U256, ) -> Result, Self::Error> { let code = self.contracts.load_code(contract_name); - self.raw_instantiate(code, signer, data, value, gas_limit, storage_deposit_limit) - .await + self.raw_instantiate( + code, + signer, + data, + E::eth_to_native(value), + gas_limit, + E::eth_to_native(storage_deposit_limit), + ) + .await } async fn bare_instantiate< @@ -306,13 +344,20 @@ where code: Vec, caller: &Keypair, constructor: &mut CreateBuilderPartial, - value: E::Balance, + value: U256, gas_limit: Weight, - storage_deposit_limit: E::Balance, + storage_deposit_limit: U256, ) -> Result, Self::Error> { let data = constructor_exec_input(constructor.clone()); - self.raw_instantiate(code, caller, data, value, gas_limit, storage_deposit_limit) - .await + self.raw_instantiate( + code, + caller, + data, + E::eth_to_native(value), + gas_limit, + E::eth_to_native(storage_deposit_limit), + ) + .await } async fn raw_instantiate( @@ -394,8 +439,8 @@ where contract_name: &str, caller: &Keypair, constructor: &mut CreateBuilderPartial, - value: E::Balance, - storage_deposit_limit: Option, + value: U256, + storage_deposit_limit: Option, ) -> Result, Self::Error> { let code = self.contracts.load_code(contract_name); let exec_input = constructor.clone().params().exec_input().encode(); @@ -403,8 +448,8 @@ where code, caller, exec_input, - value, - storage_deposit_limit, + E::eth_to_native(value), + storage_deposit_limit.map(|v| E::eth_to_native(v)), ) .await } @@ -473,9 +518,10 @@ where &mut self, contract_name: &str, caller: &Keypair, - storage_deposit_limit: Option, - ) -> Result, Self::Error> { + storage_deposit_limit: Option, + ) -> Result, Self::Error> { let code = self.contracts.load_code(contract_name); + let storage_deposit_limit = storage_deposit_limit.map(E::eth_to_native); let result = match self.sandbox.upload_contract( code, @@ -493,7 +539,7 @@ where code_hash: result.code_hash, dry_run: Ok(CodeUploadReturnValue { code_hash: result.code_hash, - deposit: result.deposit, + deposit: E::native_to_eth(result.deposit), }), events: (), }) @@ -519,9 +565,9 @@ where &mut self, caller: &Keypair, message: &CallBuilderFinal, - value: E::Balance, + value: U256, gas_limit: Weight, - storage_deposit_limit: E::Balance, + storage_deposit_limit: U256, ) -> Result<(Self::EventLog, Option), Self::Error> where CallBuilderFinal: Clone, @@ -536,9 +582,9 @@ where self, addr, exec_input, - value, + E::eth_to_native(value), gas_limit, - storage_deposit_limit, + E::eth_to_native(storage_deposit_limit), caller, ) .await @@ -593,16 +639,22 @@ where &mut self, caller: &Keypair, message: &CallBuilderFinal, - value: E::Balance, - storage_deposit_limit: Option, + value: U256, + storage_deposit_limit: Option, ) -> Result, Self::Error> where CallBuilderFinal: Clone, { let addr = *message.clone().params().callee(); let exec_input = message.clone().params().exec_input().encode(); - self.raw_call_dry_run(addr, exec_input, value, storage_deposit_limit, caller) - .await + self.raw_call_dry_run( + addr, + exec_input, + E::eth_to_native(value), + storage_deposit_limit.map(|v| E::eth_to_native(v)), + caller, + ) + .await } /// Important: For an uncomplicated UX of the E2E testing environment we @@ -708,6 +760,10 @@ where ContractsBalanceOf: Send + Sync, ContractsBalanceOf: Into + TryFrom + Bounded, MomentOf: Into, + BalanceOf: + Into + TryFrom + Bounded + From + Into, + as TryFrom>::Error: Debug, + >::Error: Debug, ::Nonce: Into, // todo ::Hash: IsType, diff --git a/integration-tests/internal/call-builder-return-value/lib.rs b/integration-tests/internal/call-builder-return-value/lib.rs index a81bc033aa6..38c9ec57074 100755 --- a/integration-tests/internal/call-builder-return-value/lib.rs +++ b/integration-tests/internal/call-builder-return-value/lib.rs @@ -127,7 +127,7 @@ mod call_builder { mut client: Client, ) -> E2EResult<()> { let origin = client - .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000) + .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000.into()) .await; let expected_value = 42; @@ -171,7 +171,7 @@ mod call_builder { mut client: Client, ) -> E2EResult<()> { let origin = client - .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000) + .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000.into()) .await; let mut constructor = CallBuilderReturnValueRef::new(42); @@ -215,7 +215,7 @@ mod call_builder { mut client: Client, ) -> E2EResult<()> { let origin = client - .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000) + .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000.into()) .await; let mut constructor = CallBuilderReturnValueRef::new(0); @@ -258,7 +258,7 @@ mod call_builder { mut client: Client, ) -> E2EResult<()> { let origin = client - .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000) + .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000.into()) .await; let mut constructor = CallBuilderReturnValueRef::new(0); diff --git a/integration-tests/internal/lang-err/call-builder/lib.rs b/integration-tests/internal/lang-err/call-builder/lib.rs index caf1380279b..875245ad215 100755 --- a/integration-tests/internal/lang-err/call-builder/lib.rs +++ b/integration-tests/internal/lang-err/call-builder/lib.rs @@ -183,7 +183,7 @@ mod call_builder { mut client: Client, ) -> E2EResult<()> { let origin = client - .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000) + .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000.into()) .await; let mut constructor = CallBuilderTestRef::new(); diff --git a/integration-tests/public/contract-invocation/lib.rs b/integration-tests/public/contract-invocation/lib.rs index 9a7188affb4..5f904846c01 100644 --- a/integration-tests/public/contract-invocation/lib.rs +++ b/integration-tests/public/contract-invocation/lib.rs @@ -431,7 +431,7 @@ mod instantiate_contract { mut client: Client, ) -> E2EResult<()> { let origin = client - .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000) + .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000.into()) .await; let mut constructor = VirtualContractVer1Ref::new(); diff --git a/integration-tests/public/contract-transfer/lib.rs b/integration-tests/public/contract-transfer/lib.rs index dfeb8e865ae..358cfc51230 100644 --- a/integration-tests/public/contract-transfer/lib.rs +++ b/integration-tests/public/contract-transfer/lib.rs @@ -197,7 +197,7 @@ pub mod give_me { let mut constructor = GiveMeRef::new(); let contract = client .instantiate("contract_transfer", &ink_e2e::alice(), &mut constructor) - .value(1_000_000_000) + .value(1_000_000_000.into()) .submit() .await .expect("instantiate failed"); @@ -208,7 +208,7 @@ pub mod give_me { let call_res = client .call(&ink_e2e::bob(), &transfer) - .value(10_000_000) + .value(10_000_000_000u128.into()) .submit() .await; @@ -236,8 +236,7 @@ pub mod give_me { let mut constructor = GiveMeRef::new(); let contract = client .instantiate("contract_transfer", &ink_e2e::bob(), &mut constructor) - // todo convert the argument type to U256 - .value(1_337_000_000) + .value(1_337_000_000_000u128.into()) .submit() .await .expect("instantiate failed"); @@ -245,18 +244,15 @@ pub mod give_me { assert_eq!( contract.trace.clone().unwrap().value, - Some(ink::env::DefaultEnvironment::native_to_eth(1_337_000_000)) + //Some(ink::env::DefaultEnvironment::native_to_eth(1_337_000_000)) + Some(1_337_000_000_000u128.into()) ); let mut call_builder = contract.call_builder::(); - let balance_before: Balance = client - .free_balance(contract.account_id) - .await - .expect("getting balance failed"); + let balance_before = client.evm_balance(contract.addr).await; // when - let transfer = call_builder.give_me(U256::from(120_000_000_0)); - + let transfer = call_builder.give_me(120_000_000_000u128.into()); let call_res = client .call(&ink_e2e::eve(), &transfer) .submit() @@ -265,18 +261,15 @@ pub mod give_me { // then let outgoing_trace = &call_res.trace.unwrap().calls[0]; - assert_eq!(outgoing_trace.value, Some(U256::from(120_000_000_0))); + assert_eq!(outgoing_trace.value, Some(120_000_000_000u128.into())); assert_eq!(outgoing_trace.from, contract_addr); assert_eq!( outgoing_trace.to, ink_e2e::address_from_keypair::(&ink_e2e::eve()) ); - let balance_after: Balance = client - .free_balance(contract.account_id) - .await - .expect("getting balance failed"); - assert_eq!(balance_before - balance_after, 12); + let balance_after = client.evm_balance(contract.addr).await; + assert_eq!(balance_before - balance_after, 120_000_000_000u128.into()); Ok(()) } diff --git a/integration-tests/public/upgradeable-contracts/delegator/lib.rs b/integration-tests/public/upgradeable-contracts/delegator/lib.rs index 7018a663d89..c4f631e918f 100644 --- a/integration-tests/public/upgradeable-contracts/delegator/lib.rs +++ b/integration-tests/public/upgradeable-contracts/delegator/lib.rs @@ -137,7 +137,7 @@ pub mod delegator { ) -> E2EResult<()> { // given let origin = client - .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000) + .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000.into()) .await; /* @@ -207,7 +207,7 @@ pub mod delegator { mut client: Client, ) -> E2EResult<()> { let origin = client - .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000) + .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000.into()) .await; /* @@ -281,7 +281,7 @@ pub mod delegator { ) -> E2EResult<()> { // given let origin = client - .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000) + .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000.into()) .await; /* diff --git a/integration-tests/solidity-abi/solidity-calls-flipper/e2e_tests.rs b/integration-tests/solidity-abi/solidity-calls-flipper/e2e_tests.rs index 41fd75e351c..e56407e7a7b 100644 --- a/integration-tests/solidity-abi/solidity-calls-flipper/e2e_tests.rs +++ b/integration-tests/solidity-abi/solidity-calls-flipper/e2e_tests.rs @@ -160,9 +160,9 @@ async fn call_ink_no_return( .raw_call( ink_addr, data_sol, - Balance::from(0u128), + 0u128.into(), DEFAULT_GAS.into(), - Balance::MAX, + Balance::MAX.into(), &signer, ) .await;