fix: 🔧 Initialize dummy revert bytecode at precompile addresses in genesis presets (#199)

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.
This commit is contained in:
Steve Degosserie 2025-10-01 17:14:14 +02:00 committed by GitHub
parent d2ff687dc0
commit 83e036e47f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 99 additions and 12 deletions

View file

@ -923,10 +923,12 @@ where
datahaven_runtime_common::impl_on_charge_evm_transaction!();
pub type Precompiles = DataHavenPrecompiles<Runtime>;
parameter_types! {
pub BlockGasLimit: U256
= U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS);
pub PrecompilesValue: DataHavenPrecompiles<Runtime> = DataHavenPrecompiles::<_>::new();
pub PrecompilesValue: Precompiles = DataHavenPrecompiles::<Runtime>::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<Self>;
type PrecompilesType = Precompiles;
type PrecompilesValue = PrecompilesValue;
type ChainId = EvmChainId;
type BlockGasLimit = BlockGasLimit;

View file

@ -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<AccountId>,
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()

View file

@ -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;

View file

@ -922,10 +922,12 @@ where
datahaven_runtime_common::impl_on_charge_evm_transaction!();
pub type Precompiles = DataHavenPrecompiles<Runtime>;
parameter_types! {
pub BlockGasLimit: U256
= U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS);
pub PrecompilesValue: DataHavenPrecompiles<Runtime> = DataHavenPrecompiles::<_>::new();
pub PrecompilesValue: Precompiles = DataHavenPrecompiles::<Runtime>::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<Self>;
type PrecompilesType = Precompiles;
type PrecompilesValue = PrecompilesValue;
type ChainId = EvmChainId;
type BlockGasLimit = BlockGasLimit;

View file

@ -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<AccountId>,
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()

View file

@ -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;

View file

@ -922,10 +922,12 @@ where
datahaven_runtime_common::impl_on_charge_evm_transaction!();
pub type Precompiles = DataHavenPrecompiles<Runtime>;
parameter_types! {
pub BlockGasLimit: U256
= U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS);
pub PrecompilesValue: DataHavenPrecompiles<Runtime> = DataHavenPrecompiles::<_>::new();
pub PrecompilesValue: Precompiles = DataHavenPrecompiles::<Runtime>::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<Self>;
type PrecompilesType = Precompiles;
type PrecompilesValue = PrecompilesValue;
type ChainId = EvmChainId;
type BlockGasLimit = BlockGasLimit;

View file

@ -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<AccountId>,
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()

View file

@ -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;