Skip to main content

lightning_signer/
monitor.rs

1use alloc::collections::BTreeSet as Set;
2
3use bitcoin::absolute::LockTime;
4use bitcoin::blockdata::block::Header as BlockHeader;
5use bitcoin::secp256k1::Secp256k1;
6use bitcoin::transaction::Version;
7use bitcoin::{BlockHash, OutPoint, Transaction, TxIn, TxOut, Txid};
8use log::*;
9use push_decoder::Listener as _;
10use serde_derive::{Deserialize, Serialize};
11use serde_with::serde_as;
12
13use crate::chain::tracker::ChainListener;
14use crate::channel::ChannelId;
15use crate::policy::validator::ChainState;
16use crate::prelude::*;
17use crate::util::transaction_utils::{decode_commitment_number, decode_commitment_tx};
18use crate::{Arc, CommitmentPointProvider};
19
20// the depth at which we consider a channel to be done
21const MIN_DEPTH: u32 = 100;
22
23// the maximum depth we will watch for HTLC sweeps on closed channels
24const MAX_CLOSING_DEPTH: u32 = 2016;
25
26#[derive(Clone, Debug, Serialize, Deserialize)]
27struct SecondLevelHTLCOutput {
28    outpoint: OutPoint,
29    spent: bool,
30}
31
32impl SecondLevelHTLCOutput {
33    fn new(outpoint: OutPoint) -> Self {
34        Self { outpoint, spent: false }
35    }
36
37    fn set_spent(&mut self, spent: bool) {
38        self.spent = spent;
39    }
40
41    fn is_spent(&self) -> bool {
42        self.spent
43    }
44
45    fn matches_outpoint(&self, outpoint: &OutPoint) -> bool {
46        self.outpoint == *outpoint
47    }
48}
49
50// Keep track of closing transaction outpoints.
51// These include the to-us output (if it exists), all HTLC outputs, and second-level HTLC outputs.
52// For each output, we keep track of whether it has been spent yet.
53#[derive(Clone, Debug, Serialize, Deserialize)]
54struct ClosingOutpoints {
55    txid: Txid,
56    our_output: Option<(u32, bool)>,
57    htlc_outputs: Vec<u32>,
58    htlc_spents: Vec<bool>,
59    second_level_htlc_outputs: Vec<SecondLevelHTLCOutput>,
60}
61
62impl ClosingOutpoints {
63    // construct a new ClosingOutpoints with all spent flags false
64    fn new(txid: Txid, our_output_index: Option<u32>, htlc_output_indexes: Vec<u32>) -> Self {
65        let v = vec![false; htlc_output_indexes.len()];
66        ClosingOutpoints {
67            txid,
68            our_output: our_output_index.map(|i| (i, false)),
69            htlc_outputs: htlc_output_indexes,
70            htlc_spents: v,
71            second_level_htlc_outputs: Vec::new(),
72        }
73    }
74
75    // does this closing tx's to-us output match this outpoint?
76    fn includes_our_output(&self, outpoint: &OutPoint) -> bool {
77        self.txid == outpoint.txid && self.our_output.map(|(i, _)| i) == Some(outpoint.vout)
78    }
79
80    // does this closing tx include an HTLC outpoint that matches?
81    fn includes_htlc_output(&self, outpoint: &OutPoint) -> bool {
82        self.txid == outpoint.txid && self.htlc_outputs.contains(&(outpoint.vout))
83    }
84
85    fn set_our_output_spent(&mut self, vout: u32, spent: bool) {
86        // safe due to PushListener logic
87        let p = self.our_output.as_mut().unwrap();
88        assert_eq!(p.0, vout);
89        p.1 = spent;
90    }
91
92    fn set_htlc_output_spent(&mut self, vout: u32, spent: bool) {
93        // safe due to PushListener logic
94        let i = self.htlc_outputs.iter().position(|&x| x == vout).unwrap();
95        self.htlc_spents[i] = spent;
96    }
97
98    /// Returns true if all relevant outputs are considered spent.
99    /// This includes:
100    /// - our main output
101    /// - first-level HTLC outputs
102    /// - second-level HTLC outputs
103    fn is_all_spent(&self) -> bool {
104        let our_output_spent = self.our_output.as_ref().map(|(_, b)| *b).unwrap_or(true);
105        let htlc_outputs_spent = self.htlc_spents.iter().all(|b| *b);
106        let second_level_htlcs_spent = self.second_level_htlc_outputs.iter().all(|h| h.is_spent());
107
108        our_output_spent && htlc_outputs_spent && second_level_htlcs_spent
109    }
110
111    fn add_second_level_htlc_output(&mut self, outpoint: OutPoint) {
112        self.second_level_htlc_outputs.push(SecondLevelHTLCOutput::new(outpoint));
113    }
114
115    fn includes_second_level_htlc_output(&self, outpoint: &OutPoint) -> bool {
116        self.second_level_htlc_outputs.iter().any(|h| h.matches_outpoint(outpoint))
117    }
118
119    fn set_second_level_htlc_spent(&mut self, outpoint: OutPoint, spent: bool) {
120        let htlc_outpoint = self
121            .second_level_htlc_outputs
122            .iter_mut()
123            .find(|h| h.matches_outpoint(&outpoint))
124            .expect("second-level HTLC outpoint");
125        htlc_outpoint.set_spent(spent);
126    }
127
128    fn remove_second_level_htlc_output(&mut self, outpoint: &OutPoint) {
129        self.second_level_htlc_outputs.retain(|h| !h.matches_outpoint(outpoint));
130    }
131}
132
133/// State
134#[serde_as]
135#[derive(Clone, Debug, Serialize, Deserialize)]
136pub struct State {
137    // Chain height
138    height: u32,
139    // funding txids
140    funding_txids: Vec<Txid>,
141    // the funding output index for each funding tx
142    funding_vouts: Vec<u32>,
143    // inputs derived from funding_txs for convenience
144    funding_inputs: Set<OutPoint>,
145    // The height where the funding transaction was confirmed
146    funding_height: Option<u32>,
147    // The actual funding outpoint on-chain
148    funding_outpoint: Option<OutPoint>,
149    // The height of a transaction that double-spends a funding input
150    funding_double_spent_height: Option<u32>,
151    // The height of a mutual-close transaction
152    mutual_closing_height: Option<u32>,
153    // The height of a unilateral-close transaction
154    unilateral_closing_height: Option<u32>,
155    // Unilateral closing transaction outpoints to watch
156    closing_outpoints: Option<ClosingOutpoints>,
157    // Unilateral closing transaction swept height
158    closing_swept_height: Option<u32>,
159    // Our commitment transaction output swept height
160    our_output_swept_height: Option<u32>,
161    // Whether we saw a block yet - used for sanity check
162    #[serde(default)]
163    saw_block: bool,
164    // Whether the node has forgotten this channel
165    #[serde(default)]
166    saw_forget_channel: bool,
167    // The associated channel_id for logging and debugging.
168    // Not persisted, but explicitly populated by new_from_persistence
169    #[serde(skip)]
170    channel_id: Option<ChannelId>,
171}
172
173// A push decoder listener.
174// We need this temporary struct so that the commitment point provider
175// is easily accessible during push event handling.
176struct PushListener<'a> {
177    commitment_point_provider: &'a dyn CommitmentPointProvider,
178    decode_state: &'a mut BlockDecodeState,
179    saw_block: bool,
180}
181
182// A state change detected in a block, to be applied to the monitor `State`.
183#[derive(Clone, Debug, Serialize, Deserialize)]
184enum StateChange {
185    // A funding transaction was confirmed.  The funding outpoint is provided.
186    FundingConfirmed(OutPoint),
187    // A funding input was spent, either by the actual funding transaction
188    // or by a double-spend.  The output is provided.
189    FundingInputSpent(OutPoint),
190    // A unilateral closing transaction was confirmed.
191    // The funding outpoint, our output index and HTLC output indexes are provided
192    UnilateralCloseConfirmed(Txid, OutPoint, Option<u32>, Vec<u32>),
193    // A mutual close transaction was confirmed.
194    MutualCloseConfirmed(Txid, OutPoint),
195    /// Our commitment output was spent
196    OurOutputSpent(u32),
197    // An HTLC commitment output was spent
198    // The htlc output index and the second-level HTLC outpoint are provided
199    HTLCOutputSpent(u32, OutPoint),
200    /// A second-level HTLC output was spent
201    SecondLevelHTLCOutputSpent(OutPoint),
202}
203
204// Keep track of the state of a block push-decoder parse state
205#[derive(Clone, Debug)]
206struct BlockDecodeState {
207    // The changes detected in the current block
208    changes: Vec<StateChange>,
209    // The version of the current transaction
210    version: i32,
211    // The input number in the current transaction
212    input_num: u32,
213    // The output number in the current transaction
214    output_num: u32,
215    // The closing transaction, if we detect one
216    closing_tx: Option<Transaction>,
217    // Tracks which HTLC outputs (vouts) were spent and where
218    // Format: [(htlc_vout, spending_input_index)]
219    spent_htlc_outputs: Vec<(u32, u32)>,
220    // The block hash
221    block_hash: Option<BlockHash>,
222    // A temporary copy of the current state, for keeping track
223    // of state changes intra-block, without changing the actual state
224    state: State,
225}
226
227impl BlockDecodeState {
228    fn new(state: &State) -> Self {
229        BlockDecodeState {
230            changes: Vec::new(),
231            version: 0,
232            input_num: 0,
233            output_num: 0,
234            closing_tx: None,
235            spent_htlc_outputs: Vec::new(),
236            block_hash: None,
237            state: state.clone(),
238        }
239    }
240
241    fn new_with_block_hash(state: &State, block_hash: &BlockHash) -> Self {
242        BlockDecodeState {
243            changes: Vec::new(),
244            version: 0,
245            input_num: 0,
246            output_num: 0,
247            closing_tx: None,
248            spent_htlc_outputs: Vec::new(),
249            block_hash: Some(*block_hash),
250            state: state.clone(),
251        }
252    }
253
254    // Add a state change for the current block.
255    // This also updates the temporary monitor state, so that intra-block
256    // processing can be done.  For example, this is needed if a closing transaction
257    // is confirmed, and then swept in the same block.
258    fn add_change(&mut self, change: StateChange) {
259        self.changes.push(change.clone());
260        let mut adds = Vec::new();
261        let mut removes = Vec::new();
262        self.state.apply_forward_change(&mut adds, &mut removes, change);
263    }
264}
265
266const MAX_COMMITMENT_OUTPUTS: u32 = 600;
267
268impl<'a> PushListener<'a> {
269    // Check if we ever saw the beginning of a block.  If not, we might get
270    // a partial set of push events from a block right after we got created,
271    // which we must ignore.
272    fn is_not_ready_for_push(&self) -> bool {
273        if self.saw_block {
274            // if we ever saw a block, then we must have seen the block start
275            // for the current block
276            assert!(self.decode_state.block_hash.is_some(), "saw block but no decode state");
277            false
278        } else {
279            // if we never saw a block, then we must not have seen the block start
280            assert!(
281                self.decode_state.block_hash.is_none(),
282                "never saw a block but decode state is present"
283            );
284            true
285        }
286    }
287}
288
289impl<'a> push_decoder::Listener for PushListener<'a> {
290    fn on_block_start(&mut self, header: &BlockHeader) {
291        // we shouldn't get more than one block start per decode state lifetime
292        // (which is the lifetime of a block stream)
293        assert!(self.decode_state.block_hash.is_none(), "saw more than one on_block_start");
294        self.decode_state.block_hash = Some(header.block_hash());
295        self.saw_block = true;
296    }
297
298    fn on_transaction_start(&mut self, version: i32) {
299        if self.is_not_ready_for_push() {
300            return;
301        }
302        let state = &mut self.decode_state;
303        state.version = version;
304        state.input_num = 0;
305        state.output_num = 0;
306        state.closing_tx = None;
307        state.spent_htlc_outputs = Vec::new();
308    }
309
310    fn on_transaction_input(&mut self, input: &TxIn) {
311        if self.is_not_ready_for_push() {
312            return;
313        }
314
315        let decode_state = &mut self.decode_state;
316
317        if decode_state.state.funding_inputs.contains(&input.previous_output) {
318            // A funding input was spent
319            decode_state.add_change(StateChange::FundingInputSpent(input.previous_output));
320        }
321
322        if Some(input.previous_output) == decode_state.state.funding_outpoint {
323            // The funding outpoint was spent - this is a closing transaction.
324            // Starting gathering it.  It will be processed in on_transaction_end.
325            // It may be either mutual or unilateral.
326            let tx = Transaction {
327                version: Version(decode_state.version),
328                lock_time: LockTime::ZERO,
329                input: vec![input.clone()],
330                output: vec![],
331            };
332            decode_state.closing_tx = Some(tx);
333        }
334
335        // Check if an output of a unilateral closing transaction was spent.
336        // split into two blocks for borrow checker
337        let closing_change = if let Some(ref c) = decode_state.state.closing_outpoints {
338            if c.includes_our_output(&input.previous_output) {
339                // We spent our output of a closing transaction
340                Some(StateChange::OurOutputSpent(input.previous_output.vout))
341            } else if c.includes_htlc_output(&input.previous_output) {
342                // Track vout and input index for second-level HTLC creation in on_transaction_end
343                decode_state
344                    .spent_htlc_outputs
345                    .push((input.previous_output.vout, decode_state.input_num));
346                None
347            } else if c.includes_second_level_htlc_output(&input.previous_output) {
348                Some(StateChange::SecondLevelHTLCOutputSpent(input.previous_output))
349            } else {
350                None
351            }
352        } else {
353            None
354        };
355
356        closing_change.map(|c| decode_state.add_change(c));
357
358        if decode_state.closing_tx.is_some() {
359            assert_eq!(decode_state.input_num, 0, "closing tx must have only one input");
360        }
361        decode_state.input_num += 1;
362    }
363
364    fn on_transaction_output(&mut self, output: &TxOut) {
365        if self.is_not_ready_for_push() {
366            return;
367        }
368
369        let decode_state = &mut self.decode_state;
370        if let Some(closing_tx) = &mut decode_state.closing_tx {
371            closing_tx.output.push(output.clone());
372            assert!(
373                decode_state.output_num < MAX_COMMITMENT_OUTPUTS,
374                "more than {} commitment outputs",
375                MAX_COMMITMENT_OUTPUTS
376            );
377        }
378
379        decode_state.output_num += 1;
380    }
381
382    fn on_transaction_end(&mut self, lock_time: LockTime, txid: Txid) {
383        if self.is_not_ready_for_push() {
384            return;
385        }
386
387        let decode_state = &mut self.decode_state;
388
389        if let Some(ind) = decode_state.state.funding_txids.iter().position(|i| *i == txid) {
390            let vout = decode_state.state.funding_vouts[ind];
391            // This was a funding transaction, which just confirmed
392            assert!(
393                vout < decode_state.output_num,
394                "tx {} doesn't have funding output index {}",
395                txid,
396                vout
397            );
398            let outpoint = OutPoint { txid, vout };
399            decode_state.add_change(StateChange::FundingConfirmed(outpoint));
400        }
401
402        // complete handling of closing tx, if this was one
403        if let Some(mut closing_tx) = decode_state.closing_tx.take() {
404            closing_tx.lock_time = lock_time;
405            // closing tx
406            assert_eq!(closing_tx.input.len(), 1);
407            let provider = self.commitment_point_provider;
408            let parameters = provider.get_transaction_parameters();
409
410            // check that the closing tx is a commitment tx, otherwise it was a mutual close
411            let commitment_number_opt = decode_commitment_number(&closing_tx, &parameters);
412            if let Some(commitment_number) = commitment_number_opt {
413                let secp_ctx = Secp256k1::new();
414                info!("unilateral close {} at commitment {} confirmed", txid, commitment_number);
415                let holder_per_commitment = provider.get_holder_commitment_point(commitment_number);
416                let cp_per_commitment =
417                    provider.get_counterparty_commitment_point(commitment_number);
418                let (our_output_index, htlc_indices) = decode_commitment_tx(
419                    &closing_tx,
420                    &holder_per_commitment,
421                    &cp_per_commitment,
422                    &parameters,
423                    &secp_ctx,
424                );
425                let spendable_htlc_indices = if htlc_indices.is_empty() {
426                    Vec::new()
427                } else {
428                    provider
429                        .get_spendable_htlc_indices(&closing_tx, commitment_number)
430                        .expect("valid spendable HTLC indices for a decoded commitment transaction")
431                };
432                debug!(
433                    "our_output_index: {:?}, htlc_indices: {:?}, spendable_htlc_indices: {:?}",
434                    our_output_index, htlc_indices, spendable_htlc_indices
435                );
436                decode_state.add_change(StateChange::UnilateralCloseConfirmed(
437                    txid,
438                    closing_tx.input[0].previous_output,
439                    our_output_index,
440                    spendable_htlc_indices,
441                ));
442            } else {
443                decode_state.add_change(StateChange::MutualCloseConfirmed(
444                    txid,
445                    closing_tx.input[0].previous_output,
446                ));
447                info!("mutual close {} confirmed", txid);
448            }
449        }
450
451        let htlc_changes: Vec<StateChange> = decode_state
452            .spent_htlc_outputs
453            .drain(..)
454            .map(|(spent_vout, input_index)| {
455                let second_level_outpoint = OutPoint { txid, vout: input_index };
456                StateChange::HTLCOutputSpent(spent_vout, second_level_outpoint)
457            })
458            .collect();
459
460        for change in htlc_changes {
461            decode_state.add_change(change);
462        }
463    }
464
465    fn on_block_end(&mut self) {
466        // we need to wait until we get the following `AddBlock` or `RemoveBlock`
467        // message before actually updating ourselves
468    }
469}
470
471impl State {
472    fn channel_id(&self) -> &ChannelId {
473        // safe because populated by new_from_persistence
474        self.channel_id.as_ref().expect("missing associated channel_id in monitor::State")
475    }
476
477    fn depth_of(&self, other_height: Option<u32>) -> u32 {
478        (self.height + 1).saturating_sub(other_height.unwrap_or(self.height + 1))
479    }
480
481    fn deep_enough_and_saw_node_forget(&self, other_height: Option<u32>, limit: u32) -> bool {
482        // If the event depth is less than MIN_DEPTH we never prune.
483        // If the event depth is greater we prune if saw_forget_channel is true.
484        let depth = self.depth_of(other_height);
485        if depth < limit {
486            // Not deep enough, we aren't done
487            false
488        } else if self.saw_forget_channel {
489            // Deep enough and the node thinks it's done too
490            true
491        } else {
492            // Deep enough, but we haven't heard from the node
493            warn!(
494                "expected forget_channel for {} overdue by {} blocks",
495                self.channel_id(),
496                depth - limit
497            );
498            false
499        }
500    }
501
502    fn diagnostic(&self, is_closed: bool) -> String {
503        if self.funding_height.is_none() {
504            format!("UNCOMFIRMED hold till funding doublespent + {}", MIN_DEPTH)
505        } else if let Some(height) = self.funding_double_spent_height {
506            format!("AGING_FUNDING_DOUBLESPENT at {} until {}", height, height + MIN_DEPTH)
507        } else if let Some(height) = self.mutual_closing_height {
508            format!("AGING_MUTUALLY_CLOSED at {} until {}", height, height + MIN_DEPTH)
509        } else if let Some(height) = self.closing_swept_height {
510            format!("AGING_CLOSING_SWEPT at {} until {}", height, height + MIN_DEPTH)
511        } else if let Some(height) = self.our_output_swept_height {
512            format!("AGING_OUR_OUTPUT_SWEPT at {} until {}", height, height + MAX_CLOSING_DEPTH)
513        } else if is_closed {
514            "CLOSING".into()
515        } else {
516            "ACTIVE".into()
517        }
518    }
519
520    fn is_done(&self) -> bool {
521        // we are done if:
522        // - funding was double spent
523        // - mutual closed
524        // - unilateral closed, and our output, as well as all HTLCs were swept
525        // and, the last confirmation is buried
526
527        if self.deep_enough_and_saw_node_forget(self.funding_double_spent_height, MIN_DEPTH) {
528            debug!(
529                "{} is_done because funding double spent {} blocks ago",
530                self.channel_id(),
531                MIN_DEPTH
532            );
533            return true;
534        }
535
536        if self.deep_enough_and_saw_node_forget(self.mutual_closing_height, MIN_DEPTH) {
537            debug!("{} is_done because mutual closed {} blocks ago", self.channel_id(), MIN_DEPTH);
538            return true;
539        }
540
541        if self.deep_enough_and_saw_node_forget(self.closing_swept_height, MIN_DEPTH) {
542            debug!("{} is_done because closing swept {} blocks ago", self.channel_id(), MIN_DEPTH);
543            return true;
544        }
545
546        return false;
547    }
548
549    fn on_add_block_end(
550        &mut self,
551        block_hash: &BlockHash,
552        decode_state: &mut BlockDecodeState,
553    ) -> (Vec<OutPoint>, Vec<OutPoint>) {
554        assert_eq!(decode_state.block_hash.as_ref(), Some(block_hash));
555
556        self.saw_block = true;
557        self.height += 1;
558
559        let closing_was_swept = self.is_closing_swept();
560        let our_output_was_swept = self.is_our_output_swept();
561
562        let mut adds = Vec::new();
563        let mut removes = Vec::new();
564
565        let changed = !decode_state.changes.is_empty();
566
567        if changed {
568            debug!(
569                "{} detected add-changes at height {}: {:?}",
570                self.channel_id(),
571                self.height,
572                decode_state.changes
573            );
574        }
575
576        // apply changes
577        for change in decode_state.changes.drain(..) {
578            self.apply_forward_change(&mut adds, &mut removes, change);
579        }
580
581        let closing_is_swept = self.is_closing_swept();
582        let our_output_is_swept = self.is_our_output_swept();
583
584        if !closing_was_swept && closing_is_swept {
585            info!("{} closing tx was swept at height {}", self.channel_id(), self.height);
586            self.closing_swept_height = Some(self.height);
587        }
588
589        if !our_output_was_swept && our_output_is_swept {
590            info!("{} our output was swept at height {}", self.channel_id(), self.height);
591            self.our_output_swept_height = Some(self.height);
592        }
593
594        if self.is_done() {
595            info!("{} done at height {}", self.channel_id(), self.height);
596        }
597
598        if changed {
599            #[cfg(not(feature = "log_pretty_print"))]
600            info!("on_add_block_end state changed: {:?}", self);
601            #[cfg(feature = "log_pretty_print")]
602            info!("on_add_block_end state changed: {:#?}", self);
603        }
604
605        (adds, removes)
606    }
607
608    fn on_remove_block_end(
609        &mut self,
610        block_hash: &BlockHash,
611        decode_state: &mut BlockDecodeState,
612    ) -> (Vec<OutPoint>, Vec<OutPoint>) {
613        assert_eq!(decode_state.block_hash.as_ref(), Some(block_hash));
614
615        let closing_was_swept = self.is_closing_swept();
616        let our_output_was_swept = self.is_our_output_swept();
617
618        let mut adds = Vec::new();
619        let mut removes = Vec::new();
620
621        let changed = !decode_state.changes.is_empty();
622
623        if changed {
624            debug!(
625                "{} detected remove-changes at height {}: {:?}",
626                self.channel_id(),
627                self.height,
628                decode_state.changes
629            );
630        }
631
632        for change in decode_state.changes.drain(..) {
633            self.apply_backward_change(&mut adds, &mut removes, change);
634        }
635
636        let closing_is_swept = self.is_closing_swept();
637        let our_output_is_swept = self.is_our_output_swept();
638
639        if closing_was_swept && !closing_is_swept {
640            info!("{} closing tx was un-swept at height {}", self.channel_id(), self.height);
641            self.closing_swept_height = None;
642        }
643
644        if our_output_was_swept && !our_output_is_swept {
645            info!("{} our output was un-swept at height {}", self.channel_id(), self.height);
646            self.our_output_swept_height = None;
647        }
648
649        self.height -= 1;
650
651        if changed {
652            #[cfg(not(feature = "log_pretty_print"))]
653            info!("on_remove_block_end state changed: {:?}", self);
654            #[cfg(feature = "log_pretty_print")]
655            info!("on_remove_block_end state changed: {:#?}", self);
656        }
657
658        // note that the caller will remove the adds and add the removes
659        (adds, removes)
660    }
661
662    // whether the unilateral closing tx was fully swept
663    fn is_closing_swept(&self) -> bool {
664        self.closing_outpoints.as_ref().map(|o| o.is_all_spent()).unwrap_or(false)
665    }
666
667    // whether our output was swept, or does not exist
668    fn is_our_output_swept(&self) -> bool {
669        self.closing_outpoints
670            .as_ref()
671            .map(|o| o.our_output.map(|(_, s)| s).unwrap_or(true))
672            .unwrap_or(false)
673    }
674
675    fn apply_forward_change(
676        &mut self,
677        adds: &mut Vec<OutPoint>,
678        removes: &mut Vec<OutPoint>,
679        change: StateChange,
680    ) {
681        // unwraps below on self.closing_outpoints are safe due to PushListener logic
682        match change {
683            StateChange::FundingConfirmed(outpoint) => {
684                self.funding_height = Some(self.height);
685                self.funding_outpoint = Some(outpoint);
686                // we may have thought we had a double-spend, but now we know we don't
687                self.funding_double_spent_height = None;
688                adds.push(outpoint);
689            }
690            StateChange::FundingInputSpent(outpoint) => {
691                // A funding input was double-spent, or funding was confirmed
692                // (in which case we'll see FundingConfirmed later on in this
693                // change list).
694                // we may have seen some other funding input double-spent, so
695                // don't overwrite the depth if it exists
696                self.funding_double_spent_height.get_or_insert(self.height);
697                // no matter whether funding, or double-spend, we want to stop watching this outpoint
698                removes.push(outpoint);
699            }
700            StateChange::UnilateralCloseConfirmed(
701                txid,
702                funding_outpoint,
703                our_output_index,
704                htlcs_indices,
705            ) => {
706                self.unilateral_closing_height = Some(self.height);
707                removes.push(funding_outpoint);
708                our_output_index.map(|i| adds.push(OutPoint { txid, vout: i }));
709                for i in htlcs_indices.iter() {
710                    adds.push(OutPoint { txid, vout: *i });
711                }
712                self.closing_outpoints =
713                    Some(ClosingOutpoints::new(txid, our_output_index, htlcs_indices));
714            }
715            StateChange::OurOutputSpent(vout) => {
716                let outpoints = self.closing_outpoints.as_mut().unwrap();
717                outpoints.set_our_output_spent(vout, true);
718                let outpoint = OutPoint { txid: outpoints.txid, vout };
719                removes.push(outpoint);
720            }
721            StateChange::HTLCOutputSpent(vout, second_level_htlc_outpoint) => {
722                let outpoints = self.closing_outpoints.as_mut().unwrap();
723                outpoints.set_htlc_output_spent(vout, true);
724                let outpoint = OutPoint { txid: outpoints.txid, vout };
725                outpoints.add_second_level_htlc_output(second_level_htlc_outpoint);
726                removes.push(outpoint);
727                adds.push(second_level_htlc_outpoint);
728            }
729            StateChange::SecondLevelHTLCOutputSpent(outpoint) => {
730                let closing_outpoints = self.closing_outpoints.as_mut().unwrap();
731                closing_outpoints.set_second_level_htlc_spent(outpoint, true);
732                removes.push(outpoint);
733            }
734            StateChange::MutualCloseConfirmed(_txid, funding_outpoint) => {
735                self.mutual_closing_height = Some(self.height);
736                removes.push(funding_outpoint);
737            }
738        }
739    }
740
741    // Note that in the logic below, we are mimicking the logic of
742    // apply_forward_change, but the caller will remove the adds and add the
743    // removes.
744    fn apply_backward_change(
745        &mut self,
746        adds: &mut Vec<OutPoint>,
747        removes: &mut Vec<OutPoint>,
748        change: StateChange,
749    ) {
750        match change {
751            StateChange::FundingConfirmed(outpoint) => {
752                // A funding tx was reorged-out
753                assert_eq!(self.funding_height, Some(self.height));
754                self.funding_height = None;
755                self.funding_outpoint = None;
756                adds.push(outpoint);
757            }
758            StateChange::FundingInputSpent(outpoint) => {
759                // A funding double-spent was reorged-out, or funding confirmation
760                // was reorged-out (in which case we'll see FundingConfirmed later
761                // on in this change list).
762                // We may have seen some other funding input double-spent, so
763                // clear out the height only if it is the current height.
764                if self.funding_double_spent_height == Some(self.height) {
765                    self.funding_double_spent_height = None
766                }
767                // no matter whether funding, or double-spend, we want to re-start watching this outpoint
768                removes.push(outpoint);
769            }
770            StateChange::UnilateralCloseConfirmed(
771                txid,
772                funding_outpoint,
773                our_output_index,
774                htlcs_indices,
775            ) => {
776                // A closing tx was reorged-out
777                assert_eq!(self.unilateral_closing_height, Some(self.height));
778                self.unilateral_closing_height = None;
779                self.closing_outpoints = None;
780                our_output_index.map(|i| adds.push(OutPoint { txid, vout: i }));
781                for i in htlcs_indices {
782                    adds.push(OutPoint { txid, vout: i });
783                }
784                removes.push(funding_outpoint)
785            }
786            StateChange::OurOutputSpent(vout) => {
787                let outpoints = self.closing_outpoints.as_mut().unwrap();
788                outpoints.set_our_output_spent(vout, false);
789                let outpoint = OutPoint { txid: outpoints.txid, vout };
790                removes.push(outpoint);
791            }
792            StateChange::HTLCOutputSpent(vout, second_level_htlc_outpoint) => {
793                let outpoints = self.closing_outpoints.as_mut().unwrap();
794                outpoints.set_htlc_output_spent(vout, false);
795                let outpoint = OutPoint { txid: outpoints.txid, vout };
796                outpoints.remove_second_level_htlc_output(&second_level_htlc_outpoint);
797                adds.push(outpoint);
798                removes.push(second_level_htlc_outpoint);
799            }
800            StateChange::SecondLevelHTLCOutputSpent(outpoint) => {
801                let closing_outpoints = self.closing_outpoints.as_mut().unwrap();
802                closing_outpoints.set_second_level_htlc_spent(outpoint, false);
803                adds.push(outpoint);
804            }
805            StateChange::MutualCloseConfirmed(_txid, funding_outpoint) => {
806                self.mutual_closing_height = None;
807                removes.push(funding_outpoint);
808            }
809        }
810    }
811}
812
813/// This is a pre-cursor to [`ChainMonitor`], before the [`CommitmentPointProvider`] is available.
814#[derive(Clone)]
815pub struct ChainMonitorBase {
816    // the first funding outpoint, used to identify the channel / channel monitor
817    pub(crate) funding_outpoint: OutPoint,
818    // the monitor state
819    state: Arc<Mutex<State>>,
820}
821
822impl ChainMonitorBase {
823    /// Create a new chain monitor.
824    /// Use add_funding to really start monitoring.
825    pub fn new(funding_outpoint: OutPoint, height: u32, chan_id: &ChannelId) -> Self {
826        let state = State {
827            height,
828            funding_txids: Vec::new(),
829            funding_vouts: Vec::new(),
830            funding_inputs: OrderedSet::new(),
831            funding_height: None,
832            funding_outpoint: None,
833            funding_double_spent_height: None,
834            mutual_closing_height: None,
835            unilateral_closing_height: None,
836            closing_outpoints: None,
837            closing_swept_height: None,
838            our_output_swept_height: None,
839            saw_block: false,
840            saw_forget_channel: false,
841            channel_id: Some(chan_id.clone()),
842        };
843
844        Self { funding_outpoint, state: Arc::new(Mutex::new(state)) }
845    }
846
847    /// recreate this monitor after restoring from persistence
848    pub fn new_from_persistence(
849        funding_outpoint: OutPoint,
850        state: State,
851        channel_id: &ChannelId,
852    ) -> Self {
853        let state = Arc::new(Mutex::new(state));
854        state.lock().unwrap().channel_id = Some(channel_id.clone());
855        Self { funding_outpoint, state }
856    }
857
858    /// Get the ChainMonitor
859    pub fn as_monitor(
860        &self,
861        commitment_point_provider: Box<dyn CommitmentPointProvider>,
862    ) -> ChainMonitor {
863        ChainMonitor {
864            funding_outpoint: self.funding_outpoint,
865            state: self.state.clone(),
866            decode_state: Arc::new(Mutex::new(None)),
867            commitment_point_provider,
868        }
869    }
870
871    /// Add a funding transaction to keep track of
872    /// For single-funding
873    pub fn add_funding_outpoint(&self, outpoint: &OutPoint) {
874        let mut state = self.get_state();
875        assert!(state.funding_txids.is_empty(), "only a single funding tx currently supported");
876        assert_eq!(state.funding_txids.len(), state.funding_vouts.len());
877        state.funding_txids.push(outpoint.txid);
878        state.funding_vouts.push(outpoint.vout);
879    }
880
881    /// Add a funding input
882    /// For single-funding
883    pub fn add_funding_inputs(&self, tx: &Transaction) {
884        let mut state = self.get_state();
885        state.funding_inputs.extend(tx.input.iter().map(|i| i.previous_output));
886    }
887
888    /// Convert to a ChainState, to be used for validation
889    pub fn as_chain_state(&self) -> ChainState {
890        let state = self.get_state();
891        ChainState {
892            current_height: state.height,
893            funding_depth: state.funding_height.map(|h| state.height + 1 - h).unwrap_or(0),
894            funding_double_spent_depth: state
895                .funding_double_spent_height
896                .map(|h| state.height + 1 - h)
897                .unwrap_or(0),
898            closing_depth: state
899                .mutual_closing_height
900                .or(state.unilateral_closing_height)
901                .map(|h| state.height + 1 - h)
902                .unwrap_or(0),
903        }
904    }
905
906    /// Whether this channel can be forgotten
907    pub fn is_done(&self) -> bool {
908        self.get_state().is_done()
909    }
910
911    /// Called when the node tells us it forgot the channel
912    pub fn forget_channel(&self) {
913        let mut state = self.get_state();
914        state.saw_forget_channel = true;
915    }
916
917    /// Returns the actual funding outpoint on-chain
918    pub fn funding_outpoint(&self) -> Option<OutPoint> {
919        self.get_state().funding_outpoint
920    }
921
922    /// Return whether forget_channel was seen
923    pub fn forget_seen(&self) -> bool {
924        self.get_state().saw_forget_channel
925    }
926
927    /// Return string describing the state
928    pub fn diagnostic(&self, is_closed: bool) -> String {
929        self.get_state().diagnostic(is_closed)
930    }
931
932    // Add this getter method
933    fn get_state(&self) -> MutexGuard<'_, State> {
934        self.state.lock().expect("lock")
935    }
936}
937
938/// Keep track of channel on-chain events.
939/// Note that this object has refcounted state, so is lightweight to clone.
940#[derive(Clone)]
941pub struct ChainMonitor {
942    /// the first funding outpoint, used to identify the channel / channel monitor
943    pub funding_outpoint: OutPoint,
944    /// the monitor state
945    pub state: Arc<Mutex<State>>,
946    // Block decode state, only while in progress
947    // Lock order: after `self.state`
948    decode_state: Arc<Mutex<Option<BlockDecodeState>>>,
949    // the commitment point provider, helps with decoding transactions
950    commitment_point_provider: Box<dyn CommitmentPointProvider>,
951}
952
953impl ChainMonitor {
954    /// Get the base
955    pub fn as_base(&self) -> ChainMonitorBase {
956        ChainMonitorBase { funding_outpoint: self.funding_outpoint, state: self.state.clone() }
957    }
958
959    /// Get the locked state
960    pub fn get_state(&self) -> MutexGuard<'_, State> {
961        self.state.lock().expect("lock")
962    }
963
964    /// Add a funding transaction to keep track of
965    /// For dual-funding
966    pub fn add_funding(&self, tx: &Transaction, vout: u32) {
967        let mut state = self.get_state();
968        assert!(state.funding_txids.is_empty(), "only a single funding tx currently supported");
969        assert_eq!(state.funding_txids.len(), state.funding_vouts.len());
970        state.funding_txids.push(tx.compute_txid());
971        state.funding_vouts.push(vout);
972        state.funding_inputs.extend(tx.input.iter().map(|i| i.previous_output));
973    }
974
975    /// Returns the number of confirmations of the funding transaction, or zero
976    /// if it wasn't confirmed yet.
977    pub fn funding_depth(&self) -> u32 {
978        let state = self.get_state();
979        state.depth_of(state.funding_height)
980    }
981
982    /// Returns the number of confirmations of a double-spend of the funding transaction
983    /// or zero if it wasn't double-spent.
984    pub fn funding_double_spent_depth(&self) -> u32 {
985        let state = self.get_state();
986        state.depth_of(state.funding_double_spent_height)
987    }
988
989    /// Returns the number of confirmations of the closing transaction, or zero
990    pub fn closing_depth(&self) -> u32 {
991        let state = self.get_state();
992        let closing_height = state.unilateral_closing_height.or(state.mutual_closing_height);
993        state.depth_of(closing_height)
994    }
995
996    /// Whether this channel can be forgotten:
997    /// - mutual close is confirmed
998    /// - unilateral close is swept
999    /// - funding transaction is double-spent
1000    /// and enough confirmations have passed
1001    pub fn is_done(&self) -> bool {
1002        self.get_state().is_done()
1003    }
1004
1005    // push compact proof transactions through, simulating a streamed block
1006    fn push_transactions(&self, block_hash: &BlockHash, txs: &[Transaction]) -> BlockDecodeState {
1007        let mut state = self.get_state();
1008
1009        // we are synced if we see a compact proof
1010        state.saw_block = true;
1011
1012        let mut decode_state = BlockDecodeState::new_with_block_hash(&*state, block_hash);
1013
1014        let mut listener = PushListener {
1015            commitment_point_provider: &*self.commitment_point_provider,
1016            decode_state: &mut decode_state,
1017            saw_block: true,
1018        };
1019
1020        // stream the transactions to the state
1021        for tx in txs {
1022            listener.on_transaction_start(tx.version.0);
1023            for input in tx.input.iter() {
1024                listener.on_transaction_input(input);
1025            }
1026
1027            for output in tx.output.iter() {
1028                listener.on_transaction_output(output);
1029            }
1030            listener.on_transaction_end(tx.lock_time, tx.compute_txid());
1031        }
1032
1033        decode_state
1034    }
1035}
1036
1037impl ChainListener for ChainMonitor {
1038    type Key = OutPoint;
1039
1040    fn key(&self) -> &Self::Key {
1041        &self.funding_outpoint
1042    }
1043
1044    fn on_add_block(
1045        &self,
1046        txs: &[Transaction],
1047        block_hash: &BlockHash,
1048    ) -> (Vec<OutPoint>, Vec<OutPoint>) {
1049        debug!("on_add_block for {}", self.funding_outpoint);
1050        let mut decode_state = self.push_transactions(block_hash, txs);
1051
1052        let mut state = self.get_state();
1053        state.on_add_block_end(block_hash, &mut decode_state)
1054    }
1055
1056    fn on_add_streamed_block_end(&self, block_hash: &BlockHash) -> (Vec<OutPoint>, Vec<OutPoint>) {
1057        let mut state = self.get_state();
1058        let mut decode_state = self.decode_state.lock().expect("lock").take();
1059        if !state.saw_block {
1060            // not ready yet, bail
1061            return (Vec::new(), Vec::new());
1062        }
1063        // safe because `on_push` must have been called first
1064        state.on_add_block_end(block_hash, decode_state.as_mut().unwrap())
1065    }
1066
1067    fn on_remove_block(
1068        &self,
1069        txs: &[Transaction],
1070        block_hash: &BlockHash,
1071    ) -> (Vec<OutPoint>, Vec<OutPoint>) {
1072        debug!("on_remove_block for {}", self.funding_outpoint);
1073        let mut decode_state = self.push_transactions(block_hash, txs);
1074
1075        let mut state = self.get_state();
1076        state.on_remove_block_end(block_hash, &mut decode_state)
1077    }
1078
1079    fn on_remove_streamed_block_end(
1080        &self,
1081        block_hash: &BlockHash,
1082    ) -> (Vec<OutPoint>, Vec<OutPoint>) {
1083        let mut state = self.get_state();
1084        let mut decode_state = self.decode_state.lock().expect("lock").take();
1085        if !state.saw_block {
1086            // not ready yet, bail
1087            return (Vec::new(), Vec::new());
1088        }
1089        // safe because `on_push` must have been called first
1090        state.on_remove_block_end(block_hash, decode_state.as_mut().unwrap())
1091    }
1092
1093    fn on_push<F>(&self, f: F)
1094    where
1095        F: FnOnce(&mut dyn push_decoder::Listener),
1096    {
1097        let mut state = self.get_state();
1098        let saw_block = state.saw_block;
1099
1100        let mut decode_state_lock = self.decode_state.lock().expect("lock");
1101
1102        let decode_state = decode_state_lock.get_or_insert_with(|| BlockDecodeState::new(&*state));
1103
1104        let mut listener = PushListener {
1105            commitment_point_provider: &*self.commitment_point_provider,
1106            decode_state,
1107            saw_block,
1108        };
1109        f(&mut listener);
1110
1111        // update the saw_block flag, in case the listener saw a block start event
1112        state.saw_block = listener.saw_block;
1113    }
1114}
1115
1116impl SendSync for ChainMonitor {}
1117
1118#[cfg(test)]
1119mod tests {
1120    use crate::channel::{
1121        Channel, ChannelBase, ChannelCommitmentPointProvider, ChannelId, ChannelSetup,
1122        CommitmentType,
1123    };
1124    use crate::node::{Node, RoutedPayment};
1125    use crate::tx::tx::HTLCInfo2;
1126    use crate::util::test_utils::htlc::make_htlc;
1127    use crate::util::test_utils::key::{make_test_counterparty_points, make_test_pubkey};
1128    use crate::util::test_utils::*;
1129    use bitcoin::block::Version;
1130    use bitcoin::hash_types::TxMerkleNode;
1131    use bitcoin::hashes::Hash;
1132    use bitcoin::CompactTarget;
1133    use test_log::test;
1134
1135    use super::*;
1136
1137    #[test]
1138    fn test_funding() {
1139        let tx = make_tx(vec![make_txin(1), make_txin(2)]);
1140        let outpoint = OutPoint::new(tx.compute_txid(), 0);
1141        let cpp = Box::new(DummyCommitmentPointProvider {});
1142        let chan_id = ChannelId::new(&[33u8; 32]);
1143        let monitor = ChainMonitorBase::new(outpoint, 0, &chan_id).as_monitor(cpp);
1144        let block_hash = BlockHash::all_zeros();
1145        monitor.add_funding(&tx, 0);
1146        monitor.on_add_block(&[], &block_hash);
1147        monitor.on_add_block(&[tx.clone()], &block_hash);
1148        assert_eq!(monitor.funding_depth(), 1);
1149        assert_eq!(monitor.funding_double_spent_depth(), 0);
1150        monitor.on_add_block(&[], &block_hash);
1151        assert_eq!(monitor.funding_depth(), 2);
1152        monitor.on_remove_block(&[], &block_hash);
1153        assert_eq!(monitor.funding_depth(), 1);
1154        monitor.on_remove_block(&[tx], &block_hash);
1155        assert_eq!(monitor.funding_depth(), 0);
1156        monitor.on_remove_block(&[], &block_hash);
1157        assert_eq!(monitor.funding_depth(), 0);
1158    }
1159
1160    #[test]
1161    fn test_funding_double_spent() {
1162        let tx = make_tx(vec![make_txin(1), make_txin(2)]);
1163        let tx2 = make_tx(vec![make_txin(2)]);
1164        let outpoint = OutPoint::new(tx.compute_txid(), 0);
1165        let cpp = Box::new(DummyCommitmentPointProvider {});
1166        let chan_id = ChannelId::new(&[33u8; 32]);
1167        let monitor = ChainMonitorBase::new(outpoint, 0, &chan_id).as_monitor(cpp);
1168        let block_hash = BlockHash::all_zeros();
1169        monitor.add_funding(&tx, 0);
1170        monitor.on_add_block(&[], &block_hash);
1171        monitor.on_add_block(&[tx2.clone()], &block_hash);
1172        assert_eq!(monitor.funding_depth(), 0);
1173        assert_eq!(monitor.funding_double_spent_depth(), 1);
1174        monitor.on_add_block(&[], &block_hash);
1175        assert_eq!(monitor.funding_depth(), 0);
1176        assert_eq!(monitor.funding_double_spent_depth(), 2);
1177        monitor.on_remove_block(&[], &block_hash);
1178        assert_eq!(monitor.funding_double_spent_depth(), 1);
1179        monitor.on_remove_block(&[tx2], &block_hash);
1180        assert_eq!(monitor.funding_double_spent_depth(), 0);
1181        monitor.on_remove_block(&[], &block_hash);
1182        assert_eq!(monitor.funding_double_spent_depth(), 0);
1183    }
1184
1185    #[test]
1186    fn test_stream() {
1187        let outpoint = OutPoint::new(Txid::from_slice(&[1; 32]).unwrap(), 0);
1188        let cpp = Box::new(DummyCommitmentPointProvider {});
1189        let chan_id = ChannelId::new(&[33u8; 32]);
1190        let monitor = ChainMonitorBase::new(outpoint, 0, &chan_id).as_monitor(cpp);
1191        let header = BlockHeader {
1192            version: Version::from_consensus(0),
1193            prev_blockhash: BlockHash::all_zeros(),
1194            merkle_root: TxMerkleNode::all_zeros(),
1195            time: 0,
1196            bits: CompactTarget::from_consensus(0),
1197            nonce: 0,
1198        };
1199        let tx = make_tx(vec![make_txin(1), make_txin(2)]);
1200
1201        // test a push when not ready (simulates creation during a stream)
1202        monitor.on_push(|listener| {
1203            listener.on_transaction_input(&tx.input[1]);
1204            listener.on_transaction_output(&tx.output[0]);
1205            listener.on_transaction_end(tx.lock_time, tx.compute_txid());
1206            listener.on_block_end();
1207        });
1208
1209        assert!(!monitor.state.lock().unwrap().saw_block);
1210
1211        // test a block push
1212        monitor.on_push(|listener| {
1213            listener.on_block_start(&header);
1214            listener.on_transaction_start(2);
1215            listener.on_transaction_input(&tx.input[0]);
1216            listener.on_transaction_input(&tx.input[1]);
1217            listener.on_transaction_output(&tx.output[0]);
1218            listener.on_transaction_end(tx.lock_time, tx.compute_txid());
1219            listener.on_block_end();
1220        });
1221        monitor.on_add_streamed_block_end(&header.block_hash());
1222
1223        assert!(monitor.state.lock().unwrap().saw_block);
1224
1225        // test another block push to ensure the state is reset
1226        monitor.on_push(|listener| {
1227            listener.on_block_start(&header);
1228            listener.on_transaction_start(2);
1229            listener.on_transaction_input(&tx.input[0]);
1230            listener.on_transaction_input(&tx.input[1]);
1231            listener.on_transaction_output(&tx.output[0]);
1232            listener.on_transaction_end(tx.lock_time, tx.compute_txid());
1233            listener.on_block_end();
1234        });
1235        monitor.on_add_streamed_block_end(&header.block_hash());
1236
1237        assert!(monitor.state.lock().unwrap().saw_block);
1238    }
1239
1240    #[test]
1241    fn test_streamed_block_operations() {
1242        let outpoint = OutPoint::new(Txid::from_slice(&[1; 32]).unwrap(), 0);
1243        let cpp = Box::new(DummyCommitmentPointProvider {});
1244        let chan_id = ChannelId::new(&[33u8; 32]);
1245        let monitor = ChainMonitorBase::new(outpoint, 0, &chan_id).as_monitor(cpp);
1246        let block_hash = BlockHash::all_zeros();
1247
1248        // Test when not ready (saw_block = false)
1249        let (adds, removes) = monitor.on_add_streamed_block_end(&block_hash);
1250        assert!(adds.is_empty());
1251        assert!(removes.is_empty());
1252
1253        let (adds, removes) = monitor.on_remove_streamed_block_end(&block_hash);
1254        assert!(adds.is_empty());
1255        assert!(removes.is_empty());
1256
1257        let funding_tx = make_tx(vec![make_txin(1), make_txin(2)]);
1258        let funding_outpoint = OutPoint::new(funding_tx.compute_txid(), 0);
1259        let monitor2 = ChainMonitorBase::new(funding_outpoint, 0, &chan_id)
1260            .as_monitor(Box::new(DummyCommitmentPointProvider {}));
1261        monitor2.add_funding(&funding_tx, 0);
1262
1263        let header = BlockHeader {
1264            version: Version::from_consensus(0),
1265            prev_blockhash: BlockHash::all_zeros(),
1266            merkle_root: TxMerkleNode::all_zeros(),
1267            time: 0,
1268            bits: CompactTarget::from_consensus(0),
1269            nonce: 0,
1270        };
1271        let header_block_hash = header.block_hash();
1272
1273        monitor2.on_push(|listener| {
1274            listener.on_block_start(&header);
1275            listener.on_transaction_start(funding_tx.version.0);
1276
1277            for input in &funding_tx.input {
1278                listener.on_transaction_input(input);
1279            }
1280
1281            for output in &funding_tx.output {
1282                listener.on_transaction_output(output);
1283            }
1284
1285            listener.on_transaction_end(funding_tx.lock_time, funding_tx.compute_txid());
1286            listener.on_block_end();
1287        });
1288
1289        let (adds, _) = monitor2.on_add_streamed_block_end(&header_block_hash);
1290        assert!(!adds.is_empty());
1291
1292        monitor2.on_push(|listener| {
1293            listener.on_block_start(&header);
1294            listener.on_transaction_start(funding_tx.version.0);
1295
1296            for input in &funding_tx.input {
1297                listener.on_transaction_input(input);
1298            }
1299
1300            for output in &funding_tx.output {
1301                listener.on_transaction_output(output);
1302            }
1303
1304            listener.on_transaction_end(funding_tx.lock_time, funding_tx.compute_txid());
1305            listener.on_block_end();
1306        });
1307
1308        let (adds, _) = monitor2.on_remove_streamed_block_end(&header_block_hash);
1309        assert!(!adds.is_empty());
1310    }
1311
1312    #[test]
1313    fn test_chain_monitor_conversions_and_getters() {
1314        let outpoint = OutPoint::new(Txid::from_slice(&[1; 32]).unwrap(), 0);
1315        let chan_id = ChannelId::new(&[33u8; 32]);
1316        let base = ChainMonitorBase::new(outpoint, 0, &chan_id);
1317
1318        let cpp = Box::new(DummyCommitmentPointProvider {});
1319        let monitor = base.as_monitor(cpp);
1320        let base2 = monitor.as_base();
1321        assert_eq!(base2.funding_outpoint, outpoint);
1322
1323        assert_eq!(base.funding_outpoint(), None);
1324        assert!(!base.forget_seen());
1325
1326        base.forget_channel();
1327        assert!(base.forget_seen());
1328    }
1329    #[test]
1330    fn test_mutual_close() {
1331        let block_hash = BlockHash::all_zeros();
1332        let (node, channel_id, monitor, funding_txid) = setup_funded_channel();
1333
1334        // channel should exist after a heartbeat
1335        node.get_heartbeat();
1336        assert!(node.get_channel(&channel_id).is_ok());
1337        assert_eq!(node.get_tracker().listeners.len(), 1);
1338
1339        let close_tx = make_tx(vec![TxIn {
1340            previous_output: OutPoint::new(funding_txid, 0),
1341            script_sig: Default::default(),
1342            sequence: Default::default(),
1343            witness: Default::default(),
1344        }]);
1345        monitor.on_add_block(&[close_tx.clone()], &block_hash);
1346        assert_eq!(monitor.closing_depth(), 1);
1347        assert!(!monitor.is_done());
1348
1349        // channel should exist after a heartbeat
1350        node.get_heartbeat();
1351        assert!(node.get_channel(&channel_id).is_ok());
1352        assert_eq!(node.get_tracker().listeners.len(), 1);
1353
1354        for _ in 1..MIN_DEPTH - 1 {
1355            monitor.on_add_block(&[], &block_hash);
1356        }
1357        assert!(!monitor.is_done());
1358        node.forget_channel(&channel_id).unwrap();
1359        monitor.on_add_block(&[], &block_hash);
1360        assert!(monitor.is_done());
1361
1362        // channel should still be there until the heartbeat
1363        assert!(node.get_channel(&channel_id).is_ok());
1364
1365        // channel should be pruned after a heartbeat
1366        node.get_heartbeat();
1367        assert!(node.get_channel(&channel_id).is_err());
1368        assert_eq!(node.get_tracker().listeners.len(), 0);
1369    }
1370
1371    #[test]
1372    fn test_mutual_close_with_forget_channel() {
1373        let block_hash = BlockHash::all_zeros();
1374        let (node, channel_id, monitor, funding_txid) = setup_funded_channel();
1375
1376        // channel should exist after a heartbeat
1377        node.get_heartbeat();
1378        assert!(node.get_channel(&channel_id).is_ok());
1379        assert_eq!(node.get_tracker().listeners.len(), 1);
1380
1381        let close_tx = make_tx(vec![TxIn {
1382            previous_output: OutPoint::new(funding_txid, 0),
1383            script_sig: Default::default(),
1384            sequence: Default::default(),
1385            witness: Default::default(),
1386        }]);
1387        monitor.on_add_block(&[close_tx.clone()], &block_hash);
1388        assert_eq!(monitor.closing_depth(), 1);
1389        assert!(!monitor.is_done());
1390
1391        // channel should exist after a heartbeat
1392        node.get_heartbeat();
1393        assert!(node.get_channel(&channel_id).is_ok());
1394        assert_eq!(node.get_tracker().listeners.len(), 1);
1395
1396        for _ in 1..MIN_DEPTH - 1 {
1397            monitor.on_add_block(&[], &block_hash);
1398        }
1399        assert!(!monitor.is_done());
1400        monitor.on_add_block(&[], &block_hash);
1401        assert!(!monitor.is_done());
1402
1403        // channel should still be there until the forget_channel
1404        assert!(node.get_channel(&channel_id).is_ok());
1405        node.forget_channel(&channel_id).unwrap();
1406
1407        // need a heartbeat to do the pruning
1408        assert!(node.get_channel(&channel_id).is_ok());
1409        node.get_heartbeat();
1410        assert!(node.get_channel(&channel_id).is_err());
1411        assert_eq!(node.get_tracker().listeners.len(), 0);
1412    }
1413
1414    #[test]
1415    fn test_mutual_close_with_missing_forget_channel() {
1416        let block_hash = BlockHash::all_zeros();
1417        let (node, channel_id, monitor, funding_txid) = setup_funded_channel();
1418
1419        // channel should exist after a heartbeat
1420        node.get_heartbeat();
1421        assert!(node.get_channel(&channel_id).is_ok());
1422        assert_eq!(node.get_tracker().listeners.len(), 1);
1423
1424        let close_tx = make_tx(vec![TxIn {
1425            previous_output: OutPoint::new(funding_txid, 0),
1426            script_sig: Default::default(),
1427            sequence: Default::default(),
1428            witness: Default::default(),
1429        }]);
1430        monitor.on_add_block(&[close_tx.clone()], &block_hash);
1431        assert_eq!(monitor.closing_depth(), 1);
1432        assert!(!monitor.is_done());
1433
1434        // channel should exist after a heartbeat
1435        node.get_heartbeat();
1436        assert!(node.get_channel(&channel_id).is_ok());
1437        assert_eq!(node.get_tracker().listeners.len(), 1);
1438
1439        for _ in 1..MIN_DEPTH - 1 {
1440            monitor.on_add_block(&[], &block_hash);
1441        }
1442        assert!(!monitor.is_done());
1443        monitor.on_add_block(&[], &block_hash);
1444
1445        // we're not done because no forget_channel seen
1446        assert!(!monitor.is_done());
1447        assert!(node.get_channel(&channel_id).is_ok());
1448
1449        // channel should still be there after heartbeat
1450        node.get_heartbeat();
1451        assert!(node.get_channel(&channel_id).is_ok());
1452
1453        // wait a long time
1454        for _ in 0..2016 - 1 {
1455            monitor.on_add_block(&[], &block_hash);
1456        }
1457        assert!(!monitor.is_done());
1458
1459        // we still don't forget the channel if the node hasn't said forget
1460        monitor.on_add_block(&[], &block_hash);
1461        assert!(!monitor.is_done());
1462
1463        // channel should still be there
1464        assert!(node.get_channel(&channel_id).is_ok());
1465
1466        // channel should not be pruned after a heartbeat
1467        node.get_heartbeat();
1468        assert!(node.get_channel(&channel_id).is_ok());
1469    }
1470
1471    #[test]
1472    fn test_unilateral_holder_close() {
1473        let block_hash = BlockHash::all_zeros();
1474        let (node, channel_id, monitor, _funding_txid) = setup_funded_channel();
1475
1476        let commit_num = 23;
1477        let feerate_per_kw = 1000;
1478        let to_holder = 100000;
1479        let to_cp = 200000;
1480        let htlcs = Vec::new();
1481        let closing_commitment_tx = node
1482            .with_channel(&channel_id, |chan| {
1483                chan.set_next_holder_commit_num_for_testing(commit_num);
1484                let per_commitment_point = chan.get_per_commitment_point(commit_num)?;
1485
1486                chan.set_next_counterparty_commit_num_for_testing(
1487                    commit_num + 1,
1488                    per_commitment_point.clone(),
1489                );
1490
1491                Ok(chan.make_holder_commitment_tx(
1492                    commit_num,
1493                    &per_commitment_point,
1494                    feerate_per_kw,
1495                    to_holder,
1496                    to_cp,
1497                    htlcs.clone(),
1498                ))
1499            })
1500            .expect("make_holder_commitment_tx failed");
1501        let closing_tx = closing_commitment_tx.trust().built_transaction().transaction.clone();
1502        let closing_txid = closing_tx.compute_txid();
1503        let holder_output_index =
1504            closing_tx.output.iter().position(|out| out.value.to_sat() == to_holder).unwrap()
1505                as u32;
1506        monitor.on_add_block(&[closing_tx.clone()], &block_hash);
1507        assert_eq!(monitor.closing_depth(), 1);
1508        assert!(!monitor.is_done());
1509        // we never forget the channel if we didn't sweep our output
1510        for _ in 1..MAX_CLOSING_DEPTH {
1511            monitor.on_add_block(&[], &block_hash);
1512        }
1513        assert!(!monitor.is_done());
1514        let sweep_cp_tx = make_tx(vec![make_txin2(closing_txid, 1 - holder_output_index)]);
1515        monitor.on_add_block(&[sweep_cp_tx], &block_hash);
1516        // we still never forget the channel
1517        for _ in 1..MAX_CLOSING_DEPTH {
1518            monitor.on_add_block(&[], &block_hash);
1519        }
1520        assert!(!monitor.is_done());
1521        let sweep_holder_tx = make_tx(vec![make_txin2(closing_txid, holder_output_index)]);
1522        monitor.on_add_block(&[sweep_holder_tx], &block_hash);
1523        // once we sweep our output, we forget the channel
1524        for _ in 1..MIN_DEPTH {
1525            monitor.on_add_block(&[], &block_hash);
1526        }
1527        node.forget_channel(&channel_id).unwrap();
1528        assert!(monitor.is_done());
1529    }
1530
1531    #[test]
1532    fn test_unilateral_cp_and_htlcs_close() {
1533        let block_hash = BlockHash::all_zeros();
1534        let (node, channel_id, monitor, _funding_txid) = setup_funded_channel();
1535
1536        let payment_hashes = make_test_payment_hashes(4);
1537        let (preimage_1, hash_1) = payment_hashes[0];
1538        let (_, hash_2) = payment_hashes[1];
1539        let (_, hash_3) = payment_hashes[2];
1540        let (_, hash_4) = payment_hashes[3];
1541
1542        let offered_htlcs = vec![make_htlc(hash_1, 500, 100), make_htlc(hash_2, 600, 150)];
1543        let received_htlcs = vec![make_htlc(hash_3, 500, 200), make_htlc(hash_4, 600, 250)];
1544
1545        let mut node_state = node.get_state();
1546        let mut payment = RoutedPayment::new();
1547        payment.preimage = Some(preimage_1);
1548        node_state.payments.insert(hash_1, payment);
1549        drop(node_state);
1550
1551        let commit_num = 23;
1552        let feerate_per_kw = 1000;
1553        let to_holder = 100000;
1554        let to_cp = 200000;
1555
1556        let htlcs = Channel::htlcs_info2_to_oic(&offered_htlcs, &received_htlcs);
1557
1558        let closing_commitment_tx = node
1559            .with_channel(&channel_id, |chan| {
1560                let per_commitment_point = make_test_pubkey(12);
1561                let info2 = chan.build_counterparty_commitment_info(
1562                    to_holder,
1563                    to_cp,
1564                    offered_htlcs.clone(),
1565                    received_htlcs.clone(),
1566                    feerate_per_kw,
1567                )?;
1568                chan.set_next_counterparty_commit_num_for_testing(
1569                    commit_num + 1,
1570                    per_commitment_point.clone(),
1571                );
1572                chan.enforcement_state.current_counterparty_commit_info = Some(info2);
1573
1574                Ok(chan.make_counterparty_commitment_tx(
1575                    &per_commitment_point,
1576                    commit_num,
1577                    feerate_per_kw,
1578                    to_holder,
1579                    to_cp,
1580                    htlcs.clone(),
1581                ))
1582            })
1583            .expect("make_counterparty_commitment_tx failed");
1584
1585        let closing_tx = closing_commitment_tx.trust().built_transaction().transaction.clone();
1586        let (closing_txid, holder_output_index, cp_output_index, htlc_output_indices) =
1587            extract_tx_info(&closing_tx, to_holder, to_cp, &htlcs);
1588
1589        assert_eq!(monitor.closing_depth(), 0);
1590        assert!(!monitor.is_done());
1591
1592        monitor.on_add_block(&[closing_tx.clone()], &block_hash);
1593        assert_eq!(monitor.closing_depth(), 1);
1594        assert!(!monitor.is_done());
1595
1596        let spendable_indices = node
1597            .with_channel(&channel_id, |chan| {
1598                chan.get_spendable_htlc_indices(&closing_tx, commit_num)
1599            })
1600            .expect("spendable indices");
1601
1602        assert_eq!(spendable_indices.len(), 3);
1603
1604        let state = monitor.get_state();
1605        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1606
1607        assert!(!closing_outpoints.is_all_spent());
1608
1609        let holder_outpoint = OutPoint { txid: closing_txid, vout: holder_output_index };
1610        let cp_outpoint = OutPoint { txid: closing_txid, vout: cp_output_index };
1611        let trackable_htlc_outpoints: Vec<OutPoint> = htlc_output_indices
1612            .iter()
1613            .enumerate()
1614            .filter(|(i, _)| htlcs[*i].amount_msat != 600_000)
1615            .map(|(_, &vout)| OutPoint { txid: closing_txid, vout })
1616            .collect();
1617
1618        assert!(closing_outpoints.includes_our_output(&holder_outpoint));
1619        assert!(!closing_outpoints.includes_our_output(&cp_outpoint));
1620        for trackable_htlc_outpoint in &trackable_htlc_outpoints {
1621            assert!(closing_outpoints.includes_htlc_output(trackable_htlc_outpoint));
1622            assert!(!closing_outpoints.includes_second_level_htlc_output(trackable_htlc_outpoint));
1623        }
1624        assert!(!closing_outpoints.includes_htlc_output(&holder_outpoint));
1625
1626        drop(state);
1627        assert!(!monitor.is_done());
1628
1629        let sweep_cp_tx = make_tx(vec![make_txin2(closing_txid, cp_output_index)]);
1630        monitor.on_add_block(&[sweep_cp_tx], &block_hash);
1631        assert!(!monitor.is_done());
1632
1633        let sweep_holder_tx = make_tx(vec![make_txin2(closing_txid, holder_output_index)]);
1634        monitor.on_add_block(&[sweep_holder_tx], &block_hash);
1635
1636        let state = monitor.get_state();
1637        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1638        assert!(!closing_outpoints.is_all_spent());
1639        drop(state);
1640
1641        let monitor1 = monitor.clone();
1642
1643        // TIMELINE 1 - HTLC output not swept
1644        assert!(!monitor.is_done());
1645        monitor.on_add_block(&[], &block_hash);
1646        assert!(!monitor.is_done());
1647
1648        // TIMELINE 2 - HTLC output swept
1649        let mut swept_htlc_txids = Vec::new();
1650        let mut second_level_outpoints = Vec::new();
1651
1652        // Sweep HTLC outputs
1653        for (_, &htlc_index) in spendable_indices.iter().enumerate() {
1654            let sweep_htlc_tx = make_tx(vec![make_txin2(closing_txid, htlc_index)]);
1655            let sweep_htlc_txid = sweep_htlc_tx.compute_txid();
1656            swept_htlc_txids.push(sweep_htlc_txid);
1657
1658            monitor1.on_add_block(&[sweep_htlc_tx], &block_hash);
1659
1660            let state = monitor1.get_state();
1661            let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1662
1663            let second_level_outpoint = OutPoint { txid: sweep_htlc_txid, vout: 0 };
1664            second_level_outpoints.push(second_level_outpoint);
1665
1666            assert!(closing_outpoints.includes_second_level_htlc_output(&second_level_outpoint));
1667            assert!(!closing_outpoints.is_all_spent());
1668            drop(state);
1669        }
1670
1671        let state = monitor1.get_state();
1672        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1673        for (_, &second_level_outpoint) in second_level_outpoints.iter().enumerate() {
1674            assert!(closing_outpoints.includes_second_level_htlc_output(&second_level_outpoint));
1675        }
1676        drop(state);
1677        assert!(!monitor1.is_done());
1678
1679        // Now sweep all second-level outputs
1680        for (i, &outpoint) in second_level_outpoints.iter().enumerate() {
1681            let sweep_second_level_tx = make_tx(vec![make_txin2(outpoint.txid, 0)]);
1682            monitor1.on_add_block(&[sweep_second_level_tx], &block_hash);
1683
1684            let state = monitor1.get_state();
1685            let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1686
1687            if i == second_level_outpoints.len() - 1 {
1688                assert!(closing_outpoints.is_all_spent());
1689            } else {
1690                assert!(!closing_outpoints.is_all_spent());
1691            }
1692            drop(state);
1693        }
1694
1695        // All outputs swept
1696        let state = monitor1.get_state();
1697        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1698        assert!(closing_outpoints.is_all_spent());
1699        drop(state);
1700
1701        for _ in 1..MIN_DEPTH {
1702            monitor1.on_add_block(&[], &block_hash);
1703        }
1704        // still not done, need forget from node
1705        assert!(!monitor1.is_done());
1706
1707        // once the node forgets we can forget all of the above
1708        node.forget_channel(&channel_id).unwrap();
1709        assert!(monitor.is_done());
1710        assert!(monitor1.is_done());
1711    }
1712
1713    #[test]
1714    fn test_unilateral_cp_and_htlcs_backward_change() {
1715        let block_hash = BlockHash::all_zeros();
1716        let (node, channel_id, monitor, _funding_txid) = setup_funded_channel();
1717
1718        let payment_hashes = make_test_payment_hashes(4);
1719        let (preimage_1, hash_1) = payment_hashes[0];
1720        let (_, hash_2) = payment_hashes[1];
1721        let (_, hash_3) = payment_hashes[2];
1722        let (_, hash_4) = payment_hashes[3];
1723
1724        let offered_htlcs = vec![
1725            HTLCInfo2 { value_sat: 500, payment_hash: hash_1, cltv_expiry: 100 },
1726            HTLCInfo2 { value_sat: 600, payment_hash: hash_2, cltv_expiry: 150 },
1727        ];
1728
1729        let received_htlcs = vec![
1730            HTLCInfo2 { value_sat: 500, payment_hash: hash_3, cltv_expiry: 200 },
1731            HTLCInfo2 { value_sat: 400, payment_hash: hash_4, cltv_expiry: 250 },
1732        ];
1733
1734        let mut node_state = node.get_state();
1735        let mut payment = RoutedPayment::new();
1736        payment.preimage = Some(preimage_1);
1737        node_state.payments.insert(hash_1, payment);
1738        drop(node_state);
1739
1740        let commit_num = 23;
1741        let feerate_per_kw = 1000;
1742        let to_holder = 100000;
1743        let to_cp = 200000;
1744
1745        let htlcs = Channel::htlcs_info2_to_oic(&offered_htlcs, &received_htlcs);
1746
1747        let closing_commitment_tx = node
1748            .with_channel(&channel_id, |chan| {
1749                let per_commitment_point = make_test_pubkey(12);
1750                let info2 = chan.build_counterparty_commitment_info(
1751                    to_holder,
1752                    to_cp,
1753                    offered_htlcs.clone(),
1754                    received_htlcs.clone(),
1755                    feerate_per_kw,
1756                )?;
1757                chan.set_next_counterparty_commit_num_for_testing(
1758                    commit_num + 1,
1759                    per_commitment_point.clone(),
1760                );
1761                chan.enforcement_state.current_counterparty_commit_info = Some(info2);
1762
1763                Ok(chan.make_counterparty_commitment_tx(
1764                    &per_commitment_point,
1765                    commit_num,
1766                    feerate_per_kw,
1767                    to_holder,
1768                    to_cp,
1769                    htlcs.clone(),
1770                ))
1771            })
1772            .expect("make_counterparty_commitment_tx failed");
1773
1774        let closing_tx = closing_commitment_tx.trust().built_transaction().transaction.clone();
1775        let (closing_txid, holder_output_index, cp_output_index, htlc_output_indices) =
1776            extract_tx_info(&closing_tx, to_holder, to_cp, &htlcs);
1777
1778        assert_eq!(monitor.closing_depth(), 0);
1779        monitor.on_add_block(&[closing_tx.clone()], &block_hash);
1780        assert_eq!(monitor.closing_depth(), 1);
1781
1782        let spendable_indices = node
1783            .with_channel(&channel_id, |chan| {
1784                chan.get_spendable_htlc_indices(&closing_tx, commit_num)
1785            })
1786            .expect("spendable indices");
1787        assert_eq!(spendable_indices.len(), 3);
1788
1789        let state = monitor.get_state();
1790        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1791        assert!(!closing_outpoints.is_all_spent());
1792
1793        let holder_outpoint = OutPoint { txid: closing_txid, vout: holder_output_index };
1794        let cp_outpoint = OutPoint { txid: closing_txid, vout: cp_output_index };
1795        // Create outpoints for HTLCs we can track (excluding the 600 sat HTLC since we can't spend it)
1796        let trackable_htlc_outpoints: Vec<OutPoint> = htlc_output_indices
1797            .iter()
1798            .enumerate()
1799            .filter(|(i, _)| htlcs[*i].amount_msat != 600_000)
1800            .map(|(_, &vout)| OutPoint { txid: closing_txid, vout })
1801            .collect();
1802
1803        assert!(!closing_outpoints.is_all_spent());
1804        assert!(closing_outpoints.includes_our_output(&holder_outpoint));
1805        assert!(!closing_outpoints.includes_our_output(&cp_outpoint));
1806        for trackable_htlc_outpoint in &trackable_htlc_outpoints {
1807            assert!(closing_outpoints.includes_htlc_output(trackable_htlc_outpoint));
1808            assert!(!closing_outpoints.includes_second_level_htlc_output(trackable_htlc_outpoint));
1809        }
1810        assert!(!closing_outpoints.includes_htlc_output(&holder_outpoint));
1811        drop(state);
1812
1813        let sweep_holder_tx = make_tx(vec![make_txin2(closing_txid, holder_output_index)]);
1814        monitor.on_add_block(&[sweep_holder_tx.clone()], &block_hash);
1815
1816        let state = monitor.get_state();
1817        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1818        assert!(!closing_outpoints.is_all_spent());
1819        drop(state);
1820
1821        let mut swept_htlc_txs = Vec::new();
1822        let mut swept_htlc_txids = Vec::new();
1823        let mut second_level_outpoints = Vec::new();
1824
1825        for (_, &htlc_index) in spendable_indices.iter().enumerate() {
1826            let sweep_htlc_tx = make_tx(vec![make_txin2(closing_txid, htlc_index)]);
1827            let sweep_htlc_txid = sweep_htlc_tx.compute_txid();
1828            swept_htlc_txs.push(sweep_htlc_tx.clone());
1829            swept_htlc_txids.push(sweep_htlc_txid);
1830
1831            monitor.on_add_block(&[sweep_htlc_tx], &block_hash);
1832
1833            let state = monitor.get_state();
1834            let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1835
1836            let second_level_outpoint = OutPoint { txid: sweep_htlc_txid, vout: 0 };
1837            second_level_outpoints.push(second_level_outpoint);
1838
1839            assert!(closing_outpoints.includes_second_level_htlc_output(&second_level_outpoint));
1840            assert!(!closing_outpoints.is_all_spent());
1841            drop(state);
1842        }
1843
1844        let mut sweep_second_level_txs = Vec::new();
1845        for (i, &outpoint) in second_level_outpoints.iter().enumerate() {
1846            let sweep_second_level_tx = make_tx(vec![make_txin2(outpoint.txid, 0)]);
1847            sweep_second_level_txs.push(sweep_second_level_tx.clone());
1848            monitor.on_add_block(&[sweep_second_level_tx], &block_hash);
1849
1850            let state = monitor.get_state();
1851            let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1852
1853            if i == second_level_outpoints.len() - 1 {
1854                assert!(closing_outpoints.is_all_spent());
1855            } else {
1856                assert!(!closing_outpoints.is_all_spent());
1857            }
1858            drop(state);
1859        }
1860
1861        let state = monitor.get_state();
1862        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1863        assert!(closing_outpoints.is_all_spent());
1864        drop(state);
1865
1866        // Roll back second-level HTLC spend
1867        for (i, sweep_second_level_tx) in sweep_second_level_txs.iter().rev().enumerate() {
1868            monitor.on_remove_block(&[sweep_second_level_tx.clone()], &block_hash);
1869
1870            let state = monitor.get_state();
1871            let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1872            assert!(!closing_outpoints.is_all_spent());
1873
1874            let remaining_second_levels = second_level_outpoints.len() - 1 - i;
1875            if remaining_second_levels > 0 {
1876                for &outpoint in second_level_outpoints.iter().take(remaining_second_levels) {
1877                    assert!(closing_outpoints.includes_second_level_htlc_output(&outpoint));
1878                }
1879            }
1880            drop(state);
1881        }
1882
1883        // Roll back first-level HTLC spends
1884        for (i, sweep_htlc_tx) in swept_htlc_txs.iter().rev().enumerate() {
1885            monitor.on_remove_block(&[sweep_htlc_tx.clone()], &block_hash);
1886
1887            let state = monitor.get_state();
1888            let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1889
1890            let rolled_back_second_level =
1891                &second_level_outpoints[second_level_outpoints.len() - 1 - i];
1892            assert!(!closing_outpoints.includes_second_level_htlc_output(rolled_back_second_level));
1893
1894            let rolled_back_htlc =
1895                &trackable_htlc_outpoints[trackable_htlc_outpoints.len() - 1 - i];
1896            assert!(closing_outpoints.includes_htlc_output(rolled_back_htlc));
1897
1898            assert!(!closing_outpoints.is_all_spent());
1899            drop(state);
1900        }
1901
1902        // Roll back holder output spend
1903        monitor.on_remove_block(&[sweep_holder_tx], &block_hash);
1904        let state = monitor.get_state();
1905        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1906        assert!(closing_outpoints.includes_our_output(&holder_outpoint));
1907        for trackable_htlc_outpoint in &trackable_htlc_outpoints {
1908            assert!(closing_outpoints.includes_htlc_output(trackable_htlc_outpoint));
1909        }
1910        assert!(!closing_outpoints.is_all_spent());
1911        drop(state);
1912
1913        // Roll back unilateral close
1914        monitor.on_remove_block(&[closing_tx], &block_hash);
1915        let state = monitor.get_state();
1916        assert!(state.closing_outpoints.is_none());
1917        assert_eq!(state.unilateral_closing_height, None);
1918    }
1919
1920    #[test]
1921    fn test_apply_backward_change_funding_confirmed() {
1922        let funding_tx = make_tx(vec![make_txin(1), make_txin(2)]);
1923        let funding_outpoint = OutPoint::new(funding_tx.compute_txid(), 0);
1924        let setup = make_channel_setup(funding_outpoint);
1925        let (node, channel_id) =
1926            init_node_and_channel(TEST_NODE_CONFIG, TEST_SEED[1], setup.clone());
1927        let channel = node.get_channel(&channel_id).unwrap();
1928        let cpp = Box::new(ChannelCommitmentPointProvider::new(channel.clone()));
1929        let monitor = node
1930            .with_channel(&channel_id, |chan| Ok(chan.monitor.clone().as_monitor(cpp.clone())))
1931            .unwrap();
1932        let block_hash = BlockHash::all_zeros();
1933
1934        monitor.on_add_block(&[], &block_hash);
1935        monitor.on_add_block(&[funding_tx.clone()], &block_hash);
1936        assert_eq!(monitor.funding_depth(), 1);
1937        assert!(monitor.get_state().funding_outpoint.is_some());
1938
1939        monitor.on_remove_block(&[funding_tx], &block_hash);
1940        assert_eq!(monitor.funding_depth(), 0);
1941        assert!(monitor.get_state().funding_outpoint.is_none());
1942    }
1943
1944    #[test]
1945    fn test_apply_backward_change_mutual_close() {
1946        let block_hash = BlockHash::all_zeros();
1947        let (_, _, monitor, funding_txid) = setup_funded_channel();
1948
1949        let close_tx = make_tx(vec![TxIn {
1950            previous_output: OutPoint::new(funding_txid, 0),
1951            script_sig: Default::default(),
1952            sequence: Default::default(),
1953            witness: Default::default(),
1954        }]);
1955
1956        monitor.on_add_block(&[close_tx.clone()], &block_hash);
1957        assert_eq!(monitor.closing_depth(), 1);
1958        assert!(monitor.get_state().mutual_closing_height.is_some());
1959
1960        monitor.on_remove_block(&[close_tx], &block_hash);
1961        assert_eq!(monitor.closing_depth(), 0);
1962        assert!(monitor.get_state().mutual_closing_height.is_none());
1963    }
1964
1965    #[test]
1966    fn test_closing_outpoints_is_all_spent_logic() {
1967        let txid = Txid::all_zeros();
1968        let mut closing_outpoints = ClosingOutpoints::new(txid, Some(0), vec![1, 2]);
1969
1970        assert!(!closing_outpoints.is_all_spent());
1971
1972        closing_outpoints.set_our_output_spent(0, true);
1973        assert!(!closing_outpoints.is_all_spent());
1974
1975        closing_outpoints.set_htlc_output_spent(1, true);
1976        assert!(!closing_outpoints.is_all_spent());
1977
1978        closing_outpoints.set_htlc_output_spent(2, true);
1979        // All first-level spent, no second-level
1980        assert!(closing_outpoints.is_all_spent());
1981
1982        let second_level_outpoint = OutPoint { txid, vout: 10 };
1983        closing_outpoints.add_second_level_htlc_output(second_level_outpoint);
1984        assert!(!closing_outpoints.is_all_spent());
1985
1986        closing_outpoints.set_second_level_htlc_spent(second_level_outpoint, true);
1987        assert!(closing_outpoints.is_all_spent());
1988    }
1989
1990    #[test]
1991    fn test_closing_outpoints_without_our_output() {
1992        let txid = Txid::all_zeros();
1993        let mut closing_outpoints = ClosingOutpoints::new(txid, None, vec![1]);
1994
1995        assert!(!closing_outpoints.is_all_spent());
1996
1997        closing_outpoints.set_htlc_output_spent(1, true);
1998        assert!(closing_outpoints.is_all_spent());
1999    }
2000
2001    #[test]
2002    fn test_closing_outpoints_boolean_logic_edge_cases() {
2003        let txid = Txid::all_zeros();
2004
2005        let closing_outpoints = ClosingOutpoints::new(txid, None, vec![]);
2006        assert!(closing_outpoints.is_all_spent());
2007
2008        let mut closing_outpoints = ClosingOutpoints::new(txid, Some(0), vec![1]);
2009
2010        closing_outpoints.set_our_output_spent(0, false);
2011        closing_outpoints.set_htlc_output_spent(1, false);
2012        assert!(!closing_outpoints.is_all_spent());
2013
2014        closing_outpoints.set_our_output_spent(0, true);
2015        closing_outpoints.set_htlc_output_spent(1, false);
2016        assert!(!closing_outpoints.is_all_spent());
2017    }
2018
2019    #[test]
2020    fn test_closing_outpoints_second_level_management() {
2021        let txid = Txid::all_zeros();
2022        let mut closing_outpoints = ClosingOutpoints::new(txid, None, vec![]);
2023
2024        let outpoint1 = OutPoint { txid, vout: 10 };
2025        let outpoint2 = OutPoint { txid, vout: 11 };
2026
2027        closing_outpoints.add_second_level_htlc_output(outpoint1);
2028        closing_outpoints.add_second_level_htlc_output(outpoint2);
2029
2030        assert!(closing_outpoints.includes_second_level_htlc_output(&outpoint1));
2031        assert!(closing_outpoints.includes_second_level_htlc_output(&outpoint2));
2032
2033        closing_outpoints.set_second_level_htlc_spent(outpoint1, true);
2034        assert!(!closing_outpoints.is_all_spent());
2035
2036        closing_outpoints.set_second_level_htlc_spent(outpoint2, true);
2037        assert!(closing_outpoints.is_all_spent());
2038
2039        closing_outpoints.remove_second_level_htlc_output(&outpoint1);
2040        assert!(!closing_outpoints.includes_second_level_htlc_output(&outpoint1));
2041        assert!(closing_outpoints.includes_second_level_htlc_output(&outpoint2));
2042        assert!(closing_outpoints.is_all_spent());
2043    }
2044
2045    #[test]
2046    fn test_second_level_htlc_output_methods() {
2047        let outpoint = OutPoint { txid: Txid::all_zeros(), vout: 0 };
2048        let mut htlc_output = SecondLevelHTLCOutput::new(outpoint);
2049
2050        assert!(!htlc_output.is_spent());
2051        assert!(htlc_output.matches_outpoint(&outpoint));
2052
2053        let different_outpoint = OutPoint { txid: Txid::all_zeros(), vout: 1 };
2054        assert!(!htlc_output.matches_outpoint(&different_outpoint));
2055
2056        htlc_output.set_spent(true);
2057        assert!(htlc_output.is_spent());
2058
2059        htlc_output.set_spent(false);
2060        assert!(!htlc_output.is_spent());
2061    }
2062
2063    #[test]
2064    fn test_transaction_state_isolation() {
2065        let block_hash = BlockHash::all_zeros();
2066        let (_, _, monitor, funding_txid) = setup_funded_channel();
2067        let funding_outpoint = OutPoint::new(funding_txid, 0);
2068
2069        let closing_tx = make_tx(vec![TxIn {
2070            previous_output: funding_outpoint,
2071            script_sig: Default::default(),
2072            sequence: Default::default(),
2073            witness: Default::default(),
2074        }]);
2075        let closing_txid = closing_tx.compute_txid();
2076
2077        let unrelated_tx = make_tx(vec![make_txin2(Txid::all_zeros(), 0)]);
2078
2079        let mut decode_state =
2080            BlockDecodeState::new_with_block_hash(&monitor.get_state(), &block_hash);
2081        let mut listener = PushListener {
2082            commitment_point_provider: &*monitor.commitment_point_provider,
2083            decode_state: &mut decode_state,
2084            saw_block: true,
2085        };
2086
2087        listener.on_transaction_start(closing_tx.version.0);
2088        listener.on_transaction_input(&closing_tx.input[0]);
2089        listener.on_transaction_output(&closing_tx.output[0]);
2090        listener.on_transaction_end(closing_tx.lock_time, closing_txid);
2091
2092        assert!(listener.decode_state.closing_tx.is_none());
2093
2094        listener.on_transaction_start(unrelated_tx.version.0);
2095
2096        assert_eq!(listener.decode_state.version, unrelated_tx.version.0);
2097        assert_eq!(listener.decode_state.input_num, 0);
2098        assert_eq!(listener.decode_state.output_num, 0);
2099        assert!(listener.decode_state.closing_tx.is_none());
2100        assert!(listener.decode_state.spent_htlc_outputs.is_empty());
2101    }
2102
2103    #[test]
2104    fn test_is_done_conditions() {
2105        let outpoint = OutPoint::new(Txid::from_slice(&[1; 32]).unwrap(), 0);
2106        let chan_id = ChannelId::new(&[33u8; 32]);
2107
2108        let base1 = ChainMonitorBase::new(outpoint, MIN_DEPTH + 10, &chan_id);
2109        {
2110            let mut state = base1.get_state();
2111            state.funding_double_spent_height = Some(10);
2112            state.saw_forget_channel = true;
2113        }
2114        assert!(base1.is_done());
2115
2116        let base2 = ChainMonitorBase::new(outpoint, MAX_CLOSING_DEPTH + 10, &chan_id);
2117        {
2118            let mut state = base2.get_state();
2119            state.closing_swept_height = Some(10);
2120            state.saw_forget_channel = true;
2121        }
2122        assert!(base2.is_done());
2123    }
2124
2125    #[test]
2126    fn test_diagnostic_all_states() {
2127        let outpoint = OutPoint::new(Txid::from_slice(&[1; 32]).unwrap(), 0);
2128        let chan_id = ChannelId::new(&[33u8; 32]);
2129        let base = ChainMonitorBase::new(outpoint, 100, &chan_id);
2130
2131        let diagnostic = base.diagnostic(false);
2132        assert_eq!(
2133            diagnostic,
2134            format!("UNCOMFIRMED hold till funding doublespent + {}", MIN_DEPTH)
2135        );
2136
2137        {
2138            let mut state = base.get_state();
2139            state.funding_height = Some(90);
2140        }
2141        assert_eq!(base.diagnostic(false), "ACTIVE");
2142        assert_eq!(base.diagnostic(true), "CLOSING");
2143
2144        // Test all aging states
2145        let test_cases = vec![
2146            ("funding_double_spent_height", 95, MIN_DEPTH, "AGING_FUNDING_DOUBLESPENT"),
2147            ("mutual_closing_height", 98, MIN_DEPTH, "AGING_MUTUALLY_CLOSED"),
2148            ("closing_swept_height", 99, MIN_DEPTH, "AGING_CLOSING_SWEPT"),
2149            ("our_output_swept_height", 97, MAX_CLOSING_DEPTH, "AGING_OUR_OUTPUT_SWEPT"),
2150        ];
2151
2152        for (field, height, depth_limit, expected_prefix) in test_cases {
2153            {
2154                let mut state = base.get_state();
2155                state.funding_height = Some(90);
2156                state.funding_double_spent_height = None;
2157                state.mutual_closing_height = None;
2158                state.closing_swept_height = None;
2159                state.our_output_swept_height = None;
2160
2161                match field {
2162                    "funding_double_spent_height" =>
2163                        state.funding_double_spent_height = Some(height),
2164                    "mutual_closing_height" => state.mutual_closing_height = Some(height),
2165                    "closing_swept_height" => state.closing_swept_height = Some(height),
2166                    "our_output_swept_height" => state.our_output_swept_height = Some(height),
2167                    _ => unreachable!(),
2168                }
2169            }
2170
2171            let diagnostic = base.diagnostic(false);
2172            let expected =
2173                format!("{} at {} until {}", expected_prefix, height, height + depth_limit);
2174            assert_eq!(diagnostic, expected);
2175        }
2176    }
2177
2178    fn setup_funded_channel() -> (Arc<Node>, ChannelId, ChainMonitor, Txid) {
2179        let funding_tx = make_tx(vec![make_txin(1), make_txin(2)]);
2180        let funding_outpoint = OutPoint::new(funding_tx.compute_txid(), 0);
2181        let setup = make_channel_setup(funding_outpoint);
2182
2183        let (node, channel_id) =
2184            init_node_and_channel(TEST_NODE_CONFIG, TEST_SEED[1], setup.clone());
2185        let channel = node.get_channel(&channel_id).unwrap();
2186        let cpp = Box::new(ChannelCommitmentPointProvider::new(channel.clone()));
2187        let monitor = node
2188            .with_channel(&channel_id, |chan| Ok(chan.monitor.clone().as_monitor(cpp.clone())))
2189            .unwrap();
2190        let block_hash = BlockHash::all_zeros();
2191        monitor.on_add_block(&[], &block_hash);
2192        monitor.on_add_block(&[funding_tx.clone()], &block_hash);
2193        assert_eq!(monitor.funding_depth(), 1);
2194        (node, channel_id, monitor, funding_tx.compute_txid())
2195    }
2196
2197    fn make_txin2(prev_txid: Txid, prevout: u32) -> TxIn {
2198        TxIn {
2199            previous_output: OutPoint::new(prev_txid, prevout),
2200            script_sig: Default::default(),
2201            sequence: Default::default(),
2202            witness: Default::default(),
2203        }
2204    }
2205
2206    fn make_channel_setup(funding_outpoint: OutPoint) -> ChannelSetup {
2207        ChannelSetup {
2208            is_outbound: true,
2209            channel_value_sat: 3_000_000,
2210            push_value_msat: 0,
2211            funding_outpoint,
2212            holder_selected_contest_delay: 6,
2213            holder_shutdown_script: None,
2214            counterparty_points: make_test_counterparty_points(),
2215            counterparty_selected_contest_delay: 7,
2216            counterparty_shutdown_script: None,
2217            commitment_type: CommitmentType::StaticRemoteKey,
2218        }
2219    }
2220}