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
20const MIN_DEPTH: u32 = 100;
22
23const 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#[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 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 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 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 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 let i = self.htlc_outputs.iter().position(|&x| x == vout).unwrap();
95 self.htlc_spents[i] = spent;
96 }
97
98 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#[serde_as]
135#[derive(Clone, Debug, Serialize, Deserialize)]
136pub struct State {
137 height: u32,
139 funding_txids: Vec<Txid>,
141 funding_vouts: Vec<u32>,
143 funding_inputs: Set<OutPoint>,
145 funding_height: Option<u32>,
147 funding_outpoint: Option<OutPoint>,
149 funding_double_spent_height: Option<u32>,
151 mutual_closing_height: Option<u32>,
153 unilateral_closing_height: Option<u32>,
155 closing_outpoints: Option<ClosingOutpoints>,
157 closing_swept_height: Option<u32>,
159 our_output_swept_height: Option<u32>,
161 #[serde(default)]
163 saw_block: bool,
164 #[serde(default)]
166 saw_forget_channel: bool,
167 #[serde(skip)]
170 channel_id: Option<ChannelId>,
171}
172
173struct PushListener<'a> {
177 commitment_point_provider: &'a dyn CommitmentPointProvider,
178 decode_state: &'a mut BlockDecodeState,
179 saw_block: bool,
180}
181
182#[derive(Clone, Debug, Serialize, Deserialize)]
184enum StateChange {
185 FundingConfirmed(OutPoint),
187 FundingInputSpent(OutPoint),
190 UnilateralCloseConfirmed(Txid, OutPoint, Option<u32>, Vec<u32>),
193 MutualCloseConfirmed(Txid, OutPoint),
195 OurOutputSpent(u32),
197 HTLCOutputSpent(u32, OutPoint),
200 SecondLevelHTLCOutputSpent(OutPoint),
202}
203
204#[derive(Clone, Debug)]
206struct BlockDecodeState {
207 changes: Vec<StateChange>,
209 version: i32,
211 input_num: u32,
213 output_num: u32,
215 closing_tx: Option<Transaction>,
217 spent_htlc_outputs: Vec<(u32, u32)>,
220 block_hash: Option<BlockHash>,
222 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 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 fn is_not_ready_for_push(&self) -> bool {
273 if self.saw_block {
274 assert!(self.decode_state.block_hash.is_some(), "saw block but no decode state");
277 false
278 } else {
279 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 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 decode_state.add_change(StateChange::FundingInputSpent(input.previous_output));
320 }
321
322 if Some(input.previous_output) == decode_state.state.funding_outpoint {
323 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 let closing_change = if let Some(ref c) = decode_state.state.closing_outpoints {
338 if c.includes_our_output(&input.previous_output) {
339 Some(StateChange::OurOutputSpent(input.previous_output.vout))
341 } else if c.includes_htlc_output(&input.previous_output) {
342 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 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 if let Some(mut closing_tx) = decode_state.closing_tx.take() {
404 closing_tx.lock_time = lock_time;
405 assert_eq!(closing_tx.input.len(), 1);
407 let provider = self.commitment_point_provider;
408 let parameters = provider.get_transaction_parameters();
409
410 let commitment_number_opt = decode_commitment_number(&closing_tx, ¶meters);
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 ¶meters,
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 }
459}
460
461impl State {
462 fn channel_id(&self) -> &ChannelId {
463 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 let depth = self.depth_of(other_height);
475 if depth < limit {
476 false
478 } else if self.saw_forget_channel {
479 true
481 } else {
482 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 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 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 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 (adds, removes)
663 }
664
665 fn is_closing_swept(&self) -> bool {
667 self.closing_outpoints.as_ref().map(|o| o.is_all_spent()).unwrap_or(false)
668 }
669
670 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 match change {
686 StateChange::FundingConfirmed(outpoint) => {
687 self.funding_height = Some(self.height);
688 self.funding_outpoint = Some(outpoint);
689 self.funding_double_spent_height = None;
691 adds.push(outpoint);
692 }
693 StateChange::FundingInputSpent(outpoint) => {
694 self.funding_double_spent_height.get_or_insert(self.height);
700 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 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 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 if self.funding_double_spent_height == Some(self.height) {
768 self.funding_double_spent_height = None
769 }
770 removes.push(outpoint);
772 }
773 StateChange::UnilateralCloseConfirmed(
774 txid,
775 funding_outpoint,
776 our_output_index,
777 htlcs_indices,
778 ) => {
779 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#[derive(Clone)]
818pub struct ChainMonitorBase {
819 pub(crate) funding_outpoint: OutPoint,
821 state: Arc<Mutex<State>>,
823}
824
825impl ChainMonitorBase {
826 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 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 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 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 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 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 pub fn is_done(&self) -> bool {
911 self.get_state().is_done()
912 }
913
914 pub fn forget_channel(&self) {
916 let mut state = self.get_state();
917 state.saw_forget_channel = true;
918 }
919
920 pub fn funding_outpoint(&self) -> Option<OutPoint> {
922 self.get_state().funding_outpoint
923 }
924
925 pub fn forget_seen(&self) -> bool {
927 self.get_state().saw_forget_channel
928 }
929
930 pub fn diagnostic(&self, is_closed: bool) -> String {
932 self.get_state().diagnostic(is_closed)
933 }
934
935 fn get_state(&self) -> MutexGuard<State> {
937 self.state.lock().expect("lock")
938 }
939}
940
941#[derive(Clone)]
944pub struct ChainMonitor {
945 pub funding_outpoint: OutPoint,
947 pub state: Arc<Mutex<State>>,
949 decode_state: Arc<Mutex<Option<BlockDecodeState>>>,
952 commitment_point_provider: Box<dyn CommitmentPointProvider>,
954}
955
956impl ChainMonitor {
957 pub fn as_base(&self) -> ChainMonitorBase {
959 ChainMonitorBase { funding_outpoint: self.funding_outpoint, state: self.state.clone() }
960 }
961
962 pub fn get_state(&self) -> MutexGuard<State> {
964 self.state.lock().expect("lock")
965 }
966
967 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 pub fn funding_depth(&self) -> u32 {
981 let state = self.get_state();
982 state.depth_of(state.funding_height)
983 }
984
985 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 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 pub fn is_done(&self) -> bool {
1005 self.get_state().is_done()
1006 }
1007
1008 fn push_transactions(&self, block_hash: &BlockHash, txs: &[Transaction]) -> BlockDecodeState {
1010 let mut state = self.get_state();
1011
1012 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 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 return (Vec::new(), Vec::new());
1065 }
1066 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 return (Vec::new(), Vec::new());
1091 }
1092 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 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 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 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 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 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 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 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 assert!(node.get_channel(&channel_id).is_ok());
1366
1367 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 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 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 assert!(node.get_channel(&channel_id).is_ok());
1407 node.forget_channel(&channel_id).unwrap();
1408
1409 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 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 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 assert!(!monitor.is_done());
1449 assert!(node.get_channel(&channel_id).is_ok());
1450
1451 node.get_heartbeat();
1453 assert!(node.get_channel(&channel_id).is_ok());
1454
1455 for _ in 0..2016 - 1 {
1457 monitor.on_add_block(&[], &block_hash);
1458 }
1459 assert!(!monitor.is_done());
1460
1461 monitor.on_add_block(&[], &block_hash);
1463 assert!(!monitor.is_done());
1464
1465 assert!(node.get_channel(&channel_id).is_ok());
1467
1468 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 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 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 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 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 assert!(!closing_outpoints.is_all_spent());
1623 drop(state);
1624
1625 let monitor1 = monitor.clone();
1626
1627 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 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 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 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 assert!(!monitor1.is_done());
1667
1668 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 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 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 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 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 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 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}