From a661a11ca22236cf44190ec9e1a1732a8765b891 Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Mon, 10 Jun 2024 16:00:59 +0200 Subject: [PATCH 1/4] evm tracing tests --- .github/workflows/frontier-rpc-tests.yml | 4 +- Cargo.lock | 4 + bin/collator/src/evm_tracing_types.rs | 14 ++- bin/collator/src/local/service.rs | 32 ++++++- tests/integration/Cargo.toml | 16 ++++ tests/integration/src/evm_tracing.rs | 117 +++++++++++++++++++++++ tests/integration/src/lib.rs | 3 + 7 files changed, 182 insertions(+), 8 deletions(-) create mode 100644 tests/integration/src/evm_tracing.rs diff --git a/.github/workflows/frontier-rpc-tests.yml b/.github/workflows/frontier-rpc-tests.yml index ec83cafc78..7e75d73510 100644 --- a/.github/workflows/frontier-rpc-tests.yml +++ b/.github/workflows/frontier-rpc-tests.yml @@ -25,10 +25,10 @@ jobs: run: rustup target list --installed - name: Build astar-collator - run: cargo build --release --locked --features manual-seal --bin astar-collator + run: cargo build --release --locked --features manual-seal,evm-tracing --bin astar-collator - name: Clone frontier tests - run: git clone https://github.com/AstarNetwork/frontier-tests.git --depth 1 + run: git clone -b evm-tracing-test https://github.com/AstarNetwork/frontier-tests.git --depth 1 - name: Setup node uses: actions/setup-node@v4 diff --git a/Cargo.lock b/Cargo.lock index dbbc622df2..abe3a9f9c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5717,11 +5717,14 @@ dependencies = [ "astar-runtime", "astar-test-utils", "env_logger 0.10.0", + "ethereum", "fp-evm", + "fp-rpc", "frame-support", "frame-system", "hex", "libsecp256k1", + "moonbeam-rpc-primitives-debug", "orml-oracle", "pallet-assets", "pallet-balances", @@ -5729,6 +5732,7 @@ dependencies = [ "pallet-contracts", "pallet-contracts-primitives", "pallet-dapp-staking-v3", + "pallet-ethereum", "pallet-ethereum-checked", "pallet-evm", "pallet-evm-precompile-assets-erc20", diff --git a/bin/collator/src/evm_tracing_types.rs b/bin/collator/src/evm_tracing_types.rs index 77f567d502..8f1b6d7c77 100644 --- a/bin/collator/src/evm_tracing_types.rs +++ b/bin/collator/src/evm_tracing_types.rs @@ -76,12 +76,16 @@ pub struct EvmTracingConfig { #[derive(Debug, Parser)] pub struct EthApiOptions { /// Enable EVM tracing module on a non-authority node. - #[clap( - long, - conflicts_with = "collator", - conflicts_with = "validator", - value_delimiter = ',' + #[cfg_attr( + not(feature = "manual-seal"), + clap( + long, + conflicts_with = "collator", + conflicts_with = "validator", + value_delimiter = ',' + ) )] + #[cfg_attr(feature = "manual-seal", clap(long))] pub ethapi: Vec, /// Number of concurrent tracing tasks. Meant to be shared by both "debug" and "trace" modules. diff --git a/bin/collator/src/local/service.rs b/bin/collator/src/local/service.rs index 32de813ccd..59e98cd09c 100644 --- a/bin/collator/src/local/service.rs +++ b/bin/collator/src/local/service.rs @@ -347,6 +347,9 @@ pub fn start_node( prometheus_registry.clone(), )); + #[cfg(feature = "manual-seal")] + let (command_sink, commands_stream) = futures::channel::mpsc::channel(1024); + let rpc_extensions_builder = { let client = client.clone(); let network = network.clone(); @@ -376,7 +379,7 @@ pub fn start_node( overrides: overrides.clone(), enable_evm_rpc: true, // enable EVM RPC for dev node by default #[cfg(feature = "manual-seal")] - command_sink: None, + command_sink: Some(command_sink.clone()), }; crate::rpc::create_full( @@ -415,6 +418,33 @@ pub fn start_node( let slot_duration = sc_consensus_aura::slot_duration(&*client)?; + #[cfg(feature = "manual-seal")] + let aura = sc_consensus_manual_seal::run_manual_seal( + sc_consensus_manual_seal::ManualSealParams { + block_import, + env: proposer_factory, + client: client.clone(), + pool: transaction_pool.clone(), + commands_stream, + select_chain, + consensus_data_provider: Some(Box::new( + sc_consensus_manual_seal::consensus::aura::AuraConsensusDataProvider::new( + client.clone(), + ), + )), + create_inherent_data_providers: move |_, ()| async move { + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + let slot = + sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( + *timestamp, + slot_duration.clone(), + ); + Ok((slot, timestamp)) + }, + }, + ); + + #[cfg(not(feature = "manual-seal"))] let aura = sc_consensus_aura::start_aura::( StartAuraParams { slot_duration, diff --git a/tests/integration/Cargo.toml b/tests/integration/Cargo.toml index 40029481b1..ba2ded6a1e 100644 --- a/tests/integration/Cargo.toml +++ b/tests/integration/Cargo.toml @@ -52,6 +52,12 @@ astar-test-utils = { workspace = true } shibuya-runtime = { workspace = true, optional = true } shiden-runtime = { workspace = true, optional = true } +# evm-tracing tests +ethereum = { workspace = true, features = ["with-codec"], optional = true } +pallet-ethereum = { workspace = true, optional = true } +moonbeam-rpc-primitives-debug = { workspace = true, optional = true } +fp-rpc = { workspace = true, optional = true } + [features] default = ["std"] std = [ @@ -64,3 +70,13 @@ std = [ shibuya = ["shibuya-runtime"] shiden = ["shiden-runtime"] astar = ["astar-runtime"] + +evm-tracing = [ + "shibuya-runtime?/evm-tracing", + "shiden-runtime?/evm-tracing", + "astar-runtime?/evm-tracing", + "ethereum", + "pallet-ethereum", + "moonbeam-rpc-primitives-debug", + "fp-rpc", +] diff --git a/tests/integration/src/evm_tracing.rs b/tests/integration/src/evm_tracing.rs new file mode 100644 index 0000000000..a6e1f59f44 --- /dev/null +++ b/tests/integration/src/evm_tracing.rs @@ -0,0 +1,117 @@ +// This file is part of Astar. + +// Copyright (C) Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +#[cfg(test)] +#[cfg(feature = "evm-tracing")] +mod tests { + use crate::setup::*; + + use astar_primitives::Header; + use fp_rpc::ConvertTransaction; + use moonbeam_rpc_primitives_debug::runtime_decl_for_debug_runtime_api::DebugRuntimeApi; + + // A valid signed Alice transfer. + pub const VALID_ETH_TX: &str = + "02f869820501808085e8d4a51000825208943cd0a705a2dc65e5b1e1205896baa2be8a07c6e00180c\ + 001a061087911e877a5802142a89a40d231d50913db399eb50839bb2d04e612b22ec8a01aa313efdf2\ + 793bea76da6813bda611444af16a6207a8cfef2d9c8aa8f8012f7"; + + // An invalid signed Alice transfer with a gas limit artifically set to 0. + pub const INVALID_ETH_TX: &str = + "f8628085174876e800809412cb274aad8251c875c0bf6872b67d9983e53fdd01801ba011110796057\ + 0e2d49fcc2afbc582e1abd3eeb027242b92abcebcec7cdefab63ea001732f6fac84acdd5b096554230\ + 75003e7f07430652c3d6722e18f50b3d34e29"; + + pub struct TransactionConverter; + + impl ConvertTransaction for TransactionConverter { + fn convert_transaction( + &self, + transaction: pallet_ethereum::Transaction, + ) -> UncheckedExtrinsic { + UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ) + } + } + + pub fn unchecked_eth_tx(raw_hex_tx: &str) -> UncheckedExtrinsic { + let converter = TransactionConverter; + converter.convert_transaction(ethereum_transaction(raw_hex_tx)) + } + + pub fn ethereum_transaction(raw_hex_tx: &str) -> pallet_ethereum::Transaction { + let bytes = hex::decode(raw_hex_tx).expect("Transaction bytes."); + let transaction = ethereum::EnvelopedDecodable::decode(&bytes[..]); + assert!(transaction.is_ok()); + transaction.unwrap() + } + + #[test] + fn debug_runtime_api_trace_transaction() { + new_test_ext().execute_with(|| { + let non_eth_uxt = UncheckedExtrinsic::new_unsigned( + pallet_balances::Call::::transfer_allow_death { + dest: MultiAddress::Id(AccountId::from(BOB)), + value: 1 * UNIT, + } + .into(), + ); + let transaction = ethereum_transaction(VALID_ETH_TX); + let eth_uxt = unchecked_eth_tx(VALID_ETH_TX); + let block = Header { + digest: Default::default(), + extrinsics_root: Default::default(), + number: 1, + parent_hash: Default::default(), + state_root: Default::default(), + }; + assert_ok!(Runtime::trace_transaction( + vec![non_eth_uxt.clone(), eth_uxt, non_eth_uxt.clone()], + &transaction, + )); + }); + } + + #[test] + fn debug_runtime_api_trace_block() { + new_test_ext().execute_with(|| { + let non_eth_uxt = UncheckedExtrinsic::new_unsigned( + pallet_balances::Call::::transfer_allow_death { + dest: MultiAddress::Id(AccountId::from(BOB)), + value: 1 * UNIT, + } + .into(), + ); + let eth_uxt = unchecked_eth_tx(VALID_ETH_TX); + let eth_tx = ethereum_transaction(VALID_ETH_TX); + let eth_extrinsic_hash = eth_tx.hash(); + let block = Header { + digest: Default::default(), + extrinsics_root: Default::default(), + number: 1, + parent_hash: Default::default(), + state_root: Default::default(), + }; + assert_ok!(Runtime::trace_block( + vec![non_eth_uxt.clone(), eth_uxt.clone(), non_eth_uxt, eth_uxt], + vec![eth_extrinsic_hash, eth_extrinsic_hash], + )); + }); + } +} diff --git a/tests/integration/src/lib.rs b/tests/integration/src/lib.rs index 0232fa665f..44072fa405 100644 --- a/tests/integration/src/lib.rs +++ b/tests/integration/src/lib.rs @@ -46,3 +46,6 @@ mod assets_chain_extensions; #[cfg(any(feature = "shibuya", feature = "shiden", feature = "astar"))] mod oracle; + +#[cfg(any(feature = "shibuya", feature = "shiden", feature = "astar"))] +mod evm_tracing; From bdaaa378beb211ed61384274190e3b18aa5fe87b Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Mon, 10 Jun 2024 17:49:44 +0200 Subject: [PATCH 2/4] fix --- .github/workflows/frontier-rpc-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/frontier-rpc-tests.yml b/.github/workflows/frontier-rpc-tests.yml index 7e75d73510..78062d3963 100644 --- a/.github/workflows/frontier-rpc-tests.yml +++ b/.github/workflows/frontier-rpc-tests.yml @@ -28,7 +28,7 @@ jobs: run: cargo build --release --locked --features manual-seal,evm-tracing --bin astar-collator - name: Clone frontier tests - run: git clone -b evm-tracing-test https://github.com/AstarNetwork/frontier-tests.git --depth 1 + run: git clone -b feat/evm-tracing-test https://github.com/AstarNetwork/frontier-tests.git --depth 1 - name: Setup node uses: actions/setup-node@v4 From b8e560cb6360b0697b866218e036d49236630b53 Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Mon, 10 Jun 2024 19:21:06 +0200 Subject: [PATCH 3/4] update gha --- .github/workflows/frontier-rpc-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/frontier-rpc-tests.yml b/.github/workflows/frontier-rpc-tests.yml index 78062d3963..231ad7e93d 100644 --- a/.github/workflows/frontier-rpc-tests.yml +++ b/.github/workflows/frontier-rpc-tests.yml @@ -28,7 +28,7 @@ jobs: run: cargo build --release --locked --features manual-seal,evm-tracing --bin astar-collator - name: Clone frontier tests - run: git clone -b feat/evm-tracing-test https://github.com/AstarNetwork/frontier-tests.git --depth 1 + run: git clone https://github.com/AstarNetwork/frontier-tests.git --depth 1 - name: Setup node uses: actions/setup-node@v4 From 52312e7d366b2ac22585bcbd56cf03a2584428f3 Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Mon, 10 Jun 2024 19:26:18 +0200 Subject: [PATCH 4/4] fmt cargo --- tests/integration/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/Cargo.toml b/tests/integration/Cargo.toml index ba2ded6a1e..14c2c008e2 100644 --- a/tests/integration/Cargo.toml +++ b/tests/integration/Cargo.toml @@ -54,9 +54,9 @@ shiden-runtime = { workspace = true, optional = true } # evm-tracing tests ethereum = { workspace = true, features = ["with-codec"], optional = true } -pallet-ethereum = { workspace = true, optional = true } -moonbeam-rpc-primitives-debug = { workspace = true, optional = true } fp-rpc = { workspace = true, optional = true } +moonbeam-rpc-primitives-debug = { workspace = true, optional = true } +pallet-ethereum = { workspace = true, optional = true } [features] default = ["std"]