diff --git a/Cargo.lock b/Cargo.lock index a22cbb81d..53b05f1a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2802,6 +2802,7 @@ dependencies = [ "frame-support", "frame-system", "libsecp256k1", + "moonbeam-evm-tracer", "pallet-balances", "pallet-ethereum", "pallet-evm", @@ -2813,6 +2814,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std 14.0.0 (git+https://github.com/darwinia-network/polkadot-sdk?branch=release-polkadot-v1.7.2)", + "xcm-primitives", ] [[package]] diff --git a/pallet/ethtx-forwarder/Cargo.toml b/pallet/ethtx-forwarder/Cargo.toml index 3fc1bd27e..24e1a054a 100644 --- a/pallet/ethtx-forwarder/Cargo.toml +++ b/pallet/ethtx-forwarder/Cargo.toml @@ -17,6 +17,10 @@ fp-ethereum = { workspace = true } fp-evm = { workspace = true } pallet-evm = { workspace = true } +# moonbeam optional +moonbeam-evm-tracer = { workspace = true, optional = true } +xcm-primitives = { workspace = true, optional = true } + # polkadot-sdk frame-support = { workspace = true } frame-system = { workspace = true } @@ -25,6 +29,7 @@ sp-runtime = { workspace = true } sp-std = { workspace = true } [dev-dependencies] +# crates.io array-bytes = { workspace = true } libsecp256k1 = { workspace = true, features = ["std"] } sha3 = { workspace = true } @@ -52,6 +57,10 @@ std = [ "fp-evm/std", "pallet-evm/std", + # moonbeam optional + "moonbeam-evm-tracer?/std", + "xcm-primitives?/std", + # polkadot-sdk "frame-support/std", "frame-system/std", @@ -61,15 +70,29 @@ std = [ ] runtime-benchmarks = [ + # frontier + "pallet-evm/runtime-benchmarks", + + # moonbeam + "xcm-primitives?/runtime-benchmarks", + + # polkadot-sdk "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", - "pallet-evm/runtime-benchmarks", ] try-runtime = [ + # frontier + "pallet-evm/try-runtime", + # polkadot-sdk "frame-support/try-runtime", "frame-system/try-runtime", - "pallet-evm/try-runtime", "sp-runtime/try-runtime", ] + +evm-tracing = [ + # moonbeam + "moonbeam-evm-tracer", + "xcm-primitives", +] diff --git a/pallet/ethtx-forwarder/src/lib.rs b/pallet/ethtx-forwarder/src/lib.rs index 958c13597..4c4b27980 100644 --- a/pallet/ethtx-forwarder/src/lib.rs +++ b/pallet/ethtx-forwarder/src/lib.rs @@ -36,6 +36,8 @@ use fp_ethereum::{TransactionData, ValidatedTransaction}; use fp_evm::{CheckEvmTransaction, CheckEvmTransactionConfig, TransactionValidationError}; use pallet_evm::{FeeCalculator, GasWeightMapping}; // polkadot-sdk +#[cfg(feature = "evm-tracing")] +use frame_support::dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo}; use frame_support::{traits::EnsureOrigin, PalletError}; use sp_core::{Get, H160, H256, U256}; use sp_runtime::{traits::BadOrigin, DispatchError, RuntimeDebug}; @@ -86,9 +88,6 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - #[pallet::pallet] - pub struct Pallet(_); - #[pallet::origin] pub type Origin = ForwardEthOrigin; @@ -106,6 +105,8 @@ pub mod pallet { ValidationError(TxErrorWrapper), } + #[pallet::pallet] + pub struct Pallet(_); #[pallet::call] impl Pallet where @@ -121,13 +122,16 @@ pub mod pallet { request: ForwardRequest, ) -> DispatchResultWithPostInfo { let source = ensure_forward_transact(origin)?; - let transaction = Self::validated_transaction(source, request)?; - T::ValidatedTransaction::apply(source, transaction).map(|(post_info, _)| post_info) + + #[cfg(feature = "evm-tracing")] + return Self::trace_tx(source, transaction); + #[cfg(not(feature = "evm-tracing"))] + return T::ValidatedTransaction::apply(source, transaction) + .map(|(post_info, _)| post_info); } } } - impl Pallet { /// Calculates the fee for submitting such an EVM transaction. /// @@ -254,6 +258,57 @@ impl Pallet { Ok(transaction) } + + #[cfg(feature = "evm-tracing")] + fn trace_tx( + source: H160, + transaction: Transaction, + ) -> Result { + // moonbeam + use moonbeam_evm_tracer::tracer::EvmTracer; + // polkadot-sdk + use frame_support::storage::unhashed; + use xcm_primitives::{EthereumXcmTracingStatus, ETHEREUM_XCM_TRACING_STORAGE_KEY}; + + match unhashed::get(ETHEREUM_XCM_TRACING_STORAGE_KEY) { + Some(EthereumXcmTracingStatus::Block) => { + EvmTracer::emit_new(); + + let mut res = Ok(PostDispatchInfo::default()); + + EvmTracer::new().trace(|| { + res = T::ValidatedTransaction::apply(source, transaction) + .map(|(post_info, _)| post_info); + }); + + res + }, + Some(EthereumXcmTracingStatus::Transaction(traced_transaction_hash)) => + if transaction.hash() == traced_transaction_hash { + let mut res = Ok(PostDispatchInfo::default()); + + EvmTracer::new().trace(|| { + res = T::ValidatedTransaction::apply(source, transaction) + .map(|(post_info, _)| post_info); + }); + unhashed::put::( + ETHEREUM_XCM_TRACING_STORAGE_KEY, + &EthereumXcmTracingStatus::TransactionExited, + ); + + res + } else { + T::ValidatedTransaction::apply(source, transaction) + .map(|(post_info, _)| post_info) + }, + Some(EthereumXcmTracingStatus::TransactionExited) => Ok(PostDispatchInfo { + actual_weight: None, + pays_fee: frame_support::pallet_prelude::Pays::No, + }), + None => + T::ValidatedTransaction::apply(source, transaction).map(|(post_info, _)| post_info), + } + } } // TODO: replace it with upstream error type @@ -271,7 +326,6 @@ pub enum TxErrorWrapper { InvalidSignature, UnknownError, } - impl From for TxErrorWrapper { fn from(validation_error: TransactionValidationError) -> Self { match validation_error { diff --git a/runtime/crab/Cargo.toml b/runtime/crab/Cargo.toml index 28c696d67..0d0ee0e90 100644 --- a/runtime/crab/Cargo.toml +++ b/runtime/crab/Cargo.toml @@ -330,6 +330,8 @@ on-chain-release-build = [ ] evm-tracing = [ + # darwinia + "darwinia-ethtx-forwarder/evm-tracing", # moonbeam optional "moonbeam-evm-tracer", ] diff --git a/runtime/darwinia/Cargo.toml b/runtime/darwinia/Cargo.toml index 1fd7b7a75..924a8498f 100644 --- a/runtime/darwinia/Cargo.toml +++ b/runtime/darwinia/Cargo.toml @@ -364,6 +364,8 @@ on-chain-release-build = [ ] evm-tracing = [ + # darwinia + "darwinia-ethtx-forwarder/evm-tracing", # moonbeam optional "moonbeam-evm-tracer", ] diff --git a/runtime/koi/Cargo.toml b/runtime/koi/Cargo.toml index 3fbc576b3..e381a300e 100644 --- a/runtime/koi/Cargo.toml +++ b/runtime/koi/Cargo.toml @@ -355,6 +355,8 @@ on-chain-release-build = [ ] evm-tracing = [ + # darwinia + "darwinia-ethtx-forwarder/evm-tracing", # moonbeam optional "moonbeam-evm-tracer", ]