X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning-transaction-sync%2Fsrc%2Fcommon.rs;h=c635f7385c6ecbd47bb6b4e90f5abb335feca8f5;hb=63ebaccca3c284c28f24537c2c0c034f9cc9c3c4;hp=a6ee61e90f268f620caab6c059b2badee58e69d9;hpb=f71daed02d159e051e065802155d3ad77edbc124;p=rust-lightning diff --git a/lightning-transaction-sync/src/common.rs b/lightning-transaction-sync/src/common.rs index a6ee61e9..c635f738 100644 --- a/lightning-transaction-sync/src/common.rs +++ b/lightning-transaction-sync/src/common.rs @@ -1,5 +1,7 @@ -use lightning::chain::WatchedOutput; -use bitcoin::{Txid, BlockHash, Transaction, BlockHeader, OutPoint}; +use lightning::chain::{Confirm, WatchedOutput}; +use lightning::chain::channelmonitor::ANTI_REORG_DELAY; +use bitcoin::{Txid, BlockHash, Transaction, OutPoint}; +use bitcoin::block::Header; use std::collections::{HashSet, HashMap}; @@ -12,6 +14,9 @@ pub(crate) struct SyncState { // Outputs that were previously processed, but must not be forgotten yet as // as we still need to monitor any spends on-chain. pub watched_outputs: HashMap, + // Outputs for which we previously saw a spend on-chain but kept around until the spends reach + // sufficient depth. + pub outputs_spends_pending_threshold_conf: Vec<(Txid, u32, OutPoint, WatchedOutput)>, // The tip hash observed during our last sync. pub last_sync_hash: Option, // Indicates whether we need to resync, e.g., after encountering an error. @@ -23,10 +28,63 @@ impl SyncState { Self { watched_transactions: HashSet::new(), watched_outputs: HashMap::new(), + outputs_spends_pending_threshold_conf: Vec::new(), last_sync_hash: None, pending_sync: false, } } + pub fn sync_unconfirmed_transactions( + &mut self, confirmables: &Vec<&(dyn Confirm + Sync + Send)>, + unconfirmed_txs: Vec, + ) { + for txid in unconfirmed_txs { + for c in confirmables { + c.transaction_unconfirmed(&txid); + } + + self.watched_transactions.insert(txid); + + // If a previously-confirmed output spend is unconfirmed, re-add the watched output to + // the tracking map. + self.outputs_spends_pending_threshold_conf.retain(|(conf_txid, _, prev_outpoint, output)| { + if txid == *conf_txid { + self.watched_outputs.insert(*prev_outpoint, output.clone()); + false + } else { + true + } + }) + } + } + + pub fn sync_confirmed_transactions( + &mut self, confirmables: &Vec<&(dyn Confirm + Sync + Send)>, + confirmed_txs: Vec + ) { + for ctx in confirmed_txs { + for c in confirmables { + c.transactions_confirmed( + &ctx.block_header, + &[(ctx.pos, &ctx.tx)], + ctx.block_height, + ); + } + + self.watched_transactions.remove(&ctx.tx.txid()); + + for input in &ctx.tx.input { + if let Some(output) = self.watched_outputs.remove(&input.previous_output) { + self.outputs_spends_pending_threshold_conf.push((ctx.tx.txid(), ctx.block_height, input.previous_output, output)); + } + } + } + } + + pub fn prune_output_spends(&mut self, cur_height: u32) { + self.outputs_spends_pending_threshold_conf.retain(|(_, conf_height, _, _)| { + cur_height < conf_height + ANTI_REORG_DELAY - 1 + }); + } } @@ -67,9 +125,11 @@ impl FilterQueue { } } +#[derive(Debug)] pub(crate) struct ConfirmedTx { pub tx: Transaction, - pub block_header: BlockHeader, + pub txid: Txid, + pub block_header: Header, pub block_height: u32, pub pos: usize, }