feat: add preimage precompile (#211)

## Add Preimage Precompile

This PR integrates the Preimage precompile from Moonbeam into the
DataHaven runtime across all three environments (mainnet, stagenet,
testnet).

**Key Changes:**
- Added Preimage precompile implementation at address `2067` in all
runtime configurations
- Updated precompile sets in mainnet, stagenet, and testnet runtimes
- Updated `is_governance_precompile()` for the Preimage precompile
This commit is contained in:
Gonza Montiel 2025-10-09 13:16:46 +02:00 committed by GitHub
parent 0988ce46d0
commit 2d6056721a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 1228 additions and 588 deletions

1259
operator/Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -40,6 +40,7 @@ pallet-evm-precompile-conviction-voting = { path = "./precompiles/conviction-vot
pallet-evm-precompile-identity = { path = "./precompiles/identity", default-features = false }
pallet-evm-precompile-proxy = { path = "./precompiles/proxy", default-features = false }
pallet-evm-precompile-registry = { path = "./precompiles/precompile-registry", default-features = false }
pallet-evm-precompile-preimage = { path = "./precompiles/preimage", default-features = false }
# Crates.io (wasm)
alloy-core = { version = "0.8.15", default-features = false }

View file

@ -0,0 +1,48 @@
[package]
name = "pallet-evm-precompile-preimage"
authors = { workspace = true }
description = "A Precompile to make pallet-preimage calls encoding accessible to pallet-evm"
edition = "2021"
version = "0.1.0"
[dependencies]
# Substrate
frame-support = { workspace = true }
frame-system = { workspace = true }
pallet-preimage = { workspace = true }
parity-scale-codec = { workspace = true, features = ["derive"] }
sp-core = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }
# Frontier
fp-evm = { workspace = true }
pallet-evm = { workspace = true, features = ["forbid-evm-reentrancy"] }
precompile-utils = { workspace = true }
[dev-dependencies]
# Moonbeam
precompile-utils = { workspace = true, features = ["std", "testing"] }
# Substrate
pallet-balances = { workspace = true, features = ["insecure_zero_ed", "std"] }
pallet-timestamp = { workspace = true, features = ["std"] }
scale-info = { workspace = true, features = ["derive", "std"] }
sp-io = { workspace = true }
[features]
default = ["std"]
std = [
"fp-evm/std",
"frame-support/std",
"frame-system/std",
"pallet-evm/std",
"pallet-preimage/std",
"parity-scale-codec/std",
"parity-scale-codec/std",
"precompile-utils/std",
"sp-runtime/std",
"sp-std/std",
]

View file

@ -0,0 +1,37 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.3;
/// @dev The Preimage contract's address.
address constant PREIMAGE_ADDRESS = 0x0000000000000000000000000000000000000813;
/// @dev The Preimage contract's instance.
Preimage constant PREIMAGE_CONTRACT = Preimage(PREIMAGE_ADDRESS);
/// @author The Moonbeam Team
/// @title Pallet Preimage Interface
/// @title The interface through which solidity contracts will interact with the Preimage pallet
/// @custom:address 0x0000000000000000000000000000000000000813
interface Preimage {
/// @dev Register a Preimage on-chain.
/// @custom:selector cb00f603
/// @param encodedProposal The preimage to be registered on-chain
/// @return preimageHash The hash of the preimage
function notePreimage(bytes memory encodedProposal)
external
returns (bytes32 preimageHash);
/// @dev Clear an unrequested preimage from storage.
/// @custom:selector 02e71b45
/// @param hash The preimage to be cleared from storage
function unnotePreimage(bytes32 hash) external;
/// @dev A Preimage was registered on-chain.
/// @custom:selector 8cb56a8ebdafbb14e25ec706da62a7dde761968dbf1fb45be207d1b15c88c187
/// @param hash bytes32 The computed hash.
event PreimageNoted(bytes32 hash);
/// @dev A Preimage was un-registered on-chain.
/// @custom:selector be6cb9502cce812b6de50cc08f2481900ff6c7c6466df7d39c9f27a5f2b9c572
/// @param hash bytes32 The target preimage hash.
event PreimageUnnoted(bytes32 hash);
}

View file

@ -0,0 +1,113 @@
// Copyright 2019-2025 PureStake Inc.
// This file is part of Moonbeam.
// Moonbeam 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.
// Moonbeam 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 Moonbeam. If not, see <http://www.gnu.org/licenses/>.
#![cfg_attr(not(feature = "std"), no_std)]
use fp_evm::PrecompileHandle;
use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo};
use frame_support::traits::ConstU32;
use pallet_evm::AddressMapping;
use pallet_preimage::Call as PreimageCall;
use precompile_utils::prelude::*;
use sp_core::{Hasher, H256};
use sp_runtime::traits::Dispatchable;
use sp_std::{marker::PhantomData, vec::Vec};
#[cfg(test)]
mod mock;
#[cfg(test)]
mod tests;
pub const ENCODED_PROPOSAL_SIZE_LIMIT: u32 = 2u32.pow(16);
type GetEncodedProposalSizeLimit = ConstU32<ENCODED_PROPOSAL_SIZE_LIMIT>;
/// Solidity selector of the PreimageNoted log, which is the Keccak of the Log signature.
pub(crate) const SELECTOR_LOG_PREIMAGE_NOTED: [u8; 32] = keccak256!("PreimageNoted(bytes32)");
/// Solidity selector of the PreimageUnnoted log, which is the Keccak of the Log signature.
pub(crate) const SELECTOR_LOG_PREIMAGE_UNNOTED: [u8; 32] = keccak256!("PreimageUnnoted(bytes32)");
/// A precompile to wrap the functionality from pallet-preimage.
pub struct PreimagePrecompile<Runtime>(PhantomData<Runtime>);
#[precompile_utils::precompile]
impl<Runtime> PreimagePrecompile<Runtime>
where
Runtime: pallet_preimage::Config + pallet_evm::Config + frame_system::Config,
<Runtime as frame_system::Config>::Hash: TryFrom<H256> + Into<H256>,
<Runtime as frame_system::Config>::RuntimeCall:
Dispatchable<PostInfo = PostDispatchInfo> + GetDispatchInfo,
<<Runtime as frame_system::Config>::RuntimeCall as Dispatchable>::RuntimeOrigin:
From<Option<Runtime::AccountId>>,
<Runtime as frame_system::Config>::Hash: Into<H256>,
<Runtime as frame_system::Config>::RuntimeCall: From<PreimageCall<Runtime>>,
<Runtime as pallet_evm::Config>::AddressMapping: AddressMapping<Runtime::AccountId>,
{
/// Register a preimage on-chain.
///
/// Parameters:
/// * encoded_proposal: The preimage registered on-chain
#[precompile::public("notePreimage(bytes)")]
fn note_preimage(
handle: &mut impl PrecompileHandle,
encoded_proposal: BoundedBytes<GetEncodedProposalSizeLimit>,
) -> EvmResult<H256> {
let bytes: Vec<u8> = encoded_proposal.into();
let hash: H256 = Runtime::Hashing::hash(&bytes).into();
let event = log1(
handle.context().address,
SELECTOR_LOG_PREIMAGE_NOTED,
solidity::encode_arguments(H256::from(hash)),
);
handle.record_log_costs(&[&event])?;
let origin = Runtime::AddressMapping::into_account_id(handle.context().caller);
let call = PreimageCall::<Runtime>::note_preimage { bytes }.into();
<RuntimeHelper<Runtime>>::try_dispatch(handle, Some(origin).into(), call, 0)?;
event.record(handle)?;
Ok(hash)
}
/// Clear an unrequested preimage from the runtime storage.
///
/// Parameters:
/// * hash: The preimage cleared from storage
#[precompile::public("unnotePreimage(bytes32)")]
fn unnote_preimage(handle: &mut impl PrecompileHandle, hash: H256) -> EvmResult {
let event = log1(
handle.context().address,
SELECTOR_LOG_PREIMAGE_UNNOTED,
solidity::encode_arguments(H256::from(hash)),
);
handle.record_log_costs(&[&event])?;
let hash: Runtime::Hash = hash
.try_into()
.map_err(|_| RevertReason::custom("H256 is Runtime::Hash").in_field("hash"))?;
let origin = Runtime::AddressMapping::into_account_id(handle.context().caller);
let call = PreimageCall::<Runtime>::unnote_preimage { hash }.into();
<RuntimeHelper<Runtime>>::try_dispatch(handle, Some(origin).into(), call, 0)?;
event.record(handle)?;
Ok(())
}
}

View file

@ -0,0 +1,209 @@
// Copyright 2019-2025 PureStake Inc.
// This file is part of Moonbeam.
// Moonbeam 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.
// Moonbeam 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 Moonbeam. If not, see <http://www.gnu.org/licenses/>.
//! Test utilities
use super::*;
use frame_support::{construct_runtime, parameter_types, traits::Everything, weights::Weight};
use frame_system::EnsureRoot;
use pallet_evm::{EnsureAddressNever, EnsureAddressRoot, FrameSystemAccountProvider};
use precompile_utils::{precompile_set::*, testing::MockAccount};
use sp_core::{H256, U256};
use sp_runtime::{
traits::{BlakeTwo256, IdentityLookup},
BuildStorage, Perbill,
};
pub type AccountId = MockAccount;
pub type Balance = u128;
type Block = frame_system::mocking::MockBlockU32<Runtime>;
construct_runtime!(
pub enum Runtime {
System: frame_system,
Balances: pallet_balances,
Evm: pallet_evm,
Timestamp: pallet_timestamp,
Preimage: pallet_preimage,
}
);
parameter_types! {
pub const BlockHashCount: u32 = 250;
pub const MaximumBlockWeight: Weight = Weight::from_parts(1024, 1);
pub const MaximumBlockLength: u32 = 2 * 1024;
pub const AvailableBlockRatio: Perbill = Perbill::one();
pub const SS58Prefix: u8 = 42;
}
impl frame_system::Config for Runtime {
type BaseCallFilter = Everything;
type DbWeight = ();
type RuntimeOrigin = RuntimeOrigin;
type RuntimeTask = RuntimeTask;
type Nonce = u64;
type Block = Block;
type RuntimeCall = RuntimeCall;
type Hash = H256;
type Hashing = BlakeTwo256;
type AccountId = AccountId;
type Lookup = IdentityLookup<AccountId>;
type RuntimeEvent = RuntimeEvent;
type BlockHashCount = BlockHashCount;
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = pallet_balances::AccountData<Balance>;
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type BlockWeights = ();
type BlockLength = ();
type SS58Prefix = SS58Prefix;
type OnSetCode = ();
type MaxConsumers = frame_support::traits::ConstU32<16>;
type SingleBlockMigrations = ();
type MultiBlockMigrator = ();
type PreInherents = ();
type PostInherents = ();
type PostTransactions = ();
type ExtensionsWeightInfo = ();
}
parameter_types! {
pub const ExistentialDeposit: u128 = 0;
}
impl pallet_balances::Config for Runtime {
type MaxReserves = ();
type ReserveIdentifier = [u8; 4];
type MaxLocks = ();
type Balance = Balance;
type RuntimeEvent = RuntimeEvent;
type DustRemoval = ();
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type WeightInfo = ();
type RuntimeHoldReason = ();
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeFreezeReason = ();
type DoneSlashHandler = ();
}
const MAX_POV_SIZE: u64 = 5 * 1024 * 1024;
/// Block storage limit in bytes. Set to 40 KB.
const BLOCK_STORAGE_LIMIT: u64 = 40 * 1024;
parameter_types! {
pub BlockGasLimit: U256 = U256::from(u64::MAX);
pub PrecompilesValue: Precompiles<Runtime> = Precompiles::new();
pub const WeightPerGas: Weight = Weight::from_parts(1, 0);
pub GasLimitPovSizeRatio: u64 = {
let block_gas_limit = BlockGasLimit::get().min(u64::MAX.into()).low_u64();
block_gas_limit.saturating_div(MAX_POV_SIZE)
};
pub GasLimitStorageGrowthRatio: u64 = {
let block_gas_limit = BlockGasLimit::get().min(u64::MAX.into()).low_u64();
block_gas_limit.saturating_div(BLOCK_STORAGE_LIMIT)
};
}
pub type Precompiles<R> =
PrecompileSetBuilder<R, (PrecompileAt<AddressU64<1>, PreimagePrecompile<R>>,)>;
pub type PCall = PreimagePrecompileCall<Runtime>;
impl pallet_evm::Config for Runtime {
type FeeCalculator = ();
type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
type WeightPerGas = WeightPerGas;
type CallOrigin = EnsureAddressRoot<AccountId>;
type WithdrawOrigin = EnsureAddressNever<AccountId>;
type AddressMapping = AccountId;
type Currency = Balances;
type RuntimeEvent = RuntimeEvent;
type Runner = pallet_evm::runner::stack::Runner<Self>;
type PrecompilesType = Precompiles<Runtime>;
type PrecompilesValue = PrecompilesValue;
type ChainId = ();
type OnChargeTransaction = ();
type BlockGasLimit = BlockGasLimit;
type BlockHashMapping = pallet_evm::SubstrateBlockHashMapping<Self>;
type FindAuthor = ();
type OnCreate = ();
type GasLimitPovSizeRatio = GasLimitPovSizeRatio;
type GasLimitStorageGrowthRatio = GasLimitStorageGrowthRatio;
type Timestamp = Timestamp;
type WeightInfo = pallet_evm::weights::SubstrateWeight<Runtime>;
type AccountProvider = FrameSystemAccountProvider<Runtime>;
}
parameter_types! {
pub const MinimumPeriod: u64 = 5;
}
impl pallet_timestamp::Config for Runtime {
type Moment = u64;
type OnTimestampSet = ();
type MinimumPeriod = MinimumPeriod;
type WeightInfo = ();
}
impl pallet_preimage::Config for Runtime {
type WeightInfo = ();
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type ManagerOrigin = EnsureRoot<AccountId>;
type Consideration = ();
}
pub(crate) struct ExtBuilder {
// endowed accounts with balances
balances: Vec<(AccountId, Balance)>,
}
impl Default for ExtBuilder {
fn default() -> ExtBuilder {
ExtBuilder { balances: vec![] }
}
}
impl ExtBuilder {
pub(crate) fn with_balances(mut self, balances: Vec<(AccountId, Balance)>) -> Self {
self.balances = balances;
self
}
pub(crate) fn build(self) -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::<Runtime>::default()
.build_storage()
.expect("Frame system builds valid default genesis config");
pallet_balances::GenesisConfig::<Runtime> {
balances: self.balances,
}
.assimilate_storage(&mut t)
.expect("Pallet balances storage can be assimilated");
let mut ext = sp_io::TestExternalities::new(t);
ext.execute_with(|| System::set_block_number(1));
ext
}
}
pub(crate) fn events() -> Vec<RuntimeEvent> {
System::events()
.into_iter()
.map(|r| r.event)
.collect::<Vec<_>>()
}

View file

@ -0,0 +1,122 @@
// Copyright 2019-2025 PureStake Inc.
// This file is part of Moonbeam.
// Moonbeam 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.
// Moonbeam 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 Moonbeam. If not, see <http://www.gnu.org/licenses/>.
use crate::mock::*;
use crate::*;
use precompile_utils::testing::*;
use frame_support::assert_ok;
use pallet_evm::{Call as EvmCall, Event as EvmEvent};
use sp_core::{Hasher, U256};
use sp_runtime::traits::Dispatchable;
fn evm_call(input: Vec<u8>) -> EvmCall<Runtime> {
EvmCall::call {
source: Alice.into(),
target: Precompile1.into(),
input,
value: U256::zero(),
gas_limit: u64::max_value(),
max_fee_per_gas: 0.into(),
max_priority_fee_per_gas: Some(U256::zero()),
nonce: None,
access_list: Vec::new(),
}
}
fn precompiles() -> Precompiles<Runtime> {
PrecompilesValue::get()
}
#[test]
fn test_solidity_interface_has_all_function_selectors_documented_and_implemented() {
check_precompile_implements_solidity_interfaces(&["Preimage.sol"], PCall::supports_selector)
}
#[test]
fn note_unnote_preimage_logs_work() {
ExtBuilder::default()
.with_balances(vec![(Alice.into(), 100_000)])
.build()
.execute_with(|| {
let bytes = vec![1, 2, 3];
let expected_hash = sp_runtime::traits::BlakeTwo256::hash(&bytes);
// Note preimage
let input = PCall::note_preimage {
encoded_proposal: bytes.into(),
}
.into();
assert_ok!(RuntimeCall::Evm(evm_call(input)).dispatch(RuntimeOrigin::root()));
// Assert note preimage event is emitted and matching frame event preimage hash.
assert!(vec![
EvmEvent::Log {
log: log1(
Precompile1,
SELECTOR_LOG_PREIMAGE_NOTED,
solidity::encode_event_data(expected_hash)
),
}
.into(),
RuntimeEvent::Preimage(pallet_preimage::pallet::Event::Noted {
hash: expected_hash
})
]
.iter()
.all(|log| events().contains(log)));
// Unnote preimage
let input = PCall::unnote_preimage {
hash: expected_hash,
}
.into();
assert_ok!(RuntimeCall::Evm(evm_call(input)).dispatch(RuntimeOrigin::root()));
// Assert unnote preimage is emitted
assert!(events().contains(
&EvmEvent::Log {
log: log1(
Precompile1,
SELECTOR_LOG_PREIMAGE_UNNOTED,
solidity::encode_event_data(expected_hash)
),
}
.into()
));
})
}
#[test]
fn note_preimage_returns_preimage_hash() {
ExtBuilder::default()
.with_balances(vec![(Alice.into(), 40)])
.build()
.execute_with(|| {
let preimage = [1u8; 32];
let preimage_hash = <mock::Runtime as frame_system::Config>::Hashing::hash(&preimage);
precompiles()
.prepare_test(
Alice,
Precompile1,
PCall::note_preimage {
encoded_proposal: BoundedBytes::from(preimage),
},
)
.execute_returns(preimage_hash);
})
}

View file

@ -129,6 +129,7 @@ pallet-evm-precompile-call-permit = { workspace = true }
pallet-evm-precompile-collective = { workspace = true }
pallet-evm-precompile-conviction-voting = { workspace = true }
pallet-evm-precompile-identity = { workspace = true }
pallet-evm-precompile-preimage = { workspace = true }
pallet-evm-precompile-proxy = { workspace = true }
pallet-evm-precompile-registry = { workspace = true }
@ -201,6 +202,7 @@ std = [
"pallet-evm-precompile-balances-erc20/std",
"pallet-evm-precompile-batch/std",
"pallet-evm-precompile-call-permit/std",
"pallet-evm-precompile-preimage/std",
"pallet-evm-precompile-collective/std",
"pallet-evm-precompile-conviction-voting/std",
"pallet-evm-precompile-identity/std",

View file

@ -745,6 +745,7 @@ fn is_governance_precompile(precompile_name: &PrecompileName) -> bool {
PrecompileName::ConvictionVotingPrecompile
| PrecompileName::TechnicalCommitteeInstance
| PrecompileName::TreasuryCouncilInstance
| PrecompileName::PreimagePrecompile
)
}

View file

@ -26,6 +26,7 @@ use pallet_evm_precompile_conviction_voting::ConvictionVotingPrecompile;
use pallet_evm_precompile_file_system::FileSystemPrecompile;
use pallet_evm_precompile_identity::IdentityPrecompile;
use pallet_evm_precompile_modexp::Modexp;
use pallet_evm_precompile_preimage::PreimagePrecompile;
use pallet_evm_precompile_proxy::{OnlyIsProxyAndProxy, ProxyPrecompile};
use pallet_evm_precompile_registry::PrecompileRegistry;
use pallet_evm_precompile_sha3fips::Sha3FIPS256;
@ -113,6 +114,11 @@ type DataHavenPrecompilesAt<R> = (
ConvictionVotingPrecompile<R>,
(CallableByContract, CallableByPrecompile),
>,
PrecompileAt<
AddressU64<2067>,
PreimagePrecompile<R>,
(CallableByContract, CallableByPrecompile),
>,
PrecompileAt<
AddressU64<2068>,
CollectivePrecompile<R, TechnicalCommitteeInstance>,

View file

@ -126,6 +126,7 @@ xcm-executor = { workspace = true }
pallet-evm-precompile-balances-erc20 = { workspace = true }
pallet-evm-precompile-batch = { workspace = true }
pallet-evm-precompile-call-permit = { workspace = true }
pallet-evm-precompile-preimage = { workspace = true }
pallet-evm-precompile-collective = { workspace = true }
pallet-evm-precompile-conviction-voting = { workspace = true }
pallet-evm-precompile-identity = { workspace = true }
@ -201,6 +202,7 @@ std = [
"pallet-evm-precompile-balances-erc20/std",
"pallet-evm-precompile-batch/std",
"pallet-evm-precompile-call-permit/std",
"pallet-evm-precompile-preimage/std",
"pallet-evm-precompile-collective/std",
"pallet-evm-precompile-conviction-voting/std",
"pallet-evm-precompile-identity/std",

View file

@ -744,6 +744,7 @@ fn is_governance_precompile(precompile_name: &PrecompileName) -> bool {
PrecompileName::ConvictionVotingPrecompile
| PrecompileName::TechnicalCommitteeInstance
| PrecompileName::TreasuryCouncilInstance
| PrecompileName::PreimagePrecompile
)
}

View file

@ -26,6 +26,7 @@ use pallet_evm_precompile_conviction_voting::ConvictionVotingPrecompile;
use pallet_evm_precompile_file_system::FileSystemPrecompile;
use pallet_evm_precompile_identity::IdentityPrecompile;
use pallet_evm_precompile_modexp::Modexp;
use pallet_evm_precompile_preimage::PreimagePrecompile;
use pallet_evm_precompile_proxy::{OnlyIsProxyAndProxy, ProxyPrecompile};
use pallet_evm_precompile_registry::PrecompileRegistry;
use pallet_evm_precompile_sha3fips::Sha3FIPS256;
@ -113,6 +114,11 @@ type DataHavenPrecompilesAt<R> = (
ConvictionVotingPrecompile<R>,
(CallableByContract, CallableByPrecompile),
>,
PrecompileAt<
AddressU64<2067>,
PreimagePrecompile<R>,
(CallableByContract, CallableByPrecompile),
>,
PrecompileAt<
AddressU64<2068>,
CollectivePrecompile<R, TechnicalCommitteeInstance>,

View file

@ -127,6 +127,7 @@ strum_macros = { workspace = true }
pallet-evm-precompile-balances-erc20 = { workspace = true }
pallet-evm-precompile-batch = { workspace = true }
pallet-evm-precompile-call-permit = { workspace = true }
pallet-evm-precompile-preimage = { workspace = true }
pallet-evm-precompile-collective = { workspace = true }
pallet-evm-precompile-identity = { workspace = true }
pallet-evm-precompile-proxy = { workspace = true }
@ -201,6 +202,7 @@ std = [
"pallet-evm-precompile-balances-erc20/std",
"pallet-evm-precompile-batch/std",
"pallet-evm-precompile-call-permit/std",
"pallet-evm-precompile-preimage/std",
"pallet-evm-precompile-collective/std",
"pallet-evm-precompile-conviction-voting/std",
"pallet-evm-precompile-identity/std",

View file

@ -744,6 +744,7 @@ fn is_governance_precompile(precompile_name: &PrecompileName) -> bool {
PrecompileName::ConvictionVotingPrecompile
| PrecompileName::TechnicalCommitteeInstance
| PrecompileName::TreasuryCouncilInstance
| PrecompileName::PreimagePrecompile
)
}

View file

@ -26,6 +26,7 @@ use pallet_evm_precompile_conviction_voting::ConvictionVotingPrecompile;
use pallet_evm_precompile_file_system::FileSystemPrecompile;
use pallet_evm_precompile_identity::IdentityPrecompile;
use pallet_evm_precompile_modexp::Modexp;
use pallet_evm_precompile_preimage::PreimagePrecompile;
use pallet_evm_precompile_proxy::{OnlyIsProxyAndProxy, ProxyPrecompile};
use pallet_evm_precompile_registry::PrecompileRegistry;
use pallet_evm_precompile_sha3fips::Sha3FIPS256;
@ -113,6 +114,11 @@ type DataHavenPrecompilesAt<R> = (
ConvictionVotingPrecompile<R>,
(CallableByContract, CallableByPrecompile),
>,
PrecompileAt<
AddressU64<2067>,
PreimagePrecompile<R>,
(CallableByContract, CallableByPrecompile),
>,
PrecompileAt<
AddressU64<2068>,
CollectivePrecompile<R, TechnicalCommitteeInstance>,