diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index e66c4f27fbe8..2206aea78ec2 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -45,10 +45,7 @@ use frame_support::{ ord_parameter_types, parameter_types, traits::{ fungible, fungibles, - tokens::{ - imbalance::ResolveAssetTo, nonfungibles_v2::Inspect, Fortitude::Polite, - Preservation::Expendable, - }, + tokens::{imbalance::ResolveAssetTo, nonfungibles_v2::Inspect}, AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8, InstanceFilter, Nothing, TransformOrigin, }, @@ -68,7 +65,7 @@ use parachains_common::{ NORMAL_DISPATCH_RATIO, }; use sp_api::impl_runtime_apis; -use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H160}; +use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H160, U256}; use sp_runtime::{ generic, impl_opaque_keys, traits::{AccountIdConversion, BlakeTwo256, Block as BlockT, Saturating, Verify}, @@ -127,7 +124,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: alloc::borrow::Cow::Borrowed("westmint"), impl_name: alloc::borrow::Cow::Borrowed("westmint"), authoring_version: 1, - spec_version: 1_016_005, + spec_version: 1_016_006, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 16, @@ -2080,10 +2077,8 @@ impl_runtime_apis! { impl pallet_revive::ReviveApi for Runtime { - fn balance(address: H160) -> Balance { - use frame_support::traits::fungible::Inspect; - let account = ::AddressMapper::to_account_id(&address); - Balances::reducible_balance(&account, Expendable, Polite) + fn balance(address: H160) -> U256 { + Revive::evm_balance(&address) } fn nonce(address: H160) -> Nonce { @@ -2093,7 +2088,7 @@ impl_runtime_apis! { fn eth_transact( from: H160, dest: Option, - value: Balance, + value: U256, input: Vec, gas_limit: Option, storage_deposit_limit: Option, diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 5a2ff3ceb7f6..914b51fb5621 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -54,7 +54,7 @@ use frame_support::{ }, tokens::{ imbalance::ResolveAssetTo, nonfungibles_v2::Inspect, pay::PayAssetFromAccount, - Fortitude::Polite, GetSalary, PayFromAccount, Preservation::Preserve, + GetSalary, PayFromAccount, }, AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU16, ConstU32, ConstU64, Contains, Currency, EitherOfDiverse, EnsureOriginWithArg, EqualPrivilegeOnly, Imbalance, InsideBoth, @@ -86,6 +86,7 @@ use pallet_nis::WithMaximumOf; use pallet_nomination_pools::PoolId; use pallet_revive::{evm::runtime::EthExtra, AddressMapper}; use pallet_session::historical as pallet_session_historical; +use sp_core::U256; // Can't use `FungibleAdapter` here until Treasury pallet migrates to fungibles // use pallet_broker::TaskId; @@ -3205,10 +3206,8 @@ impl_runtime_apis! { impl pallet_revive::ReviveApi for Runtime { - fn balance(address: H160) -> Balance { - use frame_support::traits::fungible::Inspect; - let account = ::AddressMapper::to_account_id(&address); - Balances::reducible_balance(&account, Preserve, Polite) + fn balance(address: H160) -> U256 { + Revive::evm_balance(&address) } fn nonce(address: H160) -> Nonce { @@ -3219,7 +3218,7 @@ impl_runtime_apis! { fn eth_transact( from: H160, dest: Option, - value: Balance, + value: U256, input: Vec, gas_limit: Option, storage_deposit_limit: Option, diff --git a/substrate/frame/revive/rpc/revive_chain.metadata b/substrate/frame/revive/rpc/revive_chain.metadata index e5bfa0820b10..3560b3b90407 100644 Binary files a/substrate/frame/revive/rpc/revive_chain.metadata and b/substrate/frame/revive/rpc/revive_chain.metadata differ diff --git a/substrate/frame/revive/rpc/src/client.rs b/substrate/frame/revive/rpc/src/client.rs index bc4f59b5e26e..15a30816304a 100644 --- a/substrate/frame/revive/rpc/src/client.rs +++ b/substrate/frame/revive/rpc/src/client.rs @@ -236,7 +236,6 @@ struct ClientInner { cache: Shared>, chain_id: u64, max_block_weight: Weight, - native_to_evm_ratio: U256, } impl ClientInner { @@ -252,20 +251,10 @@ impl ClientInner { let rpc = LegacyRpcMethods::::new(RpcClient::new(rpc_client.clone())); - let (native_to_evm_ratio, chain_id, max_block_weight) = - tokio::try_join!(native_to_evm_ratio(&api), chain_id(&api), max_block_weight(&api))?; + let (chain_id, max_block_weight) = + tokio::try_join!(chain_id(&api), max_block_weight(&api))?; - Ok(Self { api, rpc_client, rpc, cache, chain_id, max_block_weight, native_to_evm_ratio }) - } - - /// Convert a native balance to an EVM balance. - fn native_to_evm_decimals(&self, value: U256) -> U256 { - value.saturating_mul(self.native_to_evm_ratio) - } - - /// Convert an evm balance to a native balance. - fn evm_to_native_decimals(&self, value: U256) -> U256 { - value / self.native_to_evm_ratio + Ok(Self { api, rpc_client, rpc, cache, chain_id, max_block_weight }) } /// Get the receipt infos from the extrinsics in a block. @@ -368,13 +357,6 @@ async fn max_block_weight(api: &OnlineClient) -> Result) -> Result { - let query = subxt_client::constants().revive().native_to_eth_ratio(); - let ratio = api.constants().at(&query)?; - Ok(U256::from(ratio)) -} - /// Extract the block timestamp. async fn extract_block_timestamp(block: &SubstrateBlock) -> Option { let extrinsics = block.extrinsics().await.ok()?; @@ -607,8 +589,9 @@ impl Client { let runtime_api = self.runtime_api(at).await?; let payload = subxt_client::apis().revive_api().balance(address); - let balance = runtime_api.call(payload).await?.into(); - Ok(self.inner.native_to_evm_decimals(balance)) + let balance = runtime_api.call(payload).await?; + + Ok(*balance) } /// Get the contract storage for the given contract address and key. @@ -659,20 +642,15 @@ impl Client { ) -> Result>, ClientError> { let runtime_api = self.runtime_api(&block).await?; - let value = self - .inner - .evm_to_native_decimals(tx.value.unwrap_or_default()) - .try_into() - .map_err(|_| ClientError::ConversionFailed)?; - // TODO: remove once subxt is updated + let value = tx.value.unwrap_or_default(); let from = tx.from.map(|v| v.0.into()); let to = tx.to.map(|v| v.0.into()); let payload = subxt_client::apis().revive_api().eth_transact( from.unwrap_or_default(), to, - value, + subxt::utils::Static(value), tx.input.clone().unwrap_or_default().0, None, None, diff --git a/substrate/frame/revive/rpc/src/subxt_client.rs b/substrate/frame/revive/rpc/src/subxt_client.rs index 11a0d51ed03e..a232b231bc7c 100644 --- a/substrate/frame/revive/rpc/src/subxt_client.rs +++ b/substrate/frame/revive/rpc/src/subxt_client.rs @@ -21,6 +21,11 @@ use subxt::config::{signed_extensions, Config, PolkadotConfig}; #[subxt::subxt( runtime_metadata_path = "revive_chain.metadata", + // TODO remove once subxt use the same U256 type + substitute_type( + path = "primitive_types::U256", + with = "::subxt::utils::Static<::sp_core::U256>" + ), substitute_type( path = "pallet_revive::primitives::EthContractResult", with = "::subxt::utils::Static<::pallet_revive::EthContractResult>" diff --git a/substrate/frame/revive/src/lib.rs b/substrate/frame/revive/src/lib.rs index c6a2d36c8662..caecf07c4071 100644 --- a/substrate/frame/revive/src/lib.rs +++ b/substrate/frame/revive/src/lib.rs @@ -59,6 +59,7 @@ use frame_support::{ pallet_prelude::DispatchClass, traits::{ fungible::{Inspect, Mutate, MutateHold}, + tokens::{Fortitude::Polite, Preservation::Preserve}, ConstU32, ConstU64, Contains, EnsureOrigin, Get, IsType, OriginTrait, Time, }, weights::{Weight, WeightMeter}, @@ -1216,7 +1217,7 @@ where /// /// - `origin`: The origin of the call. /// - `dest`: The destination address of the call. - /// - `value`: The value to transfer. + /// - `value`: The EVM value to transfer. /// - `input`: The input data. /// - `gas_limit`: The gas limit enforced during contract execution. /// - `storage_deposit_limit`: The maximum balance that can be charged to the caller for storage @@ -1228,7 +1229,7 @@ where pub fn bare_eth_transact( origin: T::AccountId, dest: Option, - value: BalanceOf, + value: U256, input: Vec, gas_limit: Weight, storage_deposit_limit: BalanceOf, @@ -1252,6 +1253,18 @@ where // Get the nonce to encode in the tx. let nonce: T::Nonce = >::account_nonce(&origin); + // Convert the value to the native balance type. + let native_value = match Self::convert_evm_to_native(value) { + Ok(v) => v, + Err(err) => + return EthContractResult { + gas_required: Default::default(), + storage_deposit: Default::default(), + fee: Default::default(), + result: Err(err.into()), + }, + }; + // Dry run the call let (mut result, dispatch_info) = match dest { // A contract call. @@ -1260,7 +1273,7 @@ where let result = crate::Pallet::::bare_call( T::RuntimeOrigin::signed(origin), dest, - value, + native_value, gas_limit, storage_deposit_limit, input.clone(), @@ -1277,7 +1290,7 @@ where // Get the dispatch info of the call. let dispatch_call: ::RuntimeCall = crate::Call::::call { dest, - value, + value: native_value, gas_limit: result.gas_required, storage_deposit_limit: result.storage_deposit, data: input.clone(), @@ -1303,7 +1316,7 @@ where // Dry run the call. let result = crate::Pallet::::bare_instantiate( T::RuntimeOrigin::signed(origin), - value, + native_value, gas_limit, storage_deposit_limit, Code::Upload(code.to_vec()), @@ -1323,7 +1336,7 @@ where // Get the dispatch info of the call. let dispatch_call: ::RuntimeCall = crate::Call::::instantiate_with_code { - value, + value: native_value, gas_limit: result.gas_required, storage_deposit_limit: result.storage_deposit, code: code.to_vec(), @@ -1336,7 +1349,7 @@ where }; let mut tx = TransactionLegacyUnsigned { - value: Self::convert_native_to_evm(value), + value, input: input.into(), nonce: nonce.into(), chain_id: Some(T::ChainId::get().into()), @@ -1375,6 +1388,12 @@ where result } + /// Get the balance with EVM decimals of the given `address`. + pub fn evm_balance(address: &H160) -> U256 { + let account = T::AddressMapper::to_account_id(&address); + Self::convert_native_to_evm(T::Currency::reducible_balance(&account, Preserve, Polite)) + } + /// A generalized version of [`Self::upload_code`]. /// /// It is identical to [`Self::upload_code`] and only differs in the information it returns. @@ -1473,8 +1492,8 @@ sp_api::decl_runtime_apis! { BlockNumber: Codec, EventRecord: Codec, { - /// Returns the free balance of the given `[H160]` address. - fn balance(address: H160) -> Balance; + /// Returns the free balance of the given `[H160]` address, using EVM decimals. + fn balance(address: H160) -> U256; /// Returns the nonce of the given `[H160]` address. fn nonce(address: H160) -> Nonce; @@ -1511,7 +1530,7 @@ sp_api::decl_runtime_apis! { fn eth_transact( origin: H160, dest: Option, - value: Balance, + value: U256, input: Vec, gas_limit: Option, storage_deposit_limit: Option,