Skip to content

Commit 7c0d0d7

Browse files
committed
Address POV Underestimations (#244)
1 parent 532ec51 commit 7c0d0d7

File tree

3 files changed

+52
-6
lines changed

3 files changed

+52
-6
lines changed

frame/evm/src/lib.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ pub use self::{
118118
#[frame_support::pallet]
119119
pub mod pallet {
120120
use super::*;
121+
use cumulus_primitives_storage_weight_reclaim::get_proof_size;
121122
use frame_support::pallet_prelude::*;
122123
use frame_system::pallet_prelude::*;
123124

@@ -684,6 +685,35 @@ pub mod pallet {
684685
#[pallet::storage]
685686
pub type AccountStorages<T: Config> =
686687
StorageDoubleMap<_, Blake2_128Concat, H160, Blake2_128Concat, H256, H256, ValueQuery>;
688+
689+
#[pallet::hooks]
690+
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
691+
fn on_initialize(_: BlockNumberFor<T>) -> Weight {
692+
let mut total_weight = Weight::zero();
693+
694+
// Do dummy read to populate the pov with the intermediates nodes,
695+
// only when proof size recording is enabled.
696+
if let Some(pov_before) = get_proof_size() {
697+
const ZERO_ACCOUNT: H160 = H160::zero();
698+
699+
// just a dummy read to populate the pov with the intermediates nodes
700+
let _ = AccountCodesMetadata::<T>::get(ZERO_ACCOUNT.clone());
701+
let (_, min_gas_weight) = T::FeeCalculator::min_gas_price();
702+
let (_, account_basic_weight) = Pallet::<T>::account_basic(&ZERO_ACCOUNT);
703+
704+
let pov = get_proof_size().unwrap_or_default() - pov_before;
705+
706+
total_weight = total_weight
707+
.saturating_add(Weight::from_parts(0, pov))
708+
.saturating_add(T::DbWeight::get().reads(1))
709+
.saturating_add(account_basic_weight)
710+
.saturating_add(min_gas_weight);
711+
712+
}
713+
714+
total_weight
715+
}
716+
}
687717
}
688718

689719
/// Utility alias for easy access to the [`AccountProvider::AccountId`] type from a given config.

frame/evm/src/runner/stack.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ where
187187
R: Default,
188188
{
189189
// Used to record the external costs in the evm through the StackState implementation
190-
let maybe_weight_info =
190+
let mut maybe_weight_info =
191191
WeightInfo::new_from_weight_limit(weight_limit, proof_size_base_cost).map_err(
192192
|_| RunnerError {
193193
error: Error::<T>::GasLimitTooLow,
@@ -220,17 +220,22 @@ where
220220
//
221221
// EIP-3607: https://eips.ethereum.org/EIPS/eip-3607
222222
// Do not allow transactions for which `tx.sender` has any code deployed.
223-
if is_transactional
224-
&& <AccountCodesMetadata<T>>::get(source)
225-
.unwrap_or_default()
226-
.size != 0
227-
{
223+
let account_code_metadata = <AccountCodesMetadata<T>>::get(source);
224+
if is_transactional && account_code_metadata.unwrap_or_default().size != 0 {
228225
return Err(RunnerError {
229226
error: Error::<T>::TransactionMustComeFromEOA,
230227
weight,
231228
});
232229
}
233230

231+
if let Some(ref mut weight_info) = maybe_weight_info {
232+
weight_info
233+
.try_record_proof_size_or_fail(ACCOUNT_CODES_METADATA_PROOF_SIZE)
234+
.map_err(|_| RunnerError {
235+
error: Error::<T>::GasLimitTooLow,
236+
weight,
237+
})?;
238+
}
234239
let total_fee_per_gas = if is_transactional {
235240
match (max_fee_per_gas, max_priority_fee_per_gas) {
236241
// Zero max_fee_per_gas for validated transactional calls exist in XCM -> EVM
@@ -339,6 +344,13 @@ where
339344
);
340345
estimated_proof_size
341346
} else {
347+
log::debug!(
348+
target: "evm",
349+
"Proof size overestimation detected! (estimated: {}, actual: {}, diff: {})",
350+
estimated_proof_size,
351+
actual_proof_size,
352+
estimated_proof_size.saturating_sub(actual_proof_size),
353+
);
342354
actual_proof_size
343355
}
344356
} else {

primitives/ethereum/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ impl TransactionData {
8484
pub fn proof_size_base_cost(&self) -> u64 {
8585
self.encode()
8686
.len()
87+
// The real struct [EIP1559Transaction] doesn't have
88+
// Option wrapper for gas_price, max_fee_per_gas and max_priority_fee_per_gas
89+
// so we need to remove the size of the Option wrapper
90+
.saturating_sub(3)
8791
// signature
8892
.saturating_add(65)
8993
// pallet index

0 commit comments

Comments
 (0)