@@ -36,7 +36,7 @@ use bitcoin::secp256k1;
36
36
use crate :: ln:: { PaymentHash , PaymentPreimage } ;
37
37
use crate :: ln:: msgs:: DecodeError ;
38
38
use crate :: ln:: chan_utils;
39
- use crate :: ln:: chan_utils:: { CounterpartyCommitmentSecrets , HTLCOutputInCommitment , HTLCClaim , ChannelTransactionParameters , HolderCommitmentTransaction } ;
39
+ use crate :: ln:: chan_utils:: { CommitmentTransaction , CounterpartyCommitmentSecrets , HTLCOutputInCommitment , HTLCClaim , ChannelTransactionParameters , HolderCommitmentTransaction , TxCreationKeys } ;
40
40
use crate :: ln:: channelmanager:: { HTLCSource , SentHTLCId } ;
41
41
use crate :: chain;
42
42
use crate :: chain:: { BestBlock , WatchedOutput } ;
@@ -1376,6 +1376,29 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
1376
1376
ret
1377
1377
}
1378
1378
1379
+ /// Gets all of the counterparty commitment transactions provided by the given update. This
1380
+ /// may be empty if the update doesn't include any new counterparty commitments. Returned
1381
+ /// commitment transactions are unsigned.
1382
+ ///
1383
+ /// This is provided so that watchtower clients in the persistence pipeline are able to build
1384
+ /// justice transactions for each counterparty commitment upon each update. It's intended to be
1385
+ /// used within an implementation of [`Persist::update_persisted_channel`], which is provided
1386
+ /// with a monitor and an update.
1387
+ ///
1388
+ /// It is expected that a watchtower client may use this method to retrieve the latest counterparty
1389
+ /// commitment transaction(s), and then hold the necessary data until a later update in which
1390
+ /// the monitor has been updated with the corresponding revocation data, at which point the
1391
+ /// monitor can sign the justice transaction.
1392
+ ///
1393
+ /// This will only return a non-empty list for monitor updates that have been created after
1394
+ /// upgrading to LDK 0.0.117+. Note that no restriction lies on the monitors themselves, which
1395
+ /// may have been created prior to upgrading.
1396
+ ///
1397
+ /// [`Persist::update_persisted_channel`]: crate::chain::chainmonitor::Persist::update_persisted_channel
1398
+ pub fn counterparty_commitment_txs_from_update ( & self , update : & ChannelMonitorUpdate ) -> Vec < CommitmentTransaction > {
1399
+ self . inner . lock ( ) . unwrap ( ) . counterparty_commitment_txs_from_update ( update)
1400
+ }
1401
+
1379
1402
pub ( crate ) fn get_min_seen_secret ( & self ) -> u64 {
1380
1403
self . inner . lock ( ) . unwrap ( ) . get_min_seen_secret ( )
1381
1404
}
@@ -2549,6 +2572,10 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
2549
2572
}
2550
2573
}
2551
2574
2575
+ #[ cfg( debug_assertions) ] {
2576
+ self . counterparty_commitment_txs_from_update ( updates) ;
2577
+ }
2578
+
2552
2579
// If the updates succeeded and we were in an already closed channel state, then there's no
2553
2580
// need to refuse any updates we expect to receive afer seeing a confirmed commitment.
2554
2581
if ret. is_ok ( ) && updates. update_id == CLOSED_CHANNEL_UPDATE_ID && self . latest_update_id == updates. update_id {
@@ -2657,6 +2684,55 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
2657
2684
ret
2658
2685
}
2659
2686
2687
+ fn build_counterparty_commitment_tx (
2688
+ & self , commitment_number : u64 , their_per_commitment_point : & PublicKey ,
2689
+ to_broadcaster_value : u64 , to_countersignatory_value : u64 , feerate_per_kw : u32 ,
2690
+ mut nondust_htlcs : Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) >
2691
+ ) -> CommitmentTransaction {
2692
+ let broadcaster_keys = & self . onchain_tx_handler . channel_transaction_parameters
2693
+ . counterparty_parameters . as_ref ( ) . unwrap ( ) . pubkeys ;
2694
+ let countersignatory_keys =
2695
+ & self . onchain_tx_handler . channel_transaction_parameters . holder_pubkeys ;
2696
+
2697
+ let broadcaster_funding_key = broadcaster_keys. funding_pubkey ;
2698
+ let countersignatory_funding_key = countersignatory_keys. funding_pubkey ;
2699
+ let keys = TxCreationKeys :: from_channel_static_keys ( & their_per_commitment_point,
2700
+ & broadcaster_keys, & countersignatory_keys, & self . onchain_tx_handler . secp_ctx ) ;
2701
+ let channel_parameters =
2702
+ & self . onchain_tx_handler . channel_transaction_parameters . as_counterparty_broadcastable ( ) ;
2703
+
2704
+ CommitmentTransaction :: new_with_auxiliary_htlc_data ( commitment_number,
2705
+ to_broadcaster_value, to_countersignatory_value, broadcaster_funding_key,
2706
+ countersignatory_funding_key, keys, feerate_per_kw, & mut nondust_htlcs,
2707
+ channel_parameters)
2708
+ }
2709
+
2710
+ pub ( crate ) fn counterparty_commitment_txs_from_update ( & self , update : & ChannelMonitorUpdate ) -> Vec < CommitmentTransaction > {
2711
+ update. updates . iter ( ) . filter_map ( |update| {
2712
+ match update {
2713
+ & ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTXInfo { commitment_txid,
2714
+ ref htlc_outputs, commitment_number, their_per_commitment_point,
2715
+ feerate_per_kw : Some ( feerate_per_kw) ,
2716
+ to_broadcaster_value_sat : Some ( to_broadcaster_value) ,
2717
+ to_countersignatory_value_sat : Some ( to_countersignatory_value) } => {
2718
+
2719
+ let nondust_htlcs = htlc_outputs. iter ( ) . filter_map ( |( htlc, _) | {
2720
+ htlc. transaction_output_index . map ( |_| ( htlc. clone ( ) , None ) )
2721
+ } ) . collect :: < Vec < _ > > ( ) ;
2722
+
2723
+ let commitment_tx = self . build_counterparty_commitment_tx ( commitment_number,
2724
+ & their_per_commitment_point, to_broadcaster_value,
2725
+ to_countersignatory_value, feerate_per_kw, nondust_htlcs) ;
2726
+
2727
+ debug_assert_eq ! ( commitment_tx. trust( ) . txid( ) , commitment_txid) ;
2728
+
2729
+ Some ( commitment_tx)
2730
+ } ,
2731
+ _ => None ,
2732
+ }
2733
+ } ) . collect ( )
2734
+ }
2735
+
2660
2736
/// Can only fail if idx is < get_min_seen_secret
2661
2737
fn get_secret ( & self , idx : u64 ) -> Option < [ u8 ; 32 ] > {
2662
2738
self . commitment_secrets . get_secret ( idx)
0 commit comments