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                info!("our_output_index: {:?}, htlc_indices: {:?}", our_output_index, htlc_indices);
426                decode_state.add_change(StateChange::UnilateralCloseConfirmed(
427                    txid,
428                    closing_tx.input[0].previous_output,
429                    our_output_index,
430                    htlc_indices,
431                ));
432            } else {
433                decode_state.add_change(StateChange::MutualCloseConfirmed(
434                    txid,
435                    closing_tx.input[0].previous_output,
436                ));
437                info!("mutual close {} confirmed", txid);
438            }
439        }
440
441        let htlc_changes: Vec<StateChange> = decode_state
442            .spent_htlc_outputs
443            .drain(..)
444            .map(|(spent_vout, input_index)| {
445                let second_level_outpoint = OutPoint { txid, vout: input_index };
446                StateChange::HTLCOutputSpent(spent_vout, second_level_outpoint)
447            })
448            .collect();
449
450        for change in htlc_changes {
451            decode_state.add_change(change);
452        }
453    }
454
455    fn on_block_end(&mut self) {
456        // we need to wait until we get the following `AddBlock` or `RemoveBlock`
457        // message before actually updating ourselves
458    }
459}
460
461impl State {
462    fn channel_id(&self) -> &ChannelId {
463        // safe because populated by new_from_persistence
464        self.channel_id.as_ref().expect("missing associated channel_id in monitor::State")
465    }
466
467    fn depth_of(&self, other_height: Option<u32>) -> u32 {
468        (self.height + 1).saturating_sub(other_height.unwrap_or(self.height + 1))
469    }
470
471    fn deep_enough_and_saw_node_forget(&self, other_height: Option<u32>, limit: u32) -> bool {
472        // If the event depth is less than MIN_DEPTH we never prune.
473        // If the event depth is greater we prune if saw_forget_channel is true.
474        let depth = self.depth_of(other_height);
475        if depth < limit {
476            // Not deep enough, we aren't done
477            false
478        } else if self.saw_forget_channel {
479            // Deep enough and the node thinks it's done too
480            true
481        } else {
482            // Deep enough, but we haven't heard from the node
483            warn!(
484                "expected forget_channel for {} overdue by {} blocks",
485                self.channel_id(),
486                depth - limit
487            );
488            false
489        }
490    }
491
492    fn diagnostic(&self, is_closed: bool) -> String {
493        if self.funding_height.is_none() {
494            format!("UNCOMFIRMED hold till funding doublespent + {}", MIN_DEPTH)
495        } else if let Some(height) = self.funding_double_spent_height {
496            format!("AGING_FUNDING_DOUBLESPENT at {} until {}", height, height + MIN_DEPTH)
497        } else if let Some(height) = self.mutual_closing_height {
498            format!("AGING_MUTUALLY_CLOSED at {} until {}", height, height + MIN_DEPTH)
499        } else if let Some(height) = self.closing_swept_height {
500            format!("AGING_CLOSING_SWEPT at {} until {}", height, height + MIN_DEPTH)
501        } else if let Some(height) = self.our_output_swept_height {
502            format!("AGING_OUR_OUTPUT_SWEPT at {} until {}", height, height + MAX_CLOSING_DEPTH)
503        } else if is_closed {
504            "CLOSING".into()
505        } else {
506            "ACTIVE".into()
507        }
508    }
509
510    fn is_done(&self) -> bool {
511        // we are done if:
512        // - funding was double spent
513        // - mutual closed
514        // - unilateral closed, and our output, as well as all HTLCs were swept
515        // and, the last confirmation is buried
516        //
517        // TODO(472) disregard received HTLCs that we can't claim (we don't have the preimage)
518
519        if self.deep_enough_and_saw_node_forget(self.funding_double_spent_height, MIN_DEPTH) {
520            debug!(
521                "{} is_done because funding double spent {} blocks ago",
522                self.channel_id(),
523                MIN_DEPTH
524            );
525            return true;
526        }
527
528        if self.deep_enough_and_saw_node_forget(self.mutual_closing_height, MIN_DEPTH) {
529            debug!("{} is_done because mutual closed {} blocks ago", self.channel_id(), MIN_DEPTH);
530            return true;
531        }
532
533        if self.deep_enough_and_saw_node_forget(self.closing_swept_height, MIN_DEPTH) {
534            debug!("{} is_done because closing swept {} blocks ago", self.channel_id(), MIN_DEPTH);
535            return true;
536        }
537
538        // since we don't yet have the logic to tell which HTLCs we can claim,
539        // time out watching them after MAX_CLOSING_DEPTH
540        if self.deep_enough_and_saw_node_forget(self.our_output_swept_height, MAX_CLOSING_DEPTH) {
541            debug!(
542                "{} is_done because closing output swept {} blocks ago",
543                self.channel_id(),
544                MAX_CLOSING_DEPTH
545            );
546            return true;
547        }
548
549        return false;
550    }
551
552    fn on_add_block_end(
553        &mut self,
554        block_hash: &BlockHash,
555        decode_state: &mut BlockDecodeState,
556    ) -> (Vec<OutPoint>, Vec<OutPoint>) {
557        assert_eq!(decode_state.block_hash.as_ref(), Some(block_hash));
558
559        self.saw_block = true;
560        self.height += 1;
561
562        let closing_was_swept = self.is_closing_swept();
563        let our_output_was_swept = self.is_our_output_swept();
564
565        let mut adds = Vec::new();
566        let mut removes = Vec::new();
567
568        let changed = !decode_state.changes.is_empty();
569
570        if changed {
571            debug!(
572                "{} detected add-changes at height {}: {:?}",
573                self.channel_id(),
574                self.height,
575                decode_state.changes
576            );
577        }
578
579        // apply changes
580        for change in decode_state.changes.drain(..) {
581            self.apply_forward_change(&mut adds, &mut removes, change);
582        }
583
584        let closing_is_swept = self.is_closing_swept();
585        let our_output_is_swept = self.is_our_output_swept();
586
587        if !closing_was_swept && closing_is_swept {
588            info!("{} closing tx was swept at height {}", self.channel_id(), self.height);
589            self.closing_swept_height = Some(self.height);
590        }
591
592        if !our_output_was_swept && our_output_is_swept {
593            info!("{} our output was swept at height {}", self.channel_id(), self.height);
594            self.our_output_swept_height = Some(self.height);
595        }
596
597        if self.is_done() {
598            info!("{} done at height {}", self.channel_id(), self.height);
599        }
600
601        if changed {
602            #[cfg(not(feature = "log_pretty_print"))]
603            info!("on_add_block_end state changed: {:?}", self);
604            #[cfg(feature = "log_pretty_print")]
605            info!("on_add_block_end state changed: {:#?}", self);
606        }
607
608        (adds, removes)
609    }
610
611    fn on_remove_block_end(
612        &mut self,
613        block_hash: &BlockHash,
614        decode_state: &mut BlockDecodeState,
615    ) -> (Vec<OutPoint>, Vec<OutPoint>) {
616        assert_eq!(decode_state.block_hash.as_ref(), Some(block_hash));
617
618        let closing_was_swept = self.is_closing_swept();
619        let our_output_was_swept = self.is_our_output_swept();
620
621        let mut adds = Vec::new();
622        let mut removes = Vec::new();
623
624        let changed = !decode_state.changes.is_empty();
625
626        if changed {
627            debug!(
628                "{} detected remove-changes at height {}: {:?}",
629                self.channel_id(),
630                self.height,
631                decode_state.changes
632            );
633        }
634
635        for change in decode_state.changes.drain(..) {
636            self.apply_backward_change(&mut adds, &mut removes, change);
637        }
638
639        let closing_is_swept = self.is_closing_swept();
640        let our_output_is_swept = self.is_our_output_swept();
641
642        if closing_was_swept && !closing_is_swept {
643            info!("{} closing tx was un-swept at height {}", self.channel_id(), self.height);
644            self.closing_swept_height = None;
645        }
646
647        if our_output_was_swept && !our_output_is_swept {
648            info!("{} our output was un-swept at height {}", self.channel_id(), self.height);
649            self.our_output_swept_height = None;
650        }
651
652        self.height -= 1;
653
654        if changed {
655            #[cfg(not(feature = "log_pretty_print"))]
656            info!("on_remove_block_end state changed: {:?}", self);
657            #[cfg(feature = "log_pretty_print")]
658            info!("on_remove_block_end state changed: {:#?}", self);
659        }
660
661        // note that the caller will remove the adds and add the removes
662        (adds, removes)
663    }
664
665    // whether the unilateral closing tx was fully swept
666    fn is_closing_swept(&self) -> bool {
667        self.closing_outpoints.as_ref().map(|o| o.is_all_spent()).unwrap_or(false)
668    }
669
670    // whether our output was swept, or does not exist
671    fn is_our_output_swept(&self) -> bool {
672        self.closing_outpoints
673            .as_ref()
674            .map(|o| o.our_output.map(|(_, s)| s).unwrap_or(true))
675            .unwrap_or(false)
676    }
677
678    fn apply_forward_change(
679        &mut self,
680        adds: &mut Vec<OutPoint>,
681        removes: &mut Vec<OutPoint>,
682        change: StateChange,
683    ) {
684        // unwraps below on self.closing_outpoints are safe due to PushListener logic
685        match change {
686            StateChange::FundingConfirmed(outpoint) => {
687                self.funding_height = Some(self.height);
688                self.funding_outpoint = Some(outpoint);
689                // we may have thought we had a double-spend, but now we know we don't
690                self.funding_double_spent_height = None;
691                adds.push(outpoint);
692            }
693            StateChange::FundingInputSpent(outpoint) => {
694                // A funding input was double-spent, or funding was confirmed
695                // (in which case we'll see FundingConfirmed later on in this
696                // change list).
697                // we may have seen some other funding input double-spent, so
698                // don't overwrite the depth if it exists
699                self.funding_double_spent_height.get_or_insert(self.height);
700                // no matter whether funding, or double-spend, we want to stop watching this outpoint
701                removes.push(outpoint);
702            }
703            StateChange::UnilateralCloseConfirmed(
704                txid,
705                funding_outpoint,
706                our_output_index,
707                htlcs_indices,
708            ) => {
709                self.unilateral_closing_height = Some(self.height);
710                removes.push(funding_outpoint);
711                our_output_index.map(|i| adds.push(OutPoint { txid, vout: i }));
712                for i in htlcs_indices.iter() {
713                    adds.push(OutPoint { txid, vout: *i });
714                }
715                self.closing_outpoints =
716                    Some(ClosingOutpoints::new(txid, our_output_index, htlcs_indices));
717            }
718            StateChange::OurOutputSpent(vout) => {
719                let outpoints = self.closing_outpoints.as_mut().unwrap();
720                outpoints.set_our_output_spent(vout, true);
721                let outpoint = OutPoint { txid: outpoints.txid, vout };
722                removes.push(outpoint);
723            }
724            StateChange::HTLCOutputSpent(vout, second_level_htlc_outpoint) => {
725                let outpoints = self.closing_outpoints.as_mut().unwrap();
726                outpoints.set_htlc_output_spent(vout, true);
727                let outpoint = OutPoint { txid: outpoints.txid, vout };
728                outpoints.add_second_level_htlc_output(second_level_htlc_outpoint);
729                removes.push(outpoint);
730                adds.push(second_level_htlc_outpoint);
731            }
732            StateChange::SecondLevelHTLCOutputSpent(outpoint) => {
733                let closing_outpoints = self.closing_outpoints.as_mut().unwrap();
734                closing_outpoints.set_second_level_htlc_spent(outpoint, true);
735                removes.push(outpoint);
736            }
737            StateChange::MutualCloseConfirmed(_txid, funding_outpoint) => {
738                self.mutual_closing_height = Some(self.height);
739                removes.push(funding_outpoint);
740            }
741        }
742    }
743
744    // Note that in the logic below, we are mimicking the logic of
745    // apply_forward_change, but the caller will remove the adds and add the
746    // removes.
747    fn apply_backward_change(
748        &mut self,
749        adds: &mut Vec<OutPoint>,
750        removes: &mut Vec<OutPoint>,
751        change: StateChange,
752    ) {
753        match change {
754            StateChange::FundingConfirmed(outpoint) => {
755                // A funding tx was reorged-out
756                assert_eq!(self.funding_height, Some(self.height));
757                self.funding_height = None;
758                self.funding_outpoint = None;
759                adds.push(outpoint);
760            }
761            StateChange::FundingInputSpent(outpoint) => {
762                // A funding double-spent was reorged-out, or funding confirmation
763                // was reorged-out (in which case we'll see FundingConfirmed later
764                // on in this change list).
765                // We may have seen some other funding input double-spent, so
766                // clear out the height only if it is the current height.
767                if self.funding_double_spent_height == Some(self.height) {
768                    self.funding_double_spent_height = None
769                }
770                // no matter whether funding, or double-spend, we want to re-start watching this outpoint
771                removes.push(outpoint);
772            }
773            StateChange::UnilateralCloseConfirmed(
774                txid,
775                funding_outpoint,
776                our_output_index,
777                htlcs_indices,
778            ) => {
779                // A closing tx was reorged-out
780                assert_eq!(self.unilateral_closing_height, Some(self.height));
781                self.unilateral_closing_height = None;
782                self.closing_outpoints = None;
783                our_output_index.map(|i| adds.push(OutPoint { txid, vout: i }));
784                for i in htlcs_indices {
785                    adds.push(OutPoint { txid, vout: i });
786                }
787                removes.push(funding_outpoint)
788            }
789            StateChange::OurOutputSpent(vout) => {
790                let outpoints = self.closing_outpoints.as_mut().unwrap();
791                outpoints.set_our_output_spent(vout, false);
792                let outpoint = OutPoint { txid: outpoints.txid, vout };
793                removes.push(outpoint);
794            }
795            StateChange::HTLCOutputSpent(vout, second_level_htlc_outpoint) => {
796                let outpoints = self.closing_outpoints.as_mut().unwrap();
797                outpoints.set_htlc_output_spent(vout, false);
798                let outpoint = OutPoint { txid: outpoints.txid, vout };
799                outpoints.remove_second_level_htlc_output(&second_level_htlc_outpoint);
800                adds.push(outpoint);
801                removes.push(second_level_htlc_outpoint);
802            }
803            StateChange::SecondLevelHTLCOutputSpent(outpoint) => {
804                let closing_outpoints = self.closing_outpoints.as_mut().unwrap();
805                closing_outpoints.set_second_level_htlc_spent(outpoint, false);
806                adds.push(outpoint);
807            }
808            StateChange::MutualCloseConfirmed(_txid, funding_outpoint) => {
809                self.mutual_closing_height = None;
810                removes.push(funding_outpoint);
811            }
812        }
813    }
814}
815
816/// This is a pre-cursor to [`ChainMonitor`], before the [`CommitmentPointProvider`] is available.
817#[derive(Clone)]
818pub struct ChainMonitorBase {
819    // the first funding outpoint, used to identify the channel / channel monitor
820    pub(crate) funding_outpoint: OutPoint,
821    // the monitor state
822    state: Arc<Mutex<State>>,
823}
824
825impl ChainMonitorBase {
826    /// Create a new chain monitor.
827    /// Use add_funding to really start monitoring.
828    pub fn new(funding_outpoint: OutPoint, height: u32, chan_id: &ChannelId) -> Self {
829        let state = State {
830            height,
831            funding_txids: Vec::new(),
832            funding_vouts: Vec::new(),
833            funding_inputs: OrderedSet::new(),
834            funding_height: None,
835            funding_outpoint: None,
836            funding_double_spent_height: None,
837            mutual_closing_height: None,
838            unilateral_closing_height: None,
839            closing_outpoints: None,
840            closing_swept_height: None,
841            our_output_swept_height: None,
842            saw_block: false,
843            saw_forget_channel: false,
844            channel_id: Some(chan_id.clone()),
845        };
846
847        Self { funding_outpoint, state: Arc::new(Mutex::new(state)) }
848    }
849
850    /// recreate this monitor after restoring from persistence
851    pub fn new_from_persistence(
852        funding_outpoint: OutPoint,
853        state: State,
854        channel_id: &ChannelId,
855    ) -> Self {
856        let state = Arc::new(Mutex::new(state));
857        state.lock().unwrap().channel_id = Some(channel_id.clone());
858        Self { funding_outpoint, state }
859    }
860
861    /// Get the ChainMonitor
862    pub fn as_monitor(
863        &self,
864        commitment_point_provider: Box<dyn CommitmentPointProvider>,
865    ) -> ChainMonitor {
866        ChainMonitor {
867            funding_outpoint: self.funding_outpoint,
868            state: self.state.clone(),
869            decode_state: Arc::new(Mutex::new(None)),
870            commitment_point_provider,
871        }
872    }
873
874    /// Add a funding transaction to keep track of
875    /// For single-funding
876    pub fn add_funding_outpoint(&self, outpoint: &OutPoint) {
877        let mut state = self.get_state();
878        assert!(state.funding_txids.is_empty(), "only a single funding tx currently supported");
879        assert_eq!(state.funding_txids.len(), state.funding_vouts.len());
880        state.funding_txids.push(outpoint.txid);
881        state.funding_vouts.push(outpoint.vout);
882    }
883
884    /// Add a funding input
885    /// For single-funding
886    pub fn add_funding_inputs(&self, tx: &Transaction) {
887        let mut state = self.get_state();
888        state.funding_inputs.extend(tx.input.iter().map(|i| i.previous_output));
889    }
890
891    /// Convert to a ChainState, to be used for validation
892    pub fn as_chain_state(&self) -> ChainState {
893        let state = self.get_state();
894        ChainState {
895            current_height: state.height,
896            funding_depth: state.funding_height.map(|h| state.height + 1 - h).unwrap_or(0),
897            funding_double_spent_depth: state
898                .funding_double_spent_height
899                .map(|h| state.height + 1 - h)
900                .unwrap_or(0),
901            closing_depth: state
902                .mutual_closing_height
903                .or(state.unilateral_closing_height)
904                .map(|h| state.height + 1 - h)
905                .unwrap_or(0),
906        }
907    }
908
909    /// Whether this channel can be forgotten
910    pub fn is_done(&self) -> bool {
911        self.get_state().is_done()
912    }
913
914    /// Called when the node tells us it forgot the channel
915    pub fn forget_channel(&self) {
916        let mut state = self.get_state();
917        state.saw_forget_channel = true;
918    }
919
920    /// Returns the actual funding outpoint on-chain
921    pub fn funding_outpoint(&self) -> Option<OutPoint> {
922        self.get_state().funding_outpoint
923    }
924
925    /// Return whether forget_channel was seen
926    pub fn forget_seen(&self) -> bool {
927        self.get_state().saw_forget_channel
928    }
929
930    /// Return string describing the state
931    pub fn diagnostic(&self, is_closed: bool) -> String {
932        self.get_state().diagnostic(is_closed)
933    }
934
935    // Add this getter method
936    fn get_state(&self) -> MutexGuard<State> {
937        self.state.lock().expect("lock")
938    }
939}
940
941/// Keep track of channel on-chain events.
942/// Note that this object has refcounted state, so is lightweight to clone.
943#[derive(Clone)]
944pub struct ChainMonitor {
945    /// the first funding outpoint, used to identify the channel / channel monitor
946    pub funding_outpoint: OutPoint,
947    /// the monitor state
948    pub state: Arc<Mutex<State>>,
949    // Block decode state, only while in progress
950    // Lock order: after `self.state`
951    decode_state: Arc<Mutex<Option<BlockDecodeState>>>,
952    // the commitment point provider, helps with decoding transactions
953    commitment_point_provider: Box<dyn CommitmentPointProvider>,
954}
955
956impl ChainMonitor {
957    /// Get the base
958    pub fn as_base(&self) -> ChainMonitorBase {
959        ChainMonitorBase { funding_outpoint: self.funding_outpoint, state: self.state.clone() }
960    }
961
962    /// Get the locked state
963    pub fn get_state(&self) -> MutexGuard<State> {
964        self.state.lock().expect("lock")
965    }
966
967    /// Add a funding transaction to keep track of
968    /// For dual-funding
969    pub fn add_funding(&self, tx: &Transaction, vout: u32) {
970        let mut state = self.get_state();
971        assert!(state.funding_txids.is_empty(), "only a single funding tx currently supported");
972        assert_eq!(state.funding_txids.len(), state.funding_vouts.len());
973        state.funding_txids.push(tx.compute_txid());
974        state.funding_vouts.push(vout);
975        state.funding_inputs.extend(tx.input.iter().map(|i| i.previous_output));
976    }
977
978    /// Returns the number of confirmations of the funding transaction, or zero
979    /// if it wasn't confirmed yet.
980    pub fn funding_depth(&self) -> u32 {
981        let state = self.get_state();
982        state.depth_of(state.funding_height)
983    }
984
985    /// Returns the number of confirmations of a double-spend of the funding transaction
986    /// or zero if it wasn't double-spent.
987    pub fn funding_double_spent_depth(&self) -> u32 {
988        let state = self.get_state();
989        state.depth_of(state.funding_double_spent_height)
990    }
991
992    /// Returns the number of confirmations of the closing transaction, or zero
993    pub fn closing_depth(&self) -> u32 {
994        let state = self.get_state();
995        let closing_height = state.unilateral_closing_height.or(state.mutual_closing_height);
996        state.depth_of(closing_height)
997    }
998
999    /// Whether this channel can be forgotten:
1000    /// - mutual close is confirmed
1001    /// - unilateral close is swept
1002    /// - funding transaction is double-spent
1003    /// and enough confirmations have passed
1004    pub fn is_done(&self) -> bool {
1005        self.get_state().is_done()
1006    }
1007
1008    // push compact proof transactions through, simulating a streamed block
1009    fn push_transactions(&self, block_hash: &BlockHash, txs: &[Transaction]) -> BlockDecodeState {
1010        let mut state = self.get_state();
1011
1012        // we are synced if we see a compact proof
1013        state.saw_block = true;
1014
1015        let mut decode_state = BlockDecodeState::new_with_block_hash(&*state, block_hash);
1016
1017        let mut listener = PushListener {
1018            commitment_point_provider: &*self.commitment_point_provider,
1019            decode_state: &mut decode_state,
1020            saw_block: true,
1021        };
1022
1023        // stream the transactions to the state
1024        for tx in txs {
1025            listener.on_transaction_start(tx.version.0);
1026            for input in tx.input.iter() {
1027                listener.on_transaction_input(input);
1028            }
1029
1030            for output in tx.output.iter() {
1031                listener.on_transaction_output(output);
1032            }
1033            listener.on_transaction_end(tx.lock_time, tx.compute_txid());
1034        }
1035
1036        decode_state
1037    }
1038}
1039
1040impl ChainListener for ChainMonitor {
1041    type Key = OutPoint;
1042
1043    fn key(&self) -> &Self::Key {
1044        &self.funding_outpoint
1045    }
1046
1047    fn on_add_block(
1048        &self,
1049        txs: &[Transaction],
1050        block_hash: &BlockHash,
1051    ) -> (Vec<OutPoint>, Vec<OutPoint>) {
1052        debug!("on_add_block for {}", self.funding_outpoint);
1053        let mut decode_state = self.push_transactions(block_hash, txs);
1054
1055        let mut state = self.get_state();
1056        state.on_add_block_end(block_hash, &mut decode_state)
1057    }
1058
1059    fn on_add_streamed_block_end(&self, block_hash: &BlockHash) -> (Vec<OutPoint>, Vec<OutPoint>) {
1060        let mut state = self.get_state();
1061        let mut decode_state = self.decode_state.lock().expect("lock").take();
1062        if !state.saw_block {
1063            // not ready yet, bail
1064            return (Vec::new(), Vec::new());
1065        }
1066        // safe because `on_push` must have been called first
1067        state.on_add_block_end(block_hash, decode_state.as_mut().unwrap())
1068    }
1069
1070    fn on_remove_block(
1071        &self,
1072        txs: &[Transaction],
1073        block_hash: &BlockHash,
1074    ) -> (Vec<OutPoint>, Vec<OutPoint>) {
1075        debug!("on_remove_block for {}", self.funding_outpoint);
1076        let mut decode_state = self.push_transactions(block_hash, txs);
1077
1078        let mut state = self.get_state();
1079        state.on_remove_block_end(block_hash, &mut decode_state)
1080    }
1081
1082    fn on_remove_streamed_block_end(
1083        &self,
1084        block_hash: &BlockHash,
1085    ) -> (Vec<OutPoint>, Vec<OutPoint>) {
1086        let mut state = self.get_state();
1087        let mut decode_state = self.decode_state.lock().expect("lock").take();
1088        if !state.saw_block {
1089            // not ready yet, bail
1090            return (Vec::new(), Vec::new());
1091        }
1092        // safe because `on_push` must have been called first
1093        state.on_remove_block_end(block_hash, decode_state.as_mut().unwrap())
1094    }
1095
1096    fn on_push<F>(&self, f: F)
1097    where
1098        F: FnOnce(&mut dyn push_decoder::Listener),
1099    {
1100        let mut state = self.get_state();
1101        let saw_block = state.saw_block;
1102
1103        let mut decode_state_lock = self.decode_state.lock().expect("lock");
1104
1105        let decode_state = decode_state_lock.get_or_insert_with(|| BlockDecodeState::new(&*state));
1106
1107        let mut listener = PushListener {
1108            commitment_point_provider: &*self.commitment_point_provider,
1109            decode_state,
1110            saw_block,
1111        };
1112        f(&mut listener);
1113
1114        // update the saw_block flag, in case the listener saw a block start event
1115        state.saw_block = listener.saw_block;
1116    }
1117}
1118
1119impl SendSync for ChainMonitor {}
1120
1121#[cfg(test)]
1122mod tests {
1123    use crate::channel::{
1124        ChannelBase, ChannelCommitmentPointProvider, ChannelId, ChannelSetup, CommitmentType,
1125    };
1126    use crate::node::Node;
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 lightning::ln::chan_utils::HTLCOutputInCommitment;
1134    use lightning::types::payment::PaymentHash;
1135    use test_log::test;
1136
1137    use super::*;
1138
1139    #[test]
1140    fn test_funding() {
1141        let tx = make_tx(vec![make_txin(1), make_txin(2)]);
1142        let outpoint = OutPoint::new(tx.compute_txid(), 0);
1143        let cpp = Box::new(DummyCommitmentPointProvider {});
1144        let chan_id = ChannelId::new(&[33u8; 32]);
1145        let monitor = ChainMonitorBase::new(outpoint, 0, &chan_id).as_monitor(cpp);
1146        let block_hash = BlockHash::all_zeros();
1147        monitor.add_funding(&tx, 0);
1148        monitor.on_add_block(&[], &block_hash);
1149        monitor.on_add_block(&[tx.clone()], &block_hash);
1150        assert_eq!(monitor.funding_depth(), 1);
1151        assert_eq!(monitor.funding_double_spent_depth(), 0);
1152        monitor.on_add_block(&[], &block_hash);
1153        assert_eq!(monitor.funding_depth(), 2);
1154        monitor.on_remove_block(&[], &block_hash);
1155        assert_eq!(monitor.funding_depth(), 1);
1156        monitor.on_remove_block(&[tx], &block_hash);
1157        assert_eq!(monitor.funding_depth(), 0);
1158        monitor.on_remove_block(&[], &block_hash);
1159        assert_eq!(monitor.funding_depth(), 0);
1160    }
1161
1162    #[test]
1163    fn test_funding_double_spent() {
1164        let tx = make_tx(vec![make_txin(1), make_txin(2)]);
1165        let tx2 = make_tx(vec![make_txin(2)]);
1166        let outpoint = OutPoint::new(tx.compute_txid(), 0);
1167        let cpp = Box::new(DummyCommitmentPointProvider {});
1168        let chan_id = ChannelId::new(&[33u8; 32]);
1169        let monitor = ChainMonitorBase::new(outpoint, 0, &chan_id).as_monitor(cpp);
1170        let block_hash = BlockHash::all_zeros();
1171        monitor.add_funding(&tx, 0);
1172        monitor.on_add_block(&[], &block_hash);
1173        monitor.on_add_block(&[tx2.clone()], &block_hash);
1174        assert_eq!(monitor.funding_depth(), 0);
1175        assert_eq!(monitor.funding_double_spent_depth(), 1);
1176        monitor.on_add_block(&[], &block_hash);
1177        assert_eq!(monitor.funding_depth(), 0);
1178        assert_eq!(monitor.funding_double_spent_depth(), 2);
1179        monitor.on_remove_block(&[], &block_hash);
1180        assert_eq!(monitor.funding_double_spent_depth(), 1);
1181        monitor.on_remove_block(&[tx2], &block_hash);
1182        assert_eq!(monitor.funding_double_spent_depth(), 0);
1183        monitor.on_remove_block(&[], &block_hash);
1184        assert_eq!(monitor.funding_double_spent_depth(), 0);
1185    }
1186
1187    #[test]
1188    fn test_stream() {
1189        let outpoint = OutPoint::new(Txid::from_slice(&[1; 32]).unwrap(), 0);
1190        let cpp = Box::new(DummyCommitmentPointProvider {});
1191        let chan_id = ChannelId::new(&[33u8; 32]);
1192        let monitor = ChainMonitorBase::new(outpoint, 0, &chan_id).as_monitor(cpp);
1193        let header = BlockHeader {
1194            version: Version::from_consensus(0),
1195            prev_blockhash: BlockHash::all_zeros(),
1196            merkle_root: TxMerkleNode::all_zeros(),
1197            time: 0,
1198            bits: CompactTarget::from_consensus(0),
1199            nonce: 0,
1200        };
1201        let tx = make_tx(vec![make_txin(1), make_txin(2)]);
1202
1203        // test a push when not ready (simulates creation during a stream)
1204        monitor.on_push(|listener| {
1205            listener.on_transaction_input(&tx.input[1]);
1206            listener.on_transaction_output(&tx.output[0]);
1207            listener.on_transaction_end(tx.lock_time, tx.compute_txid());
1208            listener.on_block_end();
1209        });
1210
1211        assert!(!monitor.state.lock().unwrap().saw_block);
1212
1213        // test a block push
1214        monitor.on_push(|listener| {
1215            listener.on_block_start(&header);
1216            listener.on_transaction_start(2);
1217            listener.on_transaction_input(&tx.input[0]);
1218            listener.on_transaction_input(&tx.input[1]);
1219            listener.on_transaction_output(&tx.output[0]);
1220            listener.on_transaction_end(tx.lock_time, tx.compute_txid());
1221            listener.on_block_end();
1222        });
1223        monitor.on_add_streamed_block_end(&header.block_hash());
1224
1225        assert!(monitor.state.lock().unwrap().saw_block);
1226
1227        // test another block push to ensure the state is reset
1228        monitor.on_push(|listener| {
1229            listener.on_block_start(&header);
1230            listener.on_transaction_start(2);
1231            listener.on_transaction_input(&tx.input[0]);
1232            listener.on_transaction_input(&tx.input[1]);
1233            listener.on_transaction_output(&tx.output[0]);
1234            listener.on_transaction_end(tx.lock_time, tx.compute_txid());
1235            listener.on_block_end();
1236        });
1237        monitor.on_add_streamed_block_end(&header.block_hash());
1238
1239        assert!(monitor.state.lock().unwrap().saw_block);
1240    }
1241
1242    #[test]
1243    fn test_streamed_block_operations() {
1244        let outpoint = OutPoint::new(Txid::from_slice(&[1; 32]).unwrap(), 0);
1245        let cpp = Box::new(DummyCommitmentPointProvider {});
1246        let chan_id = ChannelId::new(&[33u8; 32]);
1247        let monitor = ChainMonitorBase::new(outpoint, 0, &chan_id).as_monitor(cpp);
1248        let block_hash = BlockHash::all_zeros();
1249
1250        // Test when not ready (saw_block = false)
1251        let (adds, removes) = monitor.on_add_streamed_block_end(&block_hash);
1252        assert!(adds.is_empty());
1253        assert!(removes.is_empty());
1254
1255        let (adds, removes) = monitor.on_remove_streamed_block_end(&block_hash);
1256        assert!(adds.is_empty());
1257        assert!(removes.is_empty());
1258
1259        let funding_tx = make_tx(vec![make_txin(1), make_txin(2)]);
1260        let funding_outpoint = OutPoint::new(funding_tx.compute_txid(), 0);
1261        let monitor2 = ChainMonitorBase::new(funding_outpoint, 0, &chan_id)
1262            .as_monitor(Box::new(DummyCommitmentPointProvider {}));
1263        monitor2.add_funding(&funding_tx, 0);
1264
1265        let header = BlockHeader {
1266            version: Version::from_consensus(0),
1267            prev_blockhash: BlockHash::all_zeros(),
1268            merkle_root: TxMerkleNode::all_zeros(),
1269            time: 0,
1270            bits: CompactTarget::from_consensus(0),
1271            nonce: 0,
1272        };
1273        let header_block_hash = header.block_hash();
1274
1275        monitor2.on_push(|listener| {
1276            listener.on_block_start(&header);
1277            listener.on_transaction_start(funding_tx.version.0);
1278
1279            for input in &funding_tx.input {
1280                listener.on_transaction_input(input);
1281            }
1282
1283            for output in &funding_tx.output {
1284                listener.on_transaction_output(output);
1285            }
1286
1287            listener.on_transaction_end(funding_tx.lock_time, funding_tx.compute_txid());
1288            listener.on_block_end();
1289        });
1290
1291        let (adds, _) = monitor2.on_add_streamed_block_end(&header_block_hash);
1292        assert!(!adds.is_empty());
1293
1294        monitor2.on_push(|listener| {
1295            listener.on_block_start(&header);
1296            listener.on_transaction_start(funding_tx.version.0);
1297
1298            for input in &funding_tx.input {
1299                listener.on_transaction_input(input);
1300            }
1301
1302            for output in &funding_tx.output {
1303                listener.on_transaction_output(output);
1304            }
1305
1306            listener.on_transaction_end(funding_tx.lock_time, funding_tx.compute_txid());
1307            listener.on_block_end();
1308        });
1309
1310        let (adds, _) = monitor2.on_remove_streamed_block_end(&header_block_hash);
1311        assert!(!adds.is_empty());
1312    }
1313
1314    #[test]
1315    fn test_chain_monitor_conversions_and_getters() {
1316        let outpoint = OutPoint::new(Txid::from_slice(&[1; 32]).unwrap(), 0);
1317        let chan_id = ChannelId::new(&[33u8; 32]);
1318        let base = ChainMonitorBase::new(outpoint, 0, &chan_id);
1319
1320        let cpp = Box::new(DummyCommitmentPointProvider {});
1321        let monitor = base.as_monitor(cpp);
1322        let base2 = monitor.as_base();
1323        assert_eq!(base2.funding_outpoint, outpoint);
1324
1325        assert_eq!(base.funding_outpoint(), None);
1326        assert!(!base.forget_seen());
1327
1328        base.forget_channel();
1329        assert!(base.forget_seen());
1330    }
1331    #[test]
1332    fn test_mutual_close() {
1333        let block_hash = BlockHash::all_zeros();
1334        let (node, channel_id, monitor, funding_txid) = setup_funded_channel();
1335
1336        // channel should exist after a heartbeat
1337        node.get_heartbeat();
1338        assert!(node.get_channel(&channel_id).is_ok());
1339        assert_eq!(node.get_tracker().listeners.len(), 1);
1340
1341        let close_tx = make_tx(vec![TxIn {
1342            previous_output: OutPoint::new(funding_txid, 0),
1343            script_sig: Default::default(),
1344            sequence: Default::default(),
1345            witness: Default::default(),
1346        }]);
1347        monitor.on_add_block(&[close_tx.clone()], &block_hash);
1348        assert_eq!(monitor.closing_depth(), 1);
1349        assert!(!monitor.is_done());
1350
1351        // channel should exist after a heartbeat
1352        node.get_heartbeat();
1353        assert!(node.get_channel(&channel_id).is_ok());
1354        assert_eq!(node.get_tracker().listeners.len(), 1);
1355
1356        for _ in 1..MIN_DEPTH - 1 {
1357            monitor.on_add_block(&[], &block_hash);
1358        }
1359        assert!(!monitor.is_done());
1360        node.forget_channel(&channel_id).unwrap();
1361        monitor.on_add_block(&[], &block_hash);
1362        assert!(monitor.is_done());
1363
1364        // channel should still be there until the heartbeat
1365        assert!(node.get_channel(&channel_id).is_ok());
1366
1367        // channel should be pruned after a heartbeat
1368        node.get_heartbeat();
1369        assert!(node.get_channel(&channel_id).is_err());
1370        assert_eq!(node.get_tracker().listeners.len(), 0);
1371    }
1372
1373    #[test]
1374    fn test_mutual_close_with_forget_channel() {
1375        let block_hash = BlockHash::all_zeros();
1376        let (node, channel_id, monitor, funding_txid) = setup_funded_channel();
1377
1378        // channel should exist after a heartbeat
1379        node.get_heartbeat();
1380        assert!(node.get_channel(&channel_id).is_ok());
1381        assert_eq!(node.get_tracker().listeners.len(), 1);
1382
1383        let close_tx = make_tx(vec![TxIn {
1384            previous_output: OutPoint::new(funding_txid, 0),
1385            script_sig: Default::default(),
1386            sequence: Default::default(),
1387            witness: Default::default(),
1388        }]);
1389        monitor.on_add_block(&[close_tx.clone()], &block_hash);
1390        assert_eq!(monitor.closing_depth(), 1);
1391        assert!(!monitor.is_done());
1392
1393        // channel should exist after a heartbeat
1394        node.get_heartbeat();
1395        assert!(node.get_channel(&channel_id).is_ok());
1396        assert_eq!(node.get_tracker().listeners.len(), 1);
1397
1398        for _ in 1..MIN_DEPTH - 1 {
1399            monitor.on_add_block(&[], &block_hash);
1400        }
1401        assert!(!monitor.is_done());
1402        monitor.on_add_block(&[], &block_hash);
1403        assert!(!monitor.is_done());
1404
1405        // channel should still be there until the forget_channel
1406        assert!(node.get_channel(&channel_id).is_ok());
1407        node.forget_channel(&channel_id).unwrap();
1408
1409        // need a heartbeat to do the pruning
1410        assert!(node.get_channel(&channel_id).is_ok());
1411        node.get_heartbeat();
1412        assert!(node.get_channel(&channel_id).is_err());
1413        assert_eq!(node.get_tracker().listeners.len(), 0);
1414    }
1415
1416    #[test]
1417    fn test_mutual_close_with_missing_forget_channel() {
1418        let block_hash = BlockHash::all_zeros();
1419        let (node, channel_id, monitor, funding_txid) = setup_funded_channel();
1420
1421        // channel should exist after a heartbeat
1422        node.get_heartbeat();
1423        assert!(node.get_channel(&channel_id).is_ok());
1424        assert_eq!(node.get_tracker().listeners.len(), 1);
1425
1426        let close_tx = make_tx(vec![TxIn {
1427            previous_output: OutPoint::new(funding_txid, 0),
1428            script_sig: Default::default(),
1429            sequence: Default::default(),
1430            witness: Default::default(),
1431        }]);
1432        monitor.on_add_block(&[close_tx.clone()], &block_hash);
1433        assert_eq!(monitor.closing_depth(), 1);
1434        assert!(!monitor.is_done());
1435
1436        // channel should exist after a heartbeat
1437        node.get_heartbeat();
1438        assert!(node.get_channel(&channel_id).is_ok());
1439        assert_eq!(node.get_tracker().listeners.len(), 1);
1440
1441        for _ in 1..MIN_DEPTH - 1 {
1442            monitor.on_add_block(&[], &block_hash);
1443        }
1444        assert!(!monitor.is_done());
1445        monitor.on_add_block(&[], &block_hash);
1446
1447        // we're not done because no forget_channel seen
1448        assert!(!monitor.is_done());
1449        assert!(node.get_channel(&channel_id).is_ok());
1450
1451        // channel should still be there after heartbeat
1452        node.get_heartbeat();
1453        assert!(node.get_channel(&channel_id).is_ok());
1454
1455        // wait a long time
1456        for _ in 0..2016 - 1 {
1457            monitor.on_add_block(&[], &block_hash);
1458        }
1459        assert!(!monitor.is_done());
1460
1461        // we still don't forget the channel if the node hasn't said forget
1462        monitor.on_add_block(&[], &block_hash);
1463        assert!(!monitor.is_done());
1464
1465        // channel should still be there
1466        assert!(node.get_channel(&channel_id).is_ok());
1467
1468        // channel should not be pruned after a heartbeat
1469        node.get_heartbeat();
1470        assert!(node.get_channel(&channel_id).is_ok());
1471    }
1472
1473    #[test]
1474    fn test_unilateral_holder_close() {
1475        let block_hash = BlockHash::all_zeros();
1476        let (node, channel_id, monitor, _funding_txid) = setup_funded_channel();
1477
1478        let commit_num = 23;
1479        let feerate_per_kw = 1000;
1480        let to_holder = 100000;
1481        let to_cp = 200000;
1482        let htlcs = Vec::new();
1483        let closing_commitment_tx = node
1484            .with_channel(&channel_id, |chan| {
1485                chan.set_next_holder_commit_num_for_testing(commit_num);
1486                let per_commitment_point = chan.get_per_commitment_point(commit_num)?;
1487                let txkeys = chan.make_holder_tx_keys(&per_commitment_point);
1488
1489                Ok(chan.make_holder_commitment_tx(
1490                    commit_num,
1491                    &txkeys,
1492                    feerate_per_kw,
1493                    to_holder,
1494                    to_cp,
1495                    htlcs.clone(),
1496                ))
1497            })
1498            .expect("make_holder_commitment_tx failed");
1499        let closing_tx = closing_commitment_tx.trust().built_transaction().transaction.clone();
1500        let closing_txid = closing_tx.compute_txid();
1501        let holder_output_index =
1502            closing_tx.output.iter().position(|out| out.value.to_sat() == to_holder).unwrap()
1503                as u32;
1504        monitor.on_add_block(&[closing_tx.clone()], &block_hash);
1505        assert_eq!(monitor.closing_depth(), 1);
1506        assert!(!monitor.is_done());
1507        // we never forget the channel if we didn't sweep our output
1508        for _ in 1..MAX_CLOSING_DEPTH {
1509            monitor.on_add_block(&[], &block_hash);
1510        }
1511        assert!(!monitor.is_done());
1512        let sweep_cp_tx = make_tx(vec![make_txin2(closing_txid, 1 - holder_output_index)]);
1513        monitor.on_add_block(&[sweep_cp_tx], &block_hash);
1514        // we still never forget the channel
1515        for _ in 1..MAX_CLOSING_DEPTH {
1516            monitor.on_add_block(&[], &block_hash);
1517        }
1518        assert!(!monitor.is_done());
1519        let sweep_holder_tx = make_tx(vec![make_txin2(closing_txid, holder_output_index)]);
1520        monitor.on_add_block(&[sweep_holder_tx], &block_hash);
1521        // once we sweep our output, we forget the channel
1522        for _ in 1..MIN_DEPTH {
1523            monitor.on_add_block(&[], &block_hash);
1524        }
1525        node.forget_channel(&channel_id).unwrap();
1526        assert!(monitor.is_done());
1527    }
1528
1529    #[test]
1530    fn test_unilateral_cp_and_htlcs_close() {
1531        let block_hash = BlockHash::all_zeros();
1532        let (node, channel_id, monitor, _funding_txid) = setup_funded_channel();
1533
1534        let commit_num = 23;
1535        let feerate_per_kw = 1000;
1536        let to_holder = 100000;
1537        let to_cp = 200000;
1538        let htlcs = vec![HTLCOutputInCommitment {
1539            offered: false,
1540            amount_msat: 10000,
1541            cltv_expiry: 0,
1542            payment_hash: PaymentHash([0; 32]),
1543            transaction_output_index: None,
1544        }];
1545
1546        let closing_commitment_tx = node
1547            .with_channel(&channel_id, |chan| {
1548                let per_commitment_point = make_test_pubkey(12);
1549                chan.set_next_counterparty_commit_num_for_testing(
1550                    commit_num + 1,
1551                    per_commitment_point.clone(),
1552                );
1553                Ok(chan.make_counterparty_commitment_tx(
1554                    &per_commitment_point,
1555                    commit_num,
1556                    feerate_per_kw,
1557                    to_holder,
1558                    to_cp,
1559                    htlcs.clone(),
1560                ))
1561            })
1562            .expect("make_holder_commitment_tx failed");
1563
1564        let closing_tx = closing_commitment_tx.trust().built_transaction().transaction.clone();
1565        let closing_txid = closing_tx.compute_txid();
1566        let holder_output_index =
1567            closing_tx.output.iter().position(|out| out.value.to_sat() == to_holder).unwrap()
1568                as u32;
1569        let cp_output_index =
1570            closing_tx.output.iter().position(|out| out.value.to_sat() == to_cp).unwrap() as u32;
1571        let htlc_output_index = closing_tx
1572            .output
1573            .iter()
1574            .position(|out| out.value.to_sat() == htlcs[0].amount_msat / 1000)
1575            .unwrap() as u32;
1576
1577        assert_eq!(monitor.closing_depth(), 0);
1578        assert!(!monitor.is_done());
1579
1580        monitor.on_add_block(&[closing_tx.clone()], &block_hash);
1581        assert_eq!(monitor.closing_depth(), 1);
1582        assert!(!monitor.is_done());
1583
1584        let state = monitor.get_state();
1585        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1586
1587        assert!(!closing_outpoints.is_all_spent());
1588
1589        let holder_outpoint = OutPoint { txid: closing_txid, vout: holder_output_index };
1590        let cp_outpoint = OutPoint { txid: closing_txid, vout: cp_output_index };
1591        let htlc_outpoint = OutPoint { txid: closing_txid, vout: htlc_output_index };
1592
1593        assert!(closing_outpoints.includes_our_output(&holder_outpoint));
1594        assert!(!closing_outpoints.includes_our_output(&cp_outpoint));
1595        assert!(closing_outpoints.includes_htlc_output(&htlc_outpoint));
1596        assert!(!closing_outpoints.includes_htlc_output(&holder_outpoint));
1597
1598        assert!(!closing_outpoints.includes_second_level_htlc_output(&htlc_outpoint));
1599
1600        drop(state);
1601
1602        for _ in 1..MAX_CLOSING_DEPTH {
1603            monitor.on_add_block(&[], &block_hash);
1604        }
1605        assert!(!monitor.is_done());
1606
1607        let sweep_cp_tx = make_tx(vec![make_txin2(closing_txid, cp_output_index)]);
1608        monitor.on_add_block(&[sweep_cp_tx], &block_hash);
1609
1610        // Still not done because our output isn't swept
1611        for _ in 1..MAX_CLOSING_DEPTH {
1612            monitor.on_add_block(&[], &block_hash);
1613        }
1614        assert!(!monitor.is_done());
1615
1616        let sweep_holder_tx = make_tx(vec![make_txin2(closing_txid, holder_output_index)]);
1617        monitor.on_add_block(&[sweep_holder_tx], &block_hash);
1618
1619        let state = monitor.get_state();
1620        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1621        // Our output should be marked as spent, but HTLCs not yet
1622        assert!(!closing_outpoints.is_all_spent());
1623        drop(state);
1624
1625        let monitor1 = monitor.clone();
1626
1627        // TIMELINE 1 - HTLC output not swept
1628        for _ in 1..MAX_CLOSING_DEPTH - 1 {
1629            monitor.on_add_block(&[], &block_hash);
1630        }
1631        assert!(!monitor.is_done());
1632        monitor.on_add_block(&[], &block_hash);
1633        assert!(!monitor.is_done());
1634
1635        // TIMELINE 2 - HTLC output swept
1636        let sweep_htlc_tx = make_tx(vec![make_txin2(closing_txid, htlc_output_index)]);
1637        let sweep_htlc_txid = sweep_htlc_tx.compute_txid();
1638        monitor1.on_add_block(&[sweep_htlc_tx], &block_hash);
1639
1640        let state = monitor1.get_state();
1641        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1642        let second_level_outpoint = OutPoint { txid: sweep_htlc_txid, vout: 0 };
1643        assert!(closing_outpoints.includes_second_level_htlc_output(&second_level_outpoint));
1644        // Second-level not swept yet
1645        assert!(!closing_outpoints.is_all_spent());
1646        drop(state);
1647
1648        for _ in 1..MAX_CLOSING_DEPTH {
1649            monitor1.on_add_block(&[], &block_hash);
1650        }
1651        assert!(!monitor1.is_done());
1652
1653        let sweep_second_level_tx = make_tx(vec![make_txin2(sweep_htlc_txid, 0)]);
1654        monitor1.on_add_block(&[sweep_second_level_tx], &block_hash);
1655
1656        let state = monitor1.get_state();
1657        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1658        // Now all outputs should be spent
1659        assert!(closing_outpoints.is_all_spent());
1660        drop(state);
1661
1662        for _ in 1..MAX_CLOSING_DEPTH {
1663            monitor1.on_add_block(&[], &block_hash);
1664        }
1665        // still not done, need forget from node
1666        assert!(!monitor1.is_done());
1667
1668        // once the node forgets we can forget all of the above
1669        node.forget_channel(&channel_id).unwrap();
1670        assert!(monitor.is_done());
1671        assert!(monitor1.is_done());
1672    }
1673
1674    #[test]
1675    fn test_unilateral_cp_and_htlcs_backward_change() {
1676        let block_hash = BlockHash::all_zeros();
1677        let (node, channel_id, monitor, _funding_txid) = setup_funded_channel();
1678
1679        let commit_num = 23;
1680        let feerate_per_kw = 1000;
1681        let to_holder = 100000;
1682        let to_cp = 200000;
1683        let htlcs = vec![HTLCOutputInCommitment {
1684            offered: false,
1685            amount_msat: 10000,
1686            cltv_expiry: 0,
1687            payment_hash: PaymentHash([0; 32]),
1688            transaction_output_index: None,
1689        }];
1690
1691        let closing_commitment_tx = node
1692            .with_channel(&channel_id, |chan| {
1693                let per_commitment_point = make_test_pubkey(12);
1694                chan.set_next_counterparty_commit_num_for_testing(
1695                    commit_num + 1,
1696                    per_commitment_point.clone(),
1697                );
1698                Ok(chan.make_counterparty_commitment_tx(
1699                    &per_commitment_point,
1700                    commit_num,
1701                    feerate_per_kw,
1702                    to_holder,
1703                    to_cp,
1704                    htlcs.clone(),
1705                ))
1706            })
1707            .expect("make_counterparty_commitment_tx failed");
1708
1709        let closing_tx = closing_commitment_tx.trust().built_transaction().transaction.clone();
1710        let closing_txid = closing_tx.compute_txid();
1711        let holder_output_index =
1712            closing_tx.output.iter().position(|out| out.value.to_sat() == to_holder).unwrap()
1713                as u32;
1714        let htlc_output_index = closing_tx
1715            .output
1716            .iter()
1717            .position(|out| out.value.to_sat() == htlcs[0].amount_msat / 1000)
1718            .unwrap() as u32;
1719
1720        monitor.on_add_block(&[closing_tx.clone()], &block_hash);
1721        assert_eq!(monitor.closing_depth(), 1);
1722        let state = monitor.get_state();
1723        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1724        let htlc_outpoint = OutPoint { txid: closing_txid, vout: htlc_output_index };
1725        assert!(closing_outpoints.includes_htlc_output(&htlc_outpoint));
1726        assert!(!closing_outpoints.is_all_spent());
1727        drop(state);
1728
1729        let sweep_holder_tx = make_tx(vec![make_txin2(closing_txid, holder_output_index)]);
1730        monitor.on_add_block(&[sweep_holder_tx.clone()], &block_hash);
1731
1732        let sweep_htlc_tx = make_tx(vec![make_txin2(closing_txid, htlc_output_index)]);
1733        let sweep_htlc_txid = sweep_htlc_tx.compute_txid();
1734        monitor.on_add_block(&[sweep_htlc_tx.clone()], &block_hash);
1735
1736        let state = monitor.get_state();
1737        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1738        let second_level_outpoint = OutPoint { txid: sweep_htlc_txid, vout: 0 };
1739        assert!(closing_outpoints.includes_second_level_htlc_output(&second_level_outpoint));
1740        assert!(!closing_outpoints.is_all_spent());
1741        drop(state);
1742
1743        let sweep_second_level_tx = make_tx(vec![make_txin2(sweep_htlc_txid, 0)]);
1744        monitor.on_add_block(&[sweep_second_level_tx.clone()], &block_hash);
1745
1746        let state = monitor.get_state();
1747        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1748        assert!(closing_outpoints.is_all_spent());
1749        drop(state);
1750
1751        // Roll back second-level HTLC spend
1752        monitor.on_remove_block(&[sweep_second_level_tx], &block_hash);
1753        let state = monitor.get_state();
1754        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1755        assert!(!closing_outpoints.is_all_spent());
1756        drop(state);
1757
1758        // Roll back first-level HTLC spend
1759        monitor.on_remove_block(&[sweep_htlc_tx], &block_hash);
1760        let state = monitor.get_state();
1761        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1762        assert!(!closing_outpoints.includes_second_level_htlc_output(&second_level_outpoint));
1763        assert!(!closing_outpoints.is_all_spent());
1764        drop(state);
1765
1766        // Roll back holder output spend
1767        monitor.on_remove_block(&[sweep_holder_tx], &block_hash);
1768        let state = monitor.get_state();
1769        let closing_outpoints = state.closing_outpoints.as_ref().unwrap();
1770        let holder_outpoint = OutPoint { txid: closing_txid, vout: holder_output_index };
1771        assert!(closing_outpoints.includes_our_output(&holder_outpoint));
1772        assert!(!closing_outpoints.is_all_spent());
1773        drop(state);
1774
1775        // Roll back unilateral close
1776        monitor.on_remove_block(&[closing_tx], &block_hash);
1777        let state = monitor.get_state();
1778        assert!(state.closing_outpoints.is_none());
1779        assert_eq!(state.unilateral_closing_height, None);
1780    }
1781
1782    #[test]
1783    fn test_apply_backward_change_funding_confirmed() {
1784        let funding_tx = make_tx(vec![make_txin(1), make_txin(2)]);
1785        let funding_outpoint = OutPoint::new(funding_tx.compute_txid(), 0);
1786        let setup = make_channel_setup(funding_outpoint);
1787        let (node, channel_id) =
1788            init_node_and_channel(TEST_NODE_CONFIG, TEST_SEED[1], setup.clone());
1789        let channel = node.get_channel(&channel_id).unwrap();
1790        let cpp = Box::new(ChannelCommitmentPointProvider::new(channel.clone()));
1791        let monitor = node
1792            .with_channel(&channel_id, |chan| Ok(chan.monitor.clone().as_monitor(cpp.clone())))
1793            .unwrap();
1794        let block_hash = BlockHash::all_zeros();
1795
1796        monitor.on_add_block(&[], &block_hash);
1797        monitor.on_add_block(&[funding_tx.clone()], &block_hash);
1798        assert_eq!(monitor.funding_depth(), 1);
1799        assert!(monitor.get_state().funding_outpoint.is_some());
1800
1801        monitor.on_remove_block(&[funding_tx], &block_hash);
1802        assert_eq!(monitor.funding_depth(), 0);
1803        assert!(monitor.get_state().funding_outpoint.is_none());
1804    }
1805
1806    #[test]
1807    fn test_apply_backward_change_mutual_close() {
1808        let block_hash = BlockHash::all_zeros();
1809        let (_, _, monitor, funding_txid) = setup_funded_channel();
1810
1811        let close_tx = make_tx(vec![TxIn {
1812            previous_output: OutPoint::new(funding_txid, 0),
1813            script_sig: Default::default(),
1814            sequence: Default::default(),
1815            witness: Default::default(),
1816        }]);
1817
1818        monitor.on_add_block(&[close_tx.clone()], &block_hash);
1819        assert_eq!(monitor.closing_depth(), 1);
1820        assert!(monitor.get_state().mutual_closing_height.is_some());
1821
1822        monitor.on_remove_block(&[close_tx], &block_hash);
1823        assert_eq!(monitor.closing_depth(), 0);
1824        assert!(monitor.get_state().mutual_closing_height.is_none());
1825    }
1826
1827    #[test]
1828    fn test_closing_outpoints_is_all_spent_logic() {
1829        let txid = Txid::all_zeros();
1830        let mut closing_outpoints = ClosingOutpoints::new(txid, Some(0), vec![1, 2]);
1831
1832        assert!(!closing_outpoints.is_all_spent());
1833
1834        closing_outpoints.set_our_output_spent(0, true);
1835        assert!(!closing_outpoints.is_all_spent());
1836
1837        closing_outpoints.set_htlc_output_spent(1, true);
1838        assert!(!closing_outpoints.is_all_spent());
1839
1840        closing_outpoints.set_htlc_output_spent(2, true);
1841        // All first-level spent, no second-level
1842        assert!(closing_outpoints.is_all_spent());
1843
1844        let second_level_outpoint = OutPoint { txid, vout: 10 };
1845        closing_outpoints.add_second_level_htlc_output(second_level_outpoint);
1846        assert!(!closing_outpoints.is_all_spent());
1847
1848        closing_outpoints.set_second_level_htlc_spent(second_level_outpoint, true);
1849        assert!(closing_outpoints.is_all_spent());
1850    }
1851
1852    #[test]
1853    fn test_closing_outpoints_without_our_output() {
1854        let txid = Txid::all_zeros();
1855        let mut closing_outpoints = ClosingOutpoints::new(txid, None, vec![1]);
1856
1857        assert!(!closing_outpoints.is_all_spent());
1858
1859        closing_outpoints.set_htlc_output_spent(1, true);
1860        assert!(closing_outpoints.is_all_spent());
1861    }
1862
1863    #[test]
1864    fn test_closing_outpoints_boolean_logic_edge_cases() {
1865        let txid = Txid::all_zeros();
1866
1867        let closing_outpoints = ClosingOutpoints::new(txid, None, vec![]);
1868        assert!(closing_outpoints.is_all_spent());
1869
1870        let mut closing_outpoints = ClosingOutpoints::new(txid, Some(0), vec![1]);
1871
1872        closing_outpoints.set_our_output_spent(0, false);
1873        closing_outpoints.set_htlc_output_spent(1, false);
1874        assert!(!closing_outpoints.is_all_spent());
1875
1876        closing_outpoints.set_our_output_spent(0, true);
1877        closing_outpoints.set_htlc_output_spent(1, false);
1878        assert!(!closing_outpoints.is_all_spent());
1879    }
1880
1881    #[test]
1882    fn test_closing_outpoints_second_level_management() {
1883        let txid = Txid::all_zeros();
1884        let mut closing_outpoints = ClosingOutpoints::new(txid, None, vec![]);
1885
1886        let outpoint1 = OutPoint { txid, vout: 10 };
1887        let outpoint2 = OutPoint { txid, vout: 11 };
1888
1889        closing_outpoints.add_second_level_htlc_output(outpoint1);
1890        closing_outpoints.add_second_level_htlc_output(outpoint2);
1891
1892        assert!(closing_outpoints.includes_second_level_htlc_output(&outpoint1));
1893        assert!(closing_outpoints.includes_second_level_htlc_output(&outpoint2));
1894
1895        closing_outpoints.set_second_level_htlc_spent(outpoint1, true);
1896        assert!(!closing_outpoints.is_all_spent());
1897
1898        closing_outpoints.set_second_level_htlc_spent(outpoint2, true);
1899        assert!(closing_outpoints.is_all_spent());
1900
1901        closing_outpoints.remove_second_level_htlc_output(&outpoint1);
1902        assert!(!closing_outpoints.includes_second_level_htlc_output(&outpoint1));
1903        assert!(closing_outpoints.includes_second_level_htlc_output(&outpoint2));
1904        assert!(closing_outpoints.is_all_spent());
1905    }
1906
1907    #[test]
1908    fn test_second_level_htlc_output_methods() {
1909        let outpoint = OutPoint { txid: Txid::all_zeros(), vout: 0 };
1910        let mut htlc_output = SecondLevelHTLCOutput::new(outpoint);
1911
1912        assert!(!htlc_output.is_spent());
1913        assert!(htlc_output.matches_outpoint(&outpoint));
1914
1915        let different_outpoint = OutPoint { txid: Txid::all_zeros(), vout: 1 };
1916        assert!(!htlc_output.matches_outpoint(&different_outpoint));
1917
1918        htlc_output.set_spent(true);
1919        assert!(htlc_output.is_spent());
1920
1921        htlc_output.set_spent(false);
1922        assert!(!htlc_output.is_spent());
1923    }
1924
1925    #[test]
1926    fn test_transaction_state_isolation() {
1927        let block_hash = BlockHash::all_zeros();
1928        let (_, _, monitor, funding_txid) = setup_funded_channel();
1929        let funding_outpoint = OutPoint::new(funding_txid, 0);
1930
1931        let closing_tx = make_tx(vec![TxIn {
1932            previous_output: funding_outpoint,
1933            script_sig: Default::default(),
1934            sequence: Default::default(),
1935            witness: Default::default(),
1936        }]);
1937        let closing_txid = closing_tx.compute_txid();
1938
1939        let unrelated_tx = make_tx(vec![make_txin2(Txid::all_zeros(), 0)]);
1940
1941        let mut decode_state =
1942            BlockDecodeState::new_with_block_hash(&monitor.get_state(), &block_hash);
1943        let mut listener = PushListener {
1944            commitment_point_provider: &*monitor.commitment_point_provider,
1945            decode_state: &mut decode_state,
1946            saw_block: true,
1947        };
1948
1949        listener.on_transaction_start(closing_tx.version.0);
1950        listener.on_transaction_input(&closing_tx.input[0]);
1951        listener.on_transaction_output(&closing_tx.output[0]);
1952        listener.on_transaction_end(closing_tx.lock_time, closing_txid);
1953
1954        assert!(listener.decode_state.closing_tx.is_none());
1955
1956        listener.on_transaction_start(unrelated_tx.version.0);
1957
1958        assert_eq!(listener.decode_state.version, unrelated_tx.version.0);
1959        assert_eq!(listener.decode_state.input_num, 0);
1960        assert_eq!(listener.decode_state.output_num, 0);
1961        assert!(listener.decode_state.closing_tx.is_none());
1962        assert!(listener.decode_state.spent_htlc_outputs.is_empty());
1963    }
1964
1965    #[test]
1966    fn test_is_done_conditions() {
1967        let outpoint = OutPoint::new(Txid::from_slice(&[1; 32]).unwrap(), 0);
1968        let chan_id = ChannelId::new(&[33u8; 32]);
1969
1970        let base1 = ChainMonitorBase::new(outpoint, MIN_DEPTH + 10, &chan_id);
1971        {
1972            let mut state = base1.get_state();
1973            state.funding_double_spent_height = Some(10);
1974            state.saw_forget_channel = true;
1975        }
1976        assert!(base1.is_done());
1977
1978        let base2 = ChainMonitorBase::new(outpoint, MAX_CLOSING_DEPTH + 10, &chan_id);
1979        {
1980            let mut state = base2.get_state();
1981            state.our_output_swept_height = Some(10);
1982            state.saw_forget_channel = true;
1983        }
1984        assert!(base2.is_done());
1985    }
1986
1987    #[test]
1988    fn test_diagnostic_all_states() {
1989        let outpoint = OutPoint::new(Txid::from_slice(&[1; 32]).unwrap(), 0);
1990        let chan_id = ChannelId::new(&[33u8; 32]);
1991        let base = ChainMonitorBase::new(outpoint, 100, &chan_id);
1992
1993        let diagnostic = base.diagnostic(false);
1994        assert_eq!(
1995            diagnostic,
1996            format!("UNCOMFIRMED hold till funding doublespent + {}", MIN_DEPTH)
1997        );
1998
1999        {
2000            let mut state = base.get_state();
2001            state.funding_height = Some(90);
2002        }
2003        assert_eq!(base.diagnostic(false), "ACTIVE");
2004        assert_eq!(base.diagnostic(true), "CLOSING");
2005
2006        // Test all aging states
2007        let test_cases = vec![
2008            ("funding_double_spent_height", 95, MIN_DEPTH, "AGING_FUNDING_DOUBLESPENT"),
2009            ("mutual_closing_height", 98, MIN_DEPTH, "AGING_MUTUALLY_CLOSED"),
2010            ("closing_swept_height", 99, MIN_DEPTH, "AGING_CLOSING_SWEPT"),
2011            ("our_output_swept_height", 97, MAX_CLOSING_DEPTH, "AGING_OUR_OUTPUT_SWEPT"),
2012        ];
2013
2014        for (field, height, depth_limit, expected_prefix) in test_cases {
2015            {
2016                let mut state = base.get_state();
2017                state.funding_height = Some(90);
2018                state.funding_double_spent_height = None;
2019                state.mutual_closing_height = None;
2020                state.closing_swept_height = None;
2021                state.our_output_swept_height = None;
2022
2023                match field {
2024                    "funding_double_spent_height" =>
2025                        state.funding_double_spent_height = Some(height),
2026                    "mutual_closing_height" => state.mutual_closing_height = Some(height),
2027                    "closing_swept_height" => state.closing_swept_height = Some(height),
2028                    "our_output_swept_height" => state.our_output_swept_height = Some(height),
2029                    _ => unreachable!(),
2030                }
2031            }
2032
2033            let diagnostic = base.diagnostic(false);
2034            let expected =
2035                format!("{} at {} until {}", expected_prefix, height, height + depth_limit);
2036            assert_eq!(diagnostic, expected);
2037        }
2038    }
2039
2040    fn setup_funded_channel() -> (Arc<Node>, ChannelId, ChainMonitor, Txid) {
2041        let funding_tx = make_tx(vec![make_txin(1), make_txin(2)]);
2042        let funding_outpoint = OutPoint::new(funding_tx.compute_txid(), 0);
2043        let setup = make_channel_setup(funding_outpoint);
2044
2045        let (node, channel_id) =
2046            init_node_and_channel(TEST_NODE_CONFIG, TEST_SEED[1], setup.clone());
2047        let channel = node.get_channel(&channel_id).unwrap();
2048        let cpp = Box::new(ChannelCommitmentPointProvider::new(channel.clone()));
2049        let monitor = node
2050            .with_channel(&channel_id, |chan| Ok(chan.monitor.clone().as_monitor(cpp.clone())))
2051            .unwrap();
2052        let block_hash = BlockHash::all_zeros();
2053        monitor.on_add_block(&[], &block_hash);
2054        monitor.on_add_block(&[funding_tx.clone()], &block_hash);
2055        assert_eq!(monitor.funding_depth(), 1);
2056        (node, channel_id, monitor, funding_tx.compute_txid())
2057    }
2058
2059    fn make_txin2(prev_txid: Txid, prevout: u32) -> TxIn {
2060        TxIn {
2061            previous_output: OutPoint::new(prev_txid, prevout),
2062            script_sig: Default::default(),
2063            sequence: Default::default(),
2064            witness: Default::default(),
2065        }
2066    }
2067
2068    fn make_channel_setup(funding_outpoint: OutPoint) -> ChannelSetup {
2069        ChannelSetup {
2070            is_outbound: true,
2071            channel_value_sat: 3_000_000,
2072            push_value_msat: 0,
2073            funding_outpoint,
2074            holder_selected_contest_delay: 6,
2075            holder_shutdown_script: None,
2076            counterparty_points: make_test_counterparty_points(),
2077            counterparty_selected_contest_delay: 7,
2078            counterparty_shutdown_script: None,
2079            commitment_type: CommitmentType::StaticRemoteKey,
2080        }
2081    }
2082}