Skip to content

Commit

Permalink
feat: add frontier evm
Browse files Browse the repository at this point in the history
Signed-off-by: Gregory Hill <gregorydhill@outlook.com>
  • Loading branch information
gregdhill committed Jul 20, 2023
1 parent 9e53f12 commit 96890df
Show file tree
Hide file tree
Showing 23 changed files with 2,866 additions and 303 deletions.
1,424 changes: 1,182 additions & 242 deletions Cargo.lock

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions parachain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ name = "interbtc-parachain"
substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.31" }

[dependencies]
async-trait = "0.1"
clap = { version = "4.0.9", features = [ "derive" ] }
log = "0.4.8"
codec = { package = "parity-scale-codec", version = "3.1.5" }
Expand Down Expand Up @@ -112,6 +113,14 @@ polkadot-cli = { git = "https://github.com/paritytech/polkadot", branch = "relea
polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.31" }
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.31" }

# Frontier dependencies
fc-consensus = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42" }
fc-db = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42" }
fc-mapping-sync = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42", features = ["sql"] }
fc-rpc = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42" }
fc-rpc-core = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42" }
fp-rpc = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42" }

[features]
default = []

Expand Down
33 changes: 31 additions & 2 deletions parachain/runtime/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ targets = ['x86_64-unknown-linux-gnu']
# Substrate dependencies
sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.31", default-features = false }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.31", default-features = false }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.31", default-features = false }
frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.31", default-features = false }
frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.31", default-features = false }
xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.31", default-features = false }
Expand All @@ -20,6 +21,9 @@ frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch =
pallet-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.31", default-features = false }
pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.31", default-features = false }

# Cumulus dependencies
parachain-info = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.31", default-features = false }

# Parachain dependencies
btc-relay = { path = "../../../crates/btc-relay", default-features = false }
currency = { path = "../../../crates/currency", default-features = false }
Expand Down Expand Up @@ -48,12 +52,20 @@ primitives = { package = "interbtc-primitives", path = "../../../primitives", de
orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "3fcd3cf9e63fe80fd9671912833a900ba09d1cc0", default-features = false }
orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "3fcd3cf9e63fe80fd9671912833a900ba09d1cc0", default-features = false }
orml-vesting = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "3fcd3cf9e63fe80fd9671912833a900ba09d1cc0", default-features = false }
orml-asset-registry = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "3fcd3cf9e63fe80fd9671912833a900ba09d1cc0", default-features = false }

orml-xtokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "3fcd3cf9e63fe80fd9671912833a900ba09d1cc0", default-features = false }
orml-xcm-support = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "3fcd3cf9e63fe80fd9671912833a900ba09d1cc0", default-features = false }
orml-unknown-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "3fcd3cf9e63fe80fd9671912833a900ba09d1cc0", default-features = false }
orml-asset-registry= { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "3fcd3cf9e63fe80fd9671912833a900ba09d1cc0", default-features = false }

# Frontier dependencies
pallet-base-fee = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42", default-features = false }
pallet-ethereum = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42", default-features = false }
pallet-evm = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42", default-features = false }
pallet-evm-chain-id = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42", default-features = false }
pallet-evm-precompile-modexp = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42", default-features = false }
pallet-evm-precompile-sha3fips = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42", default-features = false }
pallet-evm-precompile-simple = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42", default-features = false }

# TODO: enable weak dependency activation when available
# https://github.com/rust-lang/cargo/issues/8832
Expand All @@ -64,12 +76,15 @@ default = ["std"]
std = [
"sp-std/std",
"sp-runtime/std",
"sp-core/std",
"frame-support/std",
"frame-system/std",
"frame-benchmarking?/std",
"xcm/std",
"xcm-executor/std",

"parachain-info/std",

"btc-relay/std",
"currency/std",
"security/std",
Expand Down Expand Up @@ -101,12 +116,21 @@ std = [
"orml-xtokens/std",
"orml-xcm-support/std",
"orml-unknown-tokens/std",

"pallet-base-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",
]
dev-interlay = []
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"currency/try-runtime",
"parachain-info/try-runtime",
"orml-tokens/try-runtime",
"supply/try-runtime",
"orml-vesting/try-runtime",
Expand All @@ -130,7 +154,12 @@ try-runtime = [
"loans/try-runtime",
"democracy/try-runtime",
"orml-xtokens/try-runtime",
"orml-unknown-tokens/try-runtime"
"orml-unknown-tokens/try-runtime",

"pallet-base-fee/try-runtime",
"pallet-ethereum/try-runtime",
"pallet-evm/try-runtime",
"pallet-evm-chain-id/try-runtime",
]
runtime-benchmarks = [
"frame-benchmarking",
Expand Down
71 changes: 71 additions & 0 deletions parachain/runtime/common/src/evm/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use frame_support::{
traits::OnRuntimeUpgrade,
weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight},
};
use pallet_ethereum::{Transaction, TransactionAction};
use sp_core::Get;
use sp_runtime::Permill;
use sp_std::marker::PhantomData;

pub mod precompiles;

/// Current approximation of the gas/s consumption (Moonbeam)
pub const GAS_PER_SECOND: u64 = 40_000_000;
/// Approximate ratio of the amount of Weight per Gas (Moonbeam)
pub const WEIGHT_PER_GAS: u64 = WEIGHT_REF_TIME_PER_SECOND / GAS_PER_SECOND;

/// Sets the ideal block fullness to 50%.
/// If the block weight is between:
/// - 0-50% the gas fee will decrease
/// - 50-100% the gas fee will increase
pub struct BaseFeeThreshold;
impl pallet_base_fee::BaseFeeThreshold for BaseFeeThreshold {
fn lower() -> Permill {
Permill::zero()
}
fn ideal() -> Permill {
Permill::from_parts(500_000)
}
fn upper() -> Permill {
Permill::from_parts(1_000_000)
}
}

/// Get the "action" (call or create) of an Ethereum transaction
pub trait GetTransactionAction {
fn action(&self) -> TransactionAction;
}

impl GetTransactionAction for Transaction {
fn action(&self) -> TransactionAction {
match self {
Transaction::Legacy(transaction) => transaction.action,
Transaction::EIP2930(transaction) => transaction.action,
Transaction::EIP1559(transaction) => transaction.action,
}
}
}

/// Set the EVM chain ID based on the parachain ID
pub struct SetEvmChainId<T>(PhantomData<T>);
impl<T> OnRuntimeUpgrade for SetEvmChainId<T>
where
T: frame_system::Config + parachain_info::Config + pallet_evm_chain_id::Config,
{
fn on_runtime_upgrade() -> Weight {
let para_id: u32 = parachain_info::Pallet::<T>::parachain_id().into();
let evm_id: u64 = para_id.into();
pallet_evm_chain_id::ChainId::<T>::put(evm_id);
<T as frame_system::Config>::DbWeight::get().reads_writes(1, 1)
}

#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<sp_std::vec::Vec<u8>, &'static str> {
Ok(Default::default())
}

#[cfg(feature = "try-runtime")]
fn post_upgrade(_: sp_std::vec::Vec<u8>) -> Result<(), &'static str> {
Ok(())
}
}
45 changes: 45 additions & 0 deletions parachain/runtime/common/src/evm/precompiles.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use pallet_evm::{IsPrecompileResult, Precompile, PrecompileHandle, PrecompileResult, PrecompileSet};
use sp_core::H160;
use sp_std::marker::PhantomData;

use pallet_evm_precompile_modexp::Modexp;
use pallet_evm_precompile_simple::{ECRecover, Identity, Ripemd160, Sha256};

pub struct InterBtcPrecompiles<R>(PhantomData<R>);

impl<R> InterBtcPrecompiles<R> {
pub fn new() -> Self {
Self(Default::default())
}
pub fn used_addresses() -> [H160; 5] {
[hash(1), hash(2), hash(3), hash(4), hash(5)]
}
}

impl<R> PrecompileSet for InterBtcPrecompiles<R>
where
R: pallet_evm::Config,
{
fn execute(&self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {
match handle.code_address() {
// Ethereum precompiles:
a if a == hash(1) => Some(ECRecover::execute(handle)),
a if a == hash(2) => Some(Sha256::execute(handle)),
a if a == hash(3) => Some(Ripemd160::execute(handle)),
a if a == hash(4) => Some(Identity::execute(handle)),
a if a == hash(5) => Some(Modexp::execute(handle)),
_ => None,
}
}

fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult {
IsPrecompileResult::Answer {
is_precompile: Self::used_addresses().contains(&address),
extra_cost: 0,
}
}
}

fn hash(a: u64) -> H160 {
H160::from_low_u64_be(a)
}
2 changes: 2 additions & 0 deletions parachain/runtime/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use sp_std::prelude::*;
#[cfg(feature = "runtime-benchmarks")]
pub mod benchmarking;

pub mod evm;

// The relay chain is limited to 12s to include parachain blocks.
pub const MILLISECS_PER_BLOCK: u64 = 12000;
pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
Expand Down
30 changes: 28 additions & 2 deletions parachain/runtime/interlay/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,20 @@ dex-stable-rpc-runtime-api = { path = "../../../crates/dex-stable/rpc/runtime-ap
orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "dc39cfddefb10ef0de23655e2c3dcdab66a19404", default-features = false }
orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "dc39cfddefb10ef0de23655e2c3dcdab66a19404", default-features = false }
orml-vesting = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "dc39cfddefb10ef0de23655e2c3dcdab66a19404", default-features = false }
orml-asset-registry= { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "dc39cfddefb10ef0de23655e2c3dcdab66a19404", default-features = false }

orml-xtokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "dc39cfddefb10ef0de23655e2c3dcdab66a19404", default-features = false }
orml-xcm-support = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "dc39cfddefb10ef0de23655e2c3dcdab66a19404", default-features = false }
orml-unknown-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "dc39cfddefb10ef0de23655e2c3dcdab66a19404", default-features = false }
orml-asset-registry= { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "dc39cfddefb10ef0de23655e2c3dcdab66a19404", default-features = false }

# Frontier dependencies
fp-rpc = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42", default-features = false }
fp-self-contained = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42", default-features = false }
pallet-base-fee = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42", default-features = false }
pallet-ethereum = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42", default-features = false }
pallet-evm = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42", default-features = false }
pallet-evm-chain-id = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42", default-features = false }
pallet-evm-precompile-dispatch = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42", default-features = false }

[dev-dependencies]
hex = '0.4.2'
Expand Down Expand Up @@ -251,11 +260,19 @@ std = [
"orml-tokens/std",
"orml-traits/std",
"orml-vesting/std",
"orml-asset-registry/std",

"orml-xtokens/std",
"orml-xcm-support/std",
"orml-unknown-tokens/std",
"orml-asset-registry/std",

"fp-rpc/std",
"fp-self-contained/std",
"pallet-base-fee/std",
"pallet-ethereum/std",
"pallet-evm/std",
"pallet-evm-chain-id/std",
"pallet-evm-precompile-dispatch/std",
]
runtime-benchmarks = [
"frame-benchmarking",
Expand Down Expand Up @@ -303,6 +320,9 @@ runtime-benchmarks = [

"runtime-common/runtime-benchmarks",
"primitives/runtime-benchmarks",

"pallet-ethereum/runtime-benchmarks",
"pallet-evm/runtime-benchmarks",
]
disable-runtime-api = []
try-runtime = [
Expand Down Expand Up @@ -366,5 +386,11 @@ try-runtime = [
"orml-xtokens/try-runtime",
"orml-unknown-tokens/try-runtime",
"multi-transaction-payment/try-runtime",

"fp-self-contained/try-runtime",
"pallet-base-fee/try-runtime",
"pallet-ethereum/try-runtime",
"pallet-evm/try-runtime",
"pallet-evm-chain-id/try-runtime",
]
vesting-any = []
90 changes: 90 additions & 0 deletions parachain/runtime/interlay/src/evm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use crate::{
AccountId, Aura, BaseFee, EVMChainId, NativeCurrency, Runtime, RuntimeEvent, Timestamp, MAXIMUM_BLOCK_WEIGHT,
NORMAL_DISPATCH_RATIO,
};
use frame_support::{
parameter_types,
traits::{ConstU32, FindAuthor},
weights::Weight,
ConsensusEngineId,
};
use pallet_ethereum::PostLogContent;
use pallet_evm::{EnsureAddressRoot, EnsureAddressTruncated, FixedGasWeightMapping, HashedAddressMapping};
use sp_core::{crypto::ByteArray, H160, U256};
use sp_runtime::{traits::BlakeTwo256, Permill};
use sp_std::marker::PhantomData;

pub use runtime_common::evm::{
precompiles::InterBtcPrecompiles, BaseFeeThreshold, GetTransactionAction, SetEvmChainId, WEIGHT_PER_GAS,
};

parameter_types! {
pub DefaultBaseFeePerGas: U256 = U256::from(1_000_000_000);
pub DefaultElasticity: Permill = Permill::from_parts(125_000);
}

impl pallet_base_fee::Config for Runtime {
type DefaultBaseFeePerGas = DefaultBaseFeePerGas;
type DefaultElasticity = DefaultElasticity;
type RuntimeEvent = RuntimeEvent;
type Threshold = BaseFeeThreshold;
}

parameter_types! {
pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes;
}

impl pallet_ethereum::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;
type PostLogContent = PostBlockAndTxnHashes;
type ExtraDataLength = ConstU32<30>;
}

pub struct FindAuthorTruncated<F>(PhantomData<F>);
impl<F: FindAuthor<u32>> FindAuthor<H160> for FindAuthorTruncated<F> {
fn find_author<'a, I>(digests: I) -> Option<H160>
where
I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
{
if let Some(author_index) = F::find_author(digests) {
let authority_id = Aura::authorities()[author_index as usize].clone();
return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24]));
}
None
}
}

parameter_types! {
pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS);
pub PrecompilesValue: InterBtcPrecompiles<Runtime> = InterBtcPrecompiles::<_>::new();
pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0);
/// The amount of gas per pov, taken from Moonbeam:
/// ceil(MAXIMUM_BLOCK_WEIGHT.ref_time() / MAXIMUM_BLOCK_WEIGHT.proof_size() / WEIGHT_PER_GAS)
pub const GasLimitPovSizeRatio: u64 = 4;
}

impl pallet_evm::Config for Runtime {
type AddressMapping = HashedAddressMapping<BlakeTwo256>;
type BlockGasLimit = BlockGasLimit;
type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;
type CallOrigin = EnsureAddressRoot<AccountId>;
type WithdrawOrigin = EnsureAddressTruncated;
type ChainId = EVMChainId;
type Currency = NativeCurrency;
type FeeCalculator = BaseFee;
type FindAuthor = FindAuthorTruncated<Aura>;
type GasWeightMapping = FixedGasWeightMapping<Self>;
type OnChargeTransaction = ();
type OnCreate = ();
type PrecompilesType = InterBtcPrecompiles<Self>;
type PrecompilesValue = PrecompilesValue;
type Runner = pallet_evm::runner::stack::Runner<Self>;
type RuntimeEvent = RuntimeEvent;
type WeightPerGas = WeightPerGas;
type GasLimitPovSizeRatio = GasLimitPovSizeRatio;
type Timestamp = Timestamp;
type WeightInfo = pallet_evm::weights::SubstrateWeight<Runtime>;
}

impl pallet_evm_chain_id::Config for Runtime {}
Loading

0 comments on commit 96890df

Please sign in to comment.