|
1 | 1 | use arraydeque::{ArrayDeque, Wrapping}; |
2 | | -use itertools::Itertools; |
| 2 | +use itertools::{Either, Itertools}; |
3 | 3 |
|
4 | 4 | #[cfg(not(feature = "liquid"))] |
5 | 5 | use bitcoin::consensus::encode::serialize; |
@@ -340,7 +340,7 @@ impl Mempool { |
340 | 340 | self.txstore.insert(txid, tx); |
341 | 341 | } |
342 | 342 | // Phase 2: index history and spend edges (can fail if some txos cannot be found) |
343 | | - let txos = match self.lookup_txos(&self.get_prevouts(&txids)) { |
| 343 | + let txos = match self.lookup_txos(self.get_prevouts(&txids)) { |
344 | 344 | Ok(txos) => txos, |
345 | 345 | Err(err) => { |
346 | 346 | warn!("lookup txouts failed: {}", err); |
@@ -427,34 +427,29 @@ impl Mempool { |
427 | 427 | } |
428 | 428 | } |
429 | 429 |
|
430 | | - pub fn lookup_txo(&self, outpoint: &OutPoint) -> Result<TxOut> { |
431 | | - let mut outpoints = BTreeSet::new(); |
432 | | - outpoints.insert(*outpoint); |
433 | | - Ok(self.lookup_txos(&outpoints)?.remove(outpoint).unwrap()) |
| 430 | + fn lookup_txo(&self, outpoint: &OutPoint) -> Option<TxOut> { |
| 431 | + self.txstore |
| 432 | + .get(&outpoint.txid) |
| 433 | + .and_then(|tx| tx.output.get(outpoint.vout as usize).cloned()) |
434 | 434 | } |
435 | 435 |
|
436 | | - pub fn lookup_txos(&self, outpoints: &BTreeSet<OutPoint>) -> Result<HashMap<OutPoint, TxOut>> { |
| 436 | + pub fn lookup_txos(&self, outpoints: BTreeSet<OutPoint>) -> Result<HashMap<OutPoint, TxOut>> { |
437 | 437 | let _timer = self |
438 | 438 | .latency |
439 | 439 | .with_label_values(&["lookup_txos"]) |
440 | 440 | .start_timer(); |
441 | 441 |
|
442 | | - let confirmed_txos = self.chain.lookup_avail_txos(outpoints); |
| 442 | + // Get the txos available in the mempool, skipping over (and collecting) missing ones |
| 443 | + let (mut txos, remain_outpoints): (HashMap<_, _>, _) = outpoints |
| 444 | + .into_iter() |
| 445 | + .partition_map(|outpoint| match self.lookup_txo(&outpoint) { |
| 446 | + Some(txout) => Either::Left((outpoint, txout)), |
| 447 | + None => Either::Right(outpoint), |
| 448 | + }); |
443 | 449 |
|
444 | | - let mempool_txos = outpoints |
445 | | - .iter() |
446 | | - .filter(|outpoint| !confirmed_txos.contains_key(outpoint)) |
447 | | - .map(|outpoint| { |
448 | | - self.txstore |
449 | | - .get(&outpoint.txid) |
450 | | - .and_then(|tx| tx.output.get(outpoint.vout as usize).cloned()) |
451 | | - .map(|txout| (*outpoint, txout)) |
452 | | - .chain_err(|| format!("missing outpoint {:?}", outpoint)) |
453 | | - }) |
454 | | - .collect::<Result<HashMap<OutPoint, TxOut>>>()?; |
| 450 | + // Get the remaining txos from the chain (fails if any are missing) |
| 451 | + txos.extend(self.chain.lookup_txos(remain_outpoints)?); |
455 | 452 |
|
456 | | - let mut txos = confirmed_txos; |
457 | | - txos.extend(mempool_txos); |
458 | 453 | Ok(txos) |
459 | 454 | } |
460 | 455 |
|
|
0 commit comments