Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add evm-chain-id pallet (paritytech#804)
Browse files Browse the repository at this point in the history
* Add evm-chain-id pallet

Signed-off-by: koushiro <koushiro.cqx@gmail.com>

* Add some doc

Signed-off-by: koushiro <koushiro.cqx@gmail.com>
koushiro authored Aug 3, 2022
1 parent efe1866 commit cf0fae7
Showing 7 changed files with 174 additions and 41 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ members = [
"frame/dynamic-fee",
"frame/ethereum",
"frame/evm",
"frame/evm-chain-id",
"frame/hotfix-sufficients",
"frame/evm/precompile/sha3fips",
"frame/evm/precompile/simple",
36 changes: 36 additions & 0 deletions frame/evm-chain-id/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[package]
name = "pallet-evm-chain-id"
version = "1.0.0-dev"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
license = "Apache-2.0"
readme = "README.md"
description = "EVM chain id storage pallet"
repository = "https://github.com/paritytech/frontier/"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
serde = { version = "1.0", features = ["derive"], optional = true }

# Parity
codec = { package = "parity-scale-codec", version = "3.1", default-features = false, features = ["derive"] }
scale-info = { version = "2.1", default-features = false, features = ["derive"] }

# Substrate FRAME
frame-support = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
frame-system = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }

[features]
default = ["std"]
std = [
"serde",
# Parity
"codec/std",
"scale-info/std",
# Substrate FRAME
"frame-support/std",
"frame-system/std",
]
try-runtime = ["frame-support/try-runtime"]
68 changes: 68 additions & 0 deletions frame/evm-chain-id/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-License-Identifier: Apache-2.0
// This file is part of Frontier.
//
// Copyright (c) 2022 Parity Technologies (UK) Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! # EVM chain ID pallet
//!
//! The pallet that stores the numeric Ethereum-style chain id in the runtime.
//! It can simplify setting up multiple networks with different chain ID by configuring the
//! chain spec without requiring changes to the runtime config.
//!
//! **NOTE**: we recommend that the production chains still use the const parameter type, as
//! this extra storage access would imply some performance penalty.
// Ensure we're `no_std` when compiling for Wasm.
#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
use frame_support::pallet_prelude::*;

const STORAGE_VERSION: StorageVersion = StorageVersion::new(0);

#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
pub struct Pallet<T>(PhantomData<T>);

#[pallet::config]
pub trait Config: frame_system::Config {}

impl<T: Config> Get<u64> for Pallet<T> {
fn get() -> u64 {
Self::chain_id()
}
}

/// The EVM chain ID.
#[pallet::storage]
#[pallet::getter(fn chain_id)]
pub type ChainId<T> = StorageValue<_, u64, ValueQuery>;

#[pallet::genesis_config]
#[derive(Default)]
pub struct GenesisConfig {
pub chain_id: u64,
}

#[pallet::genesis_build]
impl<T: Config> GenesisBuild<T> for GenesisConfig {
fn build(&self) {
ChainId::<T>::put(self.chain_id);
}
}
}
48 changes: 30 additions & 18 deletions template/node/src/chain_spec.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use frontier_template_runtime::{AccountId, GenesisConfig, Signature, WASM_BINARY};
use std::{collections::BTreeMap, str::FromStr};

use sc_service::ChainType;
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
use sp_core::{sr25519, Pair, Public, H160, U256};
use sp_finality_grandpa::AuthorityId as GrandpaId;
use sp_runtime::traits::{IdentifyAccount, Verify};
use std::{collections::BTreeMap, str::FromStr};

use frontier_template_runtime::{AccountId, GenesisConfig, Signature, WASM_BINARY};

// The URL for the telemetry server.
// const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
@@ -46,8 +48,6 @@ pub fn development_config() -> Result<ChainSpec, String> {
move || {
testnet_genesis(
wasm_binary,
// Initial PoA authorities
vec![authority_keys_from_seed("Alice")],
// Sudo account
get_account_id_from_seed::<sr25519::Public>("Alice"),
// Pre-funded accounts
@@ -57,7 +57,9 @@ pub fn development_config() -> Result<ChainSpec, String> {
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
],
true,
// Initial PoA authorities
vec![authority_keys_from_seed("Alice")],
42,
)
},
// Bootnodes
@@ -87,10 +89,6 @@ pub fn local_testnet_config() -> Result<ChainSpec, String> {
testnet_genesis(
wasm_binary,
// Initial PoA authorities
vec![
authority_keys_from_seed("Alice"),
authority_keys_from_seed("Bob"),
],
// Sudo account
get_account_id_from_seed::<sr25519::Public>("Alice"),
// Pre-funded accounts
@@ -108,7 +106,11 @@ pub fn local_testnet_config() -> Result<ChainSpec, String> {
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
],
true,
vec![
authority_keys_from_seed("Alice"),
authority_keys_from_seed("Bob"),
],
42,
)
},
// Bootnodes
@@ -128,19 +130,28 @@ pub fn local_testnet_config() -> Result<ChainSpec, String> {
/// Configure initial storage state for FRAME modules.
fn testnet_genesis(
wasm_binary: &[u8],
initial_authorities: Vec<(AuraId, GrandpaId)>,
root_key: AccountId,
sudo_key: AccountId,
endowed_accounts: Vec<AccountId>,
_enable_println: bool,
initial_authorities: Vec<(AuraId, GrandpaId)>,
chain_id: u64,
) -> GenesisConfig {
use frontier_template_runtime::{
AuraConfig, BalancesConfig, EVMConfig, GrandpaConfig, SudoConfig, SystemConfig,
AuraConfig, BalancesConfig, EVMChainIdConfig, EVMConfig, GrandpaConfig, SudoConfig,
SystemConfig,
};

GenesisConfig {
// System
system: SystemConfig {
// Add Wasm runtime to storage.
code: wasm_binary.to_vec(),
},
sudo: SudoConfig {
// Assign network admin rights.
key: Some(sudo_key),
},

// Monetary
balances: BalancesConfig {
// Configure endowed accounts with initial balance of 1 << 60.
balances: endowed_accounts
@@ -150,6 +161,8 @@ fn testnet_genesis(
.collect(),
},
transaction_payment: Default::default(),

// Consensus
aura: AuraConfig {
authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(),
},
@@ -159,10 +172,9 @@ fn testnet_genesis(
.map(|x| (x.1.clone(), 1))
.collect(),
},
sudo: SudoConfig {
// Assign network admin rights.
key: Some(root_key),
},

// EVM compatibility
evm_chain_id: EVMChainIdConfig { chain_id },
evm: EVMConfig {
accounts: {
let mut map = BTreeMap::new();
2 changes: 2 additions & 0 deletions template/runtime/Cargo.toml
Original file line number Diff line number Diff line change
@@ -55,6 +55,7 @@ pallet-base-fee = { path = "../../frame/base-fee", default-features = false }
pallet-dynamic-fee = { path = "../../frame/dynamic-fee", default-features = false }
pallet-ethereum = { path = "../../frame/ethereum", default-features = false }
pallet-evm = { path = "../../frame/evm", default-features = false }
pallet-evm-chain-id = { path = "../../frame/evm-chain-id", default-features = false }
pallet-evm-precompile-modexp = { path = "../../frame/evm/precompile/modexp", default-features = false }
pallet-evm-precompile-sha3fips = { path = "../../frame/evm/precompile/sha3fips", default-features = false }
pallet-evm-precompile-simple = { path = "../../frame/evm/precompile/simple", default-features = false }
@@ -108,6 +109,7 @@ std = [
"pallet-dynamic-fee/std",
"pallet-ethereum/std",
"pallet-evm/std",
"pallet-evm-chain-id/std",
"pallet-evm-precompile-modexp/std",
"pallet-evm-precompile-sha3fips/std",
"pallet-evm-precompile-simple/std",
48 changes: 25 additions & 23 deletions template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ use sp_core::{
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
traits::{
AccountIdLookup, BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable,
AccountIdLookup, BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable, Get,
IdentifyAccount, NumberFor, PostDispatchInfoOf, UniqueSaturatedInto, Verify,
},
transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError},
@@ -168,12 +168,10 @@ impl frame_system::Config for Runtime {
type BlockWeights = BlockWeights;
/// The maximum length of a block (in bytes).
type BlockLength = BlockLength;
/// The identifier used to distinguish between accounts.
type AccountId = AccountId;
/// The ubiquitous origin type.
type Origin = Origin;
/// The aggregated dispatch type that is available for extrinsics.
type Call = Call;
/// The lookup mechanism to get account ID from whatever is passed in dispatchers.
type Lookup = AccountIdLookup<AccountId, ()>;
/// The index type for storing how many extrinsics an account has signed.
type Index = Index;
/// The index type for blocks.
@@ -182,12 +180,14 @@ impl frame_system::Config for Runtime {
type Hash = Hash;
/// The hashing algorithm used.
type Hashing = BlakeTwo256;
/// The identifier used to distinguish between accounts.
type AccountId = AccountId;
/// The lookup mechanism to get account ID from whatever is passed in dispatchers.
type Lookup = AccountIdLookup<AccountId, ()>;
/// The header type.
type Header = generic::Header<BlockNumber, BlakeTwo256>;
/// The ubiquitous event type.
type Event = Event;
/// The ubiquitous origin type.
type Origin = Origin;
/// Maximum number of block number to block hash mappings to keep (oldest pruned first).
type BlockHashCount = BlockHashCount;
/// The weight of database operations that the runtime can invoke.
@@ -198,12 +198,12 @@ impl frame_system::Config for Runtime {
///
/// This type is being generated by `construct_runtime!`.
type PalletInfo = PalletInfo;
/// The data to be stored in an account.
type AccountData = pallet_balances::AccountData<Balance>;
/// What to do if a new account is created.
type OnNewAccount = ();
/// What to do if an account is fully reaped from the system.
type OnKilledAccount = ();
/// The data to be stored in an account.
type AccountData = pallet_balances::AccountData<Balance>;
/// Weight information for the extrinsics of this pallet.
type SystemWeightInfo = ();
/// This is used as an identifier of the chain. 42 is the generic substrate prefix.
@@ -219,16 +219,14 @@ parameter_types! {

impl pallet_aura::Config for Runtime {
type AuthorityId = AuraId;
type DisabledValidators = ();
type MaxAuthorities = MaxAuthorities;
type DisabledValidators = ();
}

impl pallet_grandpa::Config for Runtime {
type Event = Event;
type Call = Call;

type KeyOwnerProofSystem = ();

type KeyOwnerProof =
<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;

@@ -237,6 +235,8 @@ impl pallet_grandpa::Config for Runtime {
GrandpaId,
)>>::IdentificationTuple;

type KeyOwnerProofSystem = ();

type HandleEquivocation = ();

type WeightInfo = ();
@@ -250,12 +250,12 @@ parameter_types! {
impl pallet_timestamp::Config for Runtime {
/// A timestamp: milliseconds since the unix epoch.
type Moment = u64;
type MinimumPeriod = MinimumPeriod;
type WeightInfo = ();
#[cfg(feature = "aura")]
type OnTimestampSet = Aura;
#[cfg(feature = "manual-seal")]
type OnTimestampSet = ();
type MinimumPeriod = MinimumPeriod;
type WeightInfo = ();
}

parameter_types! {
@@ -266,17 +266,17 @@ parameter_types! {
}

impl pallet_balances::Config for Runtime {
type MaxLocks = MaxLocks;
type MaxReserves = ();
type ReserveIdentifier = [u8; 8];
/// The type for recording an account's balance.
type Balance = Balance;
type DustRemoval = ();
/// The ubiquitous event type.
type Event = Event;
type DustRemoval = ();
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type WeightInfo = ();
type MaxLocks = MaxLocks;
type MaxReserves = ();
type ReserveIdentifier = [u8; 8];
}

parameter_types! {
@@ -297,6 +297,8 @@ impl pallet_sudo::Config for Runtime {
type Call = Call;
}

impl pallet_evm_chain_id::Config for Runtime {}

pub struct FindAuthorTruncated<F>(PhantomData<F>);
impl<F: FindAuthor<u32>> FindAuthor<H160> for FindAuthorTruncated<F> {
fn find_author<'a, I>(digests: I) -> Option<H160>
@@ -322,7 +324,6 @@ impl GasWeightMapping for FixedGasWeightMapping {
}

parameter_types! {
pub const ChainId: u64 = 42;
pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WEIGHT_PER_GAS);
pub PrecompilesValue: FrontierPrecompiles<Runtime> = FrontierPrecompiles::<_>::new();
}
@@ -336,11 +337,11 @@ impl pallet_evm::Config for Runtime {
type AddressMapping = HashedAddressMapping<BlakeTwo256>;
type Currency = Balances;
type Event = Event;
type Runner = pallet_evm::runner::stack::Runner<Self>;
type PrecompilesType = FrontierPrecompiles<Self>;
type PrecompilesValue = PrecompilesValue;
type ChainId = ChainId;
type ChainId = EVMChainId;
type BlockGasLimit = BlockGasLimit;
type Runner = pallet_evm::runner::stack::Runner<Self>;
type OnChargeTransaction = ();
type FindAuthor = FindAuthorTruncated<Aura>;
}
@@ -350,15 +351,15 @@ impl pallet_ethereum::Config for Runtime {
type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;
}

frame_support::parameter_types! {
parameter_types! {
pub BoundDivision: U256 = U256::from(1024);
}

impl pallet_dynamic_fee::Config for Runtime {
type MinGasPriceBoundDivisor = BoundDivision;
}

frame_support::parameter_types! {
parameter_types! {
pub IsActive: bool = true;
pub DefaultBaseFeePerGas: U256 = U256::from(1_000_000_000);
}
@@ -404,6 +405,7 @@ construct_runtime!(
Sudo: pallet_sudo,
Ethereum: pallet_ethereum,
EVM: pallet_evm,
EVMChainId: pallet_evm_chain_id,
DynamicFee: pallet_dynamic_fee,
BaseFee: pallet_base_fee,
HotfixSufficients: pallet_hotfix_sufficients,

0 comments on commit cf0fae7

Please sign in to comment.