9
9
10
10
//! Utitilies for bumping transactions originating from [`super::Event`]s.
11
11
12
+ use alloc:: collections:: BTreeMap ;
12
13
use core:: convert:: TryInto ;
13
14
use core:: ops:: Deref ;
14
15
@@ -48,49 +49,57 @@ const fn fee_for_weight(feerate_sat_per_1000_weight: u32, weight: u64) -> u64 {
48
49
( ( feerate_sat_per_1000_weight as u64 * weight) + 1000 - 1 ) / 1000
49
50
}
50
51
52
+ /// The parameters required to derive a channel signer via [`SignerProvider`].
53
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
54
+ pub struct ChannelDerivationParameters {
55
+ /// The value in satoshis of the channel we're attempting to spend the anchor output of.
56
+ pub value_satoshis : u64 ,
57
+ /// The unique identifier to re-derive the signer for the associated channel.
58
+ pub keys_id : [ u8 ; 32 ] ,
59
+ /// The necessary channel parameters that need to be provided to the re-derived signer through
60
+ /// [`ChannelSigner::provide_channel_parameters`].
61
+ ///
62
+ /// [`ChannelSigner::provide_channel_parameters`]: crate::sign::ChannelSigner::provide_channel_parameters
63
+ pub transaction_parameters : ChannelTransactionParameters ,
64
+ }
65
+
51
66
/// A descriptor used to sign for a commitment transaction's anchor output.
52
67
#[ derive( Clone , Debug , PartialEq , Eq ) ]
53
68
pub struct AnchorDescriptor {
54
- /// A unique identifier used along with `channel_value_satoshis` to re-derive the
55
- /// [`InMemorySigner`] required to sign `input`.
56
- ///
57
- /// [`InMemorySigner`]: crate::sign::InMemorySigner
58
- pub channel_keys_id : [ u8 ; 32 ] ,
59
- /// The value in satoshis of the channel we're attempting to spend the anchor output of. This is
60
- /// used along with `channel_keys_id` to re-derive the [`InMemorySigner`] required to sign
61
- /// `input`.
62
- ///
63
- /// [`InMemorySigner`]: crate::sign::InMemorySigner
64
- pub channel_value_satoshis : u64 ,
69
+ /// The parameters required to derive the signer for the anchor input.
70
+ pub channel_derivation_parameters : ChannelDerivationParameters ,
65
71
/// The transaction input's outpoint corresponding to the commitment transaction's anchor
66
72
/// output.
67
73
pub outpoint : OutPoint ,
68
74
}
69
75
76
+ impl AnchorDescriptor {
77
+ /// Derives the channel signer required to sign the anchor input.
78
+ pub fn derive_channel_signer < SP : Deref > ( & self , signer_provider : & SP ) -> <SP :: Target as SignerProvider >:: Signer
79
+ where
80
+ SP :: Target : SignerProvider
81
+ {
82
+ let mut signer = signer_provider. derive_channel_signer (
83
+ self . channel_derivation_parameters . value_satoshis ,
84
+ self . channel_derivation_parameters . keys_id ,
85
+ ) ;
86
+ signer. provide_channel_parameters ( & self . channel_derivation_parameters . transaction_parameters ) ;
87
+ signer
88
+ }
89
+ }
90
+
70
91
/// A descriptor used to sign for a commitment transaction's HTLC output.
71
92
#[ derive( Clone , Debug , PartialEq , Eq ) ]
72
93
pub struct HTLCDescriptor {
73
- /// A unique identifier used along with `channel_value_satoshis` to re-derive the
74
- /// [`InMemorySigner`] required to sign `input`.
75
- ///
76
- /// [`InMemorySigner`]: crate::sign::InMemorySigner
77
- pub channel_keys_id : [ u8 ; 32 ] ,
78
- /// The value in satoshis of the channel we're attempting to spend the anchor output of. This is
79
- /// used along with `channel_keys_id` to re-derive the [`InMemorySigner`] required to sign
80
- /// `input`.
81
- ///
82
- /// [`InMemorySigner`]: crate::sign::InMemorySigner
83
- pub channel_value_satoshis : u64 ,
84
- /// The necessary channel parameters that need to be provided to the re-derived
85
- /// [`InMemorySigner`] through [`ChannelSigner::provide_channel_parameters`].
86
- ///
87
- /// [`InMemorySigner`]: crate::sign::InMemorySigner
88
- /// [`ChannelSigner::provide_channel_parameters`]: crate::sign::ChannelSigner::provide_channel_parameters
89
- pub channel_parameters : ChannelTransactionParameters ,
94
+ /// The parameters required to derive the signer for the HTLC input.
95
+ pub channel_derivation_parameters : ChannelDerivationParameters ,
90
96
/// The txid of the commitment transaction in which the HTLC output lives.
91
97
pub commitment_txid : Txid ,
92
98
/// The number of the commitment transaction in which the HTLC output lives.
93
99
pub per_commitment_number : u64 ,
100
+ /// The public key corresponding to the number of the commitment transaction in which the HTLC
101
+ /// output lives.
102
+ pub per_commitment_point : PublicKey ,
94
103
/// The details of the HTLC as it appears in the commitment transaction.
95
104
pub htlc : HTLCOutputInCommitment ,
96
105
/// The preimage, if `Some`, to claim the HTLC output with. If `None`, the timeout path must be
@@ -109,17 +118,15 @@ impl HTLCDescriptor {
109
118
110
119
/// Returns the delayed output created as a result of spending the HTLC output in the commitment
111
120
/// transaction.
112
- pub fn tx_output < C : secp256k1:: Signing + secp256k1:: Verification > (
113
- & self , per_commitment_point : & PublicKey , secp : & Secp256k1 < C >
114
- ) -> TxOut {
115
- let channel_params = self . channel_parameters . as_holder_broadcastable ( ) ;
121
+ pub fn tx_output < C : secp256k1:: Signing + secp256k1:: Verification > ( & self , secp : & Secp256k1 < C > ) -> TxOut {
122
+ let channel_params = self . channel_derivation_parameters . transaction_parameters . as_holder_broadcastable ( ) ;
116
123
let broadcaster_keys = channel_params. broadcaster_pubkeys ( ) ;
117
124
let counterparty_keys = channel_params. countersignatory_pubkeys ( ) ;
118
125
let broadcaster_delayed_key = chan_utils:: derive_public_key (
119
- secp, per_commitment_point, & broadcaster_keys. delayed_payment_basepoint
126
+ secp, & self . per_commitment_point , & broadcaster_keys. delayed_payment_basepoint
120
127
) ;
121
128
let counterparty_revocation_key = chan_utils:: derive_public_revocation_key (
122
- secp, per_commitment_point, & counterparty_keys. revocation_basepoint
129
+ secp, & self . per_commitment_point , & counterparty_keys. revocation_basepoint
123
130
) ;
124
131
chan_utils:: build_htlc_output (
125
132
0 /* feerate_per_kw */ , channel_params. contest_delay ( ) , & self . htlc ,
@@ -128,20 +135,18 @@ impl HTLCDescriptor {
128
135
}
129
136
130
137
/// Returns the witness script of the HTLC output in the commitment transaction.
131
- pub fn witness_script < C : secp256k1:: Signing + secp256k1:: Verification > (
132
- & self , per_commitment_point : & PublicKey , secp : & Secp256k1 < C >
133
- ) -> Script {
134
- let channel_params = self . channel_parameters . as_holder_broadcastable ( ) ;
138
+ pub fn witness_script < C : secp256k1:: Signing + secp256k1:: Verification > ( & self , secp : & Secp256k1 < C > ) -> Script {
139
+ let channel_params = self . channel_derivation_parameters . transaction_parameters . as_holder_broadcastable ( ) ;
135
140
let broadcaster_keys = channel_params. broadcaster_pubkeys ( ) ;
136
141
let counterparty_keys = channel_params. countersignatory_pubkeys ( ) ;
137
142
let broadcaster_htlc_key = chan_utils:: derive_public_key (
138
- secp, per_commitment_point, & broadcaster_keys. htlc_basepoint
143
+ secp, & self . per_commitment_point , & broadcaster_keys. htlc_basepoint
139
144
) ;
140
145
let counterparty_htlc_key = chan_utils:: derive_public_key (
141
- secp, per_commitment_point, & counterparty_keys. htlc_basepoint
146
+ secp, & self . per_commitment_point , & counterparty_keys. htlc_basepoint
142
147
) ;
143
148
let counterparty_revocation_key = chan_utils:: derive_public_revocation_key (
144
- secp, per_commitment_point, & counterparty_keys. revocation_basepoint
149
+ secp, & self . per_commitment_point , & counterparty_keys. revocation_basepoint
145
150
) ;
146
151
chan_utils:: get_htlc_redeemscript_with_explicit_keys (
147
152
& self . htlc , & ChannelTypeFeatures :: anchors_zero_htlc_fee_and_dependencies ( ) , & broadcaster_htlc_key, & counterparty_htlc_key,
@@ -156,6 +161,19 @@ impl HTLCDescriptor {
156
161
signature, & self . counterparty_sig , & self . preimage , witness_script, & ChannelTypeFeatures :: anchors_zero_htlc_fee_and_dependencies ( ) /* opt_anchors */
157
162
)
158
163
}
164
+
165
+ /// Derives the channel signer required to sign the HTLC input.
166
+ pub fn derive_channel_signer < SP : Deref > ( & self , signer_provider : & SP ) -> <SP :: Target as SignerProvider >:: Signer
167
+ where
168
+ SP :: Target : SignerProvider
169
+ {
170
+ let mut signer = signer_provider. derive_channel_signer (
171
+ self . channel_derivation_parameters . value_satoshis ,
172
+ self . channel_derivation_parameters . keys_id ,
173
+ ) ;
174
+ signer. provide_channel_parameters ( & self . channel_derivation_parameters . transaction_parameters ) ;
175
+ signer
176
+ }
159
177
}
160
178
161
179
/// Represents the different types of transactions, originating from LDK, to be bumped.
@@ -662,9 +680,7 @@ where
662
680
debug_assert_eq ! ( anchor_tx. output. len( ) , 1 ) ;
663
681
664
682
self . utxo_source . sign_tx ( & mut anchor_tx) ?;
665
- let signer = self . signer_provider . derive_channel_signer (
666
- anchor_descriptor. channel_value_satoshis , anchor_descriptor. channel_keys_id ,
667
- ) ;
683
+ let signer = anchor_descriptor. derive_channel_signer ( & self . signer_provider ) ;
668
684
let anchor_sig = signer. sign_holder_anchor_input ( & anchor_tx, 0 , & self . secp ) ?;
669
685
anchor_tx. input [ 0 ] . witness =
670
686
chan_utils:: build_anchor_input_witness ( & signer. pubkeys ( ) . funding_pubkey , & anchor_sig) ;
@@ -678,7 +694,7 @@ where
678
694
fn build_htlc_tx (
679
695
& self , claim_id : ClaimId , target_feerate_sat_per_1000_weight : u32 ,
680
696
htlc_descriptors : & [ HTLCDescriptor ] , tx_lock_time : PackedLockTime ,
681
- ) -> Result < ( Transaction , HashMap < [ u8 ; 32 ] , < SP :: Target as SignerProvider > :: Signer > ) , ( ) > {
697
+ ) -> Result < Transaction , ( ) > {
682
698
let mut tx = Transaction {
683
699
version : 2 ,
684
700
lock_time : tx_lock_time,
@@ -687,19 +703,8 @@ where
687
703
} ;
688
704
// Unfortunately, we need to derive the signer for each HTLC ahead of time to obtain its
689
705
// input.
690
- let mut signers = HashMap :: new ( ) ;
691
706
let mut must_spend = Vec :: with_capacity ( htlc_descriptors. len ( ) ) ;
692
707
for htlc_descriptor in htlc_descriptors {
693
- let signer = signers. entry ( htlc_descriptor. channel_keys_id )
694
- . or_insert_with ( ||
695
- self . signer_provider . derive_channel_signer (
696
- htlc_descriptor. channel_value_satoshis , htlc_descriptor. channel_keys_id ,
697
- )
698
- ) ;
699
- let per_commitment_point = signer. get_per_commitment_point (
700
- htlc_descriptor. per_commitment_number , & self . secp
701
- ) ;
702
-
703
708
let htlc_input = htlc_descriptor. unsigned_tx_input ( ) ;
704
709
must_spend. push ( Input {
705
710
outpoint : htlc_input. previous_output . clone ( ) ,
@@ -710,15 +715,15 @@ where
710
715
} ,
711
716
} ) ;
712
717
tx. input . push ( htlc_input) ;
713
- let htlc_output = htlc_descriptor. tx_output ( & per_commitment_point , & self . secp ) ;
718
+ let htlc_output = htlc_descriptor. tx_output ( & self . secp ) ;
714
719
tx. output . push ( htlc_output) ;
715
720
}
716
721
717
722
let coin_selection = self . utxo_source . select_confirmed_utxos (
718
723
claim_id, & must_spend, & tx. output , target_feerate_sat_per_1000_weight,
719
724
) ?;
720
725
self . process_coin_selection ( & mut tx, coin_selection) ;
721
- Ok ( ( tx , signers ) )
726
+ Ok ( tx )
722
727
}
723
728
724
729
/// Handles a [`BumpTransactionEvent::HTLCResolution`] event variant by producing a
@@ -727,20 +732,22 @@ where
727
732
& self , claim_id : ClaimId , target_feerate_sat_per_1000_weight : u32 ,
728
733
htlc_descriptors : & [ HTLCDescriptor ] , tx_lock_time : PackedLockTime ,
729
734
) -> Result < ( ) , ( ) > {
730
- let ( mut htlc_tx, signers ) = self . build_htlc_tx (
735
+ let mut htlc_tx = self . build_htlc_tx (
731
736
claim_id, target_feerate_sat_per_1000_weight, htlc_descriptors, tx_lock_time,
732
737
) ?;
733
738
734
739
self . utxo_source . sign_tx ( & mut htlc_tx) ?;
740
+ let mut signers = BTreeMap :: new ( ) ;
735
741
for ( idx, htlc_descriptor) in htlc_descriptors. iter ( ) . enumerate ( ) {
736
- let signer = signers. get ( & htlc_descriptor. channel_keys_id ) . unwrap ( ) ;
737
- let htlc_sig = signer. sign_holder_htlc_transaction (
738
- & htlc_tx, idx, htlc_descriptor, & self . secp
739
- ) ?;
740
- let per_commitment_point = signer. get_per_commitment_point (
741
- htlc_descriptor. per_commitment_number , & self . secp
742
- ) ;
743
- let witness_script = htlc_descriptor. witness_script ( & per_commitment_point, & self . secp ) ;
742
+ let signer = if let Some ( signer) = signers. get ( & htlc_descriptor. channel_derivation_parameters . keys_id ) {
743
+ signer
744
+ } else {
745
+ let signer = htlc_descriptor. derive_channel_signer ( & self . signer_provider ) ;
746
+ signers. insert ( htlc_descriptor. channel_derivation_parameters . keys_id , signer) ;
747
+ signers. get ( & htlc_descriptor. channel_derivation_parameters . keys_id ) . expect ( "Signer was just added" )
748
+ } ;
749
+ let htlc_sig = signer. sign_holder_htlc_transaction ( & htlc_tx, idx, htlc_descriptor, & self . secp ) ?;
750
+ let witness_script = htlc_descriptor. witness_script ( & self . secp ) ;
744
751
htlc_tx. input [ idx] . witness = htlc_descriptor. tx_input_witness ( & htlc_sig, & witness_script) ;
745
752
}
746
753
0 commit comments