@@ -15,7 +15,8 @@ use secp256k1;
15
15
16
16
use ln:: msgs:: DecodeError ;
17
17
use ln:: channelmonitor:: { ANTI_REORG_DELAY , CLTV_SHARED_CLAIM_BUFFER , InputMaterial , ClaimRequest } ;
18
- use ln:: chan_utils:: { HTLCType , LocalCommitmentTransaction } ;
18
+ use ln:: chan_utils;
19
+ use ln:: chan_utils:: { HTLCType , LocalCommitmentTransaction , TxCreationKeys } ;
19
20
use chain:: chaininterface:: { FeeEstimator , BroadcasterInterface , ConfirmationTarget , MIN_RELAY_FEE_SAT_PER_1000_WEIGHT } ;
20
21
use chain:: keysinterface:: ChannelKeys ;
21
22
use util:: logger:: Logger ;
@@ -47,6 +48,14 @@ enum OnchainEvent {
47
48
}
48
49
}
49
50
51
+ /// Cache public keys and feerate used to compute any HTLC transaction.
52
+ /// We only keep state for latest 2 commitment transactions as we should
53
+ /// never have to generate HTLC txn for revoked local commitment
54
+ struct HTLCTxCache {
55
+ local_keys : TxCreationKeys ,
56
+ feerate_per_kw : u64 ,
57
+ }
58
+
50
59
/// Higher-level cache structure needed to re-generate bumped claim txn if needed
51
60
#[ derive( Clone , PartialEq ) ]
52
61
pub struct ClaimTxBumpMaterial {
@@ -144,6 +153,8 @@ pub struct OnchainTxHandler<ChanSigner: ChannelKeys> {
144
153
funding_redeemscript : Script ,
145
154
local_commitment : Option < LocalCommitmentTransaction > ,
146
155
prev_local_commitment : Option < LocalCommitmentTransaction > ,
156
+ current_htlc_cache : Option < HTLCTxCache > ,
157
+ prev_htlc_cache : Option < HTLCTxCache > ,
147
158
148
159
key_storage : ChanSigner ,
149
160
@@ -187,6 +198,27 @@ impl<ChanSigner: ChannelKeys + Writeable> OnchainTxHandler<ChanSigner> {
187
198
self . local_commitment . write ( writer) ?;
188
199
self . prev_local_commitment . write ( writer) ?;
189
200
201
+ macro_rules! serialize_htlc_cache {
202
+ ( $cache: expr) => {
203
+ $cache. local_keys. write( writer) ?;
204
+ $cache. feerate_per_kw. write( writer) ?;
205
+ }
206
+ }
207
+
208
+ if let Some ( ref current) = self . current_htlc_cache {
209
+ writer. write_all ( & [ 1 ; 1 ] ) ?;
210
+ serialize_htlc_cache ! ( current) ;
211
+ } else {
212
+ writer. write_all ( & [ 0 ; 1 ] ) ?;
213
+ }
214
+
215
+ if let Some ( ref prev) = self . prev_htlc_cache {
216
+ writer. write_all ( & [ 1 ; 1 ] ) ?;
217
+ serialize_htlc_cache ! ( prev) ;
218
+ } else {
219
+ writer. write_all ( & [ 0 ; 1 ] ) ?;
220
+ }
221
+
190
222
self . key_storage . write ( writer) ?;
191
223
192
224
writer. write_all ( & byte_utils:: be64_to_array ( self . pending_claim_requests . len ( ) as u64 ) ) ?;
@@ -231,6 +263,35 @@ impl<ChanSigner: ChannelKeys + Readable> ReadableArgs<Arc<Logger>> for OnchainTx
231
263
let local_commitment = Readable :: read ( reader) ?;
232
264
let prev_local_commitment = Readable :: read ( reader) ?;
233
265
266
+ macro_rules! read_htlc_cache {
267
+ ( ) => {
268
+ {
269
+ let local_keys = Readable :: read( reader) ?;
270
+ let feerate_per_kw = Readable :: read( reader) ?;
271
+ HTLCTxCache {
272
+ local_keys,
273
+ feerate_per_kw,
274
+ }
275
+ }
276
+ }
277
+ }
278
+
279
+ let current_htlc_cache = match <u8 as Readable >:: read ( reader) ? {
280
+ 0 => None ,
281
+ 1 => {
282
+ Some ( read_htlc_cache ! ( ) )
283
+ }
284
+ _ => return Err ( DecodeError :: InvalidValue ) ,
285
+ } ;
286
+
287
+ let prev_htlc_cache = match <u8 as Readable >:: read ( reader) ? {
288
+ 0 => None ,
289
+ 1 => {
290
+ Some ( read_htlc_cache ! ( ) )
291
+ }
292
+ _ => return Err ( DecodeError :: InvalidValue ) ,
293
+ } ;
294
+
234
295
let key_storage = Readable :: read ( reader) ?;
235
296
236
297
let pending_claim_requests_len: u64 = Readable :: read ( reader) ?;
@@ -281,6 +342,8 @@ impl<ChanSigner: ChannelKeys + Readable> ReadableArgs<Arc<Logger>> for OnchainTx
281
342
funding_redeemscript,
282
343
local_commitment,
283
344
prev_local_commitment,
345
+ current_htlc_cache,
346
+ prev_htlc_cache,
284
347
key_storage,
285
348
claimable_outpoints,
286
349
pending_claim_requests,
@@ -301,6 +364,8 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
301
364
funding_redeemscript,
302
365
local_commitment : None ,
303
366
prev_local_commitment : None ,
367
+ current_htlc_cache : None ,
368
+ prev_htlc_cache : None ,
304
369
key_storage,
305
370
pending_claim_requests : HashMap :: new ( ) ,
306
371
claimable_outpoints : HashMap :: new ( ) ,
@@ -756,7 +821,7 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
756
821
}
757
822
}
758
823
759
- pub ( super ) fn provide_latest_local_tx ( & mut self , tx : LocalCommitmentTransaction ) -> Result < ( ) , ( ) > {
824
+ pub ( super ) fn provide_latest_local_tx ( & mut self , tx : LocalCommitmentTransaction , local_keys : chan_utils :: TxCreationKeys , feerate_per_kw : u64 ) -> Result < ( ) , ( ) > {
760
825
// To prevent any unsafe state discrepancy between offchain and onchain, once local
761
826
// commitment transaction has been signed due to an event (either block height for
762
827
// HTLC-timeout or channel force-closure), don't allow any further update of local
@@ -767,6 +832,11 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
767
832
}
768
833
self . prev_local_commitment = self . local_commitment . take ( ) ;
769
834
self . local_commitment = Some ( tx) ;
835
+ self . prev_htlc_cache = self . current_htlc_cache . take ( ) ;
836
+ self . current_htlc_cache = Some ( HTLCTxCache {
837
+ local_keys,
838
+ feerate_per_kw,
839
+ } ) ;
770
840
Ok ( ( ) )
771
841
}
772
842
0 commit comments