Skip to content

Commit

Permalink
Replace frontier's RuntimeHelper with manual dispatcher
Browse files Browse the repository at this point in the history
  • Loading branch information
ales-otf committed Jan 28, 2025
1 parent 00dc331 commit dfb641d
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 104 deletions.
45 changes: 0 additions & 45 deletions Cargo.lock

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

16 changes: 7 additions & 9 deletions runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ name = "spec_version"
path = "src/spec_version.rs"

[dependencies]
ed25519-dalek = { workspace = true, default-features = false, features = ["alloc"] }
ed25519-dalek = { workspace = true, default-features = false, features = [
"alloc",
] }
subtensor-macros.workspace = true
subtensor-custom-rpc-runtime-api = { path = "../pallets/subtensor/runtime-api", default-features = false }
smallvec = { workspace = true }
Expand Down Expand Up @@ -98,7 +100,6 @@ pallet-commitments = { default-features = false, path = "../pallets/commitments"
fp-evm = { workspace = true }
fp-rpc = { workspace = true }
fp-self-contained = { workspace = true }
precompile-utils = { workspace = true }

# Frontier FRAME
pallet-base-fee = { workspace = true }
Expand Down Expand Up @@ -133,9 +134,7 @@ substrate-wasm-builder = { workspace = true, optional = true }
[features]
default = ["std"]
pow-faucet = ["pallet-subtensor/pow-faucet"]
fast-blocks = [
"pallet-subtensor/fast-blocks"
]
fast-blocks = ["pallet-subtensor/fast-blocks"]
std = [
"frame-try-runtime?/std",
"frame-system-benchmarking?/std",
Expand Down Expand Up @@ -192,7 +191,6 @@ std = [
"fp-evm/std",
"fp-rpc/std",
"fp-self-contained/std",
"precompile-utils/std",
# Frontier FRAME
"pallet-base-fee/std",
"pallet-dynamic-fee/std",
Expand All @@ -211,7 +209,7 @@ std = [
"hex/std",
"rand_chacha/std",
"sha2/std",
"w3f-bls/std"
"w3f-bls/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
Expand Down Expand Up @@ -240,7 +238,7 @@ runtime-benchmarks = [
"pallet-ethereum/runtime-benchmarks",
"pallet-evm/runtime-benchmarks",
"pallet-hotfix-sufficients/runtime-benchmarks",
"pallet-drand/runtime-benchmarks"
"pallet-drand/runtime-benchmarks",
]
try-runtime = [
"frame-try-runtime/try-runtime",
Expand Down Expand Up @@ -276,6 +274,6 @@ try-runtime = [
"pallet-ethereum/try-runtime",
"pallet-evm/try-runtime",
"pallet-evm-chain-id/try-runtime",
"pallet-drand/try-runtime"
"pallet-drand/try-runtime",
]
metadata-hash = ["substrate-wasm-builder/metadata-hash"]
32 changes: 10 additions & 22 deletions runtime/src/precompiles/balance_transfer.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use frame_system::RawOrigin;
use pallet_evm::{
BalanceConverter, ExitError, ExitSucceed, PrecompileFailure, PrecompileHandle,
PrecompileOutput, PrecompileResult,
BalanceConverter, ExitError, ExitSucceed, PrecompileHandle, PrecompileOutput, PrecompileResult,
};
use precompile_utils::prelude::RuntimeHelper;
use sp_core::U256;
use sp_runtime::traits::UniqueSaturatedInto;
use sp_std::vec;

use crate::precompiles::{bytes_to_account_id, get_method_id, get_slice};
use crate::{Runtime, RuntimeCall};
use crate::precompiles::{
bytes_to_account_id, get_method_id, get_slice, try_dispatch_runtime_call,
};
use crate::Runtime;

pub const BALANCE_TRANSFER_INDEX: u64 = 2048;

Expand Down Expand Up @@ -37,7 +36,7 @@ impl BalanceTransferPrecompile {
}

// Forward all received value to the destination address
let amount: U256 = handle.context().apparent_value;
let amount = handle.context().apparent_value;

// Use BalanceConverter to convert EVM amount to Substrate balance
let amount_sub =
Expand All @@ -55,23 +54,12 @@ impl BalanceTransferPrecompile {
let account_id_src = bytes_to_account_id(&CONTRACT_ADDRESS_SS58)?;
let account_id_dst = bytes_to_account_id(address_bytes_dst)?;

let call = RuntimeCall::Balances(pallet_balances::Call::<Runtime>::transfer_allow_death {
let call = pallet_balances::Call::<Runtime>::transfer_allow_death {
dest: account_id_dst.into(),
value: amount_sub.unique_saturated_into(),
});
};
let origin = RawOrigin::Signed(account_id_src).into();

// Dispatch the call
RuntimeHelper::<Runtime>::try_dispatch(
handle,
RawOrigin::Signed(account_id_src).into(),
call,
)
.map(|_| PrecompileOutput {
exit_status: ExitSucceed::Returned,
output: vec![],
})
.map_err(|_| PrecompileFailure::Error {
exit_status: ExitError::OutOfFund,
})
try_dispatch_runtime_call(handle, call, origin)
}
}
82 changes: 78 additions & 4 deletions runtime/src/precompiles/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
extern crate alloc;

use alloc::format;
use core::marker::PhantomData;
use sp_core::{hashing::keccak_256, H160};
use sp_runtime::AccountId32;

use frame_support::dispatch::{GetDispatchInfo, Pays};
use frame_system::RawOrigin;
use pallet_evm::{
ExitError, IsPrecompileResult, Precompile, PrecompileFailure, PrecompileHandle,
PrecompileResult, PrecompileSet,
ExitError, ExitSucceed, GasWeightMapping, IsPrecompileResult, Precompile, PrecompileFailure,
PrecompileHandle, PrecompileOutput, PrecompileResult, PrecompileSet,
};
use pallet_evm_precompile_modexp::Modexp;
use pallet_evm_precompile_sha3fips::Sha3FIPS256;
use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256};
use sp_core::{hashing::keccak_256, H160};
use sp_runtime::{traits::Dispatchable, AccountId32};

use crate::{Runtime, RuntimeCall};

// Include custom precompiles
mod balance_transfer;
Expand Down Expand Up @@ -130,3 +137,70 @@ pub fn get_slice(data: &[u8], from: usize, to: usize) -> Result<&[u8], Precompil
})
}
}

/// Dispatches a runtime call, but also checks and records the gas costs.
fn try_dispatch_runtime_call(
handle: &mut impl PrecompileHandle,
call: impl Into<RuntimeCall>,
origin: RawOrigin<AccountId32>,
) -> PrecompileResult {
let call = Into::<RuntimeCall>::into(call);
let info = call.get_dispatch_info();

let target_gas = handle.gas_limit();
if let Some(gas) = target_gas {
let valid_weight =
<Runtime as pallet_evm::Config>::GasWeightMapping::gas_to_weight(gas, false).ref_time();
if info.weight.ref_time() > valid_weight {
return Err(PrecompileFailure::Error {
exit_status: ExitError::OutOfGas,
});
}
}

handle.record_external_cost(
Some(info.weight.ref_time()),
Some(info.weight.proof_size()),
None,
)?;

match call.dispatch(origin.into()) {
Ok(post_info) => {
if post_info.pays_fee(&info) == Pays::Yes {
let actual_weight = post_info.actual_weight.unwrap_or(info.weight);
let cost =
<Runtime as pallet_evm::Config>::GasWeightMapping::weight_to_gas(actual_weight);
handle.record_cost(cost)?;

handle.refund_external_cost(
Some(
info.weight
.ref_time()
.saturating_sub(actual_weight.ref_time()),
),
Some(
info.weight
.proof_size()
.saturating_sub(actual_weight.proof_size()),
),
);
}

log::info!("Dispatch succeeded. Post info: {:?}", post_info);

Ok(PrecompileOutput {
exit_status: ExitSucceed::Returned,
output: Default::default(),
})
}
Err(e) => {
log::error!("Dispatch failed. Error: {:?}", e);
log::warn!("Returning error PrecompileFailure::Error");
Err(PrecompileFailure::Error {
exit_status: ExitError::Other(
format!("dispatch execution failed: {}", <&'static str>::from(e)).into(),
),
})
}
}
}
26 changes: 2 additions & 24 deletions runtime/src/precompiles/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,14 @@ use pallet_evm::{
AddressMapping, BalanceConverter, ExitError, ExitSucceed, HashedAddressMapping,
PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult,
};
use precompile_utils::prelude::RuntimeHelper;
use sp_core::crypto::Ss58Codec;
use sp_core::U256;
use sp_runtime::traits::{BlakeTwo256, Dispatchable, StaticLookup, UniqueSaturatedInto};
use sp_runtime::AccountId32;
use sp_std::vec;

use crate::{
precompiles::{get_method_id, get_slice},
precompiles::{get_method_id, get_slice, try_dispatch_runtime_call},
ProxyType, Runtime, RuntimeCall,
};

Expand Down Expand Up @@ -214,28 +213,7 @@ impl StakingPrecompile {
Self::transfer_back_to_caller(&account_id, amount)?;
}

match RuntimeHelper::<Runtime>::try_dispatch(
handle,
RawOrigin::Signed(account_id.clone()).into(),
call,
) {
Ok(post_info) => {
log::info!("Dispatch succeeded. Post info: {:?}", post_info);

Ok(PrecompileOutput {
exit_status: ExitSucceed::Returned,
output: vec![],
})
}

Err(dispatch_error) => {
log::error!("Dispatch failed. Error: {:?}", dispatch_error);
log::warn!("Returning error PrecompileFailure::Error");
Err(PrecompileFailure::Error {
exit_status: ExitError::Other("Subtensor call failed".into()),
})
}
}
try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id.clone()).into())
}

fn transfer_back_to_caller(
Expand Down

0 comments on commit dfb641d

Please sign in to comment.