Skip to content

Commit

Permalink
fix: remove naive seen_txns cache (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
anna-carroll authored Dec 13, 2024
1 parent 32a6998 commit 59ba745
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 52 deletions.
1 change: 0 additions & 1 deletion src/tasks/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ impl BlockBuilder {
tracing::error!(error = %e, "error polling transactions");
}
}
self.tx_poller.evict();
}

async fn _get_bundles(&mut self, in_progress: &mut InProgressBlock) {
Expand Down
53 changes: 2 additions & 51 deletions src/tasks/tx_poller.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
use std::time::Duration;
use std::{collections::HashMap, time};

use alloy::consensus::TxEnvelope;
use alloy_primitives::TxHash;

use eyre::Error;
use reqwest::{Client, Url};
use serde::{Deserialize, Serialize};
use serde_json::from_slice;

pub use crate::config::BuilderConfig;

use metrics::counter;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TxPoolResponse {
transactions: Vec<TxEnvelope>,
Expand All @@ -24,63 +17,21 @@ pub struct TxPoller {
pub config: BuilderConfig,
// Reqwest client for fetching transactions from the tx-pool
pub client: Client,
// Maintain a set of transaction hashes to their expiration times
pub seen_txns: HashMap<TxHash, time::Instant>,
}

/// TxPoller implements a poller that fetches unique transactions from the transaction pool.
impl TxPoller {
/// returns a new TxPoller with the given config.
pub fn new(config: &BuilderConfig) -> Self {
Self { config: config.clone(), client: Client::new(), seen_txns: HashMap::new() }
Self { config: config.clone(), client: Client::new() }
}

/// polls the tx-pool for unique transactions and evicts expired transactions.
/// unique transactions that haven't been seen before are sent into the builder pipeline.
pub async fn check_tx_cache(&mut self) -> Result<Vec<TxEnvelope>, Error> {
let mut unique: Vec<TxEnvelope> = Vec::new();

let url: Url = Url::parse(&self.config.tx_pool_url)?.join("transactions")?;
let result = self.client.get(url).send().await?;
let response: TxPoolResponse = from_slice(result.text().await?.as_bytes())?;

response.transactions.iter().for_each(|entry| {
self.check_seen_txs(entry.clone(), &mut unique);
});

Ok(unique)
}

/// checks if the transaction has been seen before and if not, adds it to the unique transactions list.
fn check_seen_txs(&mut self, tx: TxEnvelope, unique: &mut Vec<TxEnvelope>) {
self.seen_txns.entry(*tx.tx_hash()).or_insert_with(|| {
// add to unique transactions
unique.push(tx.clone());
counter!("builder.unique_txs").increment(1);
// expiry is now + cache_duration
time::Instant::now() + Duration::from_secs(self.config.tx_pool_cache_duration)
});
}

/// removes entries from seen_txns that have lived past expiry
pub fn evict(&mut self) {
let expired_keys: Vec<TxHash> = self
.seen_txns
.iter()
.filter_map(
|(key, &expiration)| {
if !expiration.elapsed().is_zero() {
Some(*key)
} else {
None
}
},
)
.collect();

for key in expired_keys {
self.seen_txns.remove(&key);
counter!("builder.evicted_txs").increment(1);
}
Ok(response.transactions)
}
}

0 comments on commit 59ba745

Please sign in to comment.