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

feat: eip-7623 #1744

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
30 changes: 20 additions & 10 deletions crates/interpreter/src/gas/calc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,17 +371,14 @@ pub fn validate_initial_tx_gas(
authorization_list_num: u64,
) -> u64 {
let mut initial_gas = 0;
let zero_data_len = input.iter().filter(|v| **v == 0).count() as u64;
let non_zero_data_len = input.len() as u64 - zero_data_len;

// initdate stipend
initial_gas += zero_data_len * TRANSACTION_ZERO_DATA;
// EIP-2028: Transaction data gas cost reduction
initial_gas += non_zero_data_len
* if spec_id.is_enabled_in(SpecId::ISTANBUL) {
16
let tokens_in_calldata = get_tokens_in_calldata(input, spec_id.is_enabled_in(SpecId::ISTANBUL));
initial_gas += tokens_in_calldata
* if spec_id.is_enabled_in(SpecId::PRAGUE) {
// EIP-7623: Deduct full cost floor per token to avoid invalidation after execution
TOTAL_COST_FLOOR_PER_TOKEN
} else {
68
STANDARD_TOKEN_COST
};

// get number of access list account and storages.
Expand Down Expand Up @@ -409,10 +406,23 @@ pub fn validate_initial_tx_gas(
initial_gas += initcode_cost(input.len() as u64)
}

// EIP-7702
// EIP-7702
if spec_id.is_enabled_in(SpecId::PRAGUE) {
initial_gas += authorization_list_num * eip7702::PER_EMPTY_ACCOUNT_COST;
}

initial_gas
}

/// Retrieve the total number of tokens in calldata.
pub fn get_tokens_in_calldata(input: &[u8], is_istanbul: bool) -> u64 {
let zero_data_len = input.iter().filter(|v| **v == 0).count() as u64;
let non_zero_data_len = input.len() as u64 - zero_data_len;
let non_zero_data_multiplier = if is_istanbul {
// EIP-2028: Transaction data gas cost reduction
NON_ZERO_BYTE_MULTIPLIER_ISTANBUL
} else {
NON_ZERO_BYTE_MULTIPLIER
};
zero_data_len + non_zero_data_len * non_zero_data_multiplier
}
16 changes: 13 additions & 3 deletions crates/interpreter/src/gas/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,19 @@ pub const SSTORE_SET: u64 = 20000;
pub const SSTORE_RESET: u64 = 5000;
pub const REFUND_SSTORE_CLEARS: i64 = 15000;

pub const TRANSACTION_ZERO_DATA: u64 = 4;
pub const TRANSACTION_NON_ZERO_DATA_INIT: u64 = 16;
pub const TRANSACTION_NON_ZERO_DATA_FRONTIER: u64 = 68;
/// The standard cost of calldata token.
pub const STANDARD_TOKEN_COST: u64 = 4;
/// The cost of a non-zero byte in calldata.
pub const NON_ZERO_BYTE_DATA_COST: u64 = 68;
/// The multiplier for a non zero byte in calldata.
pub const NON_ZERO_BYTE_MULTIPLIER: u64 = NON_ZERO_BYTE_DATA_COST / STANDARD_TOKEN_COST;
/// The cost of a non-zero byte in calldata adjusted by [EIP-2028](https://eips.ethereum.org/EIPS/eip-2028).
pub const NON_ZERO_BYTE_DATA_COST_ISTANBUL: u64 = 16;
/// The multiplier for a non zero byte in calldata adjusted by [EIP-2028](https://eips.ethereum.org/EIPS/eip-2028).
pub const NON_ZERO_BYTE_MULTIPLIER_ISTANBUL: u64 =
NON_ZERO_BYTE_DATA_COST_ISTANBUL / STANDARD_TOKEN_COST;
// The cost floor per token as defined by [EIP-2028](https://eips.ethereum.org/EIPS/eip-2028).
pub const TOTAL_COST_FLOOR_PER_TOKEN: u64 = 10;

pub const EOF_CREATE_GAS: u64 = 32000;

Expand Down
22 changes: 21 additions & 1 deletion crates/revm/src/handler/mainnet/post_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{
},
Context, FrameResult,
};
use revm_interpreter::{gas::*, Host};

/// Mainnet end handle does not change the output.
#[inline]
Expand Down Expand Up @@ -57,12 +58,31 @@ pub fn reward_beneficiary<SPEC: Spec, EXT, DB: Database>(
}

pub fn refund<SPEC: Spec, EXT, DB: Database>(
_context: &mut Context<EXT, DB>,
context: &mut Context<EXT, DB>,
gas: &mut Gas,
eip7702_refund: i64,
) {
gas.record_refund(eip7702_refund);

// EIP-7623: Increase calldata cost
if context.evm.spec_id().is_enabled_in(SpecId::PRAGUE) {
let tokens_in_calldata = get_tokens_in_calldata(
context.env().tx.data.as_ref(),
true, // Istanbul is enabled in Prague
);
let token_cost_difference =
tokens_in_calldata * (TOTAL_COST_FLOOR_PER_TOKEN - STANDARD_TOKEN_COST);
// We already charged token cost floor as part of intrinsic gas, subtract the difference from current gas used.
let standard_cost = gas.spent() - token_cost_difference;
let floor = 21_000 + tokens_in_calldata * TOTAL_COST_FLOOR_PER_TOKEN;

if standard_cost > floor {
// Return gas charged as token cost floor.
// TODO: should it be refund instead?
gas.erase_cost(token_cost_difference);
}
}

// Calculate gas refund for transaction.
// If spec is set to london, it will decrease the maximum refund amount to 5th part of
// gas spend. (Before london it was 2th part of gas spend)
Expand Down
Loading