From 3c6cc42c23d5797132365a99c8afd18a3ee974ff Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Wed, 5 Jul 2023 22:12:34 -0400 Subject: [PATCH] Modify get_transactions to split requests as to not hit the restricted RPC limits --- coins/monero/src/bin/reserialize_chain.rs | 27 ++++++++++------- coins/monero/src/rpc/mod.rs | 37 ++++++++++++++--------- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/coins/monero/src/bin/reserialize_chain.rs b/coins/monero/src/bin/reserialize_chain.rs index df209009..7668513e 100644 --- a/coins/monero/src/bin/reserialize_chain.rs +++ b/coins/monero/src/bin/reserialize_chain.rs @@ -44,18 +44,23 @@ async fn check_block(rpc: Arc>, block_i: usize) { txs: Vec, } - let txs: TransactionsResponse = rpc - .rpc_call( - "get_transactions", - Some(json!({ - "txs_hashes": block.txs.iter().map(hex::encode).collect::>() - })), - ) - .await - .expect("couldn't call get_transactions"); - assert!(txs.missed_tx.is_empty()); + let mut hashes_hex = block.txs.iter().map(hex::encode).collect::>(); + let mut all_txs = vec![]; + while !hashes_hex.is_empty() { + let txs: TransactionsResponse = rpc + .rpc_call( + "get_transactions", + Some(json!({ + "txs_hashes": hashes_hex.drain(.. hashes_hex.len().min(100)).collect::>(), + })), + ) + .await + .expect("couldn't call get_transactions"); + assert!(txs.missed_tx.is_empty()); + all_txs.extend(txs.txs); + } - for (tx_hash, tx_res) in block.txs.into_iter().zip(txs.txs.into_iter()) { + for (tx_hash, tx_res) in block.txs.into_iter().zip(all_txs.into_iter()) { assert_eq!( tx_res.tx_hash, hex::encode(tx_hash), diff --git a/coins/monero/src/rpc/mod.rs b/coins/monero/src/rpc/mod.rs index 224b1b35..d0936271 100644 --- a/coins/monero/src/rpc/mod.rs +++ b/coins/monero/src/rpc/mod.rs @@ -198,23 +198,32 @@ impl Rpc { return Ok(vec![]); } - let txs: TransactionsResponse = self - .rpc_call( - "get_transactions", - Some(json!({ - "txs_hashes": hashes.iter().map(hex::encode).collect::>() - })), - ) - .await?; + let mut hashes_hex = hashes.iter().map(hex::encode).collect::>(); + let mut all_txs = Vec::with_capacity(hashes.len()); + while !hashes_hex.is_empty() { + // Monero errors if more than 100 is requested unless using a non-restricted RPC + const TXS_PER_REQUEST: usize = 100; + let this_count = TXS_PER_REQUEST.min(hashes_hex.len()); - if !txs.missed_tx.is_empty() { - Err(RpcError::TransactionsNotFound( - txs.missed_tx.iter().map(|hash| hash_hex(hash)).collect::>()?, - ))?; + let txs: TransactionsResponse = self + .rpc_call( + "get_transactions", + Some(json!({ + "txs_hashes": hashes_hex.drain(.. this_count).collect::>(), + })), + ) + .await?; + + if !txs.missed_tx.is_empty() { + Err(RpcError::TransactionsNotFound( + txs.missed_tx.iter().map(|hash| hash_hex(hash)).collect::>()?, + ))?; + } + + all_txs.extend(txs.txs); } - txs - .txs + all_txs .iter() .enumerate() .map(|(i, res)| {