mirror of
https://github.com/romanz/electrs.git
synced 2025-02-24 06:57:53 +01:00
Fix txid
index collision handling
This commit is contained in:
parent
6f301a0167
commit
ca2841f432
2 changed files with 38 additions and 13 deletions
|
@ -356,18 +356,26 @@ impl Rpc {
|
|||
fn transaction_get(&self, args: &TxGetArgs) -> Result<Value> {
|
||||
let (txid, verbose) = args.into();
|
||||
if verbose {
|
||||
let blockhash = self.tracker.get_blockhash_by_txid(txid);
|
||||
let blockhash = self
|
||||
.tracker
|
||||
.lookup_transaction(&self.daemon, txid)?
|
||||
.map(|(blockhash, _tx)| blockhash);
|
||||
return self.daemon.get_transaction_info(&txid, blockhash);
|
||||
}
|
||||
let cached = self.cache.get_tx(&txid, |tx| serialize(tx).to_hex());
|
||||
Ok(match cached {
|
||||
Some(tx_hex) => json!(tx_hex),
|
||||
None => {
|
||||
debug!("tx cache miss: txid={}", txid);
|
||||
let blockhash = self.tracker.get_blockhash_by_txid(txid);
|
||||
json!(self.daemon.get_transaction_hex(&txid, blockhash)?)
|
||||
if let Some(tx) = self.cache.get_tx(&txid, |tx| serialize(tx)) {
|
||||
return Ok(json!(tx.to_hex()));
|
||||
}
|
||||
})
|
||||
debug!("tx cache miss: txid={}", txid);
|
||||
// use internal index to load confirmed transaction without an RPC
|
||||
if let Some(tx) = self
|
||||
.tracker
|
||||
.lookup_transaction(&self.daemon, txid)?
|
||||
.map(|(_blockhash, tx)| tx)
|
||||
{
|
||||
return Ok(json!(serialize(&tx).to_hex()));
|
||||
}
|
||||
// load unconfirmed transaction via RPC
|
||||
Ok(json!(self.daemon.get_transaction_hex(&txid, None)?))
|
||||
}
|
||||
|
||||
fn transaction_get_merkle(&self, (txid, height): &(Txid, usize)) -> Result<Value> {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use anyhow::{Context, Result};
|
||||
use bitcoin::{BlockHash, Txid};
|
||||
use bitcoin::{BlockHash, Transaction, Txid};
|
||||
|
||||
use crate::{
|
||||
cache::Cache,
|
||||
|
@ -93,8 +93,25 @@ impl Tracker {
|
|||
status.get_balance(self.chain())
|
||||
}
|
||||
|
||||
pub(crate) fn get_blockhash_by_txid(&self, txid: Txid) -> Option<BlockHash> {
|
||||
pub(crate) fn lookup_transaction(
|
||||
&self,
|
||||
daemon: &Daemon,
|
||||
txid: Txid,
|
||||
) -> Result<Option<(BlockHash, Transaction)>> {
|
||||
// Note: there are two blocks with coinbase transactions having same txid (see BIP-30)
|
||||
self.index.filter_by_txid(txid).next()
|
||||
let blockhashes = self.index.filter_by_txid(txid);
|
||||
let mut result = None;
|
||||
daemon.for_blocks(blockhashes, |blockhash, block| {
|
||||
for tx in block.txdata {
|
||||
if result.is_some() {
|
||||
return;
|
||||
}
|
||||
if tx.txid() == txid {
|
||||
result = Some((blockhash, tx));
|
||||
return;
|
||||
}
|
||||
}
|
||||
})?;
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue