@@ -923,8 +923,16 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
923
923
/// The set of payment hashes from inbound payments for which we know the preimage. Payment
924
924
/// preimages that are not included in any unrevoked local commitment transaction or unrevoked
925
925
/// remote commitment transactions are automatically removed when commitment transactions are
926
- /// revoked.
927
- payment_preimages : HashMap < PaymentHash , PaymentPreimage > ,
926
+ /// revoked. Note that this happens one revocation after it theoretically could, leaving
927
+ /// preimages present here for the previous state even when the channel is "at rest". This is a
928
+ /// good safety buffer, but also is important as it ensures we retain payment preimages for the
929
+ /// previous local commitment transaction, which may have been broadcast already when we see
930
+ /// the revocation (in setups with redundant monitors).
931
+ ///
932
+ /// We also store [`PaymentClaimDetails`] here, tracking the payment information(s) for this
933
+ /// preimage for inbound payments. This allows us to rebuild the inbound payment information on
934
+ /// startup even if we lost our `ChannelManager`.
935
+ payment_preimages : HashMap < PaymentHash , ( PaymentPreimage , Vec < PaymentClaimDetails > ) > ,
928
936
929
937
// Note that `MonitorEvent`s MUST NOT be generated during update processing, only generated
930
938
// during chain data processing. This prevents a race in `ChainMonitor::update_channel` (and
@@ -1150,7 +1158,7 @@ impl<Signer: EcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
1150
1158
writer. write_all ( & byte_utils:: be48_to_array ( self . current_holder_commitment_number ) ) ?;
1151
1159
1152
1160
writer. write_all ( & ( self . payment_preimages . len ( ) as u64 ) . to_be_bytes ( ) ) ?;
1153
- for payment_preimage in self . payment_preimages . values ( ) {
1161
+ for ( payment_preimage, _ ) in self . payment_preimages . values ( ) {
1154
1162
writer. write_all ( & payment_preimage. 0 [ ..] ) ?;
1155
1163
}
1156
1164
@@ -1228,6 +1236,7 @@ impl<Signer: EcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
1228
1236
( 19 , self . channel_id, required) ,
1229
1237
( 21 , self . balances_empty_height, option) ,
1230
1238
( 23 , self . holder_pays_commitment_tx_fee, option) ,
1239
+ ( 25 , self . payment_preimages, required) ,
1231
1240
} ) ;
1232
1241
1233
1242
Ok ( ( ) )
@@ -2201,7 +2210,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
2201
2210
outbound_payment,
2202
2211
} ) ;
2203
2212
}
2204
- } else if let Some ( payment_preimage) = self . payment_preimages . get ( & htlc. payment_hash ) {
2213
+ } else if let Some ( ( payment_preimage, _ ) ) = self . payment_preimages . get ( & htlc. payment_hash ) {
2205
2214
// Otherwise (the payment was inbound), only expose it as claimable if
2206
2215
// we know the preimage.
2207
2216
// Note that if there is a pending claim, but it did not use the
@@ -2422,7 +2431,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
2422
2431
outbound_payment,
2423
2432
} ) ;
2424
2433
}
2425
- } else if us. payment_preimages . get ( & htlc. payment_hash ) . is_some ( ) {
2434
+ } else if us. payment_preimages . contains_key ( & htlc. payment_hash ) {
2426
2435
inbound_claiming_htlc_rounded_msat += rounded_value_msat;
2427
2436
if htlc. transaction_output_index . is_some ( ) {
2428
2437
claimable_inbound_htlc_value_sat += htlc. amount_msat / 1000 ;
@@ -2577,7 +2586,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
2577
2586
res
2578
2587
}
2579
2588
2580
- pub ( crate ) fn get_stored_preimages ( & self ) -> HashMap < PaymentHash , PaymentPreimage > {
2589
+ pub ( crate ) fn get_stored_preimages ( & self ) -> HashMap < PaymentHash , ( PaymentPreimage , Vec < PaymentClaimDetails > ) > {
2581
2590
self . inner . lock ( ) . unwrap ( ) . payment_preimages . clone ( )
2582
2591
}
2583
2592
}
@@ -2936,6 +2945,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
2936
2945
2937
2946
/// Provides a payment_hash->payment_preimage mapping. Will be automatically pruned when all
2938
2947
/// commitment_tx_infos which contain the payment hash have been revoked.
2948
+ ///
2949
+ /// Note that this is often called multiple times for the same payment and must be idempotent.
2939
2950
fn provide_payment_preimage < B : Deref , F : Deref , L : Deref > (
2940
2951
& mut self , payment_hash : & PaymentHash , payment_preimage : & PaymentPreimage ,
2941
2952
payment_info : & Option < PaymentClaimDetails > , broadcaster : & B ,
@@ -2944,8 +2955,17 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
2944
2955
F :: Target : FeeEstimator ,
2945
2956
L :: Target : Logger ,
2946
2957
{
2947
- // TODO: Store payment_info (but do not override any existing values)
2948
- self . payment_preimages . insert ( payment_hash. clone ( ) , payment_preimage. clone ( ) ) ;
2958
+ self . payment_preimages . entry ( payment_hash. clone ( ) )
2959
+ . and_modify ( |( _, payment_infos) | {
2960
+ if let Some ( payment_info) = payment_info {
2961
+ if !payment_infos. contains ( & payment_info) {
2962
+ payment_infos. push ( payment_info. clone ( ) ) ;
2963
+ }
2964
+ }
2965
+ } )
2966
+ . or_insert_with ( || {
2967
+ ( payment_preimage. clone ( ) , payment_info. clone ( ) . into_iter ( ) . collect ( ) )
2968
+ } ) ;
2949
2969
2950
2970
let confirmed_spend_txid = self . funding_spend_confirmed . or_else ( || {
2951
2971
self . onchain_events_awaiting_threshold_conf . iter ( ) . find_map ( |event| match event. event {
@@ -3602,7 +3622,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3602
3622
return ( claimable_outpoints, to_counterparty_output_info) ;
3603
3623
}
3604
3624
}
3605
- let preimage = if htlc. offered { if let Some ( p ) = self . payment_preimages . get ( & htlc. payment_hash ) { Some ( * p) } else { None } } else { None } ;
3625
+ let preimage = if htlc. offered { if let Some ( ( p , _ ) ) = self . payment_preimages . get ( & htlc. payment_hash ) { Some ( * p) } else { None } } else { None } ;
3606
3626
if preimage. is_some ( ) || !htlc. offered {
3607
3627
let counterparty_htlc_outp = if htlc. offered {
3608
3628
PackageSolvingData :: CounterpartyOfferedHTLCOutput (
@@ -3690,7 +3710,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3690
3710
) ;
3691
3711
( htlc_output, conf_height)
3692
3712
} else {
3693
- let payment_preimage = if let Some ( preimage) = self . payment_preimages . get ( & htlc. payment_hash ) {
3713
+ let payment_preimage = if let Some ( ( preimage, _ ) ) = self . payment_preimages . get ( & htlc. payment_hash ) {
3694
3714
preimage. clone ( )
3695
3715
} else {
3696
3716
// We can't build an HTLC-Success transaction without the preimage
@@ -3844,7 +3864,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3844
3864
for htlc in self . current_holder_commitment_tx . htlc_outputs . iter ( ) {
3845
3865
if let Some ( vout) = htlc. 0 . transaction_output_index {
3846
3866
let preimage = if !htlc. 0 . offered {
3847
- if let Some ( preimage) = self . payment_preimages . get ( & htlc. 0 . payment_hash ) { Some ( preimage. clone ( ) ) } else {
3867
+ if let Some ( ( preimage, _ ) ) = self . payment_preimages . get ( & htlc. 0 . payment_hash ) { Some ( preimage. clone ( ) ) } else {
3848
3868
// We can't build an HTLC-Success transaction without the preimage
3849
3869
continue ;
3850
3870
}
@@ -4817,7 +4837,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
4817
4837
for _ in 0 ..payment_preimages_len {
4818
4838
let preimage: PaymentPreimage = Readable :: read ( reader) ?;
4819
4839
let hash = PaymentHash ( Sha256 :: hash ( & preimage. 0 [ ..] ) . to_byte_array ( ) ) ;
4820
- if let Some ( _) = payment_preimages. insert ( hash, preimage) {
4840
+ if let Some ( _) = payment_preimages. insert ( hash, ( preimage, Vec :: new ( ) ) ) {
4821
4841
return Err ( DecodeError :: InvalidValue ) ;
4822
4842
}
4823
4843
}
@@ -4900,6 +4920,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
4900
4920
let mut balances_empty_height = None ;
4901
4921
let mut channel_id = None ;
4902
4922
let mut holder_pays_commitment_tx_fee = None ;
4923
+ let mut payment_preimages_with_info: Option < HashMap < _ , _ > > = None ;
4903
4924
read_tlv_fields ! ( reader, {
4904
4925
( 1 , funding_spend_confirmed, option) ,
4905
4926
( 3 , htlcs_resolved_on_chain, optional_vec) ,
@@ -4913,7 +4934,24 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
4913
4934
( 19 , channel_id, option) ,
4914
4935
( 21 , balances_empty_height, option) ,
4915
4936
( 23 , holder_pays_commitment_tx_fee, option) ,
4937
+ ( 25 , payment_preimages_with_info, option) ,
4916
4938
} ) ;
4939
+ if let Some ( payment_preimages_with_info) = payment_preimages_with_info {
4940
+ if payment_preimages_with_info. len ( ) != payment_preimages. len ( ) {
4941
+ return Err ( DecodeError :: InvalidValue ) ;
4942
+ }
4943
+ for ( payment_hash, ( payment_preimage, _) ) in payment_preimages. iter ( ) {
4944
+ // Note that because `payment_preimages` is built back from preimages directly,
4945
+ // checking that the two maps have the same hash -> preimage pairs also checks that
4946
+ // the payment hashes in `payment_preimages_with_info`'s preimages match its
4947
+ // hashes.
4948
+ let new_preimage = payment_preimages_with_info. get ( payment_hash) . map ( |( p, _) | p) ;
4949
+ if new_preimage != Some ( payment_preimage) {
4950
+ return Err ( DecodeError :: InvalidValue ) ;
4951
+ }
4952
+ }
4953
+ payment_preimages = payment_preimages_with_info;
4954
+ }
4917
4955
4918
4956
// `HolderForceClosedWithInfo` replaced `HolderForceClosed` in v0.0.122. If we have both
4919
4957
// events, we can remove the `HolderForceClosed` event and just keep the `HolderForceClosedWithInfo`.
0 commit comments