diff --git a/Cargo.lock b/Cargo.lock index 1e74b9a8ae..20e0320b67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2607,7 +2607,9 @@ dependencies = [ "domain-runtime-primitives", "domain-test-primitives", "domain-test-service", + "ethereum", "evm-domain-test-runtime", + "fp-self-contained", "frame-system", "futures", "futures-timer", @@ -2615,6 +2617,8 @@ dependencies = [ "pallet-balances", "pallet-domain-sudo", "pallet-domains", + "pallet-ethereum", + "pallet-evm", "pallet-evm-tracker", "pallet-messenger", "pallet-sudo", diff --git a/crates/sp-domains-fraud-proof/Cargo.toml b/crates/sp-domains-fraud-proof/Cargo.toml index 427e20c9e6..2f956f00e9 100644 --- a/crates/sp-domains-fraud-proof/Cargo.toml +++ b/crates/sp-domains-fraud-proof/Cargo.toml @@ -45,13 +45,13 @@ domain-block-builder = { version = "0.1.0", path = "../../domains/client/block-b domain-block-preprocessor = { version = "0.1.0", path = "../../domains/client/block-preprocessor" } domain-test-service = { version = "0.1.0", path = "../../domains/test/service" } ethereum = "0.15.0" -fp-rpc = { version = "3.0.0-dev", git = "https://github.com/autonomys/frontier", rev = "f80f9e2bad338f3bf3854b256b3c4edea23e5968", features = ['default'] } -fp-self-contained = { version = "1.0.0-dev", git = "https://github.com/autonomys/frontier", rev = "f80f9e2bad338f3bf3854b256b3c4edea23e5968", features = ['default'] } +fp-rpc = { version = "3.0.0-dev", git = "https://github.com/autonomys/frontier", rev = "f80f9e2bad338f3bf3854b256b3c4edea23e5968" } +fp-self-contained = { version = "1.0.0-dev", git = "https://github.com/autonomys/frontier", rev = "f80f9e2bad338f3bf3854b256b3c4edea23e5968" } frame-system = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "94a1a8143a89bbe9f938c1939ff68abc1519a305" } futures = "0.3.31" libsecp256k1 = { version = "0.7.1", features = ["static-context", "hmac"] } pallet-balances = { git = "https://github.com/subspace/polkadot-sdk", rev = "94a1a8143a89bbe9f938c1939ff68abc1519a305" } -pallet-ethereum = { git = "https://github.com/autonomys/frontier", rev = "f80f9e2bad338f3bf3854b256b3c4edea23e5968", features = ['default'] } +pallet-ethereum = { git = "https://github.com/autonomys/frontier", rev = "f80f9e2bad338f3bf3854b256b3c4edea23e5968" } parking_lot = "0.12.2" rand = { version = "0.8.5", features = ["min_const_gen"] } rlp = "0.5.2" diff --git a/crates/sp-domains-fraud-proof/src/tests.rs b/crates/sp-domains-fraud-proof/src/tests.rs index 28fe93af83..264667b07c 100644 --- a/crates/sp-domains-fraud-proof/src/tests.rs +++ b/crates/sp-domains-fraud-proof/src/tests.rs @@ -1,14 +1,13 @@ use codec::Encode; use domain_runtime_primitives::{Balance, CheckExtrinsicsValidityError}; use domain_test_service::evm_domain_test_runtime::{ - Runtime as TestRuntime, RuntimeCall, Signature, UncheckedExtrinsic as RuntimeUncheckedExtrinsic, + Runtime as TestRuntime, RuntimeCall, Signature, UncheckedExtrinsic as EvmUncheckedExtrinsic, }; use domain_test_service::EcdsaKeyring::{Alice, Charlie}; use domain_test_service::Sr25519Keyring::Ferdie; use domain_test_service::{construct_extrinsic_raw_payload, EvmDomainNode}; -use ethereum::TransactionV2 as Transaction; +use ethereum::TransactionV2 as EthereumTransaction; use fp_rpc::EthereumRuntimeRPCApi; -use pallet_ethereum::Call; use rand::distributions::{Distribution, Uniform}; use sc_client_api::{HeaderBackend, StorageProof}; use sc_service::{BasePath, Role}; @@ -25,11 +24,13 @@ use sp_runtime::OpaqueExtrinsic; use subspace_test_service::{produce_block_with, produce_blocks, MockConsensusNode}; use tempfile::TempDir; -/// Generate a self-contained EVM domain extrinsic. // This function depends on the macro-constructed `TestRuntime::RuntimeCall` enum, so it can't be // shared via `sp_domains::test_ethereum`. -pub fn generate_evm_domain_extrinsic(tx: Transaction) -> RuntimeUncheckedExtrinsic { - let call = Call::::transact { transaction: tx }; + +/// Generate a self-contained EVM domain extrinsic, which can be passed to +/// `runtime_api().check_extrinsics_and_do_pre_dispatch()`. +pub fn generate_eth_domain_sc_extrinsic(tx: EthereumTransaction) -> EvmUncheckedExtrinsic { + let call = pallet_ethereum::Call::::transact { transaction: tx }; fp_self_contained::UncheckedExtrinsic::new(RuntimeCall::Ethereum(call), None).unwrap() } @@ -97,7 +98,7 @@ async fn benchmark_bundle_with_evm_tx( vec![1u8; 100], gas_price, ); - generate_evm_domain_extrinsic(evm_tx) + generate_eth_domain_sc_extrinsic(evm_tx) } 1 => { let evm_tx = generate_eip2930_tx::( @@ -107,7 +108,7 @@ async fn benchmark_bundle_with_evm_tx( vec![1u8; 100], gas_price, ); - generate_evm_domain_extrinsic(evm_tx) + generate_eth_domain_sc_extrinsic(evm_tx) } 2 => { let evm_tx = generate_legacy_tx::( @@ -117,7 +118,7 @@ async fn benchmark_bundle_with_evm_tx( vec![1u8; 100], gas_price, ); - generate_evm_domain_extrinsic(evm_tx) + generate_eth_domain_sc_extrinsic(evm_tx) } 3 => { let ecdsa_key = Pair::from_seed_slice(&account_info.private_key.0).unwrap(); @@ -624,7 +625,15 @@ async fn test_evm_domain_block_fee() { // Construct and send evm transaction #[allow(clippy::type_complexity)] let tx_generators: Vec< - Box, U256) -> Transaction>, + Box< + dyn Fn( + AccountInfo, + U256, + ethereum::TransactionAction, + Vec, + U256, + ) -> EthereumTransaction, + >, > = vec![ Box::new(generate_eip2930_tx::), Box::new(generate_eip1559_tx::), @@ -635,7 +644,7 @@ async fn test_evm_domain_block_fee() { .zip(tx_generators.into_iter()) .enumerate() { - let tx = generate_evm_domain_extrinsic(tx_generator( + let tx = generate_eth_domain_sc_extrinsic(tx_generator( acc.clone(), U256::zero(), ethereum::TransactionAction::Create, diff --git a/crates/sp-domains/src/test_ethereum.rs b/crates/sp-domains/src/test_ethereum.rs index 760b3f2732..34fc9ccdae 100644 --- a/crates/sp-domains/src/test_ethereum.rs +++ b/crates/sp-domains/src/test_ethereum.rs @@ -31,6 +31,18 @@ pub fn address_build(seed_number: u128) -> AccountInfo { } } +pub fn max_extrinsic_gas( + multiplier: u64, +) -> u64 { + let limits: frame_system::limits::BlockWeights = + ::BlockWeights::get(); + // `limits.get(DispatchClass::Normal).max_extrinsic` is too large to use as `gas_limit` + // thus use `base_extrinsic` + let max_extrinsic = limits.get(DispatchClass::Normal).base_extrinsic * multiplier; + + ::GasWeightMapping::weight_to_gas(max_extrinsic) +} + pub fn generate_legacy_tx( account_info: AccountInfo, nonce: U256, @@ -38,18 +50,10 @@ pub fn generate_legacy_tx, gas_price: U256, ) -> Transaction { - let limits: frame_system::limits::BlockWeights = - ::BlockWeights::get(); - // `limits.get(DispatchClass::Normal).max_extrinsic` is too large to use as `gas_limit` - // thus use `base_extrinsic` - let max_extrinsic = limits.get(DispatchClass::Normal).base_extrinsic * 1000; - let max_extrinsic_gas = - ::GasWeightMapping::weight_to_gas(max_extrinsic); - LegacyUnsignedTransaction { nonce, gas_price, - gas_limit: U256::from(max_extrinsic_gas), + gas_limit: U256::from(max_extrinsic_gas::(1000)), action, value: U256::zero(), input, @@ -64,18 +68,10 @@ pub fn generate_eip2930_tx, gas_price: U256, ) -> Transaction { - let limits: frame_system::limits::BlockWeights = - ::BlockWeights::get(); - // `limits.get(DispatchClass::Normal).max_extrinsic` is too large to use as `gas_limit` - // thus use `base_extrinsic` - let max_extrinsic = limits.get(DispatchClass::Normal).base_extrinsic * 100; - let max_extrinsic_gas = - ::GasWeightMapping::weight_to_gas(max_extrinsic); - EIP2930UnsignedTransaction { nonce, gas_price, - gas_limit: U256::from(max_extrinsic_gas), + gas_limit: U256::from(max_extrinsic_gas::(100)), action, value: U256::one(), input, @@ -90,19 +86,11 @@ pub fn generate_eip1559_tx, gas_price: U256, ) -> Transaction { - let limits: frame_system::limits::BlockWeights = - ::BlockWeights::get(); - // `limits.get(DispatchClass::Normal).max_extrinsic` is too large to use as `gas_limit` - // thus use `base_extrinsic` - let max_extrinsic = limits.get(DispatchClass::Normal).base_extrinsic * 1000; - let max_extrinsic_gas = - ::GasWeightMapping::weight_to_gas(max_extrinsic); - EIP1559UnsignedTransaction { nonce, max_priority_fee_per_gas: U256::from(1), max_fee_per_gas: gas_price, - gas_limit: U256::from(max_extrinsic_gas), + gas_limit: U256::from(max_extrinsic_gas::(1000)), action, value: U256::zero(), input, diff --git a/domains/client/domain-operator/Cargo.toml b/domains/client/domain-operator/Cargo.toml index 20372d8d0a..764500fe3c 100644 --- a/domains/client/domain-operator/Cargo.toml +++ b/domains/client/domain-operator/Cargo.toml @@ -54,12 +54,16 @@ auto-id-domain-test-runtime = { version = "0.1.0", path = "../../test/runtime/au cross-domain-message-gossip = { path = "../../client/cross-domain-message-gossip" } domain-test-service = { version = "0.1.0", path = "../../test/service" } domain-test-primitives = { version = "0.1.0", path = "../../test/primitives" } +ethereum = "0.15.0" evm-domain-test-runtime = { version = "0.1.0", path = "../../test/runtime/evm" } +fp-self-contained = { version = "1.0.0-dev", git = "https://github.com/autonomys/frontier", rev = "f80f9e2bad338f3bf3854b256b3c4edea23e5968" } frame-system = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "94a1a8143a89bbe9f938c1939ff68abc1519a305" } hex-literal = "0.4.1" pallet-balances = { git = "https://github.com/subspace/polkadot-sdk", rev = "94a1a8143a89bbe9f938c1939ff68abc1519a305" } pallet-domains = { version = "0.1.0", path = "../../../crates/pallet-domains" } pallet-domain-sudo = { version = "0.1.0", path = "../../pallets/domain-sudo" } +pallet-ethereum = { git = "https://github.com/autonomys/frontier", rev = "f80f9e2bad338f3bf3854b256b3c4edea23e5968" } +pallet-evm = { version = "6.0.0-dev", git = "https://github.com/autonomys/frontier", rev = "f80f9e2bad338f3bf3854b256b3c4edea23e5968" } pallet-evm-tracker = { version = "0.1.0", path = "../../pallets/evm-tracker" } pallet-messenger = { version = "0.1.0", path = "../../../domains/pallets/messenger" } pallet-sudo = { git = "https://github.com/subspace/polkadot-sdk", rev = "94a1a8143a89bbe9f938c1939ff68abc1519a305" } diff --git a/domains/client/domain-operator/src/tests.rs b/domains/client/domain-operator/src/tests.rs index 79639dfb9e..76f1f0b8c0 100644 --- a/domains/client/domain-operator/src/tests.rs +++ b/domains/client/domain-operator/src/tests.rs @@ -8,10 +8,13 @@ use codec::{Decode, Encode}; use cross_domain_message_gossip::get_channel_state; use domain_runtime_primitives::{AccountId20Converter, AccountIdConverter, Hash}; use domain_test_primitives::{OnchainStateApi, TimestampApi}; -use domain_test_service::evm_domain_test_runtime::{Header, UncheckedExtrinsic}; +use domain_test_service::evm_domain_test_runtime::{ + Header, Runtime as TestRuntime, RuntimeCall, UncheckedExtrinsic as EvmUncheckedExtrinsic, +}; use domain_test_service::EcdsaKeyring::{Alice, Bob, Charlie, Eve}; use domain_test_service::Sr25519Keyring::{self, Alice as Sr25519Alice, Ferdie}; use domain_test_service::{construct_extrinsic_generic, AUTO_ID_DOMAIN_ID, EVM_DOMAIN_ID}; +use ethereum::TransactionV2 as EthereumTransaction; use futures::StreamExt; use hex_literal::hex; use pallet_domains::OperatorConfig; @@ -27,10 +30,11 @@ use sp_api::{ProvideRuntimeApi, StorageProof}; use sp_consensus::SyncOracle; use sp_core::storage::StateVersion; use sp_core::traits::{FetchRuntimeCode, SpawnEssentialNamed}; -use sp_core::{Pair, H256}; +use sp_core::{Pair, H256, U256}; use sp_domain_digests::AsPredigest; use sp_domains::core_api::DomainCoreApi; use sp_domains::merkle_tree::MerkleTree; +use sp_domains::test_ethereum::{max_extrinsic_gas, AccountInfo}; use sp_domains::{ Bundle, BundleValidity, ChainId, ChannelId, DomainsApi, HeaderHashingFor, InboxedBundle, InvalidBundleType, PermissionedActionAllowedBy, Transfers, @@ -46,7 +50,7 @@ use sp_messenger::MessengerApi; use sp_mmr_primitives::{EncodableOpaqueLeaf, LeafProof as MmrProof}; use sp_runtime::generic::{BlockId, DigestItem}; use sp_runtime::traits::{ - BlakeTwo256, Block as BlockT, Convert, Hash as HashT, Header as HeaderT, Zero, + BlakeTwo256, Block as BlockT, Convert, Extrinsic, Hash as HashT, Header as HeaderT, Zero, }; use sp_runtime::transaction_validity::{ InvalidTransaction, TransactionSource, TransactionValidityError, @@ -78,6 +82,52 @@ fn number_of(consensus_node: &MockConsensusNode, block_hash: Hash) -> u32 { .unwrap_or_else(|| panic!("header {block_hash} not in the chain")) } +// These functions depend on the macro-constructed `TestRuntime::RuntimeCall` enum, so they can't +// be shared via `sp_domains::test_ethereum`. + +/// Generate a self-contained EVM domain extrinsic, which can be passed to +/// `runtime_api().check_extrinsics_and_do_pre_dispatch()`. +pub fn generate_eth_domain_sc_extrinsic(tx: EthereumTransaction) -> EvmUncheckedExtrinsic { + let call = pallet_ethereum::Call::::transact { transaction: tx }; + fp_self_contained::UncheckedExtrinsic::new(RuntimeCall::Ethereum(call), None).unwrap() +} + +/// Generate a pallet-evm call, which can be passed to `construct_and_send_extrinsic_with()`. +pub fn generate_evm_domain_call_extrinsic( + account_info: AccountInfo, + nonce: Option, + init: Vec, + max_fee_per_gas: U256, + use_create: bool, +) -> ::RuntimeCall { + let call = if use_create { + pallet_evm::Call::::create { + source: account_info.address, + init, + value: U256::zero(), + gas_limit: max_extrinsic_gas::(1000), + max_fee_per_gas, + access_list: vec![], + max_priority_fee_per_gas: Some(U256::from(1)), + nonce, + } + } else { + pallet_evm::Call::::create2 { + source: account_info.address, + init, + salt: H256::zero(), + value: U256::zero(), + gas_limit: max_extrinsic_gas::(1000), + max_fee_per_gas, + access_list: vec![], + max_priority_fee_per_gas: Some(U256::from(1)), + nonce, + } + }; + + RuntimeCall::EVM(call) +} + #[tokio::test(flavor = "multi_thread")] async fn test_domain_instance_bootstrapper() { let directory = TempDir::new().expect("Must be able to create temporary directory"); @@ -3394,7 +3444,7 @@ async fn set_new_code_should_work() { .unwrap() .into_iter() .map(|encoded_extrinsic| { - UncheckedExtrinsic::decode(&mut encoded_extrinsic.encode().as_slice()).unwrap() + EvmUncheckedExtrinsic::decode(&mut encoded_extrinsic.encode().as_slice()).unwrap() }) .collect::>(); panic!("`set_code` not executed, extrinsics in the block: {extrinsics:?}")