Skip to content

Commit

Permalink
fix(gas): refactor bundle gas calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-miao committed Oct 3, 2023
1 parent d1bfebb commit 10c13ed
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 21 deletions.
16 changes: 4 additions & 12 deletions crates/builder/src/bundle_proposer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,8 @@ use crate::emit::{BuilderEvent, OpRejectionReason, SkipReason};

/// A user op must be valid for at least this long into the future to be included.
const TIME_RANGE_BUFFER: Duration = Duration::from_secs(60);
/// Entrypoint requires a buffer over the user operation gas limits in the bundle transaction
const BUNDLE_TRANSACTION_GAS_OVERHEAD_BUFFER: u64 = 5000;
/// Extra buffer percent to add on the bundle transaction gas estimate to be sure it will be enough
const BUNDLE_TRANSACTION_GAS_OVERHEAD_PERCENT: u64 = 5;
/// The fixed gas overhead for any EVM transaction
const EVM_TRANSACTION_GAS_OVERHEAD: u64 = 21000;

#[derive(Debug, Default)]
pub(crate) struct Bundle {
Expand Down Expand Up @@ -741,11 +737,7 @@ impl ProposalContext {
}

fn get_total_gas_limit(&self, chain_id: u64) -> U256 {
self.iter_ops()
.map(|op| gas::user_operation_gas_limit(op, chain_id, false))
.fold(U256::zero(), |acc, c| acc + c)
+ BUNDLE_TRANSACTION_GAS_OVERHEAD_BUFFER
+ EVM_TRANSACTION_GAS_OVERHEAD
gas::bundle_gas_limit(self.iter_ops(), chain_id)
}

fn iter_ops_with_simulations(&self) -> impl Iterator<Item = &OpWithSimulation> + '_ {
Expand Down Expand Up @@ -789,8 +781,8 @@ mod tests {
op.pre_verification_gas
+ op.verification_gas_limit * 2
+ op.call_gas_limit
+ BUNDLE_TRANSACTION_GAS_OVERHEAD_BUFFER
+ EVM_TRANSACTION_GAS_OVERHEAD,
+ U256::from(5_000)
+ U256::from(21_000),
BUNDLE_TRANSACTION_GAS_OVERHEAD_PERCENT,
);

Expand Down Expand Up @@ -1202,7 +1194,7 @@ mod tests {
assert_eq!(
bundle.gas_estimate,
U256::from(math::increase_by_percent(
10_000_000 + BUNDLE_TRANSACTION_GAS_OVERHEAD_BUFFER + EVM_TRANSACTION_GAS_OVERHEAD,
10_000_000 + 5_000 + 21_000,
BUNDLE_TRANSACTION_GAS_OVERHEAD_PERCENT
))
);
Expand Down
35 changes: 27 additions & 8 deletions crates/sim/src/gas/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ use super::polygon::Polygon;
// see: https://github.com/eth-infinitism/bundler/blob/main/packages/sdk/src/calcPreVerificationGas.ts
#[derive(Clone, Copy, Debug)]
struct GasOverheads {
fixed: U256,
bundle_transaction_gas_buffer: U256,
transaction_gas_overhead: U256,
per_user_op: U256,
per_user_op_word: U256,
zero_byte: U256,
Expand All @@ -43,8 +44,9 @@ struct GasOverheads {
impl Default for GasOverheads {
fn default() -> Self {
Self {
fixed: 21000.into(),
per_user_op: 18300.into(),
bundle_transaction_gas_buffer: 5_000.into(), // Entrypoint requires a buffer over the user operation gas limits in the bundle transaction
transaction_gas_overhead: 21_000.into(), // The fixed gas overhead for any EVM transaction
per_user_op: 18_300.into(),
per_user_op_word: 4.into(),
zero_byte: 4.into(),
non_zero_byte: 16.into(),
Expand Down Expand Up @@ -72,7 +74,7 @@ pub async fn calc_pre_verification_gas<P: Provider>(
provider: Arc<P>,
chain_id: u64,
) -> anyhow::Result<U256> {
let static_gas = calc_static_pre_verification_gas(full_op, true);
let static_gas = calc_static_pre_verification_gas(full_op, GasOverheads::default(), true);
let dynamic_gas = match chain_id {
_ if ARBITRUM_CHAIN_IDS.contains(&chain_id) => {
provider
Expand All @@ -92,6 +94,20 @@ pub async fn calc_pre_verification_gas<P: Provider>(
Ok(static_gas + dynamic_gas)
}

/// Compute the gas limit for the bundle composed of the given user operations
pub fn bundle_gas_limit<'a, I>(iter_ops: I, chain_id: u64) -> U256
where
I: Iterator<Item = &'a UserOperation>,
{
let ov = GasOverheads::default();
iter_ops
.map(|op| user_operation_gas_limit(op, chain_id, false))
.fold(
ov.bundle_transaction_gas_buffer + ov.transaction_gas_overhead,
|acc, c| acc + c,
)
}

/// Returns the gas limit for the user operation that applies to bundle transaction's limit
pub fn user_operation_gas_limit(
uo: &UserOperation,
Expand All @@ -102,7 +118,7 @@ pub fn user_operation_gas_limit(
// but this not part of the execution gas limit of the transaction.
// In such cases we only consider the static portion of the pre_verification_gas in the gas limit.
let pvg = if OP_BEDROCK_CHAIN_IDS.contains(&chain_id) | ARBITRUM_CHAIN_IDS.contains(&chain_id) {
calc_static_pre_verification_gas(uo, include_fixed_gas_overhead)
calc_static_pre_verification_gas(uo, GasOverheads::default(), include_fixed_gas_overhead)
} else {
uo.pre_verification_gas
};
Expand All @@ -117,8 +133,11 @@ pub fn user_operation_max_gas_cost(uo: &UserOperation) -> U256 {
* (uo.pre_verification_gas + uo.call_gas_limit + uo.verification_gas_limit * mul)
}

fn calc_static_pre_verification_gas(op: &UserOperation, include_fixed_gas_overhead: bool) -> U256 {
let ov = GasOverheads::default();
fn calc_static_pre_verification_gas(
op: &UserOperation,
ov: GasOverheads,
include_fixed_gas_overhead: bool,
) -> U256 {
let encoded_op = op.clone().encode();
let length_in_words = encoded_op.len() / 32; // size of packed user op is always a multiple of 32 bytes
let call_data_cost: U256 = encoded_op
Expand All @@ -137,7 +156,7 @@ fn calc_static_pre_verification_gas(op: &UserOperation, include_fixed_gas_overhe
+ ov.per_user_op
+ ov.per_user_op_word * length_in_words
+ (if include_fixed_gas_overhead {
ov.fixed
ov.transaction_gas_overhead
} else {
0.into()
})
Expand Down
2 changes: 1 addition & 1 deletion crates/sim/src/precheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ impl<P: Provider, E: EntryPoint> PrecheckerImpl<P, E> {
max_verification_gas,
));
}
let total_gas_limit = gas::user_operation_gas_limit(op, chain_id, false);
let total_gas_limit = gas::user_operation_gas_limit(op, chain_id, true);
if total_gas_limit > max_total_execution_gas {
violations.push(PrecheckViolation::TotalGasLimitTooHigh(
total_gas_limit,
Expand Down

0 comments on commit 10c13ed

Please sign in to comment.