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

refactor: modify uo gas limit calcs & v0.6 builder #828

Merged
merged 2 commits into from
Oct 7, 2024
Merged
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
7 changes: 4 additions & 3 deletions bin/rundler/chain_specs/arbitrum.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
name = "Arbitrum"
id = 42161

calldata_pre_verification_gas = true
l1_gas_oracle_contract_type = "ARBITRUM_NITRO"
l1_gas_oracle_contract_address = "0x00000000000000000000000000000000000000C8"
da_pre_verification_gas = true
da_gas_oracle_contract_type = "ARBITRUM_NITRO"
da_gas_oracle_contract_address = "0x00000000000000000000000000000000000000C8"
include_da_gas_in_gas_limit = true

supports_eip1559 = false
max_transaction_size_bytes = 95000
7 changes: 3 additions & 4 deletions bin/rundler/chain_specs/base.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
name = "Base"
id = 8453

calldata_pre_verification_gas = true
l1_gas_oracle_contract_type = "OPTIMISM_BEDROCK"
l1_gas_oracle_contract_address = "0x420000000000000000000000000000000000000F"
include_l1_gas_in_gas_limit = false
da_pre_verification_gas = true
da_gas_oracle_contract_type = "OPTIMISM_BEDROCK"
da_gas_oracle_contract_address = "0x420000000000000000000000000000000000000F"

max_transaction_size_bytes = 130000

Expand Down
7 changes: 3 additions & 4 deletions bin/rundler/chain_specs/optimism.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
name = "Optimism"
id = 10

calldata_pre_verification_gas = true
l1_gas_oracle_contract_type = "OPTIMISM_BEDROCK"
l1_gas_oracle_contract_address = "0x420000000000000000000000000000000000000F"
include_l1_gas_in_gas_limit = false
da_pre_verification_gas = true
da_gas_oracle_contract_type = "OPTIMISM_BEDROCK"
da_gas_oracle_contract_address = "0x420000000000000000000000000000000000000F"

priority_fee_oracle_type = "USAGE_BASED"
min_max_priority_fee_per_gas = 100000
Expand Down
6 changes: 3 additions & 3 deletions crates/builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ mockall = {workspace = true, optional = true }

[dev-dependencies]
mockall.workspace = true
rundler-types = { path = "../types", features = ["test-utils"] }
rundler-provider = { path = "../provider", features = ["test-utils"] }
rundler-sim = { path = "../sim", features = ["test-utils"] }
rundler-types = { workspace = true, features = ["test-utils"] }
rundler-provider = { workspace = true, features = ["test-utils"] }
rundler-sim = { workspace = true, features = ["test-utils"] }

[build-dependencies]
tonic-build.workspace = true
67 changes: 26 additions & 41 deletions crates/builder/src/bundle_proposer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use linked_hash_map::LinkedHashMap;
#[cfg(test)]
use mockall::automock;
use rundler_provider::{
BundleHandler, EntryPoint, EvmProvider, HandleOpsOut, L1GasProvider, SignatureAggregator,
BundleHandler, DAGasProvider, EntryPoint, EvmProvider, HandleOpsOut, SignatureAggregator,
};
use rundler_sim::{
gas, ExpectedStorage, FeeEstimator, PriorityFeeMode, SimulationError, SimulationResult,
Expand Down Expand Up @@ -163,7 +163,7 @@ where
UO: UserOperation + From<UserOperationVariant>,
UserOperationVariant: AsRef<UO>,
S: Simulator<UO = UO>,
E: EntryPoint + SignatureAggregator<UO = UO> + BundleHandler<UO = UO> + L1GasProvider<UO = UO>,
E: EntryPoint + SignatureAggregator<UO = UO> + BundleHandler<UO = UO> + DAGasProvider<UO = UO>,
P: EvmProvider,
M: Pool,
F: FeeEstimator,
Expand Down Expand Up @@ -307,7 +307,7 @@ where
UO: UserOperation + From<UserOperationVariant>,
UserOperationVariant: AsRef<UO>,
S: Simulator<UO = UO>,
E: EntryPoint + SignatureAggregator<UO = UO> + BundleHandler<UO = UO> + L1GasProvider<UO = UO>,
E: EntryPoint + SignatureAggregator<UO = UO> + BundleHandler<UO = UO> + DAGasProvider<UO = UO>,
P: EvmProvider,
M: Pool,
F: FeeEstimator,
Expand Down Expand Up @@ -470,7 +470,7 @@ where
let mut context = ProposalContext::<UO>::new();
let mut paymasters_to_reject = Vec::<EntityInfo>::new();

let mut gas_spent = self.settings.chain_spec.transaction_intrinsic_gas();
let mut gas_spent = rundler_types::bundle_shared_gas(&self.settings.chain_spec);
let mut constructed_bundle_size = BUNDLE_BYTE_OVERHEAD;
for (po, simulation) in ops_with_simulations {
let op = po.clone().uo;
Expand Down Expand Up @@ -525,8 +525,7 @@ where
}

// Skip this op if the bundle does not have enough remaining gas to execute it.
let required_gas = gas_spent
+ gas::user_operation_execution_gas_limit(&self.settings.chain_spec, &op, false);
let required_gas = gas_spent + op.execution_gas_limit(&self.settings.chain_spec, None);
if required_gas > self.settings.max_bundle_gas {
continue;
}
Expand Down Expand Up @@ -562,8 +561,7 @@ where
}

// Update the running gas that would need to be be spent to execute the bundle so far.
gas_spent +=
gas::user_operation_execution_gas_limit(&self.settings.chain_spec, &op, false);
gas_spent += op.execution_gas_limit(&self.settings.chain_spec, None);

constructed_bundle_size =
constructed_bundle_size.saturating_add(op_size_with_offset_word);
Expand Down Expand Up @@ -1000,8 +998,7 @@ where
for op in ops {
// Here we use optimistic gas limits for the UOs by assuming none of the paymaster UOs use postOp calls.
// This way after simulation once we have determined if each UO actually uses a postOp call or not we can still pack a full bundle
let gas =
gas::user_operation_execution_gas_limit(&self.settings.chain_spec, &op.uo, false);
let gas = op.uo.execution_gas_limit(&self.settings.chain_spec, None);
if gas_left < gas {
self.emit(BuilderEvent::skipped_op(
self.builder_index,
Expand Down Expand Up @@ -1241,9 +1238,9 @@ impl<UO: UserOperation> ProposalContext<UO> {
// needed to have the buffer for each op.

self.iter_ops_with_simulations()
.map(|sim_op| gas::user_operation_gas_limit(chain_spec, &sim_op.op, false))
.map(|sim_op| sim_op.op.gas_limit(chain_spec, None))
.sum::<u128>()
+ chain_spec.transaction_intrinsic_gas()
+ rundler_types::bundle_shared_gas(chain_spec)
}

fn iter_ops_with_simulations(&self) -> impl Iterator<Item = &OpWithSimulation<UO>> + '_ {
Expand Down Expand Up @@ -1420,8 +1417,8 @@ mod tests {
use rundler_sim::{MockFeeEstimator, MockSimulator};
use rundler_types::{
pool::{MockPool, SimulationViolation},
v0_6::{UserOperation, ENTRY_POINT_INNER_GAS_OVERHEAD},
UserOperation as UserOperationTrait, ValidTimeRange,
v0_6::UserOperation,
UserOperation as _, ValidTimeRange,
};

use super::*;
Expand All @@ -1444,11 +1441,7 @@ mod tests {
let cs = ChainSpec::default();

let expected_gas: u64 = math::increase_by_percent(
op.pre_verification_gas
+ op.verification_gas_limit * 2
+ op.call_gas_limit
+ cs.transaction_intrinsic_gas()
+ ENTRY_POINT_INNER_GAS_OVERHEAD,
op.gas_limit(&cs, Some(1)),
BUNDLE_TRANSACTION_GAS_OVERHEAD_PERCENT,
)
.try_into()
Expand Down Expand Up @@ -1931,6 +1924,13 @@ mod tests {
)
.await;

let cs = ChainSpec::default();
let expected_gas_limit: u64 = (op1.gas_limit(&cs, None)
+ op2.gas_limit(&cs, None)
+ rundler_types::bundle_shared_gas(&cs))
.try_into()
.unwrap();

assert_eq!(bundle.entity_updates, vec![]);
assert_eq!(bundle.rejected_ops, vec![]);
assert_eq!(
Expand All @@ -1942,10 +1942,7 @@ mod tests {
);
assert_eq!(
bundle.gas_estimate,
math::increase_by_percent(
9_000_000 + 2 * 5_000 + 21_000,
BUNDLE_TRANSACTION_GAS_OVERHEAD_PERCENT
)
math::increase_by_percent(expected_gas_limit, BUNDLE_TRANSACTION_GAS_OVERHEAD_PERCENT)
);
}

Expand Down Expand Up @@ -1983,15 +1980,9 @@ mod tests {
entity_updates: BTreeMap::new(),
};

let expected_gas_limit = op1.pre_verification_gas
+ op1.verification_gas_limit * 2
+ op1.call_gas_limit
+ 5_000
+ op2.pre_verification_gas
+ op2.verification_gas_limit * 2
+ op2.call_gas_limit
+ 5_000
+ 21_000;
let expected_gas_limit = op1.gas_limit(&cs, None)
+ op2.gas_limit(&cs, None)
+ rundler_types::bundle_shared_gas(&cs);

assert_eq!(context.get_bundle_gas_limit(&cs), expected_gas_limit);
}
Expand Down Expand Up @@ -2031,15 +2022,9 @@ mod tests {
};
let gas_limit = context.get_bundle_gas_limit(&cs);

let expected_gas_limit = op1.pre_verification_gas
+ op1.verification_gas_limit * 3
+ op1.call_gas_limit
+ 5_000
+ op2.pre_verification_gas
+ op2.verification_gas_limit * 2
+ op2.call_gas_limit
+ 5_000
+ 21_000;
let expected_gas_limit = op1.gas_limit(&cs, None)
+ op2.gas_limit(&cs, None)
+ rundler_types::bundle_shared_gas(&cs);

assert_eq!(gas_limit, expected_gas_limit);
}
Expand Down
4 changes: 2 additions & 2 deletions crates/pool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ mockall = {workspace = true, optional = true }

[dev-dependencies]
mockall.workspace = true
rundler-sim = { path = "../sim", features = ["test-utils"] }
rundler-provider = { path = "../provider", features = ["test-utils"] }
rundler-sim = { workspace = true, features = ["test-utils"] }
rundler-provider = { workspace = true, features = ["test-utils"] }
reth-tasks.workspace = true

[build-dependencies]
Expand Down
32 changes: 18 additions & 14 deletions crates/pool/src/server/remote/protos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,21 +68,25 @@ pub trait TryUoFromProto<T>: Sized {
impl TryUoFromProto<UserOperationV06> for v0_6::UserOperation {
fn try_uo_from_proto(
op: UserOperationV06,
_chain_spec: &ChainSpec,
chain_spec: &ChainSpec,
) -> Result<Self, ConversionError> {
Ok(v0_6::UserOperation {
sender: from_bytes(&op.sender)?,
nonce: from_bytes(&op.nonce)?,
init_code: op.init_code.into(),
call_data: op.call_data.into(),
call_gas_limit: from_bytes(&op.call_gas_limit)?,
verification_gas_limit: from_bytes(&op.verification_gas_limit)?,
pre_verification_gas: from_bytes(&op.pre_verification_gas)?,
max_fee_per_gas: from_bytes(&op.max_fee_per_gas)?,
max_priority_fee_per_gas: from_bytes(&op.max_priority_fee_per_gas)?,
paymaster_and_data: op.paymaster_and_data.into(),
signature: op.signature.into(),
})
Ok(v0_6::UserOperationBuilder::new(
chain_spec,
v0_6::UserOperationRequiredFields {
sender: from_bytes(&op.sender)?,
nonce: from_bytes(&op.nonce)?,
init_code: op.init_code.into(),
call_data: op.call_data.into(),
call_gas_limit: from_bytes(&op.call_gas_limit)?,
verification_gas_limit: from_bytes(&op.verification_gas_limit)?,
pre_verification_gas: from_bytes(&op.pre_verification_gas)?,
max_fee_per_gas: from_bytes(&op.max_fee_per_gas)?,
max_priority_fee_per_gas: from_bytes(&op.max_priority_fee_per_gas)?,
paymaster_and_data: op.paymaster_and_data.into(),
signature: op.signature.into(),
},
)
.build())
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/provider/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ mockall = {workspace = true, optional = true }
test-utils = [ "mockall" ]

[dev-dependencies]
rundler-provider = { path = ".", features = ["test-utils"] }
rundler-provider = { workspace = true, features = ["test-utils"] }
alloy-provider = {workspace = true, features=["debug-api", "anvil-node"]}
alloy-node-bindings = "0.4.2"
tokio.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion crates/provider/src/alloy/entry_point/arbitrum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ sol! {
}
}

pub(crate) async fn estimate_l1_gas<AP: AlloyProvider<T>, T: Transport + Clone>(
pub(crate) async fn estimate_da_gas<AP: AlloyProvider<T>, T: Transport + Clone>(
provider: AP,
oracle_address: Address,
to_address: Address,
Expand Down
32 changes: 16 additions & 16 deletions crates/provider/src/alloy/entry_point/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use alloy_provider::Provider as AlloyProvider;
use alloy_rlp::Encodable;
use alloy_rpc_types_eth::TransactionRequest;
use alloy_transport::Transport;
use rundler_types::chain::{ChainSpec, L1GasOracleContractType};
use rundler_types::chain::{ChainSpec, DAGasOracleContractType};

use crate::ProviderResult;

Expand All @@ -28,41 +28,41 @@ mod arbitrum;
mod optimism;

#[derive(Debug, Default, Clone)]
enum L1GasOracle {
enum DAGasOracle {
ArbitrumNitro(Address),
OptimismBedrock(Address),
#[default]
None,
}

impl L1GasOracle {
fn new(chain_spec: &ChainSpec) -> L1GasOracle {
match chain_spec.l1_gas_oracle_contract_type {
L1GasOracleContractType::ArbitrumNitro => {
L1GasOracle::ArbitrumNitro(chain_spec.l1_gas_oracle_contract_address)
impl DAGasOracle {
fn new(chain_spec: &ChainSpec) -> DAGasOracle {
match chain_spec.da_gas_oracle_contract_type {
DAGasOracleContractType::ArbitrumNitro => {
DAGasOracle::ArbitrumNitro(chain_spec.da_gas_oracle_contract_address)
}
L1GasOracleContractType::OptimismBedrock => {
L1GasOracle::OptimismBedrock(chain_spec.l1_gas_oracle_contract_address)
DAGasOracleContractType::OptimismBedrock => {
DAGasOracle::OptimismBedrock(chain_spec.da_gas_oracle_contract_address)
}
L1GasOracleContractType::None => L1GasOracle::None,
DAGasOracleContractType::None => DAGasOracle::None,
}
}

async fn estimate_l1_gas<AP: AlloyProvider<T>, T: Transport + Clone>(
async fn estimate_da_gas<AP: AlloyProvider<T>, T: Transport + Clone>(
&self,
provider: AP,
to_address: Address,
data: Bytes,
gas_price: u128,
) -> ProviderResult<u128> {
match self {
L1GasOracle::ArbitrumNitro(oracle_address) => {
arbitrum::estimate_l1_gas(provider, *oracle_address, to_address, data).await
DAGasOracle::ArbitrumNitro(oracle_address) => {
arbitrum::estimate_da_gas(provider, *oracle_address, to_address, data).await
}
L1GasOracle::OptimismBedrock(oracle_address) => {
optimism::estimate_l1_gas(provider, *oracle_address, data, gas_price).await
DAGasOracle::OptimismBedrock(oracle_address) => {
optimism::estimate_da_gas(provider, *oracle_address, data, gas_price).await
}
L1GasOracle::None => Ok(0),
DAGasOracle::None => Ok(0),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/provider/src/alloy/entry_point/optimism.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ sol! {
}
}

pub(crate) async fn estimate_l1_gas<AP: AlloyProvider<T>, T: Transport + Clone>(
pub(crate) async fn estimate_da_gas<AP: AlloyProvider<T>, T: Transport + Clone>(
provider: AP,
oracle_address: Address,
data: Bytes,
Expand All @@ -41,7 +41,7 @@ pub(crate) async fn estimate_l1_gas<AP: AlloyProvider<T>, T: Transport + Clone>(
.await?
._0
.try_into()
.context("failed to convert L1 fee to u128")?;
.context("failed to convert DA fee to u128")?;

Ok(l1_fee.checked_div(gas_price).unwrap_or(u128::MAX))
}
Loading
Loading