Skip to content

Commit 6dae0e5

Browse files
TarekkMARomarQ
authored andcommitted
Address POV Underestimations (#244)
1 parent 01f6ebb commit 6dae0e5

File tree

3 files changed

+55
-8
lines changed

3 files changed

+55
-8
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

@@ -672,6 +673,35 @@ pub mod pallet {
672673
#[pallet::storage]
673674
pub type AccountStorages<T: Config> =
674675
StorageDoubleMap<_, Blake2_128Concat, H160, Blake2_128Concat, H256, H256, ValueQuery>;
676+
677+
#[pallet::hooks]
678+
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
679+
fn on_initialize(_: BlockNumberFor<T>) -> Weight {
680+
let mut total_weight = Weight::zero();
681+
682+
// Do dummy read to populate the pov with the intermediates nodes,
683+
// only when proof size recording is enabled.
684+
if let Some(pov_before) = get_proof_size() {
685+
const ZERO_ACCOUNT: H160 = H160::zero();
686+
687+
// just a dummy read to populate the pov with the intermediates nodes
688+
let _ = AccountCodesMetadata::<T>::get(ZERO_ACCOUNT.clone());
689+
let (_, min_gas_weight) = T::FeeCalculator::min_gas_price();
690+
let (_, account_basic_weight) = Pallet::<T>::account_basic(&ZERO_ACCOUNT);
691+
692+
let pov = get_proof_size().unwrap_or_default() - pov_before;
693+
694+
total_weight = total_weight
695+
.saturating_add(Weight::from_parts(0, pov))
696+
.saturating_add(T::DbWeight::get().reads(1))
697+
.saturating_add(account_basic_weight)
698+
.saturating_add(min_gas_weight);
699+
700+
}
701+
702+
total_weight
703+
}
704+
}
675705
}
676706

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

frame/evm/src/runner/stack.rs

Lines changed: 21 additions & 8 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
@@ -332,12 +337,20 @@ where
332337
if actual_proof_size > estimated_proof_size {
333338
log::debug!(
334339
target: "evm",
335-
"Proof size underestimation detected! (estimated: {}, actual: {})",
340+
"Proof size underestimation detected! (estimated: {}, actual: {}, diff: {})",
336341
estimated_proof_size,
337-
actual_proof_size
342+
actual_proof_size,
343+
actual_proof_size.saturating_sub(estimated_proof_size),
338344
);
339345
estimated_proof_size
340346
} 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+
);
341354
actual_proof_size
342355
}
343356
} 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)