Skip to content

Commit 1e3d30a

Browse files
author
Grigoriy Simonov
committed
feat: add OnCheckEvmTransaction callback
1 parent 3c75079 commit 1e3d30a

File tree

8 files changed

+177
-111
lines changed

8 files changed

+177
-111
lines changed

frame/ethereum/src/lib.rs

+27-11
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ use frame_support::{
4848
weights::Weight,
4949
};
5050
use frame_system::{pallet_prelude::OriginFor, CheckWeight, WeightInfo};
51-
use pallet_evm::{BlockHashMapping, FeeCalculator, GasWeightMapping, Runner};
51+
use pallet_evm::{
52+
BlockHashMapping, FeeCalculator, GasWeightMapping, OnCheckEvmTransaction, Runner,
53+
};
5254
use sp_runtime::{
5355
generic::DigestItem,
5456
traits::{DispatchInfoOf, Dispatchable, One, Saturating, UniqueSaturatedInto, Zero},
@@ -499,7 +501,8 @@ impl<T: Config> Pallet<T> {
499501
let (base_fee, _) = T::FeeCalculator::min_gas_price();
500502
let (who, _) = pallet_evm::Pallet::<T>::account_basic(&origin);
501503

502-
let _ = CheckEvmTransaction::<InvalidTransactionWrapper>::new(
504+
let mut v = CheckEvmTransaction::<InvalidTransactionWrapper>::new(
505+
who.clone(),
503506
CheckEvmTransactionConfig {
504507
evm_config: T::config(),
505508
block_gas_limit: T::BlockGasLimit::get(),
@@ -510,13 +513,19 @@ impl<T: Config> Pallet<T> {
510513
transaction_data.clone().into(),
511514
weight_limit,
512515
proof_size_base_cost,
516+
);
517+
518+
T::OnCheckEvmTransaction::<InvalidTransactionWrapper>::on_check_evm_transaction(
519+
&mut v, &origin,
513520
)
514-
.validate_in_pool_for(&who)
515-
.and_then(|v| v.with_chain_id())
516-
.and_then(|v| v.with_base_fee())
517-
.and_then(|v| v.with_balance_for(&who))
518521
.map_err(|e| e.0)?;
519522

523+
v.validate_in_pool_for()
524+
.and_then(|v| v.with_chain_id())
525+
.and_then(|v| v.with_base_fee())
526+
.and_then(|v| v.with_balance())
527+
.map_err(|e| e.0)?;
528+
520529
let priority = match (
521530
transaction_data.gas_price,
522531
transaction_data.max_fee_per_gas,
@@ -875,7 +884,8 @@ impl<T: Config> Pallet<T> {
875884
_ => (None, None),
876885
};
877886

878-
let _ = CheckEvmTransaction::<InvalidTransactionWrapper>::new(
887+
let mut v = CheckEvmTransaction::<InvalidTransactionWrapper>::new(
888+
who,
879889
CheckEvmTransactionConfig {
880890
evm_config: T::config(),
881891
block_gas_limit: T::BlockGasLimit::get(),
@@ -886,13 +896,19 @@ impl<T: Config> Pallet<T> {
886896
transaction_data.into(),
887897
weight_limit,
888898
proof_size_base_cost,
899+
);
900+
901+
T::OnCheckEvmTransaction::<InvalidTransactionWrapper>::on_check_evm_transaction(
902+
&mut v, &origin,
889903
)
890-
.validate_in_block_for(&who)
891-
.and_then(|v| v.with_chain_id())
892-
.and_then(|v| v.with_base_fee())
893-
.and_then(|v| v.with_balance_for(&who))
894904
.map_err(|e| TransactionValidityError::Invalid(e.0))?;
895905

906+
v.validate_in_block()
907+
.and_then(|v| v.with_chain_id())
908+
.and_then(|v| v.with_base_fee())
909+
.and_then(|v| v.with_balance())
910+
.map_err(|e| TransactionValidityError::Invalid(e.0))?;
911+
896912
Ok(())
897913
}
898914

frame/ethereum/src/mock.rs

+1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ impl pallet_evm::Config for Test {
180180
type GasLimitPovSizeRatio = GasLimitPovSizeRatio;
181181
type Timestamp = Timestamp;
182182
type WeightInfo = ();
183+
type OnCheckEvmTransaction<E: From<pallet_evm::InvalidEvmTransactionError>> = ();
183184
}
184185

185186
parameter_types! {

frame/evm/precompile/dispatch/src/mock.rs

+1
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ impl pallet_evm::Config for Test {
166166
type GasLimitPovSizeRatio = ();
167167
type Timestamp = Timestamp;
168168
type WeightInfo = ();
169+
type OnCheckEvmTransaction<E: From<pallet_evm::InvalidEvmTransactionError>> = ();
169170
}
170171

171172
pub(crate) struct MockHandle {

frame/evm/src/lib.rs

+20-4
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ use sp_std::{cmp::min, collections::btree_map::BTreeMap, vec::Vec};
9595
use fp_account::AccountId20;
9696
use fp_evm::GenesisAccount;
9797
pub use fp_evm::{
98-
Account, CallInfo, CreateInfo, ExecutionInfoV2 as ExecutionInfo, FeeCalculator,
99-
InvalidEvmTransactionError, IsPrecompileResult, LinearCostPrecompile, Log, Precompile,
100-
PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, PrecompileSet,
101-
Vicinity,
98+
Account, CallInfo, CheckEvmTransaction, CreateInfo, ExecutionInfoV2 as ExecutionInfo,
99+
FeeCalculator, InvalidEvmTransactionError, IsPrecompileResult, LinearCostPrecompile, Log,
100+
Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult,
101+
PrecompileSet, Vicinity,
102102
};
103103

104104
pub use self::{
@@ -177,6 +177,12 @@ pub mod pallet {
177177
fn config() -> &'static EvmConfig {
178178
&SHANGHAI_CONFIG
179179
}
180+
181+
// Called when transaction info for validation is created
182+
type OnCheckEvmTransaction<E: From<InvalidEvmTransactionError>>: OnCheckEvmTransaction<
183+
Self,
184+
E,
185+
>;
180186
}
181187

182188
#[pallet::call]
@@ -1047,3 +1053,13 @@ impl<T> OnCreate<T> for Tuple {
10471053
)*)
10481054
}
10491055
}
1056+
1057+
pub trait OnCheckEvmTransaction<T: Config, E: From<InvalidEvmTransactionError>> {
1058+
fn on_check_evm_transaction(v: &mut CheckEvmTransaction<E>, origin: &H160) -> Result<(), E>;
1059+
}
1060+
1061+
impl<T: Config, E: From<InvalidEvmTransactionError>> OnCheckEvmTransaction<T, E> for () {
1062+
fn on_check_evm_transaction(_v: &mut CheckEvmTransaction<E>, _origin: &H160) -> Result<(), E> {
1063+
Ok(())
1064+
}
1065+
}

frame/evm/src/mock.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ use sp_std::{boxed::Box, prelude::*, str::FromStr};
3232

3333
use crate::{
3434
EnsureAddressNever, EnsureAddressRoot, FeeCalculator, IdentityAddressMapping,
35-
IsPrecompileResult, Precompile, PrecompileHandle, PrecompileResult, PrecompileSet,
35+
InvalidEvmTransactionError, IsPrecompileResult, Precompile, PrecompileHandle, PrecompileResult,
36+
PrecompileSet,
3637
};
3738

3839
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
@@ -162,6 +163,7 @@ impl crate::Config for Test {
162163
type GasLimitPovSizeRatio = GasLimitPovSizeRatio;
163164
type Timestamp = Timestamp;
164165
type WeightInfo = ();
166+
type OnCheckEvmTransaction<E: From<InvalidEvmTransactionError>> = ();
165167
}
166168

167169
/// Example PrecompileSet with only Identity precompile.

frame/evm/src/runner/stack.rs

+18-13
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717

1818
//! EVM stack-based runner.
1919
20+
use crate::{
21+
runner::Runner as RunnerT, AccountCodes, AccountCodesMetadata, AccountStorages, AddressMapping,
22+
BalanceOf, BlockHashMapping, Config, Error, Event, FeeCalculator, OnChargeEVMTransaction,
23+
OnCheckEvmTransaction, OnCreate, Pallet, RunnerError,
24+
};
2025
use evm::{
2126
backend::Backend as BackendT,
2227
executor::stack::{Accessed, StackExecutor, StackState as StackStateT, StackSubstateMetadata},
@@ -47,12 +52,6 @@ use fp_evm::{
4752
ACCOUNT_STORAGE_PROOF_SIZE, IS_EMPTY_CHECK_PROOF_SIZE, WRITE_PROOF_SIZE,
4853
};
4954

50-
use crate::{
51-
runner::Runner as RunnerT, AccountCodes, AccountCodesMetadata, AccountStorages, AddressMapping,
52-
BalanceOf, BlockHashMapping, Config, Error, Event, FeeCalculator, OnChargeEVMTransaction,
53-
OnCreate, Pallet, RunnerError,
54-
};
55-
5655
#[cfg(feature = "forbid-evm-reentrancy")]
5756
environmental::thread_local_impl!(static IN_EVM: environmental::RefCell<bool> = environmental::RefCell::new(false));
5857

@@ -371,8 +370,10 @@ where
371370
let (base_fee, mut weight) = T::FeeCalculator::min_gas_price();
372371
let (source_account, inner_weight) = Pallet::<T>::account_basic(&source);
373372
weight = weight.saturating_add(inner_weight);
373+
let nonce = nonce.unwrap_or(source_account.nonce);
374374

375-
let _ = fp_evm::CheckEvmTransaction::<Self::Error>::new(
375+
let mut v = fp_evm::CheckEvmTransaction::<Self::Error>::new(
376+
source_account,
376377
fp_evm::CheckEvmTransactionConfig {
377378
evm_config,
378379
block_gas_limit: T::BlockGasLimit::get(),
@@ -384,7 +385,7 @@ where
384385
chain_id: Some(T::ChainId::get()),
385386
to: target,
386387
input,
387-
nonce: nonce.unwrap_or(source_account.nonce),
388+
nonce,
388389
gas_limit: gas_limit.into(),
389390
gas_price: None,
390391
max_fee_per_gas,
@@ -394,11 +395,15 @@ where
394395
},
395396
weight_limit,
396397
proof_size_base_cost,
397-
)
398-
.validate_in_block_for(&source_account)
399-
.and_then(|v| v.with_base_fee())
400-
.and_then(|v| v.with_balance_for(&source_account))
401-
.map_err(|error| RunnerError { error, weight })?;
398+
);
399+
400+
T::OnCheckEvmTransaction::<Error<T>>::on_check_evm_transaction(&mut v, &source)
401+
.map_err(|error| RunnerError { error, weight })?;
402+
403+
v.validate_in_block()
404+
.and_then(|v| v.with_base_fee())
405+
.and_then(|v| v.with_balance())
406+
.map_err(|error| RunnerError { error, weight })?;
402407
Ok(())
403408
}
404409

0 commit comments

Comments
 (0)