Skip to content

Commit

Permalink
feat(pool): add a configurable maximum time allowed in pool
Browse files Browse the repository at this point in the history
  • Loading branch information
dancoombs committed Jan 9, 2025
1 parent 62d6907 commit 7f09531
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 3 deletions.
8 changes: 8 additions & 0 deletions bin/rundler/src/cli/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ pub struct PoolArgs {
default_value = "0.0"
)]
pub gas_limit_efficiency_reject_threshold: f32,

#[arg(
long = "pool.max_time_in_pool_secs",
name = "pool.max_time_in_pool_secs",
env = "POOL_MAX_TIME_IN_POOL_SECS"
)]
pub max_time_in_pool_secs: Option<u64>,
}

impl PoolArgs {
Expand Down Expand Up @@ -235,6 +242,7 @@ impl PoolArgs {
drop_min_num_blocks: self.drop_min_num_blocks,
da_gas_tracking_enabled,
gas_limit_efficiency_reject_threshold: self.gas_limit_efficiency_reject_threshold,
max_time_in_pool: self.max_time_in_pool_secs.map(Duration::from_secs),
};

let mut pool_configs = vec![];
Expand Down
3 changes: 3 additions & 0 deletions crates/pool/src/mempool/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ mod uo_pool;
use std::{
collections::{HashMap, HashSet},
sync::Arc,
time::Duration,
};

use alloy_primitives::{Address, B256};
Expand Down Expand Up @@ -170,6 +171,8 @@ pub struct PoolConfig {
/// Gas limit efficiency is defined as the ratio of the gas limit to the gas used.
/// This applies to all the verification, call, and paymaster gas limits.
pub gas_limit_efficiency_reject_threshold: f32,
/// Maximum time a UO is allowed in the pool before being dropped
pub max_time_in_pool: Option<Duration>,
}

/// Origin of an operation.
Expand Down
50 changes: 49 additions & 1 deletion crates/pool/src/mempool/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::{
cmp::Ordering,
collections::{hash_map::Entry, BTreeSet, HashMap, HashSet},
sync::Arc,
time::{Duration, SystemTime, UNIX_EPOCH},
time::{Duration, Instant, SystemTime, UNIX_EPOCH},
};

use alloy_primitives::{Address, B256};
Expand Down Expand Up @@ -47,6 +47,7 @@ pub(crate) struct PoolInnerConfig {
throttled_entity_mempool_count: u64,
throttled_entity_live_blocks: u64,
da_gas_tracking_enabled: bool,
max_time_in_pool: Option<Duration>,
}

impl From<PoolConfig> for PoolInnerConfig {
Expand All @@ -59,6 +60,7 @@ impl From<PoolConfig> for PoolInnerConfig {
throttled_entity_mempool_count: config.throttled_entity_mempool_count,
throttled_entity_live_blocks: config.throttled_entity_live_blocks,
da_gas_tracking_enabled: config.da_gas_tracking_enabled,
max_time_in_pool: config.max_time_in_pool,
}
}
}
Expand Down Expand Up @@ -259,6 +261,18 @@ where
});
expired.push(*hash);
continue;
} else if self
.config
.max_time_in_pool
.is_some_and(|m| op.elapsed_time_in_pool() > m)
{
events.push(PoolEvent::RemovedOp {
op_hash: *hash,
reason: OpRemovalReason::Expired {
valid_until: sys_block_time.into(),
},
});
expired.push(*hash);
}

if self.da_gas_oracle.is_some() && block_da_data.is_some() {
Expand Down Expand Up @@ -657,6 +671,7 @@ struct OrderedPoolOperation {
po: Arc<PoolOperation>,
submission_id: u64,
eligible: RwLock<bool>,
insertion_time: Instant,
}

impl OrderedPoolOperation {
Expand All @@ -665,6 +680,7 @@ impl OrderedPoolOperation {
po,
submission_id,
eligible: RwLock::new(eligible),
insertion_time: Instant::now(),
}
}

Expand All @@ -687,6 +703,10 @@ impl OrderedPoolOperation {
fn set_ineligible(&self) {
*self.eligible.write() = false;
}

fn elapsed_time_in_pool(&self) -> Duration {
self.insertion_time.elapsed()
}
}

impl Eq for OrderedPoolOperation {}
Expand Down Expand Up @@ -1402,6 +1422,33 @@ mod tests {
assert_eq!(pool.best_operations().collect::<Vec<_>>().len(), 0);
}

#[tokio::test]
async fn test_max_time_in_pool() {
let mut conf = conf();
conf.max_time_in_pool = Some(Duration::from_secs(1));
let po = create_op(Address::random(), 0, 10);
let mut pool = pool_with_conf(conf.clone());

let hash = pool.add_operation(po.clone(), 0).unwrap();
assert!(pool.get_operation_by_hash(hash).is_some());
pool.do_maintenance(
0,
0.into(),
Some(&DAGasBlockData::default()),
FeeUpdate::default(),
);
assert!(pool.get_operation_by_hash(hash).is_some());

tokio::time::sleep(Duration::from_secs(2)).await;
pool.do_maintenance(
0,
0.into(),
Some(&DAGasBlockData::default()),
FeeUpdate::default(),
);
assert!(pool.get_operation_by_hash(hash).is_none());
}

fn conf() -> PoolInnerConfig {
PoolInnerConfig {
chain_spec: ChainSpec::default(),
Expand All @@ -1411,6 +1458,7 @@ mod tests {
throttled_entity_mempool_count: 4,
throttled_entity_live_blocks: 10,
da_gas_tracking_enabled: false,
max_time_in_pool: None,
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/pool/src/mempool/uo_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1900,6 +1900,7 @@ mod tests {
reputation_tracking_enabled: true,
drop_min_num_blocks: 10,
gas_limit_efficiency_reject_threshold: 0.0,
max_time_in_pool: None,
}
}

Expand Down
9 changes: 7 additions & 2 deletions crates/types/src/timestamp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
use std::{
error::Error,
fmt,
fmt::{Debug, Display, Formatter},
fmt::{self, Debug, Display, Formatter},
ops::{Add, AddAssign, Sub, SubAssign},
time::{Duration, SystemTime, UNIX_EPOCH},
};
Expand Down Expand Up @@ -70,6 +69,12 @@ impl From<u64> for Timestamp {
}
}

impl From<Duration> for Timestamp {
fn from(duration: Duration) -> Self {
Self(duration.as_secs())
}
}

impl Add<Duration> for Timestamp {
type Output = Self;

Expand Down
2 changes: 2 additions & 0 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ List of command line options for configuring the Pool.
- env: *POOL_DROP_MIN_NUM_BLOCKS*
- `--pool.gas_limit_efficiency_reject_threshold`: The ratio of gas used to gas limit under which to reject UOs upon entry to the mempool (default: `0.0` disabled)
- env: *POOL_GAS_LIMIT_EFFICIENCY_REJECT_THRESHOLD*
- `--pool.max_time_in_pool_secs`: The maximum amount of time a UO is allowed to be in the mempool, in seconds. (default: `None`)
- env: *POOL_MAX_TIME_IN_POOL_SECS*

## Builder Options

Expand Down

0 comments on commit 7f09531

Please sign in to comment.