From 83e036e47fb033d44fc075652b2c659ae1b15f54 Mon Sep 17 00:00:00 2001 From: Steve Degosserie <723552+stiiifff@users.noreply.github.com> Date: Wed, 1 Oct 2025 17:14:14 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=94=A7=20Initialize=20dummy=20reve?= =?UTF-8?q?rt=20bytecode=20at=20precompile=20addresses=20in=20genesis=20pr?= =?UTF-8?q?esets=20(#199)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To ensure that the runtime precompiles they can be called from within contracts, there must be some code deployed at the precompile address. This PR ensure the simplest bytecode (which reverts) is deployed at genesis time for all addresses of precompiles present in the runtime. --- operator/runtime/mainnet/src/configs/mod.rs | 6 ++-- .../mainnet/src/genesis_config_presets.rs | 30 +++++++++++++++++-- operator/runtime/mainnet/src/lib.rs | 1 + operator/runtime/stagenet/src/configs/mod.rs | 6 ++-- .../stagenet/src/genesis_config_presets.rs | 30 +++++++++++++++++-- operator/runtime/stagenet/src/lib.rs | 1 + operator/runtime/testnet/src/configs/mod.rs | 6 ++-- .../testnet/src/genesis_config_presets.rs | 30 +++++++++++++++++-- operator/runtime/testnet/src/lib.rs | 1 + 9 files changed, 99 insertions(+), 12 deletions(-) diff --git a/operator/runtime/mainnet/src/configs/mod.rs b/operator/runtime/mainnet/src/configs/mod.rs index ebe0eafe..11edcc24 100644 --- a/operator/runtime/mainnet/src/configs/mod.rs +++ b/operator/runtime/mainnet/src/configs/mod.rs @@ -923,10 +923,12 @@ where datahaven_runtime_common::impl_on_charge_evm_transaction!(); +pub type Precompiles = DataHavenPrecompiles; + parameter_types! { pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS); - pub PrecompilesValue: DataHavenPrecompiles = DataHavenPrecompiles::<_>::new(); + pub PrecompilesValue: Precompiles = DataHavenPrecompiles::::new(); pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0); pub SuicideQuickClearLimit: u32 = 0; /// The amount of gas per pov. A ratio of 16 if we convert ref_time to gas and we compare @@ -952,7 +954,7 @@ impl pallet_evm::Config for Runtime { type AddressMapping = IdentityAddressMapping; type Currency = Balances; type RuntimeEvent = RuntimeEvent; - type PrecompilesType = DataHavenPrecompiles; + type PrecompilesType = Precompiles; type PrecompilesValue = PrecompilesValue; type ChainId = EvmChainId; type BlockGasLimit = BlockGasLimit; diff --git a/operator/runtime/mainnet/src/genesis_config_presets.rs b/operator/runtime/mainnet/src/genesis_config_presets.rs index e4e8f98a..0552a536 100644 --- a/operator/runtime/mainnet/src/genesis_config_presets.rs +++ b/operator/runtime/mainnet/src/genesis_config_presets.rs @@ -1,8 +1,10 @@ use crate::{ - configs::BABE_GENESIS_EPOCH_CONFIG, AccountId, BalancesConfig, RuntimeGenesisConfig, - SessionKeys, Signature, SudoConfig, TechnicalCommitteeConfig, TreasuryCouncilConfig, + configs::BABE_GENESIS_EPOCH_CONFIG, AccountId, BalancesConfig, EvmConfig, Precompiles, + RuntimeGenesisConfig, SessionKeys, Signature, SudoConfig, TechnicalCommitteeConfig, + TreasuryCouncilConfig, }; use alloc::{format, vec, vec::Vec}; +use fp_evm::GenesisAccount; use hex_literal::hex; use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use serde_json::Value; @@ -24,6 +26,12 @@ fn testnet_genesis( technical_committee_members: Vec, evm_chain_id: u64, ) -> Value { + // This is the simplest bytecode to revert without returning any data. + // We will pre-deploy it under all of our precompiles to ensure they can be called from + // within contracts. + // (PUSH1 0x00 PUSH1 0x00 REVERT) + let revert_bytecode = vec![0x60, 0x00, 0x60, 0x00, 0xFD]; + let config = RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts @@ -36,6 +44,24 @@ fn testnet_genesis( epoch_config: BABE_GENESIS_EPOCH_CONFIG, ..Default::default() }, + evm: EvmConfig { + // We need _some_ code inserted at the precompile address so that + // the evm will actually call the address. + accounts: Precompiles::used_addresses() + .map(|addr| { + ( + addr.into(), + GenesisAccount { + nonce: Default::default(), + balance: Default::default(), + storage: Default::default(), + code: revert_bytecode.clone(), + }, + ) + }) + .collect(), + ..Default::default() + }, evm_chain_id: pallet_evm_chain_id::GenesisConfig { chain_id: evm_chain_id, ..Default::default() diff --git a/operator/runtime/mainnet/src/lib.rs b/operator/runtime/mainnet/src/lib.rs index a48f440d..954238e5 100644 --- a/operator/runtime/mainnet/src/lib.rs +++ b/operator/runtime/mainnet/src/lib.rs @@ -14,6 +14,7 @@ pub mod weights; // Re-export governance for tests pub use configs::governance; +pub use configs::Precompiles; use alloc::{borrow::Cow, vec::Vec}; use codec::Encode; diff --git a/operator/runtime/stagenet/src/configs/mod.rs b/operator/runtime/stagenet/src/configs/mod.rs index b4c87aa2..6df2639f 100644 --- a/operator/runtime/stagenet/src/configs/mod.rs +++ b/operator/runtime/stagenet/src/configs/mod.rs @@ -922,10 +922,12 @@ where datahaven_runtime_common::impl_on_charge_evm_transaction!(); +pub type Precompiles = DataHavenPrecompiles; + parameter_types! { pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS); - pub PrecompilesValue: DataHavenPrecompiles = DataHavenPrecompiles::<_>::new(); + pub PrecompilesValue: Precompiles = DataHavenPrecompiles::::new(); pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0); pub SuicideQuickClearLimit: u32 = 0; /// The amount of gas per pov. A ratio of 16 if we convert ref_time to gas and we compare @@ -951,7 +953,7 @@ impl pallet_evm::Config for Runtime { type AddressMapping = IdentityAddressMapping; type Currency = Balances; type RuntimeEvent = RuntimeEvent; - type PrecompilesType = DataHavenPrecompiles; + type PrecompilesType = Precompiles; type PrecompilesValue = PrecompilesValue; type ChainId = EvmChainId; type BlockGasLimit = BlockGasLimit; diff --git a/operator/runtime/stagenet/src/genesis_config_presets.rs b/operator/runtime/stagenet/src/genesis_config_presets.rs index 4f26c10d..d739052d 100644 --- a/operator/runtime/stagenet/src/genesis_config_presets.rs +++ b/operator/runtime/stagenet/src/genesis_config_presets.rs @@ -1,8 +1,10 @@ use crate::{ - configs::BABE_GENESIS_EPOCH_CONFIG, AccountId, BalancesConfig, RuntimeGenesisConfig, - SessionKeys, Signature, SudoConfig, TechnicalCommitteeConfig, TreasuryCouncilConfig, + configs::BABE_GENESIS_EPOCH_CONFIG, AccountId, BalancesConfig, EvmConfig, Precompiles, + RuntimeGenesisConfig, SessionKeys, Signature, SudoConfig, TechnicalCommitteeConfig, + TreasuryCouncilConfig, }; use alloc::{format, vec, vec::Vec}; +use fp_evm::GenesisAccount; use hex_literal::hex; use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use serde_json::Value; @@ -24,6 +26,12 @@ fn testnet_genesis( technical_committee_members: Vec, evm_chain_id: u64, ) -> Value { + // This is the simplest bytecode to revert without returning any data. + // We will pre-deploy it under all of our precompiles to ensure they can be called from + // within contracts. + // (PUSH1 0x00 PUSH1 0x00 REVERT) + let revert_bytecode = vec![0x60, 0x00, 0x60, 0x00, 0xFD]; + let config = RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts @@ -36,6 +44,24 @@ fn testnet_genesis( epoch_config: BABE_GENESIS_EPOCH_CONFIG, ..Default::default() }, + evm: EvmConfig { + // We need _some_ code inserted at the precompile address so that + // the evm will actually call the address. + accounts: Precompiles::used_addresses() + .map(|addr| { + ( + addr.into(), + GenesisAccount { + nonce: Default::default(), + balance: Default::default(), + storage: Default::default(), + code: revert_bytecode.clone(), + }, + ) + }) + .collect(), + ..Default::default() + }, evm_chain_id: pallet_evm_chain_id::GenesisConfig { chain_id: evm_chain_id, ..Default::default() diff --git a/operator/runtime/stagenet/src/lib.rs b/operator/runtime/stagenet/src/lib.rs index f655967c..d536edd9 100644 --- a/operator/runtime/stagenet/src/lib.rs +++ b/operator/runtime/stagenet/src/lib.rs @@ -14,6 +14,7 @@ pub mod weights; // Re-export governance for tests pub use configs::governance; +pub use configs::Precompiles; use alloc::{borrow::Cow, vec::Vec}; use codec::Encode; diff --git a/operator/runtime/testnet/src/configs/mod.rs b/operator/runtime/testnet/src/configs/mod.rs index 7576e645..d3163efa 100644 --- a/operator/runtime/testnet/src/configs/mod.rs +++ b/operator/runtime/testnet/src/configs/mod.rs @@ -922,10 +922,12 @@ where datahaven_runtime_common::impl_on_charge_evm_transaction!(); +pub type Precompiles = DataHavenPrecompiles; + parameter_types! { pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS); - pub PrecompilesValue: DataHavenPrecompiles = DataHavenPrecompiles::<_>::new(); + pub PrecompilesValue: Precompiles = DataHavenPrecompiles::::new(); pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0); pub SuicideQuickClearLimit: u32 = 0; /// The amount of gas per pov. A ratio of 16 if we convert ref_time to gas and we compare @@ -951,7 +953,7 @@ impl pallet_evm::Config for Runtime { type AddressMapping = IdentityAddressMapping; type Currency = Balances; type RuntimeEvent = RuntimeEvent; - type PrecompilesType = DataHavenPrecompiles; + type PrecompilesType = Precompiles; type PrecompilesValue = PrecompilesValue; type ChainId = EvmChainId; type BlockGasLimit = BlockGasLimit; diff --git a/operator/runtime/testnet/src/genesis_config_presets.rs b/operator/runtime/testnet/src/genesis_config_presets.rs index 9f345904..56f0eddb 100644 --- a/operator/runtime/testnet/src/genesis_config_presets.rs +++ b/operator/runtime/testnet/src/genesis_config_presets.rs @@ -1,8 +1,10 @@ use crate::{ - configs::BABE_GENESIS_EPOCH_CONFIG, AccountId, BalancesConfig, RuntimeGenesisConfig, - SessionKeys, Signature, SudoConfig, TechnicalCommitteeConfig, TreasuryCouncilConfig, + configs::BABE_GENESIS_EPOCH_CONFIG, AccountId, BalancesConfig, EvmConfig, Precompiles, + RuntimeGenesisConfig, SessionKeys, Signature, SudoConfig, TechnicalCommitteeConfig, + TreasuryCouncilConfig, }; use alloc::{format, vec, vec::Vec}; +use fp_evm::GenesisAccount; use hex_literal::hex; use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use serde_json::Value; @@ -24,6 +26,12 @@ fn testnet_genesis( technical_committee_members: Vec, evm_chain_id: u64, ) -> Value { + // This is the simplest bytecode to revert without returning any data. + // We will pre-deploy it under all of our precompiles to ensure they can be called from + // within contracts. + // (PUSH1 0x00 PUSH1 0x00 REVERT) + let revert_bytecode = vec![0x60, 0x00, 0x60, 0x00, 0xFD]; + let config = RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts @@ -36,6 +44,24 @@ fn testnet_genesis( epoch_config: BABE_GENESIS_EPOCH_CONFIG, ..Default::default() }, + evm: EvmConfig { + // We need _some_ code inserted at the precompile address so that + // the evm will actually call the address. + accounts: Precompiles::used_addresses() + .map(|addr| { + ( + addr.into(), + GenesisAccount { + nonce: Default::default(), + balance: Default::default(), + storage: Default::default(), + code: revert_bytecode.clone(), + }, + ) + }) + .collect(), + ..Default::default() + }, evm_chain_id: pallet_evm_chain_id::GenesisConfig { chain_id: evm_chain_id, ..Default::default() diff --git a/operator/runtime/testnet/src/lib.rs b/operator/runtime/testnet/src/lib.rs index 780a7508..1e217379 100644 --- a/operator/runtime/testnet/src/lib.rs +++ b/operator/runtime/testnet/src/lib.rs @@ -13,6 +13,7 @@ pub mod precompiles; pub mod weights; // Re-export governance for tests pub use configs::governance; +pub use configs::Precompiles; use alloc::{borrow::Cow, vec::Vec}; use codec::Encode;