From 2747e6f3692447a96bbe955e7a8f856b03ac7b2e Mon Sep 17 00:00:00 2001 From: Roznovjak Date: Wed, 21 Feb 2024 15:08:34 +0100 Subject: [PATCH 1/3] restricted contract deployment --- Cargo.lock | 6 +- integration-tests/Cargo.toml | 2 +- integration-tests/src/call_filter.rs | 38 ++++++++ integration-tests/src/evm.rs | 53 +++++++++++ pallets/evm-accounts/Cargo.toml | 2 +- pallets/evm-accounts/README.md | 13 ++- pallets/evm-accounts/src/benchmarking.rs | 39 +++++++- pallets/evm-accounts/src/lib.rs | 86 +++++++++++++++++- pallets/evm-accounts/src/mock.rs | 2 + pallets/evm-accounts/src/tests.rs | 65 ++++++++++++++ pallets/evm-accounts/src/weights.rs | 21 +++++ runtime/hydradx/Cargo.toml | 2 +- runtime/hydradx/src/evm/mod.rs | 1 + runtime/hydradx/src/lib.rs | 98 ++++++++++++++++++--- runtime/hydradx/src/system.rs | 3 + runtime/hydradx/src/weights/evm_accounts.rs | 9 ++ 16 files changed, 417 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 69219d89f..9bc50cea7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4619,7 +4619,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "209.0.0" +version = "210.0.0" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", @@ -7643,7 +7643,7 @@ dependencies = [ [[package]] name = "pallet-evm-accounts" -version = "1.0.0" +version = "1.1.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -11330,7 +11330,7 @@ dependencies = [ [[package]] name = "runtime-integration-tests" -version = "1.17.5" +version = "1.17.6" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 808800428..540b323bf 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "runtime-integration-tests" -version = "1.17.5" +version = "1.17.6" description = "Integration tests" authors = ["GalacticCouncil"] edition = "2021" diff --git a/integration-tests/src/call_filter.rs b/integration-tests/src/call_filter.rs index 5f331df7a..3563f15ea 100644 --- a/integration-tests/src/call_filter.rs +++ b/integration-tests/src/call_filter.rs @@ -267,3 +267,41 @@ fn calling_orml_xcm_extrinsic_should_be_filtered_by_call_filter() { assert!(!hydradx_runtime::CallFilter::contains(&call)); }); } + +#[test] +fn create_contract_from_evm_pallet_should_be_filtered_by_call_filter() { + use sp_core::{H160, H256, U256}; + + TestNet::reset(); + + Hydra::execute_with(|| { + // the values here don't need to make sense, all we need is a valid Call + let call = hydradx_runtime::RuntimeCall::EVM(pallet_evm::Call::create { + source: H160::default(), + init: vec![0, 1, 1, 0], + value: U256::zero(), + gas_limit: 1000000, + max_fee_per_gas: U256::from(100000u64), + max_priority_fee_per_gas: None, + nonce: None, + access_list: [].into(), + }); + + assert!(!hydradx_runtime::CallFilter::contains(&call)); + + // the values here don't need to make sense, all we need is a valid Call + let call = hydradx_runtime::RuntimeCall::EVM(pallet_evm::Call::create2 { + source: H160::default(), + init: vec![0, 1, 1, 0], + salt: H256::zero(), + value: U256::zero(), + gas_limit: 1000000, + max_fee_per_gas: U256::from(100000u64), + max_priority_fee_per_gas: None, + nonce: None, + access_list: [].into(), + }); + + assert!(!hydradx_runtime::CallFilter::contains(&call)); + }); +} diff --git a/integration-tests/src/evm.rs b/integration-tests/src/evm.rs index 035832a79..ebe821042 100644 --- a/integration-tests/src/evm.rs +++ b/integration-tests/src/evm.rs @@ -961,6 +961,59 @@ mod currency_precompile { } } +mod contract_deployment { + use super::*; + use frame_support::assert_noop; + use pretty_assertions::assert_eq; + + #[test] + fn create_contract_from_runtime_rpc_should_be_rejected_if_address_is_not_whitelisted() { + TestNet::reset(); + + Hydra::execute_with(|| { + assert_noop!( + hydradx_runtime::Runtime::create( + evm_address(), + vec![0, 1, 1, 0], + U256::zero(), + U256::from(100000u64), + None, + None, + None, + false, + None, + ), + pallet_evm_accounts::Error::::AddressNotWhitelisted + ); + }); + } + + #[test] + fn create_contract_from_runtime_rpc_should_be_accepted_if_address_is_whitelisted() { + TestNet::reset(); + + Hydra::execute_with(|| { + let evm_address = EVMAccounts::evm_address(&Into::::into(ALICE)); + assert_ok!(EVMAccounts::add_contract_deployer( + hydradx_runtime::RuntimeOrigin::root(), + evm_address + )); + + assert_ok!(hydradx_runtime::Runtime::create( + evm_address, + vec![0, 1, 1, 0], + U256::zero(), + U256::from(100000u64), + None, + None, + None, + false, + None, + )); + }); + } +} + #[test] fn dispatch_should_work_with_remark() { TestNet::reset(); diff --git a/pallets/evm-accounts/Cargo.toml b/pallets/evm-accounts/Cargo.toml index 201561ef0..0c78ff593 100644 --- a/pallets/evm-accounts/Cargo.toml +++ b/pallets/evm-accounts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-evm-accounts" -version = "1.0.0" +version = "1.1.0" authors = ['GalacticCouncil'] edition = "2021" license = "Apache-2.0" diff --git a/pallets/evm-accounts/README.md b/pallets/evm-accounts/README.md index 4151f2e36..8e2a80b72 100644 --- a/pallets/evm-accounts/README.md +++ b/pallets/evm-accounts/README.md @@ -8,10 +8,11 @@ ## Overview -The pallet allows users to bind their Substrate account to the EVM address. +The pallet allows users to bind their Substrate account to the EVM address and to grant a permission to deploy smart contracts. The purpose of this pallet is to make interaction with the EVM easier. Binding an address is not necessary for interacting with the EVM. +### Binding Without binding, we are unable to get the original Substrate address from the EVM address inside of the EVM. Inside of the EVM, we have access only to the EVM address (first 20 bytes of a Substrate account). In this case we create and use a truncated version of the original Substrate address that called the EVM. @@ -20,6 +21,14 @@ The original and truncated address are two different Substrate addresses. With binding, we store the last 12 bytes of the Substrate address. Then we can get the original Substrate address by concatenating these 12 bytes stored in the storage to the EVM address. +### Smart contract deployment +This pallet also allows granting a permission to deploy smart contracts. +`ControllerOrigin` can add this permission to EVM addresses. +The list of whitelisted accounts is stored in the storage of this pallet. + ### Dispatchable Functions -* `bind_evm_address` - Binds a Substrate address to EVM address. \ No newline at end of file +* `bind_evm_address` - Binds a Substrate address to EVM address. +* `add_contract_deployer` - Adds a permission to deploy smart contracts. +* `remove_contract_deployer` - Removes a permission of whitelisted address to deploy smart contracts. +* `renounce_contract_deployer` - Renounce caller's permission to deploy smart contracts. diff --git a/pallets/evm-accounts/src/benchmarking.rs b/pallets/evm-accounts/src/benchmarking.rs index 8f785f257..da4485efa 100644 --- a/pallets/evm-accounts/src/benchmarking.rs +++ b/pallets/evm-accounts/src/benchmarking.rs @@ -16,6 +16,7 @@ #![cfg(feature = "runtime-benchmarks")] use super::*; +use crate::Pallet as EVMAccounts; use frame_benchmarking::{account, benchmarks}; use frame_system::RawOrigin; @@ -33,9 +34,45 @@ benchmarks! { }: _(RawOrigin::Signed(user.clone())) verify { - let evm_address = Pallet::::evm_address(&user); assert!(AccountExtension::::contains_key(evm_address)); } + add_contract_deployer { + let user: T::AccountId = account("user", 0, 1); + let evm_address = Pallet::::evm_address(&user); + assert!(!ContractDeployer::::contains_key(evm_address)); + + }: _(RawOrigin::Root, evm_address) + verify { + assert!(ContractDeployer::::contains_key(evm_address)); + } + + remove_contract_deployer { + let user: T::AccountId = account("user", 0, 1); + let evm_address = Pallet::::evm_address(&user); + + EVMAccounts::::add_contract_deployer(RawOrigin::Root.into(), evm_address)?; + + assert!(ContractDeployer::::contains_key(evm_address)); + + }: _(RawOrigin::Root, evm_address) + verify { + assert!(!ContractDeployer::::contains_key(evm_address)); + } + + renounce_contract_deployer { + let user: T::AccountId = account("user", 0, 1); + let evm_address = Pallet::::evm_address(&user); + + EVMAccounts::::add_contract_deployer(RawOrigin::Root.into(), evm_address)?; + EVMAccounts::::bind_evm_address(RawOrigin::Signed(user.clone()).into())?; + + assert!(ContractDeployer::::contains_key(evm_address)); + + }: _(RawOrigin::Signed(user)) + verify { + assert!(!ContractDeployer::::contains_key(evm_address)); + } + impl_benchmark_test_suite!(Pallet, crate::mock::ExtBuilder::default().build(), crate::mock::Test); } diff --git a/pallets/evm-accounts/src/lib.rs b/pallets/evm-accounts/src/lib.rs index 9a2e389c3..37bd74782 100644 --- a/pallets/evm-accounts/src/lib.rs +++ b/pallets/evm-accounts/src/lib.rs @@ -23,10 +23,11 @@ //! //! ## Overview //! -//! The pallet allows users to bind their Substrate account to the EVM address. +//! The pallet allows users to bind their Substrate account to the EVM address and to grant a permission to deploy smart contracts. //! The purpose of this pallet is to make interaction with the EVM easier. //! Binding an address is not necessary for interacting with the EVM. //! +//! ### Binding //! Without binding, we are unable to get the original Substrate address from the EVM address inside //! of the EVM. Inside of the EVM, we have access only to the EVM address (first 20 bytes of a Substrate account). //! In this case we create and use a truncated version of the original Substrate address that called the EVM. @@ -35,9 +36,17 @@ //! With binding, we store the last 12 bytes of the Substrate address. Then we can get the original //! Substrate address by concatenating these 12 bytes stored in the storage to the EVM address. //! +//! ### Smart contract deployment +//! This pallet also allows granting a permission to deploy smart contracts. +//! `ControllerOrigin` can add this permission to EVM addresses. +//! The list of whitelisted accounts is stored in the storage of this pallet. +//! //! ### Dispatchable Functions //! //! * `bind_evm_address` - Binds a Substrate address to EVM address. +//! * `add_contract_deployer` - Adds a permission to deploy smart contracts. +//! * `remove_contract_deployer` - Removes a permission of whitelisted address to deploy smart contracts. +//! * `renounce_contract_deployer` - Renounce caller's permission to deploy smart contracts. #![cfg_attr(not(feature = "std"), no_std)] @@ -88,6 +97,9 @@ pub mod pallet { #[pallet::constant] type FeeMultiplier: Get; + /// Origin that can whitelist addresses for smart contract deployment. + type ControllerOrigin: EnsureOrigin; + /// Weight information for extrinsic in this pallet. type WeightInfo: WeightInfo; } @@ -97,11 +109,19 @@ pub mod pallet { #[pallet::getter(fn account)] pub(super) type AccountExtension = StorageMap<_, Blake2_128Concat, EvmAddress, AccountIdLast12Bytes>; + /// Whitelisted addresses that are allowed to deploy smart contracts. + #[pallet::storage] + pub(super) type ContractDeployer = StorageMap<_, Blake2_128Concat, EvmAddress, ()>; + #[pallet::event] #[pallet::generate_deposit(pub(crate) fn deposit_event)] pub enum Event { /// Binding was created. Bound { account: T::AccountId, address: EvmAddress }, + /// Deployer was added. + DeployerAdded { who: EvmAddress }, + /// Deployer was removed. + DeployerRemoved { who: EvmAddress }, } #[pallet::error] @@ -113,6 +133,8 @@ pub mod pallet { AddressAlreadyBound, /// Bound address cannot be used BoundAddressCannotBeUsed, + /// Address not whitelisted + AddressNotWhitelisted, } #[pallet::hooks] @@ -179,6 +201,64 @@ pub mod pallet { Ok(()) } + + /// Adds an EVM address to the list of addresses that are allowed to deploy smart contracts. + /// + /// Parameters: + /// - `origin`: Substrate account whitelisting an address. Must be `ControllerOrigin`. + /// - `address`: EVM address that is whitelisted + /// + /// Emits `DeployerAdded` event when successful. + #[pallet::call_index(1)] + #[pallet::weight(::WeightInfo::add_contract_deployer())] + pub fn add_contract_deployer(origin: OriginFor, address: EvmAddress) -> DispatchResult { + T::ControllerOrigin::ensure_origin(origin.clone())?; + + >::insert(address, ()); + + Self::deposit_event(Event::DeployerAdded { who: address }); + + Ok(()) + } + + /// Removes an EVM address from the list of addresses that are allowed to deploy smart contracts. + /// + /// Parameters: + /// - `origin`: Substrate account removing the EVM address from the whitelist. Must be `ControllerOrigin`. + /// - `address`: EVM address that is removed from the whitelist + /// + /// Emits `DeployerRemoved` event when successful. + #[pallet::call_index(2)] + #[pallet::weight(::WeightInfo::remove_contract_deployer())] + pub fn remove_contract_deployer(origin: OriginFor, address: EvmAddress) -> DispatchResult { + T::ControllerOrigin::ensure_origin(origin.clone())?; + + >::remove(address); + + Self::deposit_event(Event::DeployerRemoved { who: address }); + + Ok(()) + } + + /// Removes the account's EVM address from the list of addresses that are allowed to deploy smart contracts. + /// Based on the best practices, this extrinsic can be called by any whitelisted account to renounce their own permission. + /// + /// Parameters: + /// - `origin`: Substrate account removing their EVM address from the whitelist. + /// + /// Emits `DeployerRemoved` event when successful. + #[pallet::call_index(3)] + #[pallet::weight(::WeightInfo::renounce_contract_deployer())] + pub fn renounce_contract_deployer(origin: OriginFor) -> DispatchResult { + let who = ensure_signed(origin.clone())?; + let address = Self::evm_address(&who); + + >::remove(address); + + Self::deposit_event(Event::DeployerRemoved { who: address }); + + Ok(()) + } } } @@ -216,4 +296,8 @@ where pub fn account_id(evm_address: EvmAddress) -> T::AccountId { Self::bound_account_id(evm_address).unwrap_or_else(|| Self::truncated_account_id(evm_address)) } + + pub fn can_deploy_contracts(evm_address: EvmAddress) -> bool { + ContractDeployer::::contains_key(evm_address) + } } diff --git a/pallets/evm-accounts/src/mock.rs b/pallets/evm-accounts/src/mock.rs index 13f1aae10..fb2b601de 100644 --- a/pallets/evm-accounts/src/mock.rs +++ b/pallets/evm-accounts/src/mock.rs @@ -9,6 +9,7 @@ use frame_support::sp_runtime::{ BuildStorage, MultiSignature, }; use frame_support::traits::Everything; +use frame_system::EnsureRoot; use orml_traits::parameter_type_with_key; pub use sp_core::{H160, H256}; use std::cell::RefCell; @@ -59,6 +60,7 @@ impl Config for Test { type RuntimeEvent = RuntimeEvent; type FeeMultiplier = sp_core::ConstU32<10>; type EvmNonceProvider = EvmNonceProviderMock; + type ControllerOrigin = EnsureRoot; type WeightInfo = (); } diff --git a/pallets/evm-accounts/src/tests.rs b/pallets/evm-accounts/src/tests.rs index a743e54b5..7aaf7e532 100644 --- a/pallets/evm-accounts/src/tests.rs +++ b/pallets/evm-accounts/src/tests.rs @@ -81,3 +81,68 @@ fn bind_address_should_fail_when_already_bound() { ); }); } + +#[test] +fn add_contract_deployer_should_store_address_in_the_storage() { + ExtBuilder::default().build().execute_with(|| { + // Arrange + let evm_address = EVMAccounts::evm_address(&ALICE); + assert!(!EVMAccounts::can_deploy_contracts(evm_address)); + + // Act + assert_ok!(EVMAccounts::add_contract_deployer(RuntimeOrigin::root(), evm_address)); + + // Assert + assert!(EVMAccounts::can_deploy_contracts(evm_address)); + expect_events(vec![Event::DeployerAdded { who: evm_address }.into()]); + + // adding the address again should be ok + assert_ok!(EVMAccounts::add_contract_deployer(RuntimeOrigin::root(), evm_address)); + }); +} + +#[test] +fn remove_contract_deployer_should_remove_address_from_the_storage() { + ExtBuilder::default().build().execute_with(|| { + // Arrange + let evm_address = EVMAccounts::evm_address(&ALICE); + assert_ok!(EVMAccounts::add_contract_deployer(RuntimeOrigin::root(), evm_address)); + assert!(EVMAccounts::can_deploy_contracts(evm_address)); + + // Act + assert_ok!(EVMAccounts::remove_contract_deployer( + RuntimeOrigin::root(), + evm_address + )); + + // Assert + assert!(!EVMAccounts::can_deploy_contracts(evm_address)); + expect_events(vec![Event::DeployerRemoved { who: evm_address }.into()]); + + // removing the address again should be ok + assert_ok!(EVMAccounts::remove_contract_deployer( + RuntimeOrigin::root(), + evm_address + )); + }); +} + +#[test] +fn renounce_contract_deployer_should_remove_address_from_the_storage() { + ExtBuilder::default().build().execute_with(|| { + // Arrange + let evm_address = EVMAccounts::evm_address(&ALICE); + assert_ok!(EVMAccounts::add_contract_deployer(RuntimeOrigin::root(), evm_address)); + assert!(EVMAccounts::can_deploy_contracts(evm_address)); + + // Act + assert_ok!(EVMAccounts::renounce_contract_deployer(RuntimeOrigin::signed(ALICE))); + + // Assert + assert!(!EVMAccounts::can_deploy_contracts(evm_address)); + expect_events(vec![Event::DeployerRemoved { who: evm_address }.into()]); + + // ronouncing the address again should be ok + assert_ok!(EVMAccounts::renounce_contract_deployer(RuntimeOrigin::signed(ALICE))); + }); +} diff --git a/pallets/evm-accounts/src/weights.rs b/pallets/evm-accounts/src/weights.rs index e2d910360..09de821f2 100644 --- a/pallets/evm-accounts/src/weights.rs +++ b/pallets/evm-accounts/src/weights.rs @@ -49,6 +49,9 @@ use sp_std::marker::PhantomData; pub trait WeightInfo { fn bind_evm_address() -> Weight; + fn add_contract_deployer() -> Weight; + fn remove_contract_deployer() -> Weight; + fn renounce_contract_deployer() -> Weight; } pub struct HydraWeight(PhantomData); @@ -73,6 +76,15 @@ impl WeightInfo for HydraWeight { .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) } + fn add_contract_deployer() -> Weight { + Weight::zero() + } + fn remove_contract_deployer() -> Weight { + Weight::zero() + } + fn renounce_contract_deployer() -> Weight { + Weight::zero() + } } // For backwards compatibility and tests @@ -96,4 +108,13 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(5)) .saturating_add(RocksDbWeight::get().writes(1)) } + fn add_contract_deployer() -> Weight { + Weight::zero() + } + fn remove_contract_deployer() -> Weight { + Weight::zero() + } + fn renounce_contract_deployer() -> Weight { + Weight::zero() + } } diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index c56f86ac4..199149c65 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-runtime" -version = "209.0.0" +version = "210.0.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" diff --git a/runtime/hydradx/src/evm/mod.rs b/runtime/hydradx/src/evm/mod.rs index 0beab4083..6fd468e20 100644 --- a/runtime/hydradx/src/evm/mod.rs +++ b/runtime/hydradx/src/evm/mod.rs @@ -176,5 +176,6 @@ impl pallet_evm_accounts::Config for crate::Runtime { type RuntimeEvent = crate::RuntimeEvent; type FeeMultiplier = sp_core::ConstU32<50>; type EvmNonceProvider = EvmNonceProvider; + type ControllerOrigin = crate::SuperMajorityTechCommittee; type WeightInfo = crate::weights::evm_accounts::HydraWeight; } diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index d1bd56142..6e9531c34 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -107,7 +107,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("hydradx"), impl_name: create_runtime_str!("hydradx"), authoring_version: 1, - spec_version: 209, + spec_version: 210, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -509,19 +509,91 @@ impl_runtime_apis! { } fn create( - _from: H160, - _data: Vec, - _value: U256, - _gas_limit: U256, - _max_fee_per_gas: Option, - _max_priority_fee_per_gas: Option, - _nonce: Option, - _estimate: bool, - _access_list: Option)>>, + from: H160, + data: Vec, + value: U256, + gas_limit: U256, + max_fee_per_gas: Option, + max_priority_fee_per_gas: Option, + nonce: Option, + estimate: bool, + access_list: Option)>>, ) -> Result { - Err(sp_runtime::DispatchError::Other( - "Creating contracts is not currently supported", - )) + let config = if estimate { + let mut config = ::config().clone(); + config.estimate = true; + Some(config) + } else { + None + }; + + let is_transactional = false; + let validate = true; + + // Reused approach from Moonbeam since Frontier implementation doesn't support this + let mut estimated_transaction_len = data.len() + + // to: 20 + // from: 20 + // value: 32 + // gas_limit: 32 + // nonce: 32 + // 1 byte transaction action variant + // chain id 8 bytes + // 65 bytes signature + 210; + if max_fee_per_gas.is_some() { + estimated_transaction_len += 32; + } + if max_priority_fee_per_gas.is_some() { + estimated_transaction_len += 32; + } + if access_list.is_some() { + estimated_transaction_len += access_list.encoded_size(); + } + + let gas_limit = gas_limit.min(u64::MAX.into()).low_u64(); + let without_base_extrinsic_weight = true; + + let (weight_limit, proof_size_base_cost) = + match ::GasWeightMapping::gas_to_weight( + gas_limit, + without_base_extrinsic_weight + ) { + weight_limit if weight_limit.proof_size() > 0 => { + (Some(weight_limit), Some(estimated_transaction_len as u64)) + } + _ => (None, None), + }; + + // don't allow calling EVM RPC or Runtime API from a bound address + if EVMAccounts::bound_account_id(from).is_some() { + return Err(pallet_evm_accounts::Error::::BoundAddressCannotBeUsed.into()) + }; + + // the address needs to have a permission to deploy smart contract + if !EVMAccounts::can_deploy_contracts(from) { + return Err(pallet_evm_accounts::Error::::AddressNotWhitelisted.into()) + }; + + #[allow(clippy::or_fun_call)] // suggestion not helpful here + ::Runner::create( + from, + data, + value, + gas_limit.unique_saturated_into(), + max_fee_per_gas, + max_priority_fee_per_gas, + nonce, + Vec::new(), + is_transactional, + validate, + weight_limit, + proof_size_base_cost, + config + .as_ref() + .unwrap_or(::config()), + ) + .map_err(|err| err.error.into()) } fn current_transaction_statuses() -> Option> { diff --git a/runtime/hydradx/src/system.rs b/runtime/hydradx/src/system.rs index f3de7c715..d17300846 100644 --- a/runtime/hydradx/src/system.rs +++ b/runtime/hydradx/src/system.rs @@ -95,6 +95,9 @@ impl Contains for CallFilter { match call { RuntimeCall::PolkadotXcm(pallet_xcm::Call::send { .. }) => true, + // create and create2 are only allowed through RPC or Runtime API + RuntimeCall::EVM(pallet_evm::Call::create { .. }) => false, + RuntimeCall::EVM(pallet_evm::Call::create2 { .. }) => false, RuntimeCall::PolkadotXcm(_) => false, RuntimeCall::OrmlXcm(_) => false, _ => true, diff --git a/runtime/hydradx/src/weights/evm_accounts.rs b/runtime/hydradx/src/weights/evm_accounts.rs index 69a0f04ad..14604fdec 100644 --- a/runtime/hydradx/src/weights/evm_accounts.rs +++ b/runtime/hydradx/src/weights/evm_accounts.rs @@ -73,4 +73,13 @@ impl WeightInfo for HydraWeight { .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) } + fn add_contract_deployer() -> Weight { + Weight::zero() + } + fn remove_contract_deployer() -> Weight { + Weight::zero() + } + fn renounce_contract_deployer() -> Weight { + Weight::zero() + } } From 1eaf251b8c261e0bd1db4554c0e0bb10509dcd5b Mon Sep 17 00:00:00 2001 From: Roznovjak Date: Wed, 21 Feb 2024 15:25:23 +0100 Subject: [PATCH 2/3] rebenchmarking --- pallets/evm-accounts/src/benchmarking.rs | 2 +- pallets/evm-accounts/src/tests.rs | 2 +- pallets/evm-accounts/src/weights.rs | 68 ++++++++++++++++----- runtime/hydradx/src/weights/evm_accounts.rs | 39 +++++++++--- 4 files changed, 84 insertions(+), 27 deletions(-) diff --git a/pallets/evm-accounts/src/benchmarking.rs b/pallets/evm-accounts/src/benchmarking.rs index da4485efa..9214eab69 100644 --- a/pallets/evm-accounts/src/benchmarking.rs +++ b/pallets/evm-accounts/src/benchmarking.rs @@ -1,4 +1,4 @@ -// Copyright (C) 2020-2022 Intergalactic, Limited (GIB). +// Copyright (C) 2020-2024 Intergalactic, Limited (GIB). // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/pallets/evm-accounts/src/tests.rs b/pallets/evm-accounts/src/tests.rs index 7aaf7e532..0ae79fbb2 100644 --- a/pallets/evm-accounts/src/tests.rs +++ b/pallets/evm-accounts/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of HydraDX-node. -// Copyright (C) 2020-2022 Intergalactic, Limited (GIB). +// Copyright (C) 2020-2024 Intergalactic, Limited (GIB). // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/pallets/evm-accounts/src/weights.rs b/pallets/evm-accounts/src/weights.rs index 09de821f2..4ba3fa82c 100644 --- a/pallets/evm-accounts/src/weights.rs +++ b/pallets/evm-accounts/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of HydraDX. -// Copyright (C) 2020-2023 Intergalactic, Limited (GIB). +// Copyright (C) 2020-2024 Intergalactic, Limited (GIB). // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,7 +18,7 @@ //! Autogenerated weights for `pallet_evm_accounts` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-02-13, STEPS: `10`, REPEAT: `30`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-02-21, STEPS: `10`, REPEAT: `30`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `bench-bot`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: 1024 @@ -57,8 +57,8 @@ pub trait WeightInfo { pub struct HydraWeight(PhantomData); impl WeightInfo for HydraWeight { - /// Storage: `EVMAccounts::BoundAccount` (r:1 w:1) - /// Proof: `EVMAccounts::BoundAccount` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `EVMAccounts::AccountExtension` (r:1 w:1) + /// Proof: `EVMAccounts::AccountExtension` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::NextAssetId` (r:1 w:0) @@ -71,26 +71,44 @@ impl WeightInfo for HydraWeight { // Proof Size summary in bytes: // Measured: `479` // Estimated: `4087` - // Minimum execution time: 35_419_000 picoseconds. - Weight::from_parts(35_955_000, 4087) + // Minimum execution time: 36_357_000 picoseconds. + Weight::from_parts(36_601_000, 4087) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `EVMAccounts::ContractDeployer` (r:0 w:1) + /// Proof: `EVMAccounts::ContractDeployer` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn add_contract_deployer() -> Weight { - Weight::zero() + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_157_000 picoseconds. + Weight::from_parts(13_481_000, 0).saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `EVMAccounts::ContractDeployer` (r:0 w:1) + /// Proof: `EVMAccounts::ContractDeployer` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn remove_contract_deployer() -> Weight { - Weight::zero() + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_196_000 picoseconds. + Weight::from_parts(13_517_000, 0).saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `EVMAccounts::ContractDeployer` (r:0 w:1) + /// Proof: `EVMAccounts::ContractDeployer` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn renounce_contract_deployer() -> Weight { - Weight::zero() + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_153_000 picoseconds. + Weight::from_parts(13_380_000, 0).saturating_add(T::DbWeight::get().writes(1)) } } // For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `EVMAccounts::BoundAccount` (r:1 w:1) - /// Proof: `EVMAccounts::BoundAccount` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `EVMAccounts::AccountExtension` (r:1 w:1) + /// Proof: `EVMAccounts::AccountExtension` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::NextAssetId` (r:1 w:0) @@ -103,18 +121,36 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `479` // Estimated: `4087` - // Minimum execution time: 35_419_000 picoseconds. - Weight::from_parts(35_955_000, 4087) + // Minimum execution time: 36_357_000 picoseconds. + Weight::from_parts(36_601_000, 4087) .saturating_add(RocksDbWeight::get().reads(5)) .saturating_add(RocksDbWeight::get().writes(1)) } + /// Storage: `EVMAccounts::ContractDeployer` (r:0 w:1) + /// Proof: `EVMAccounts::ContractDeployer` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn add_contract_deployer() -> Weight { - Weight::zero() + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_157_000 picoseconds. + Weight::from_parts(13_481_000, 0).saturating_add(RocksDbWeight::get().writes(1)) } + /// Storage: `EVMAccounts::ContractDeployer` (r:0 w:1) + /// Proof: `EVMAccounts::ContractDeployer` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn remove_contract_deployer() -> Weight { - Weight::zero() + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_196_000 picoseconds. + Weight::from_parts(13_517_000, 0).saturating_add(RocksDbWeight::get().writes(1)) } + /// Storage: `EVMAccounts::ContractDeployer` (r:0 w:1) + /// Proof: `EVMAccounts::ContractDeployer` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn renounce_contract_deployer() -> Weight { - Weight::zero() + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_153_000 picoseconds. + Weight::from_parts(13_380_000, 0).saturating_add(RocksDbWeight::get().writes(1)) } } diff --git a/runtime/hydradx/src/weights/evm_accounts.rs b/runtime/hydradx/src/weights/evm_accounts.rs index 14604fdec..c33686093 100644 --- a/runtime/hydradx/src/weights/evm_accounts.rs +++ b/runtime/hydradx/src/weights/evm_accounts.rs @@ -1,6 +1,6 @@ // This file is part of HydraDX. -// Copyright (C) 2020-2023 Intergalactic, Limited (GIB). +// Copyright (C) 2020-2024 Intergalactic, Limited (GIB). // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,7 +18,7 @@ //! Autogenerated weights for `pallet_evm_accounts` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-02-13, STEPS: `10`, REPEAT: `30`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-02-21, STEPS: `10`, REPEAT: `30`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `bench-bot`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: 1024 @@ -54,8 +54,8 @@ use pallet_evm_accounts::weights::WeightInfo; pub struct HydraWeight(PhantomData); impl WeightInfo for HydraWeight { - /// Storage: `EVMAccounts::BoundAccount` (r:1 w:1) - /// Proof: `EVMAccounts::BoundAccount` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `EVMAccounts::AccountExtension` (r:1 w:1) + /// Proof: `EVMAccounts::AccountExtension` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::NextAssetId` (r:1 w:0) @@ -68,18 +68,39 @@ impl WeightInfo for HydraWeight { // Proof Size summary in bytes: // Measured: `479` // Estimated: `4087` - // Minimum execution time: 35_419_000 picoseconds. - Weight::from_parts(35_955_000, 4087) + // Minimum execution time: 36_357_000 picoseconds. + Weight::from_parts(36_601_000, 4087) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `EVMAccounts::ContractDeployer` (r:0 w:1) + /// Proof: `EVMAccounts::ContractDeployer` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn add_contract_deployer() -> Weight { - Weight::zero() + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_157_000 picoseconds. + Weight::from_parts(13_481_000, 0) + .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `EVMAccounts::ContractDeployer` (r:0 w:1) + /// Proof: `EVMAccounts::ContractDeployer` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn remove_contract_deployer() -> Weight { - Weight::zero() + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_196_000 picoseconds. + Weight::from_parts(13_517_000, 0) + .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `EVMAccounts::ContractDeployer` (r:0 w:1) + /// Proof: `EVMAccounts::ContractDeployer` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn renounce_contract_deployer() -> Weight { - Weight::zero() + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_153_000 picoseconds. + Weight::from_parts(13_380_000, 0) + .saturating_add(T::DbWeight::get().writes(1)) } } From 2e21eb98d7240124e77cd0fa5c8d3ed769a4a5f7 Mon Sep 17 00:00:00 2001 From: Roznovjak Date: Wed, 21 Feb 2024 15:30:49 +0100 Subject: [PATCH 3/3] bump runtime version --- Cargo.lock | 2 +- runtime/hydradx/Cargo.toml | 2 +- runtime/hydradx/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 50b6bb0bc..e932c7e30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4619,7 +4619,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "210.0.0" +version = "211.0.0" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index 9e6e872d6..e7f31a8dc 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-runtime" -version = "210.0.0" +version = "211.0.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index 895ffc263..de1957c81 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -107,7 +107,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("hydradx"), impl_name: create_runtime_str!("hydradx"), authoring_version: 1, - spec_version: 210, + spec_version: 211, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1,