Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace frontier's RuntimeHelper with manual dispatcher #1208

Merged
merged 1 commit into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);

// 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()))
}

fn transfer_back_to_caller(
Expand Down
Loading