diff --git a/src/config.rs b/src/config.rs index c236b8375..2c428048c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -60,6 +60,7 @@ pub struct Config { pub rest_default_chain_txs_per_page: usize, pub rest_default_max_mempool_txs: usize, pub rest_max_mempool_page_size: usize, + pub rest_max_mempool_txid_page_size: usize, #[cfg(feature = "liquid")] pub parent_network: BNetwork, @@ -245,6 +246,12 @@ impl Config { .help("The maximum number of transactions returned by the paginated /internal/mempool/txs endpoint.") .default_value("1000") ) + .arg( + Arg::with_name("rest_max_mempool_txid_page_size") + .long("rest-max-mempool-txid-page-size") + .help("The maximum number of transactions returned by the paginated /mempool/txids/page endpoint.") + .default_value("10000") + ) .arg( Arg::with_name("electrum_txs_limit") .long("electrum-txs-limit") @@ -499,6 +506,11 @@ impl Config { usize ), rest_max_mempool_page_size: value_t_or_exit!(m, "rest_max_mempool_page_size", usize), + rest_max_mempool_txid_page_size: value_t_or_exit!( + m, + "rest_max_mempool_txid_page_size", + usize + ), jsonrpc_import: m.is_present("jsonrpc_import"), light_mode: m.is_present("light_mode"), main_loop_delay: value_t_or_exit!(m, "main_loop_delay", u64), diff --git a/src/new_index/mempool.rs b/src/new_index/mempool.rs index ccd50fe18..c3841d52b 100644 --- a/src/new_index/mempool.rs +++ b/src/new_index/mempool.rs @@ -288,6 +288,24 @@ impl Mempool { self.txstore.keys().collect() } + // Get n txids after the given txid in the mempool + pub fn txids_page(&self, n: usize, start: Option) -> Vec<&Txid> { + let _timer = self + .latency + .with_label_values(&["txids_page"]) + .start_timer(); + let start_bound = match start { + Some(txid) => Excluded(txid), + None => Unbounded, + }; + + self.txstore + .range((start_bound, Unbounded)) + .take(n) + .map(|(k, _v)| k) + .collect() + } + // Get all txs in the mempool pub fn txs(&self) -> Vec { let _timer = self.latency.with_label_values(&["txs"]).start_timer(); @@ -296,7 +314,7 @@ impl Mempool { // Get n txs after the given txid in the mempool pub fn txs_page(&self, n: usize, start: Option) -> Vec { - let _timer = self.latency.with_label_values(&["txs"]).start_timer(); + let _timer = self.latency.with_label_values(&["txs_page"]).start_timer(); let mut page = Vec::with_capacity(n); let start_bound = match start { Some(txid) => Excluded(txid), diff --git a/src/rest.rs b/src/rest.rs index 375d351a0..0ac32f605 100644 --- a/src/rest.rs +++ b/src/rest.rs @@ -1256,6 +1256,17 @@ fn handle_request( (&Method::GET, Some(&"mempool"), Some(&"txids"), None, None, None) => { json_response(query.mempool().txids(), TTL_SHORT) } + (&Method::GET, Some(&"mempool"), Some(&"txids"), Some(&"page"), last_seen_txid, None) => { + let last_seen_txid = last_seen_txid.and_then(|txid| Txid::from_hex(txid).ok()); + let max_txs = query_params + .get("max_txs") + .and_then(|s| s.parse::().ok()) + .unwrap_or(config.rest_max_mempool_txid_page_size); + json_response( + query.mempool().txids_page(max_txs, last_seen_txid), + TTL_SHORT, + ) + } ( &Method::GET, Some(&INTERNAL_PREFIX),