Skip to content

Commit

Permalink
evm-tracing should replay on_idle (#2707)
Browse files Browse the repository at this point in the history
* evm-tracing should replay on_idle

* fix compilation

* fix rust tests

* not call on_finalize

* create helper function replay_on_idle
  • Loading branch information
librelois authored Mar 21, 2024
1 parent 16ca2bc commit b1c2205
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 3 deletions.
54 changes: 51 additions & 3 deletions runtime/common/src/apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,31 @@
#[macro_export]
macro_rules! impl_runtime_apis_plus_common {
{$($custom:tt)*} => {

#[cfg(feature = "evm-tracing")]
// Helper function to replay the "on_idle" hook for all pallets, we need this for
// evm-tracing because some ethereum-xcm transactions might be executed at on_idle.
//
// We need to make sure that we replay on_idle exactly the same way as the
// original block execution, but unfortunatly frame executive diosn't provide a function
// to replay only on_idle, so we need to copy here some code inside frame executive.
fn replay_on_idle() {
use frame_system::pallet_prelude::BlockNumberFor;

let weight = <frame_system::Pallet<Runtime>>::block_weight();
let max_weight = <
<Runtime as frame_system::Config>::BlockWeights as
frame_support::traits::Get<_>
>::get().max_block;
let remaining_weight = max_weight.saturating_sub(weight.total());
if remaining_weight.all_gt(Weight::zero()) {
let _ = <AllPalletsWithSystem as OnIdle<BlockNumberFor<Runtime>>>::on_idle(
<frame_system::Pallet<Runtime>>::block_number(),
remaining_weight,
);
}
}

impl_runtime_apis! {
$($custom)*

Expand Down Expand Up @@ -111,6 +136,7 @@ macro_rules! impl_runtime_apis_plus_common {
EthereumXcmTracingStatus
};
use frame_support::storage::unhashed;
use frame_system::pallet_prelude::BlockNumberFor;

// Tell the CallDispatcher we are tracing a specific Transaction.
unhashed::put::<EthereumXcmTracingStatus>(
Expand Down Expand Up @@ -138,9 +164,26 @@ macro_rules! impl_runtime_apis_plus_common {
return Ok(());
}
}
Err(sp_runtime::DispatchError::Other(
"Failed to find Ethereum transaction among the extrinsics.",
))

if let Some(EthereumXcmTracingStatus::Transaction(_)) = unhashed::get(
ETHEREUM_XCM_TRACING_STORAGE_KEY
) {
// If the transaction was not found, it might be
// an eth-xcm transaction that was executed at on_idle
replay_on_idle();
}

if let Some(EthereumXcmTracingStatus::TransactionExited) = unhashed::get(
ETHEREUM_XCM_TRACING_STORAGE_KEY
) {
// The transaction was found
Ok(())
} else {
// The transaction was not-found
Err(sp_runtime::DispatchError::Other(
"Failed to find Ethereum transaction among the extrinsics.",
))
}
}
#[cfg(not(feature = "evm-tracing"))]
Err(sp_runtime::DispatchError::Other(
Expand All @@ -158,6 +201,7 @@ macro_rules! impl_runtime_apis_plus_common {
#[cfg(feature = "evm-tracing")]
{
use moonbeam_evm_tracer::tracer::EvmTracer;
use frame_system::pallet_prelude::BlockNumberFor;
use xcm_primitives::EthereumXcmTracingStatus;

// Tell the CallDispatcher we are tracing a full Block.
Expand Down Expand Up @@ -187,6 +231,10 @@ macro_rules! impl_runtime_apis_plus_common {
};
}

// Replay on_idle
// Some XCM messages with eth-xcm transaction might be executed at on_idle
replay_on_idle();

Ok(())
}
#[cfg(not(feature = "evm-tracing"))]
Expand Down
1 change: 1 addition & 0 deletions runtime/moonbase/tests/evm_tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ mod tests {
let eth_uxt = unchecked_eth_tx(VALID_ETH_TX);
let eth_tx = ethereum_transaction(VALID_ETH_TX);
let eth_extrinsic_hash = eth_tx.hash();

assert!(Runtime::trace_block(
vec![non_eth_uxt.clone(), eth_uxt.clone(), non_eth_uxt, eth_uxt],
vec![eth_extrinsic_hash, eth_extrinsic_hash]
Expand Down
1 change: 1 addition & 0 deletions runtime/moonbeam/tests/evm_tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ mod tests {
let eth_uxt = unchecked_eth_tx(VALID_ETH_TX);
let eth_tx = ethereum_transaction(VALID_ETH_TX);
let eth_extrinsic_hash = eth_tx.hash();

assert!(Runtime::trace_block(
vec![non_eth_uxt.clone(), eth_uxt.clone(), non_eth_uxt, eth_uxt],
vec![eth_extrinsic_hash, eth_extrinsic_hash]
Expand Down
1 change: 1 addition & 0 deletions runtime/moonriver/tests/evm_tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ mod tests {
let eth_uxt = unchecked_eth_tx(VALID_ETH_TX);
let eth_tx = ethereum_transaction(VALID_ETH_TX);
let eth_extrinsic_hash = eth_tx.hash();

assert!(Runtime::trace_block(
vec![non_eth_uxt.clone(), eth_uxt.clone(), non_eth_uxt, eth_uxt],
vec![eth_extrinsic_hash, eth_extrinsic_hash]
Expand Down

0 comments on commit b1c2205

Please sign in to comment.