Allow vectorized fetch for mempool transactions
This commit is contained in:
parent
cdacf451a9
commit
1e258f4b3d
|
@ -46,6 +46,12 @@ fn block_from_value(value: Value) -> Result<Block> {
|
|||
Ok(deserialize(&block_bytes).chain_err(|| format!("failed to parse block {}", block_hex))?)
|
||||
}
|
||||
|
||||
fn tx_from_value(value: Value) -> Result<Transaction> {
|
||||
let tx_hex = value.as_str().chain_err(|| "non-string tx")?;
|
||||
let tx_bytes = hex::decode(tx_hex).chain_err(|| "non-hex tx")?;
|
||||
Ok(deserialize(&tx_bytes).chain_err(|| format!("failed to parse tx {}", tx_hex))?)
|
||||
}
|
||||
|
||||
fn parse_jsonrpc_reply(reply: &mut Value, method: &str) -> Result<Value> {
|
||||
let reply_obj = reply.as_object_mut().chain_err(|| "non-object reply")?;
|
||||
if let Some(err) = reply_obj.get("error") {
|
||||
|
@ -337,12 +343,21 @@ impl Daemon {
|
|||
.unwrap()
|
||||
.push(json!(blockhash.be_hex_string()));
|
||||
}
|
||||
let tx_hex: Value = self.request("getrawtransaction", args)?;
|
||||
Ok(
|
||||
deserialize(&hex::decode(tx_hex.as_str().chain_err(|| "non-string tx")?)
|
||||
.chain_err(|| "non-hex tx")?)
|
||||
.chain_err(|| format!("failed to parse tx {}", txhash))?,
|
||||
)
|
||||
tx_from_value(self.request("getrawtransaction", args)?)
|
||||
}
|
||||
|
||||
pub fn gettransactions(&self, txhashes: &[Sha256dHash]) -> Result<Vec<Transaction>> {
|
||||
let params_list: Vec<Value> = txhashes
|
||||
.iter()
|
||||
.map(|txhash| json!([txhash.be_hex_string(), /*verbose=*/ false]))
|
||||
.collect();
|
||||
|
||||
let values = self.requests("getrawtransaction", ¶ms_list)?;
|
||||
let mut txs = vec![];
|
||||
for value in values {
|
||||
txs.push(tx_from_value(value)?);
|
||||
}
|
||||
Ok(txs)
|
||||
}
|
||||
|
||||
pub fn getmempooltxids(&self) -> Result<HashSet<Sha256dHash>> {
|
||||
|
|
|
@ -201,22 +201,23 @@ impl Tracker {
|
|||
timer.observe_duration();
|
||||
|
||||
let timer = self.stats.start_timer("add");
|
||||
for txid in new_txids.difference(&old_txids) {
|
||||
let entry = match daemon.getmempoolentry(txid) {
|
||||
Ok(entry) => entry,
|
||||
Err(err) => {
|
||||
warn!("no mempool entry {}: {}", txid, err); // e.g. new block or RBF
|
||||
continue;
|
||||
let txids_to_add: Vec<Sha256dHash> = new_txids.difference(&old_txids).cloned().collect();
|
||||
let entries: Vec<(&Sha256dHash, MempoolEntry)> = txids_to_add
|
||||
.iter()
|
||||
.filter_map(|txid| {
|
||||
match daemon.getmempoolentry(txid) {
|
||||
Ok(entry) => Some((txid, entry)),
|
||||
Err(err) => {
|
||||
warn!("no mempool entry {}: {}", txid, err); // e.g. new block or RBF
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
// The following lookup should find the transaction in mempool.
|
||||
let tx = match daemon.gettransaction(txid, /*blockhash=*/ None) {
|
||||
Ok(tx) => tx,
|
||||
Err(err) => {
|
||||
warn!("missing tx {}: {}", txid, err); // e.g. new block or RBF
|
||||
continue;
|
||||
}
|
||||
};
|
||||
})
|
||||
.collect();
|
||||
let txs = daemon.gettransactions(&txids_to_add)?;
|
||||
assert_eq!(entries.len(), txs.len());
|
||||
for ((txid, entry), tx) in entries.into_iter().zip(txs.into_iter()) {
|
||||
assert_eq!(tx.txid(), *txid);
|
||||
self.add(txid, tx, entry);
|
||||
}
|
||||
timer.observe_duration();
|
||||
|
|
Loading…
Reference in New Issue
Block a user