Skip to content
This repository has been archived by the owner on Mar 30, 2023. It is now read-only.

Commit

Permalink
Add darwinia dispatch precompile (#173)
Browse files Browse the repository at this point in the history
* Add darwinia dispatch

* Fix test

Co-authored-by: Xavier Lau <[email protected]>
Co-authored-by: fisher <[email protected]>
  • Loading branch information
3 people authored Jan 4, 2023
1 parent 7a77e00 commit 459beca
Show file tree
Hide file tree
Showing 10 changed files with 159 additions and 28 deletions.
35 changes: 18 additions & 17 deletions Cargo.lock

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

37 changes: 37 additions & 0 deletions precompile/dispatch/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[package]
authors = ["Darwinia Network <[email protected]>"]
description = "Call dispatch precompile for EVM pallet."
edition = "2021"
homepage = "https://darwinia.network"
license = "GPL-3.0"
name = "darwinia-precompile-dispatch"
readme = "README.md"
repository = "https://github.com/darwinia-network/darwinia"
version = "6.0.0"

[dependencies]
# frontier
fp-evm = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }
pallet-evm = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }

# moonbeam
precompile-utils = { default-features = false, git = "https://github.com/darwinia-network/moonbeam.git", branch = "polkadot-v0.9.30" }

# substrate
frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }

[features]
default = ["std"]
std = [
# frontier
"fp-evm/std",
"pallet-evm/std",

# moonbeam
"precompile-utils/std",

# substrate
"frame-support/std",
"sp-std/std",
]
93 changes: 93 additions & 0 deletions precompile/dispatch/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// This file is part of Darwinia.
//
// Copyright (C) 2018-2023 Darwinia Network
// SPDX-License-Identifier: GPL-3.0
//
// Darwinia 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.
//
// Darwinia 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 Darwinia. If not, see <https://www.gnu.org/licenses/>.

#![cfg_attr(not(feature = "std"), no_std)]

extern crate alloc;

// std
use alloc::format;
use core::marker::PhantomData;
// frontier
use fp_evm::{ExitError, PrecompileFailure};
// moonbeam
use frame_support::{
codec::{Decode, DecodeLimit as _},
dispatch::{DispatchClass, Dispatchable, GetDispatchInfo, Pays, PostDispatchInfo},
traits::{ConstU32, Get},
};
use pallet_evm::{AddressMapping, GasWeightMapping};
use precompile_utils::prelude::*;

// `DecodeLimit` specifies the max depth a call can use when decoding, as unbounded depth
// can be used to overflow the stack.
// Default value is 8, which is the same as in XCM call decoding.
pub struct Dispatch<T, DecodeLimit = ConstU32<8>> {
_marker: PhantomData<(T, DecodeLimit)>,
}

#[precompile_utils::precompile]
impl<T, DecodeLimit> Dispatch<T, DecodeLimit>
where
T: pallet_evm::Config,
T::RuntimeCall: Dispatchable<PostInfo = PostDispatchInfo> + GetDispatchInfo + Decode,
<T::RuntimeCall as Dispatchable>::RuntimeOrigin: From<Option<T::AccountId>>,
DecodeLimit: Get<u32>,
{
#[precompile::public("execute(bytes)")]
fn execute(
handle: &mut impl PrecompileHandle,
encoded_call: UnboundedBytes,
) -> EvmResult<bool> {
let target_gas = handle.gas_limit();
let context = handle.context();

let call = T::RuntimeCall::decode_with_depth_limit(
DecodeLimit::get(),
&mut encoded_call.as_bytes(),
)
.map_err(|_| revert("decode failed"))?;
let info = call.get_dispatch_info();

let valid_call = info.pays_fee == Pays::Yes && info.class == DispatchClass::Normal;
if !valid_call {
return Err(revert("invalid call"));
}

if let Some(gas) = target_gas {
let valid_weight =
info.weight.ref_time() <= T::GasWeightMapping::gas_to_weight(gas, false).ref_time();
if !valid_weight {
return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas });
}
}

let origin = T::AddressMapping::into_account_id(context.caller);
match call.dispatch(Some(origin).into()) {
Ok(post_info) => {
let cost = T::GasWeightMapping::weight_to_gas(
post_info.actual_weight.unwrap_or(info.weight),
);

handle.record_cost(cost)?;
Ok(true)
},
Err(e) => Err(revert(format!("dispatch failed: {}", <&'static str>::from(e)))),
}
}
}
2 changes: 1 addition & 1 deletion precompile/state-storage/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
authors = ["Darwinia Network <[email protected]>"]
description = "State storage precompiles for EVM pallet."
description = "State storage precompile for EVM pallet."
edition = "2021"
homepage = "https://darwinia.network"
license = "GPL-3.0"
Expand Down
4 changes: 2 additions & 2 deletions runtime/crab/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ darwinia-message-transact = { default-features = false, path = "../../pa
darwinia-precompile-assets = { default-features = false, path = "../../precompile/assets" }
darwinia-precompile-bls12-381 = { default-features = false, path = "../../precompile/bls12-381" }
darwinia-precompile-deposit = { default-features = false, path = "../../precompile/deposit" }
darwinia-precompile-dispatch = { default-features = false, path = "../../precompile/dispatch" }
darwinia-precompile-staking = { default-features = false, path = "../../precompile/staking" }
darwinia-precompile-state-storage = { default-features = false, path = "../../precompile/state-storage" }
darwinia-staking = { default-features = false, path = "../../pallet/staking" }
Expand All @@ -66,7 +67,6 @@ pallet-ethereum = { default-features = false, features = ["forbid
pallet-evm = { default-features = false, features = ["forbid-evm-reentrancy"], git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }
pallet-evm-precompile-blake2 = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }
pallet-evm-precompile-bn128 = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }
pallet-evm-precompile-dispatch = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }
pallet-evm-precompile-modexp = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }
pallet-evm-precompile-simple = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }

Expand Down Expand Up @@ -155,6 +155,7 @@ std = [
"darwinia-precompile-bls12-381/std",
"darwinia-precompile-staking/std",
"darwinia-precompile-deposit/std",
"darwinia-precompile-dispatch/std",
"darwinia-precompile-state-storage/std",
"darwinia-staking/std",
"dc-primitives/std",
Expand All @@ -179,7 +180,6 @@ std = [
"pallet-evm/std",
"pallet-evm-precompile-blake2/std",
"pallet-evm-precompile-bn128/std",
"pallet-evm-precompile-dispatch/std",
"pallet-evm-precompile-modexp/std",
"pallet-evm-precompile-simple/std",

Expand Down
2 changes: 1 addition & 1 deletion runtime/crab/src/pallets/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ where
darwinia_precompile_state_storage::EthereumStorageFilter,
>>::execute(handle)),
a if a == addr(1025) =>
Some(<pallet_evm_precompile_dispatch::Dispatch<Runtime>>::execute(handle)),
Some(<darwinia_precompile_dispatch::Dispatch<Runtime>>::execute(handle)),
// [1026, 1536) reserved for assets precompiles.
a if (1026..1536).contains(&AssetIdConverter::account_to_asset_id(a.into())) =>
Some(<darwinia_precompile_assets::ERC20Assets<Runtime, AssetIdConverter>>::execute(
Expand Down
4 changes: 2 additions & 2 deletions runtime/darwinia/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ darwinia-message-transact = { default-features = false, path = "../../pa
darwinia-precompile-assets = { default-features = false, path = "../../precompile/assets" }
darwinia-precompile-bls12-381 = { default-features = false, path = "../../precompile/bls12-381" }
darwinia-precompile-deposit = { default-features = false, path = "../../precompile/deposit" }
darwinia-precompile-dispatch = { default-features = false, path = "../../precompile/dispatch" }
darwinia-precompile-staking = { default-features = false, path = "../../precompile/staking" }
darwinia-precompile-state-storage = { default-features = false, path = "../../precompile/state-storage" }
darwinia-staking = { default-features = false, path = "../../pallet/staking" }
Expand All @@ -66,7 +67,6 @@ pallet-ethereum = { default-features = false, features = ["forbid
pallet-evm = { default-features = false, features = ["forbid-evm-reentrancy"], git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }
pallet-evm-precompile-blake2 = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }
pallet-evm-precompile-bn128 = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }
pallet-evm-precompile-dispatch = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }
pallet-evm-precompile-modexp = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }
pallet-evm-precompile-simple = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }

Expand Down Expand Up @@ -155,6 +155,7 @@ std = [
"darwinia-precompile-bls12-381/std",
"darwinia-precompile-staking/std",
"darwinia-precompile-deposit/std",
"darwinia-precompile-dispatch/std",
"darwinia-precompile-state-storage/std",
"darwinia-staking/std",
"dc-primitives/std",
Expand All @@ -179,7 +180,6 @@ std = [
"pallet-evm/std",
"pallet-evm-precompile-blake2/std",
"pallet-evm-precompile-bn128/std",
"pallet-evm-precompile-dispatch/std",
"pallet-evm-precompile-modexp/std",
"pallet-evm-precompile-simple/std",

Expand Down
2 changes: 1 addition & 1 deletion runtime/darwinia/src/pallets/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ where
darwinia_precompile_state_storage::EthereumStorageFilter,
>>::execute(handle)),
a if a == addr(1025) =>
Some(<pallet_evm_precompile_dispatch::Dispatch<Runtime>>::execute(handle)),
Some(<darwinia_precompile_dispatch::Dispatch<Runtime>>::execute(handle)),
// [1026, 1536) reserved for assets precompiles.
a if (1026..1536).contains(&AssetIdConverter::account_to_asset_id(a.into())) =>
Some(<darwinia_precompile_assets::ERC20Assets<Runtime, AssetIdConverter>>::execute(
Expand Down
6 changes: 3 additions & 3 deletions runtime/pangolin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ darwinia-message-transact = { default-features = false, path = "../../pa
darwinia-precompile-assets = { default-features = false, path = "../../precompile/assets" }
darwinia-precompile-bls12-381 = { default-features = false, path = "../../precompile/bls12-381" }
darwinia-precompile-deposit = { default-features = false, path = "../../precompile/deposit" }
darwinia-precompile-dispatch = { default-features = false, path = "../../precompile/dispatch" }
darwinia-precompile-staking = { default-features = false, path = "../../precompile/staking" }
darwinia-precompile-state-storage = { default-features = false, path = "../../precompile/state-storage" }
darwinia-staking = { default-features = false, path = "../../pallet/staking" }
Expand All @@ -65,7 +66,6 @@ pallet-ethereum = { default-features = false, features = ["forbid
pallet-evm = { default-features = false, features = ["forbid-evm-reentrancy"], git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }
pallet-evm-precompile-blake2 = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }
pallet-evm-precompile-bn128 = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }
pallet-evm-precompile-dispatch = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }
pallet-evm-precompile-modexp = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }
pallet-evm-precompile-simple = { default-features = false, git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.30" }

Expand Down Expand Up @@ -152,8 +152,9 @@ std = [
"darwinia-message-transact/std",
"darwinia-precompile-assets/std",
"darwinia-precompile-bls12-381/std",
"darwinia-precompile-staking/std",
"darwinia-precompile-deposit/std",
"darwinia-precompile-dispatch/std",
"darwinia-precompile-staking/std",
"darwinia-precompile-state-storage/std",
"darwinia-staking/std",
"dc-primitives/std",
Expand All @@ -177,7 +178,6 @@ std = [
"pallet-evm/std",
"pallet-evm-precompile-blake2/std",
"pallet-evm-precompile-bn128/std",
"pallet-evm-precompile-dispatch/std",
"pallet-evm-precompile-modexp/std",
"pallet-evm-precompile-simple/std",

Expand Down
2 changes: 1 addition & 1 deletion runtime/pangolin/src/pallets/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ where
darwinia_precompile_state_storage::EthereumStorageFilter,
>>::execute(handle)),
a if a == addr(1025) =>
Some(<pallet_evm_precompile_dispatch::Dispatch<Runtime>>::execute(handle)),
Some(<darwinia_precompile_dispatch::Dispatch<Runtime>>::execute(handle)),
// [1026, 1536) reserved for assets precompiles.
a if (1026..1536).contains(&AssetIdConverter::account_to_asset_id(a.into())) =>
Some(<darwinia_precompile_assets::ERC20Assets<Runtime, AssetIdConverter>>::execute(
Expand Down

0 comments on commit 459beca

Please sign in to comment.