Skip to content

Commit

Permalink
feat(tracer): add timeout of 10s to tracer (#730)
Browse files Browse the repository at this point in the history
  • Loading branch information
0xfourzerofour committed Jun 18, 2024
1 parent 98f8e2c commit 23da122
Show file tree
Hide file tree
Showing 15 changed files with 116 additions and 53 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions bin/rundler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dotenv = "0.15.0"
ethers.workspace = true
itertools = "0.12.1"
metrics = "0.22.1"
go-parse-duration = "0.1"
metrics-exporter-prometheus = { version = "0.13.1", default-features = false, features = ["http-listener"] }
metrics-process = "1.2.1"
metrics-util = "0.16.2"
Expand Down
2 changes: 1 addition & 1 deletion bin/rundler/src/cli/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ impl BuilderArgs {
priority_fee_mode,
sender_args,
eth_poll_interval: Duration::from_millis(common.eth_poll_interval_millis),
sim_settings: common.into(),
sim_settings: common.try_into()?,
max_blocks_to_wait_for_mine: self.max_blocks_to_wait_for_mine,
replacement_fee_percent_increase: self.replacement_fee_percent_increase,
max_fee_increases: self.max_fee_increases,
Expand Down
28 changes: 23 additions & 5 deletions bin/rundler/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// You should have received a copy of the GNU General Public License along with Rundler.
// If not, see https://www.gnu.org/licenses/.

use anyhow::Context;
use anyhow::{bail, Context};
use clap::{builder::PossibleValuesParser, Args, Parser, Subcommand};

mod builder;
Expand Down Expand Up @@ -163,6 +163,17 @@ pub struct CommonArgs {
)]
min_unstake_delay: u32,

/// String representation of the timeout of a custom tracer in a format that is parsable by the
/// `ParseDuration` function on the ethereum node. See Docs: https://pkg.go.dev/time#ParseDuration
#[arg(
long = "tracer_timeout",
name = "tracer_timeout",
env = "TRACER_TIMEOUT",
default_value = "15s",
global = true
)]
tracer_timeout: String,

/// Amount of blocks to search when calling eth_getUserOperationByHash.
/// Defaults from 0 to latest block
#[arg(
Expand Down Expand Up @@ -357,14 +368,21 @@ impl TryFrom<&CommonArgs> for PrecheckSettings {
}
}

impl From<&CommonArgs> for SimulationSettings {
fn from(value: &CommonArgs) -> Self {
Self::new(
impl TryFrom<&CommonArgs> for SimulationSettings {
type Error = anyhow::Error;

fn try_from(value: &CommonArgs) -> Result<Self, Self::Error> {
if go_parse_duration::parse_duration(&value.tracer_timeout).is_err() {
bail!("Invalid value for tracer_timeout, must be parsable by the ParseDuration function. See docs https://pkg.go.dev/time#ParseDuration")
}

Ok(Self::new(
value.min_unstake_delay,
value.min_stake_value,
value.max_simulate_handle_ops_gas,
value.max_verification_gas,
)
value.tracer_timeout.clone(),
))
}
}

Expand Down
2 changes: 1 addition & 1 deletion bin/rundler/src/cli/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ impl PoolArgs {
blocklist: blocklist.clone(),
allowlist: allowlist.clone(),
precheck_settings: common.try_into()?,
sim_settings: common.into(),
sim_settings: common.try_into()?,
throttled_entity_mempool_count: self.throttled_entity_mempool_count,
throttled_entity_live_blocks: self.throttled_entity_live_blocks,
paymaster_tracking_enabled: self.paymaster_tracking_enabled,
Expand Down
8 changes: 4 additions & 4 deletions crates/builder/src/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ where
UnsafeSimulator::new(
Arc::clone(&provider),
ep_v0_6.clone(),
self.args.sim_settings,
self.args.sim_settings.clone(),
),
)
.await?
Expand All @@ -279,7 +279,7 @@ where
simulation::new_v0_6_simulator(
Arc::clone(&provider),
ep_v0_6.clone(),
self.args.sim_settings,
self.args.sim_settings.clone(),
ep.mempool_configs.clone(),
),
)
Expand Down Expand Up @@ -316,7 +316,7 @@ where
UnsafeSimulator::new(
Arc::clone(&provider),
ep_v0_7.clone(),
self.args.sim_settings,
self.args.sim_settings.clone(),
),
)
.await?
Expand All @@ -328,7 +328,7 @@ where
simulation::new_v0_7_simulator(
Arc::clone(&provider),
ep_v0_7.clone(),
self.args.sim_settings,
self.args.sim_settings.clone(),
ep.mempool_configs.clone(),
),
)
Expand Down
18 changes: 12 additions & 6 deletions crates/pool/src/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,11 @@ impl PoolTask {
);

if unsafe_mode {
let simulator =
UnsafeSimulator::new(Arc::clone(&provider), ep.clone(), pool_config.sim_settings);
let simulator = UnsafeSimulator::new(
Arc::clone(&provider),
ep.clone(),
pool_config.sim_settings.clone(),
);
Self::create_mempool(
chain_spec,
pool_config,
Expand All @@ -210,7 +213,7 @@ impl PoolTask {
let simulator = simulation::new_v0_6_simulator(
Arc::clone(&provider),
ep.clone(),
pool_config.sim_settings,
pool_config.sim_settings.clone(),
pool_config.mempool_channel_configs.clone(),
);
Self::create_mempool(
Expand Down Expand Up @@ -239,8 +242,11 @@ impl PoolTask {
);

if unsafe_mode {
let simulator =
UnsafeSimulator::new(Arc::clone(&provider), ep.clone(), pool_config.sim_settings);
let simulator = UnsafeSimulator::new(
Arc::clone(&provider),
ep.clone(),
pool_config.sim_settings.clone(),
);
Self::create_mempool(
chain_spec,
pool_config,
Expand All @@ -253,7 +259,7 @@ impl PoolTask {
let simulator = simulation::new_v0_7_simulator(
Arc::clone(&provider),
ep.clone(),
pool_config.sim_settings,
pool_config.sim_settings.clone(),
pool_config.mempool_channel_configs.clone(),
);
Self::create_mempool(
Expand Down
4 changes: 2 additions & 2 deletions crates/sim/src/simulation/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ pub(crate) fn infos_from_validation_output(
sender_address: Address,
paymaster_address: Option<Address>,
entry_point_out: &ValidationOutput,
sim_settings: Settings,
sim_settings: &Settings,
) -> EntityInfos {
let mut ei = EntityInfos::default();
ei.set_sender(
Expand Down Expand Up @@ -153,7 +153,7 @@ pub(crate) fn infos_from_validation_output(
ei
}

pub(crate) fn is_staked(info: StakeInfo, sim_settings: Settings) -> bool {
pub(crate) fn is_staked(info: StakeInfo, sim_settings: &Settings) -> bool {
info.stake >= sim_settings.min_stake_value.into()
&& info.unstake_delay_sec >= sim_settings.min_unstake_delay.into()
}
Expand Down
8 changes: 7 additions & 1 deletion crates/sim/src/simulation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ pub trait Simulator: Send + Sync + 'static {
}

/// Simulation Settings
#[derive(Debug, Copy, Clone)]
#[derive(Debug, Clone)]
pub struct Settings {
/// The minimum amount of time that a staked entity must have configured as
/// their unstake delay on the entry point contract in order to be considered staked.
Expand All @@ -162,6 +162,9 @@ pub struct Settings {
pub max_simulate_handle_ops_gas: u64,
/// The maximum amount of verification gas that can be used during the simulation call
pub max_verification_gas: u64,
/// The max duration of the custom javascript tracer. Must be in a format parseable by the
/// ParseDuration function on an ethereum node. See Docs: https://pkg.go.dev/time#ParseDuration
pub tracer_timeout: String,
}

impl Settings {
Expand All @@ -171,12 +174,14 @@ impl Settings {
min_stake_value: u128,
max_simulate_handle_ops_gas: u64,
max_verification_gas: u64,
tracer_timeout: String,
) -> Self {
Self {
min_unstake_delay,
min_stake_value,
max_simulate_handle_ops_gas,
max_verification_gas,
tracer_timeout,
}
}
}
Expand All @@ -192,6 +197,7 @@ impl Default for Settings {
// 550 million gas: currently the defaults for Alchemy eth_call
max_simulate_handle_ops_gas: 550_000_000,
max_verification_gas: 5_000_000,
tracer_timeout: "10s".to_string(),
}
}
}
10 changes: 5 additions & 5 deletions crates/sim/src/simulation/simulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ where
SimulatorImpl::new(
provider.clone(),
entry_point.clone(),
ValidationContextProviderV0_6::new(provider, entry_point, sim_settings),
ValidationContextProviderV0_6::new(provider, entry_point, sim_settings.clone()),
sim_settings,
mempool_configs,
)
Expand All @@ -86,7 +86,7 @@ where
SimulatorImpl::new(
provider.clone(),
entry_point.clone(),
ValidationContextProviderV0_7::new(provider, entry_point, sim_settings),
ValidationContextProviderV0_7::new(provider, entry_point, sim_settings.clone()),
sim_settings,
mempool_configs,
)
Expand Down Expand Up @@ -345,7 +345,7 @@ where
}

if let Some(aggregator_info) = entry_point_out.aggregator_info {
if !context::is_staked(aggregator_info.stake_info, self.sim_settings) {
if !context::is_staked(aggregator_info.stake_info, &self.sim_settings) {
// [EREP-040]
violations.push(SimulationViolation::UnstakedAggregator)
}
Expand Down Expand Up @@ -514,7 +514,7 @@ where
sender_info,
..
} = entry_point_out;
let account_is_staked = context::is_staked(sender_info, self.sim_settings);
let account_is_staked = context::is_staked(sender_info, &self.sim_settings);
let ValidationReturnInfo {
pre_op_gas,
valid_after,
Expand Down Expand Up @@ -798,7 +798,7 @@ mod tests {
paymaster_info: StakeInfo::from((U256::default(), U256::default())),
aggregator_info: None,
},
Settings::default(),
&Settings::default(),
),
tracer_out,
entry_point_out: ValidationOutput {
Expand Down
36 changes: 19 additions & 17 deletions crates/sim/src/simulation/v0_6/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ where
let paymaster_address = op.paymaster();
let tracer_out = self
.simulate_validation_tracer
.trace_simulate_validation(op.clone(), block_id, self.sim_settings.max_verification_gas)
.trace_simulate_validation(op.clone(), block_id)
.await?;
let num_phases = tracer_out.phases.len() as u32;
// Check if there are too many phases here, then check too few at the
Expand Down Expand Up @@ -107,7 +107,7 @@ where
sender_address,
paymaster_address,
&entry_point_out,
self.sim_settings,
&self.sim_settings,
);

let associated_addresses = tracer_out.associated_slots_by_address.addresses();
Expand Down Expand Up @@ -181,7 +181,12 @@ where
/// Creates a new `ValidationContextProvider` for entry point v0.6 with the given provider and entry point.
pub(crate) fn new(provider: Arc<P>, entry_point: E, sim_settings: SimulationSettings) -> Self {
Self {
simulate_validation_tracer: SimulateValidationTracerImpl::new(provider, entry_point),
simulate_validation_tracer: SimulateValidationTracerImpl::new(
provider,
entry_point,
sim_settings.max_verification_gas,
sim_settings.tracer_timeout.clone(),
),
sim_settings,
}
}
Expand Down Expand Up @@ -275,7 +280,6 @@ mod tests {
&self,
op: UserOperation,
block_id: BlockId,
max_validation_gas: u64,
) -> anyhow::Result<TracerOutput>;
}
}
Expand All @@ -284,19 +288,17 @@ mod tests {
async fn test_create_context_two_phases_unintended_revert() {
let mut tracer = MockTracer::new();

tracer
.expect_trace_simulate_validation()
.returning(|_, _, _| {
let mut tracer_output = get_test_tracer_output();
tracer_output.revert_data = Some(hex::encode(
FailedOp {
op_index: U256::from(100),
reason: "AA23 reverted (or OOG)".to_string(),
}
.encode(),
));
Ok(tracer_output)
});
tracer.expect_trace_simulate_validation().returning(|_, _| {
let mut tracer_output = get_test_tracer_output();
tracer_output.revert_data = Some(hex::encode(
FailedOp {
op_index: U256::from(100),
reason: "AA23 reverted (or OOG)".to_string(),
}
.encode(),
));
Ok(tracer_output)
});

let user_operation = UserOperation {
sender: Address::from_str("b856dbd4fa1a79a46d426f537455e7d3e79ab7c4").unwrap(),
Expand Down
Loading

0 comments on commit 23da122

Please sign in to comment.