Update coin txid if conflicting tx was confirmed

This commit is contained in:
edouard 2022-09-19 18:25:35 +02:00
parent 3cf6bcbb98
commit bb9897bdbb
2 changed files with 46 additions and 5 deletions

View File

@ -748,8 +748,9 @@ impl From<Json> for LSBlockRes {
}
}
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone)]
pub struct GetTxRes {
pub conflicting_txs: Vec<bitcoin::Txid>,
pub block_height: Option<i32>,
pub block_time: Option<u32>,
}
@ -764,7 +765,21 @@ impl From<Json> for GetTxRes {
.get("blocktime")
.and_then(Json::as_u64)
.map(|bt| bt as u32);
let conflicting_txs = json
.get("walletconflicts")
.map(|v| Json::as_array(&v))
.flatten()
.map(|array| {
array
.into_iter()
.map(|v| {
bitcoin::Txid::from_str(v.as_str().expect("wrong json format")).unwrap()
})
.collect()
});
GetTxRes {
conflicting_txs: conflicting_txs.unwrap_or_default(),
block_height,
block_time,
}

View File

@ -156,7 +156,6 @@ impl BitcoinInterface for d::BitcoinD {
let mut spent = Vec::with_capacity(outpoints.len());
let mut cache: HashMap<bitcoin::Txid, Option<d::GetTxRes>> = HashMap::new();
for (op, txid) in outpoints {
let tx: Option<&d::GetTxRes> = match cache.get(txid) {
Some(tx) => tx.as_ref(),
@ -167,16 +166,43 @@ impl BitcoinInterface for d::BitcoinD {
}
};
// There is an immutable borrow on the cache, these txs will be added once it is
// dropped.
let mut txs_to_cache: Vec<(bitcoin::Txid, Option<d::GetTxRes>)> = Vec::new();
if let Some(tx) = tx {
if let Some(block_height) = tx.block_height {
if block_height > 1 {
spent.push((*op, *txid, tx.block_time.expect("Spend is confirmed")))
}
} else {
// TODO: handle the case where new transaction which txid is not the
// coin spending_txid, spent the coin.
} else if !tx.conflicting_txs.is_empty() {
for txid in tx.conflicting_txs.clone() {
let tx: Option<&d::GetTxRes> = match cache.get(&txid) {
Some(tx) => tx.as_ref(),
None => {
let tx = self.get_transaction(&txid);
txs_to_cache.push((txid, tx));
txs_to_cache.last().unwrap().1.as_ref()
}
};
if let Some(tx) = tx {
if let Some(block_height) = tx.block_height {
if block_height > 1 {
spent.push((
*op,
txid,
tx.block_time.expect("Spend is confirmed"),
))
}
}
}
}
}
}
for (txid, res) in txs_to_cache {
cache.insert(txid, res);
}
}
spent