Allow vectorized fetch for mempool transactions

This commit is contained in:
Roman Zeyde 2018-07-12 18:59:07 +03:00
parent cdacf451a9
commit 1e258f4b3d
No known key found for this signature in database
GPG Key ID: 87CAE5FA46917CBB
2 changed files with 37 additions and 21 deletions

View File

@ -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", &params_list)?;
let mut txs = vec![];
for value in values {
txs.push(tx_from_value(value)?);
}
Ok(txs)
}
pub fn getmempooltxids(&self) -> Result<HashSet<Sha256dHash>> {

View File

@ -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();