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 fd993b1ba87ca..64d9a5a79737e 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -42,7 +42,7 @@ use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ClaimQueueOffset, CoreSelector, ParaId}; use frame_support::{ construct_runtime, derive_impl, - dispatch::{DispatchClass, DispatchInfo}, + dispatch::DispatchClass, genesis_builder_helper::{build_state, get_preset}, ord_parameter_types, parameter_types, traits::{ @@ -62,7 +62,7 @@ use frame_system::{ }; use pallet_asset_conversion_tx_payment::SwapAssetAdapter; use pallet_nfts::{DestroyWitness, PalletFeatures}; -use pallet_revive::{evm::runtime::EthExtra, AddressMapper, NonceAlreadyIncremented}; +use pallet_revive::evm::runtime::EthExtra; use pallet_xcm::EnsureXcm; use parachains_common::{ impls::DealWithFees, message_queue::*, AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, @@ -70,12 +70,10 @@ use parachains_common::{ NORMAL_DISPATCH_RATIO, }; use sp_api::impl_runtime_apis; -use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H160, U256}; +use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_runtime::{ generic, impl_opaque_keys, - traits::{ - AccountIdConversion, BlakeTwo256, Block as BlockT, Saturating, TransactionExtension, Verify, - }, + traits::{AccountIdConversion, BlakeTwo256, Block as BlockT, Saturating, Verify}, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, Perbill, Permill, RuntimeDebug, }; @@ -1482,7 +1480,11 @@ mod benches { ); } -impl_runtime_apis! { +pallet_revive::impl_runtime_apis_plus_revive!( + Runtime, + Executive, + EthExtraImpl, + impl sp_consensus_aura::AuraApi for Runtime { fn slot_duration() -> sp_consensus_aura::SlotDuration { sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION) @@ -2288,185 +2290,7 @@ impl_runtime_apis! { genesis_config_presets::preset_names() } } - - impl pallet_revive::ReviveApi for Runtime - { - fn balance(address: H160) -> U256 { - Revive::evm_balance(&address) - } - - fn block_gas_limit() -> U256 { - Revive::evm_block_gas_limit() - } - - fn gas_price() -> U256 { - Revive::evm_gas_price() - } - - fn nonce(address: H160) -> Nonce { - let account = ::AddressMapper::to_account_id(&address); - System::account_nonce(account) - } - - fn eth_transact(tx: pallet_revive::evm::GenericTransaction) -> Result, pallet_revive::EthTransactError> - { - let blockweights: BlockWeights = ::BlockWeights::get(); - let tx_fee = |pallet_call, mut dispatch_info: DispatchInfo| { - let call = RuntimeCall::Revive(pallet_call); - dispatch_info.extension_weight = EthExtraImpl::get_eth_extension(0, 0u32.into()).weight(&call); - let uxt: UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic::new_bare(call).into(); - - pallet_transaction_payment::Pallet::::compute_fee( - uxt.encoded_size() as u32, - &dispatch_info, - 0u32.into(), - ) - }; - - Revive::bare_eth_transact(tx, blockweights.max_block, tx_fee) - } - - fn call( - origin: AccountId, - dest: H160, - value: Balance, - gas_limit: Option, - storage_deposit_limit: Option, - input_data: Vec, - ) -> pallet_revive::ContractResult { - let blockweights= ::BlockWeights::get(); - Revive::bare_call( - RuntimeOrigin::signed(origin), - dest, - value, - gas_limit.unwrap_or(blockweights.max_block), - pallet_revive::DepositLimit::Balance(storage_deposit_limit.unwrap_or(u128::MAX)), - input_data, - ) - } - - fn instantiate( - origin: AccountId, - value: Balance, - gas_limit: Option, - storage_deposit_limit: Option, - code: pallet_revive::Code, - data: Vec, - salt: Option<[u8; 32]>, - ) -> pallet_revive::ContractResult - { - let blockweights= ::BlockWeights::get(); - Revive::bare_instantiate( - RuntimeOrigin::signed(origin), - value, - gas_limit.unwrap_or(blockweights.max_block), - pallet_revive::DepositLimit::Balance(storage_deposit_limit.unwrap_or(u128::MAX)), - code, - data, - salt, - NonceAlreadyIncremented::No, - ) - } - - fn upload_code( - origin: AccountId, - code: Vec, - storage_deposit_limit: Option, - ) -> pallet_revive::CodeUploadResult - { - Revive::bare_upload_code( - RuntimeOrigin::signed(origin), - code, - storage_deposit_limit.unwrap_or(u128::MAX), - ) - } - - fn get_storage( - address: H160, - key: [u8; 32], - ) -> pallet_revive::GetStorageResult { - Revive::get_storage( - address, - key - ) - } - - fn get_storage_var_key( - address: H160, - key: Vec, - ) -> pallet_revive::GetStorageResult { - Revive::get_storage_var_key( - address, - key - ) - } - - fn trace_block( - block: Block, - tracer_type: pallet_revive::evm::TracerType, - ) -> Vec<(u32, pallet_revive::evm::Trace)> { - use pallet_revive::tracing::trace; - let mut tracer = Revive::evm_tracer(tracer_type); - let mut traces = vec![]; - let (header, extrinsics) = block.deconstruct(); - Executive::initialize_block(&header); - for (index, ext) in extrinsics.into_iter().enumerate() { - trace(tracer.as_tracing(), || { - let _ = Executive::apply_extrinsic(ext); - }); - - if let Some(tx_trace) = tracer.collect_trace() { - traces.push((index as u32, tx_trace)); - } - } - - traces - } - - fn trace_tx( - block: Block, - tx_index: u32, - tracer_type: pallet_revive::evm::TracerType, - ) -> Option { - use pallet_revive::tracing::trace; - let mut tracer = Revive::evm_tracer(tracer_type); - let (header, extrinsics) = block.deconstruct(); - - Executive::initialize_block(&header); - for (index, ext) in extrinsics.into_iter().enumerate() { - if index as u32 == tx_index { - trace(tracer.as_tracing(), || { - let _ = Executive::apply_extrinsic(ext); - }); - break; - } else { - let _ = Executive::apply_extrinsic(ext); - } - } - - tracer.collect_trace() - } - - fn trace_call( - tx: pallet_revive::evm::GenericTransaction, - tracer_type: pallet_revive::evm::TracerType, - ) - -> Result - { - use pallet_revive::tracing::trace; - let mut tracer = Revive::evm_tracer(tracer_type); - let result = trace(tracer.as_tracing(), || Self::eth_transact(tx)); - - if let Some(trace) = tracer.collect_trace() { - Ok(trace) - } else if let Err(err) = result { - Err(err) - } else { - Ok(tracer.empty_trace()) - } - } - } -} +); cumulus_pallet_parachain_system::register_validate_block! { Runtime = Runtime, diff --git a/prdoc/pr_8652.prdoc b/prdoc/pr_8652.prdoc new file mode 100644 index 0000000000000..fdc8256140dcd --- /dev/null +++ b/prdoc/pr_8652.prdoc @@ -0,0 +1,10 @@ +title: '[pallet-revive] impl_revive_api macro' +doc: +- audience: Runtime Dev + description: Move pallet-revive runtime api implementation in a macro, so that we + don't repeat the code for every runtime. +crates: +- name: asset-hub-westend-runtime + bump: patch +- name: pallet-revive + bump: minor diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index e3a400b257349..b379f6f4a8855 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -40,7 +40,7 @@ use frame_election_provider_support::{ }; use frame_support::{ derive_impl, - dispatch::{DispatchClass, DispatchInfo}, + dispatch::DispatchClass, dynamic_params::{dynamic_pallet_params, dynamic_params}, genesis_builder_helper::{build_state, get_preset}, instances::{Instance1, Instance2}, @@ -85,10 +85,8 @@ use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use pallet_nfts::PalletFeatures; use pallet_nis::WithMaximumOf; use pallet_nomination_pools::PoolId; -use pallet_revive::{evm::runtime::EthExtra, AddressMapper, NonceAlreadyIncremented}; +use pallet_revive::evm::runtime::EthExtra; use pallet_session::historical as pallet_session_historical; -use sp_core::U256; -use sp_runtime::traits::TransactionExtension; // Can't use `FungibleAdapter` here until Treasury pallet migrates to fungibles // use pallet_broker::TaskId; @@ -103,7 +101,7 @@ use sp_consensus_beefy::{ mmr::MmrLeafVersion, }; use sp_consensus_grandpa::AuthorityId as GrandpaId; -use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H160}; +use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_inherents::{CheckInherentsResult, InherentData}; use sp_runtime::{ curve::PiecewiseLinear, @@ -3053,7 +3051,11 @@ mod benches { ); } -impl_runtime_apis! { +pallet_revive::impl_runtime_apis_plus_revive!( + Runtime, + Executive, + EthExtraImpl, + impl sp_api::Core for Runtime { fn version() -> RuntimeVersion { VERSION @@ -3370,182 +3372,6 @@ impl_runtime_apis! { } } - impl pallet_revive::ReviveApi for Runtime - { - fn balance(address: H160) -> U256 { - Revive::evm_balance(&address) - } - - fn block_gas_limit() -> U256 { - Revive::evm_block_gas_limit() - } - - fn gas_price() -> U256 { - Revive::evm_gas_price() - } - - fn nonce(address: H160) -> Nonce { - let account = ::AddressMapper::to_account_id(&address); - System::account_nonce(account) - } - - fn eth_transact(tx: pallet_revive::evm::GenericTransaction) -> Result, pallet_revive::EthTransactError> - { - let blockweights: BlockWeights = ::BlockWeights::get(); - let tx_fee = |pallet_call, mut dispatch_info: DispatchInfo| { - let call = RuntimeCall::Revive(pallet_call); - dispatch_info.extension_weight = EthExtraImpl::get_eth_extension(0, 0u32.into()).weight(&call); - let uxt: UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic::new_bare(call).into(); - - pallet_transaction_payment::Pallet::::compute_fee( - uxt.encoded_size() as u32, - &dispatch_info, - 0u32.into(), - ) - }; - - Revive::bare_eth_transact(tx, blockweights.max_block, tx_fee) - } - - fn call( - origin: AccountId, - dest: H160, - value: Balance, - gas_limit: Option, - storage_deposit_limit: Option, - input_data: Vec, - ) -> pallet_revive::ContractResult { - Revive::bare_call( - RuntimeOrigin::signed(origin), - dest, - value, - gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block), - pallet_revive::DepositLimit::Balance(storage_deposit_limit.unwrap_or(u128::MAX)), - input_data, - ) - } - - fn instantiate( - origin: AccountId, - value: Balance, - gas_limit: Option, - storage_deposit_limit: Option, - code: pallet_revive::Code, - data: Vec, - salt: Option<[u8; 32]>, - ) -> pallet_revive::ContractResult - { - Revive::bare_instantiate( - RuntimeOrigin::signed(origin), - value, - gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block), - pallet_revive::DepositLimit::Balance(storage_deposit_limit.unwrap_or(u128::MAX)), - code, - data, - salt, - NonceAlreadyIncremented::No, - ) - } - - fn upload_code( - origin: AccountId, - code: Vec, - storage_deposit_limit: Option, - ) -> pallet_revive::CodeUploadResult - { - Revive::bare_upload_code( - RuntimeOrigin::signed(origin), - code, - storage_deposit_limit.unwrap_or(u128::MAX), - ) - } - - fn get_storage_var_key( - address: H160, - key: Vec, - ) -> pallet_revive::GetStorageResult { - Revive::get_storage_var_key( - address, - key - ) - } - - fn get_storage( - address: H160, - key: [u8; 32], - ) -> pallet_revive::GetStorageResult { - Revive::get_storage( - address, - key - ) - } - - fn trace_block( - block: Block, - tracer_type: pallet_revive::evm::TracerType, - ) -> Vec<(u32, pallet_revive::evm::Trace)> { - use pallet_revive::tracing::trace; - let mut tracer = Revive::evm_tracer(tracer_type); - let mut traces = vec![]; - let (header, extrinsics) = block.deconstruct(); - Executive::initialize_block(&header); - for (index, ext) in extrinsics.into_iter().enumerate() { - trace(tracer.as_tracing(), || { - let _ = Executive::apply_extrinsic(ext); - }); - - if let Some(tx_trace) = tracer.collect_trace() { - traces.push((index as u32, tx_trace)); - } - } - - traces - } - - fn trace_tx( - block: Block, - tx_index: u32, - tracer_type: pallet_revive::evm::TracerType, - ) -> Option { - use pallet_revive::tracing::trace; - let mut tracer = Revive::evm_tracer(tracer_type); - let (header, extrinsics) = block.deconstruct(); - - Executive::initialize_block(&header); - for (index, ext) in extrinsics.into_iter().enumerate() { - if index as u32 == tx_index { - trace(tracer.as_tracing(), || { - let _ = Executive::apply_extrinsic(ext); - }); - break; - } else { - let _ = Executive::apply_extrinsic(ext); - } - } - - tracer.collect_trace() - } - - fn trace_call( - tx: pallet_revive::evm::GenericTransaction, - tracer_type: pallet_revive::evm::TracerType, - ) - -> Result - { - use pallet_revive::tracing::trace; - let mut tracer = Revive::evm_tracer(tracer_type); - let result = trace(tracer.as_tracing(), || Self::eth_transact(tx)); - - if let Some(trace) = tracer.collect_trace() { - Ok(trace) - } else if let Err(err) = result { - Err(err) - } else { - Ok(tracer.empty_trace()) - } - } - } - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi< Block, Balance, @@ -3906,7 +3732,8 @@ impl_runtime_apis! { genesis_config_presets::preset_names() } } -} + +); #[cfg(test)] mod tests { diff --git a/substrate/frame/revive/src/lib.rs b/substrate/frame/revive/src/lib.rs index dbfbaf76094ea..e944000975d1e 100644 --- a/substrate/frame/revive/src/lib.rs +++ b/substrate/frame/revive/src/lib.rs @@ -57,7 +57,7 @@ use codec::{Codec, Decode, Encode}; use environmental::*; use frame_support::{ dispatch::{ - DispatchErrorWithPostInfo, DispatchInfo, DispatchResultWithPostInfo, GetDispatchInfo, Pays, + DispatchErrorWithPostInfo, DispatchResultWithPostInfo, GetDispatchInfo, Pays, PostDispatchInfo, RawOrigin, }, ensure, @@ -67,7 +67,7 @@ use frame_support::{ tokens::{Fortitude::Polite, Preservation::Preserve}, ConstU32, ConstU64, Contains, EnsureOrigin, Get, IsType, OriginTrait, Time, }, - weights::{Weight, WeightMeter}, + weights::WeightMeter, BoundedVec, RuntimeDebugNoBound, }; use frame_system::{ @@ -76,7 +76,6 @@ use frame_system::{ Pallet as System, }; use scale_info::TypeInfo; -use sp_core::{H160, H256, U256}; use sp_runtime::{ traits::{BadOrigin, Bounded, Convert, Dispatchable, Saturating, Zero}, AccountId32, DispatchError, @@ -87,7 +86,13 @@ pub use crate::{ exec::{MomentOf, Origin}, pallet::*, }; +pub use codec; +pub use frame_support::{self, dispatch::DispatchInfo, weights::Weight}; +pub use frame_system::{self, limits::BlockWeights}; +pub use pallet_transaction_payment; pub use primitives::*; +pub use sp_core::{H160, H256, U256}; +pub use sp_runtime; pub use weights::WeightInfo; #[cfg(doc)] @@ -1636,3 +1641,214 @@ sp_api::decl_runtime_apis! { } } + +/// This macro wraps substrate's `impl_runtime_apis!` and implements `pallet_revive` runtime APIs. +/// +/// # Parameters +/// - `$Runtime`: The runtime type to implement the APIs for. +/// - `$Executive`: The Executive type of the runtime. +/// - `$EthExtra`: Type for additional Ethereum runtime extension. +/// - `$($rest:tt)*`: Remaining input to be forwarded to the underlying `impl_runtime_apis!`. +#[macro_export] +macro_rules! impl_runtime_apis_plus_revive { + ($Runtime: ty, $Executive: ty, $EthExtra: ty, $($rest:tt)*) => { + + impl_runtime_apis! { + $($rest)* + + impl pallet_revive::ReviveApi for $Runtime { + fn balance(address: $crate::H160) -> $crate::U256 { + $crate::Pallet::::evm_balance(&address) + } + + fn block_gas_limit() -> $crate::U256 { + $crate::Pallet::::evm_block_gas_limit() + } + + fn gas_price() -> $crate::U256 { + $crate::Pallet::::evm_gas_price() + } + + fn nonce(address: $crate::H160) -> Nonce { + use $crate::AddressMapper; + let account = ::AddressMapper::to_account_id(&address); + $crate::frame_system::Pallet::::account_nonce(account) + } + + fn eth_transact( + tx: $crate::evm::GenericTransaction, + ) -> Result<$crate::EthTransactInfo, $crate::EthTransactError> { + use $crate::{ + codec::Encode, evm::runtime::EthExtra, frame_support::traits::Get, + sp_runtime::traits::TransactionExtension, + sp_runtime::traits::Block as BlockT + }; + + let tx_fee = |pallet_call, mut dispatch_info: $crate::DispatchInfo| { + let call = + ::RuntimeCall::from(pallet_call); + dispatch_info.extension_weight = + <$EthExtra>::get_eth_extension(0, 0u32.into()).weight(&call); + + let uxt: ::Extrinsic = + $crate::sp_runtime::generic::UncheckedExtrinsic::new_bare(call).into(); + + $crate::pallet_transaction_payment::Pallet::::compute_fee( + uxt.encoded_size() as u32, + &dispatch_info, + 0u32.into(), + ) + }; + + let blockweights: $crate::BlockWeights = + ::BlockWeights::get(); + $crate::Pallet::::bare_eth_transact(tx, blockweights.max_block, tx_fee) + } + + fn call( + origin: AccountId, + dest: $crate::H160, + value: Balance, + gas_limit: Option<$crate::Weight>, + storage_deposit_limit: Option, + input_data: Vec, + ) -> $crate::ContractResult<$crate::ExecReturnValue, Balance> { + use $crate::frame_support::traits::Get; + let blockweights: $crate::BlockWeights = + ::BlockWeights::get(); + + let origin = + ::RuntimeOrigin::signed(origin); + $crate::Pallet::::bare_call( + origin, + dest, + value, + gas_limit.unwrap_or(blockweights.max_block), + $crate::DepositLimit::Balance(storage_deposit_limit.unwrap_or(u128::MAX)), + input_data, + ) + } + + fn instantiate( + origin: AccountId, + value: Balance, + gas_limit: Option<$crate::Weight>, + storage_deposit_limit: Option, + code: $crate::Code, + data: Vec, + salt: Option<[u8; 32]>, + ) -> $crate::ContractResult<$crate::InstantiateReturnValue, Balance> { + use $crate::frame_support::traits::Get; + let blockweights: $crate::BlockWeights = + ::BlockWeights::get(); + + let origin = + ::RuntimeOrigin::signed(origin); + $crate::Pallet::::bare_instantiate( + origin, + value, + gas_limit.unwrap_or(blockweights.max_block), + $crate::DepositLimit::Balance(storage_deposit_limit.unwrap_or(u128::MAX)), + code, + data, + salt, + $crate::NonceAlreadyIncremented::No, + ) + } + + fn upload_code( + origin: AccountId, + code: Vec, + storage_deposit_limit: Option, + ) -> $crate::CodeUploadResult { + let origin = + ::RuntimeOrigin::signed(origin); + $crate::Pallet::::bare_upload_code( + origin, + code, + storage_deposit_limit.unwrap_or(u128::MAX), + ) + } + + fn get_storage_var_key( + address: $crate::H160, + key: Vec, + ) -> $crate::GetStorageResult { + $crate::Pallet::::get_storage_var_key(address, key) + } + + fn get_storage(address: $crate::H160, key: [u8; 32]) -> $crate::GetStorageResult { + $crate::Pallet::::get_storage(address, key) + } + + fn trace_block( + block: Block, + tracer_type: $crate::evm::TracerType, + ) -> Vec<(u32, $crate::evm::Trace)> { + use $crate::{sp_runtime::traits::Block, tracing::trace}; + let mut tracer = $crate::Pallet::::evm_tracer(tracer_type); + let mut traces = vec![]; + let (header, extrinsics) = block.deconstruct(); + <$Executive>::initialize_block(&header); + for (index, ext) in extrinsics.into_iter().enumerate() { + let t = tracer.as_tracing(); + trace(t, || { + let _ = <$Executive>::apply_extrinsic(ext); + }); + + if let Some(tx_trace) = tracer.collect_trace() { + traces.push((index as u32, tx_trace)); + } + } + + traces + } + + fn trace_tx( + block: Block, + tx_index: u32, + tracer_type: $crate::evm::TracerType, + ) -> Option<$crate::evm::Trace> { + use $crate::{sp_runtime::traits::Block, tracing::trace}; + + let mut tracer = $crate::Pallet::::evm_tracer(tracer_type); + let (header, extrinsics) = block.deconstruct(); + + <$Executive>::initialize_block(&header); + for (index, ext) in extrinsics.into_iter().enumerate() { + if index as u32 == tx_index { + let t = tracer.as_tracing(); + trace(t, || { + let _ = <$Executive>::apply_extrinsic(ext); + }); + break; + } else { + let _ = <$Executive>::apply_extrinsic(ext); + } + } + + tracer.collect_trace() + } + + fn trace_call( + tx: $crate::evm::GenericTransaction, + tracer_type: $crate::evm::TracerType, + ) -> Result<$crate::evm::Trace, $crate::EthTransactError> { + use $crate::tracing::trace; + let mut tracer = $crate::Pallet::::evm_tracer(tracer_type); + let t = tracer.as_tracing(); + + let result = trace(t, || Self::eth_transact(tx)); + + if let Some(trace) = tracer.collect_trace() { + Ok(trace) + } else if let Err(err) = result { + Err(err) + } else { + Ok(tracer.empty_trace()) + } + } + } + } + }; +}