Skip to content
Open
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
69 changes: 61 additions & 8 deletions monad-eth-txpool/src/pool/tracked/limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,13 @@ const MAX_ADDRESSES: usize = 16 * 1024;

const MAX_TXS: usize = 64 * 1024;

const MAX_EIP2718_BYTES: usize = 4 * 1024 * 1024 * 1024;

#[derive(Clone, Debug)]
pub(super) struct TrackedTxLimitsConfig {
max_addresses: usize,
max_txs: usize,
max_eip2718_bytes: usize,

soft_tx_expiry: Duration,
hard_tx_expiry: Duration,
Expand All @@ -51,6 +54,7 @@ impl TrackedTxLimitsConfig {
Self {
max_addresses: MAX_ADDRESSES,
max_txs: MAX_TXS,
max_eip2718_bytes: MAX_EIP2718_BYTES,

soft_tx_expiry,
hard_tx_expiry,
Expand All @@ -64,6 +68,7 @@ pub(super) struct TrackedTxLimits {

addresses: usize,
txs: usize,
eip2718_bytes: usize,
}

impl TrackedTxLimits {
Expand All @@ -73,6 +78,7 @@ impl TrackedTxLimits {

addresses: 0,
txs: 0,
eip2718_bytes: 0,
}
}

Expand All @@ -95,12 +101,18 @@ impl TrackedTxLimits {
}

#[inline]
fn can_increase_limits(&self, inc_addresses: usize, inc_txs: usize) -> bool {
fn can_increase_limits(
&self,
inc_addresses: usize,
inc_txs: usize,
inc_eip2718_bytes: usize,
) -> bool {
let Self {
config,

addresses,
txs,
eip2718_bytes,
} = self;

if addresses.saturating_add(inc_addresses) > config.max_addresses {
Expand All @@ -111,6 +123,10 @@ impl TrackedTxLimits {
return false;
}

if eip2718_bytes.saturating_add(inc_eip2718_bytes) > config.max_eip2718_bytes {
return false;
}

true
}

Expand All @@ -119,8 +135,7 @@ impl TrackedTxLimits {
event_tracker: &'et mut EthTxPoolEventTracker<'t>,
tx: ValidEthTransaction,
) -> Option<TrackedTxLimitAddToken<'et, 'l, 't>> {
if !self.can_increase_limits(1, 1) {
event_tracker.drop(tx.hash(), EthTxPoolDropReason::PoolFull);
if !self.can_increase_limits(1, 1, tx.raw().eip2718_encoded_length()) {
return None;
}

Expand All @@ -137,8 +152,7 @@ impl TrackedTxLimits {
event_tracker: &'et mut EthTxPoolEventTracker<'t>,
tx: ValidEthTransaction,
) -> Option<TrackedTxLimitAddToken<'et, 'l, 't>> {
if !self.can_increase_limits(0, 1) {
event_tracker.drop(tx.hash(), EthTxPoolDropReason::PoolFull);
if !self.can_increase_limits(0, 1, tx.raw().eip2718_encoded_length()) {
return None;
}

Expand All @@ -157,12 +171,20 @@ impl TrackedTxLimits {

addresses: _,
txs,
eip2718_bytes,
} = self;

*txs = txs.checked_sub(1).unwrap_or_else(|| {
error!("txpool txs limit underflowed");
0
});

*eip2718_bytes = eip2718_bytes
.checked_sub(tx.raw().eip2718_encoded_length())
.unwrap_or_else(|| {
error!("txpool eip2718_bytes limit underflowed");
0
});
}

#[inline]
Expand All @@ -172,6 +194,7 @@ impl TrackedTxLimits {

addresses,
txs: _,
eip2718_bytes: _,
} = self;

*addresses = addresses.checked_sub(1).unwrap_or_else(|| {
Expand Down Expand Up @@ -323,12 +346,14 @@ impl<'et, 'l, 't> TrackedTxLimitAddToken<'et, 'l, 't> {

addresses,
txs,
eip2718_bytes,
},
event_tracker: _,
tx: _,
tx,
used,
} = self;

*eip2718_bytes += tx.raw().eip2718_encoded_length();
*txs += 1;

match kind {
Expand Down Expand Up @@ -422,6 +447,7 @@ mod tests {
let mut limits = TrackedTxLimits::new(TrackedTxLimitsConfig {
max_addresses: 1,
max_txs: 2,
max_eip2718_bytes: 256 * 1024,
soft_tx_expiry: Duration::from_secs(1),
hard_tx_expiry: Duration::from_secs(5),
});
Expand All @@ -437,6 +463,7 @@ mod tests {

assert_eq!(limits.addresses, 1);
assert_eq!(limits.txs, 1);
assert_eq!(limits.eip2718_bytes, tx.raw().eip2718_encoded_length());

assert!(
limits
Expand All @@ -447,6 +474,7 @@ mod tests {

assert_eq!(limits.addresses, 1);
assert_eq!(limits.txs, 1);
assert_eq!(limits.eip2718_bytes, tx.raw().eip2718_encoded_length());

limits
.prepare_add_tx_to_existing(&mut event_tracker, tx.clone())
Expand All @@ -455,16 +483,18 @@ mod tests {

assert_eq!(limits.addresses, 1);
assert_eq!(limits.txs, 2);
assert_eq!(limits.eip2718_bytes, 2 * tx.raw().eip2718_encoded_length());

assert!(
limits
.prepare_add_tx_to_existing(&mut event_tracker, tx)
.prepare_add_tx_to_existing(&mut event_tracker, tx.clone())
.is_none(),
"Exceeds max txs limit"
);

assert_eq!(limits.addresses, 1);
assert_eq!(limits.txs, 2);
assert_eq!(limits.eip2718_bytes, 2 * tx.raw().eip2718_encoded_length());
}

#[test]
Expand All @@ -475,6 +505,7 @@ mod tests {
let mut limits = TrackedTxLimits::new(TrackedTxLimitsConfig {
max_addresses,
max_txs: max_addresses + 1,
max_eip2718_bytes: 16 * 1024 * 1024,
soft_tx_expiry: Duration::from_secs(1),
hard_tx_expiry: Duration::from_secs(5),
});
Expand All @@ -492,6 +523,10 @@ mod tests {

assert_eq!(limits.addresses, max_addresses);
assert_eq!(limits.txs, max_addresses);
assert_eq!(
limits.eip2718_bytes,
max_addresses * tx.raw().eip2718_encoded_length()
);

assert!(
limits
Expand All @@ -507,6 +542,10 @@ mod tests {

assert_eq!(limits.addresses, max_addresses);
assert_eq!(limits.txs, max_addresses + 1);
assert_eq!(
limits.eip2718_bytes,
(max_addresses + 1) * tx.raw().eip2718_encoded_length()
);
}
}

Expand All @@ -519,6 +558,7 @@ mod tests {
// This use-case is not permitted by the pool but can be used for testing just txs
max_addresses: 0,
max_txs,
max_eip2718_bytes: 16 * 1024 * 1024,
soft_tx_expiry: Duration::from_secs(1),
hard_tx_expiry: Duration::from_secs(5),
});
Expand All @@ -536,6 +576,10 @@ mod tests {

assert_eq!(limits.addresses, 0);
assert_eq!(limits.txs, max_txs);
assert_eq!(
limits.eip2718_bytes,
max_txs * tx.raw().eip2718_encoded_length()
);

assert!(
limits
Expand All @@ -553,6 +597,10 @@ mod tests {

assert_eq!(limits.addresses, 0);
assert_eq!(limits.txs, max_txs);
assert_eq!(
limits.eip2718_bytes,
max_txs * tx.raw().eip2718_encoded_length()
);
}
}

Expand All @@ -563,6 +611,7 @@ mod tests {
let mut limits = TrackedTxLimits::new(TrackedTxLimitsConfig {
max_addresses: 2,
max_txs: 2,
max_eip2718_bytes: 256 * 1024,
soft_tx_expiry: Duration::from_secs(1),
hard_tx_expiry: Duration::from_secs(5),
});
Expand All @@ -579,6 +628,7 @@ mod tests {

assert_eq!(limits.addresses, 0);
assert_eq!(limits.txs, 0);
assert_eq!(limits.eip2718_bytes, 0);

limits
.prepare_add_tx_to_new_address(&mut event_tracker, tx.clone())
Expand All @@ -587,6 +637,7 @@ mod tests {

assert_eq!(limits.addresses, 1);
assert_eq!(limits.txs, 1);
assert_eq!(limits.eip2718_bytes, tx.raw().eip2718_encoded_length());

// Existing

Expand All @@ -596,13 +647,15 @@ mod tests {

assert_eq!(limits.addresses, 1);
assert_eq!(limits.txs, 1);
assert_eq!(limits.eip2718_bytes, tx.raw().eip2718_encoded_length());

limits
.prepare_add_tx_to_existing(&mut event_tracker, tx)
.prepare_add_tx_to_existing(&mut event_tracker, tx.clone())
.expect("Can add new tx")
.apply_limits();

assert_eq!(limits.addresses, 1);
assert_eq!(limits.txs, 2);
assert_eq!(limits.eip2718_bytes, 2 * tx.raw().eip2718_encoded_length());
}
}