Skip to content

Commit

Permalink
fix(levm): move insufficient max fee per blob gas check in `prepare_e…
Browse files Browse the repository at this point in the history
…xecution` (#1564)

**Motivation**

Currently we are charging the sender the entire upfront cost, even when
there are not enough funds to pay for the provided amount of blobhashes.
This returns a `TxValidation` error of type `InsufficientAccountFunds`,
when in reality the error we should be raising is
`InsufficientMaxFeePerBlobGas`.


**Description**

This patch moves the insufficient max fee per blob gas check up. Now,
before the user is charged with the entire `upfront cost`, it is checked
if the provided max fee per blob gas will cover the blobhash cost. If
not, we return a `InsufficientMaxFeePerBlobGas` error, before even
trying to charge for the upfront cost.
  • Loading branch information
lima-limon-inc authored Dec 26, 2024
1 parent 9ae9da9 commit ae08aff
Showing 1 changed file with 21 additions and 18 deletions.
39 changes: 21 additions & 18 deletions crates/vm/levm/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,15 @@ impl VM {

let blob_gas_cost = self.get_blob_gas_price()?;

// (2) INSUFFICIENT_MAX_FEE_PER_BLOB_GAS
if let Some(tx_max_fee_per_blob_gas) = self.env.tx_max_fee_per_blob_gas {
if tx_max_fee_per_blob_gas < self.get_base_fee_per_blob_gas()? {
return Err(VMError::TxValidation(
TxValidationError::InsufficientMaxFeePerBlobGas,
));
}
}

// The real cost to deduct is calculated as effective_gas_price * gas_limit + value + blob_gas_cost
let up_front_cost = gaslimit_price_product
.checked_add(value)
Expand All @@ -721,9 +730,12 @@ impl VM {
.ok_or(VMError::TxValidation(
TxValidationError::InsufficientAccountFunds,
))?;
// There is no error specified for overflow in up_front_cost in ef_tests. Maybe we can go with GasLimitPriceProductOverflow or InsufficientAccountFunds.
// There is no error specified for overflow in up_front_cost
// in ef_tests. We went for "InsufficientAccountFunds" simply
// because if the upfront cost is bigger than U256, then,
// technically, the sender will not be able to pay it.

// (2) INSUFFICIENT_ACCOUNT_FUNDS
// (3) INSUFFICIENT_ACCOUNT_FUNDS
self.decrease_account_balance(sender_address, up_front_cost)
.map_err(|_| TxValidationError::InsufficientAccountFunds)?;

Expand All @@ -734,14 +746,14 @@ impl VM {
self.increase_account_balance(receiver_address, initial_call_frame.msg_value)?;
}

// (3) INSUFFICIENT_MAX_FEE_PER_GAS
// (4) INSUFFICIENT_MAX_FEE_PER_GAS
if self.env.tx_max_fee_per_gas.unwrap_or(self.env.gas_price) < self.env.base_fee_per_gas {
return Err(VMError::TxValidation(
TxValidationError::InsufficientMaxFeePerGas,
));
}

// (4) INITCODE_SIZE_EXCEEDED
// (5) INITCODE_SIZE_EXCEEDED
if self.is_create() {
// INITCODE_SIZE_EXCEEDED
if initial_call_frame.calldata.len() > INIT_CODE_MAX_SIZE {
Expand All @@ -751,14 +763,14 @@ impl VM {
}
}

// (5) INTRINSIC_GAS_TOO_LOW
// (6) INTRINSIC_GAS_TOO_LOW
self.add_intrinsic_gas(initial_call_frame)?;

// (6) NONCE_IS_MAX
// (7) NONCE_IS_MAX
self.increment_account_nonce(sender_address)
.map_err(|_| VMError::TxValidation(TxValidationError::NonceIsMax))?;

// (7) PRIORITY_GREATER_THAN_MAX_FEE_PER_GAS
// (8) PRIORITY_GREATER_THAN_MAX_FEE_PER_GAS
if let (Some(tx_max_priority_fee), Some(tx_max_fee_per_gas)) = (
self.env.tx_max_priority_fee_per_gas,
self.env.tx_max_fee_per_gas,
Expand All @@ -770,27 +782,18 @@ impl VM {
}
}

// (8) SENDER_NOT_EOA
// (9) SENDER_NOT_EOA
if sender_account.has_code() {
return Err(VMError::TxValidation(TxValidationError::SenderNotEOA));
}

// (9) GAS_ALLOWANCE_EXCEEDED
// (10) GAS_ALLOWANCE_EXCEEDED
if self.env.gas_limit > self.env.block_gas_limit {
return Err(VMError::TxValidation(
TxValidationError::GasAllowanceExceeded,
));
}

// (10) INSUFFICIENT_MAX_FEE_PER_BLOB_GAS
if let Some(tx_max_fee_per_blob_gas) = self.env.tx_max_fee_per_blob_gas {
if tx_max_fee_per_blob_gas < self.get_base_fee_per_blob_gas()? {
return Err(VMError::TxValidation(
TxValidationError::InsufficientMaxFeePerBlobGas,
));
}
}

// Transaction is type 3 if tx_max_fee_per_blob_gas is Some
if self.env.tx_max_fee_per_blob_gas.is_some() {
let blob_hashes = &self.env.tx_blob_hashes;
Expand Down

0 comments on commit ae08aff

Please sign in to comment.