1 use lightning::chain::{Confirm, WatchedOutput};
2 use bitcoin::{Txid, BlockHash, Transaction, OutPoint};
3 use bitcoin::block::Header;
5 use std::collections::{HashSet, HashMap};
8 // Represents the current state.
9 pub(crate) struct SyncState {
10 // Transactions that were previously processed, but must not be forgotten
11 // yet since they still need to be monitored for confirmation on-chain.
12 pub watched_transactions: HashSet<Txid>,
13 // Outputs that were previously processed, but must not be forgotten yet as
14 // as we still need to monitor any spends on-chain.
15 pub watched_outputs: HashMap<OutPoint, WatchedOutput>,
16 // The tip hash observed during our last sync.
17 pub last_sync_hash: Option<BlockHash>,
18 // Indicates whether we need to resync, e.g., after encountering an error.
19 pub pending_sync: bool,
23 pub fn new() -> Self {
25 watched_transactions: HashSet::new(),
26 watched_outputs: HashMap::new(),
31 pub fn sync_unconfirmed_transactions(
32 &mut self, confirmables: &Vec<&(dyn Confirm + Sync + Send)>,
33 unconfirmed_txs: Vec<Txid>,
35 for txid in unconfirmed_txs {
36 for c in confirmables {
37 c.transaction_unconfirmed(&txid);
40 self.watched_transactions.insert(txid);
44 pub fn sync_confirmed_transactions(
45 &mut self, confirmables: &Vec<&(dyn Confirm + Sync + Send)>,
46 confirmed_txs: Vec<ConfirmedTx>
48 for ctx in confirmed_txs {
49 for c in confirmables {
50 c.transactions_confirmed(
52 &[(ctx.pos, &ctx.tx)],
57 self.watched_transactions.remove(&ctx.tx.txid());
59 for input in &ctx.tx.input {
60 self.watched_outputs.remove(&input.previous_output);
67 // A queue that is to be filled by `Filter` and drained during the next syncing round.
68 pub(crate) struct FilterQueue {
69 // Transactions that were registered via the `Filter` interface and have to be processed.
70 pub transactions: HashSet<Txid>,
71 // Outputs that were registered via the `Filter` interface and have to be processed.
72 pub outputs: HashMap<OutPoint, WatchedOutput>,
76 pub fn new() -> Self {
78 transactions: HashSet::new(),
79 outputs: HashMap::new(),
83 // Processes the transaction and output queues and adds them to the given [`SyncState`].
85 // Returns `true` if new items had been registered.
86 pub fn process_queues(&mut self, sync_state: &mut SyncState) -> bool {
87 let mut pending_registrations = false;
89 if !self.transactions.is_empty() {
90 pending_registrations = true;
92 sync_state.watched_transactions.extend(self.transactions.drain());
95 if !self.outputs.is_empty() {
96 pending_registrations = true;
98 sync_state.watched_outputs.extend(self.outputs.drain());
100 pending_registrations
105 pub(crate) struct ConfirmedTx {
107 pub block_header: Header,
108 pub block_height: u32,