Skip to content

Commit 5c975f7

Browse files
authored
Merge pull request #3322 from TheBlueMatt/2024-06-mpp-claim-without-man
Stop relying on ChannelMonitor persistence after manager read
2 parents 206ab82 + ba26432 commit 5c975f7

14 files changed

+578
-221
lines changed

ci/check-lint.sh

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
set -e
33
set -x
44
RUSTFLAGS='-D warnings' cargo clippy -- \
5+
`# Things where clippy is just wrong` \
6+
-A clippy::unwrap-or-default \
57
`# Errors` \
68
-A clippy::erasing_op \
79
-A clippy::never_loop \

fuzz/src/chanmon_consistency.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
768768
chain_monitor.latest_monitors.lock().unwrap().insert(outpoint, prev_state);
769769
}
770770
let mut monitor_refs = new_hash_map();
771-
for (outpoint, monitor) in monitors.iter_mut() {
771+
for (outpoint, monitor) in monitors.iter() {
772772
monitor_refs.insert(*outpoint, monitor);
773773
}
774774

lightning/src/chain/channelmonitor.rs

+81-20
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use crate::types::payment::{PaymentHash, PaymentPreimage};
3838
use crate::ln::msgs::DecodeError;
3939
use crate::ln::channel_keys::{DelayedPaymentKey, DelayedPaymentBasepoint, HtlcBasepoint, HtlcKey, RevocationKey, RevocationBasepoint};
4040
use crate::ln::chan_utils::{self,CommitmentTransaction, CounterpartyCommitmentSecrets, HTLCOutputInCommitment, HTLCClaim, ChannelTransactionParameters, HolderCommitmentTransaction, TxCreationKeys};
41-
use crate::ln::channelmanager::{HTLCSource, SentHTLCId};
41+
use crate::ln::channelmanager::{HTLCSource, SentHTLCId, PaymentClaimDetails};
4242
use crate::chain;
4343
use crate::chain::{BestBlock, WatchedOutput};
4444
use crate::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator, LowerBoundedFeeEstimator};
@@ -546,6 +546,9 @@ pub(crate) enum ChannelMonitorUpdateStep {
546546
},
547547
PaymentPreimage {
548548
payment_preimage: PaymentPreimage,
549+
/// If this preimage was from an inbound payment claim, information about the claim should
550+
/// be included here to enable claim replay on startup.
551+
payment_info: Option<PaymentClaimDetails>,
549552
},
550553
CommitmentSecret {
551554
idx: u64,
@@ -594,6 +597,7 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
594597
},
595598
(2, PaymentPreimage) => {
596599
(0, payment_preimage, required),
600+
(1, payment_info, option),
597601
},
598602
(3, CommitmentSecret) => {
599603
(0, idx, required),
@@ -919,8 +923,16 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
919923
/// The set of payment hashes from inbound payments for which we know the preimage. Payment
920924
/// preimages that are not included in any unrevoked local commitment transaction or unrevoked
921925
/// remote commitment transactions are automatically removed when commitment transactions are
922-
/// revoked.
923-
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>)>,
924936

925937
// Note that `MonitorEvent`s MUST NOT be generated during update processing, only generated
926938
// during chain data processing. This prevents a race in `ChainMonitor::update_channel` (and
@@ -1146,7 +1158,7 @@ impl<Signer: EcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
11461158
writer.write_all(&byte_utils::be48_to_array(self.current_holder_commitment_number))?;
11471159

11481160
writer.write_all(&(self.payment_preimages.len() as u64).to_be_bytes())?;
1149-
for payment_preimage in self.payment_preimages.values() {
1161+
for (payment_preimage, _) in self.payment_preimages.values() {
11501162
writer.write_all(&payment_preimage.0[..])?;
11511163
}
11521164

@@ -1224,6 +1236,7 @@ impl<Signer: EcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
12241236
(19, self.channel_id, required),
12251237
(21, self.balances_empty_height, option),
12261238
(23, self.holder_pays_commitment_tx_fee, option),
1239+
(25, self.payment_preimages, required),
12271240
});
12281241

12291242
Ok(())
@@ -1488,7 +1501,15 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
14881501

14891502
/// This is used to provide payment preimage(s) out-of-band during startup without updating the
14901503
/// off-chain state with a new commitment transaction.
1491-
pub(crate) fn provide_payment_preimage<B: Deref, F: Deref, L: Deref>(
1504+
///
1505+
/// It is used only for legacy (created prior to LDK 0.1) pending payments on upgrade, and the
1506+
/// flow that uses it assumes that this [`ChannelMonitor`] is persisted prior to the
1507+
/// [`ChannelManager`] being persisted (as the state necessary to call this method again is
1508+
/// removed from the [`ChannelManager`] and thus a persistence inversion would imply we do not
1509+
/// get the preimage back into this [`ChannelMonitor`] on startup).
1510+
///
1511+
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
1512+
pub(crate) fn provide_payment_preimage_unsafe_legacy<B: Deref, F: Deref, L: Deref>(
14921513
&self,
14931514
payment_hash: &PaymentHash,
14941515
payment_preimage: &PaymentPreimage,
@@ -1502,8 +1523,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
15021523
{
15031524
let mut inner = self.inner.lock().unwrap();
15041525
let logger = WithChannelMonitor::from_impl(logger, &*inner, Some(*payment_hash));
1526+
// Note that we don't pass any MPP claim parts here. This is generally not okay but in this
1527+
// case is acceptable as we only call this method from `ChannelManager` deserialization in
1528+
// cases where we are replaying a claim started on a previous version of LDK.
15051529
inner.provide_payment_preimage(
1506-
payment_hash, payment_preimage, broadcaster, fee_estimator, &logger)
1530+
payment_hash, payment_preimage, &None, broadcaster, fee_estimator, &logger)
15071531
}
15081532

15091533
/// Updates a ChannelMonitor on the basis of some new information provided by the Channel
@@ -2194,7 +2218,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
21942218
outbound_payment,
21952219
});
21962220
}
2197-
} else if let Some(payment_preimage) = self.payment_preimages.get(&htlc.payment_hash) {
2221+
} else if let Some((payment_preimage, _)) = self.payment_preimages.get(&htlc.payment_hash) {
21982222
// Otherwise (the payment was inbound), only expose it as claimable if
21992223
// we know the preimage.
22002224
// Note that if there is a pending claim, but it did not use the
@@ -2415,7 +2439,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
24152439
outbound_payment,
24162440
});
24172441
}
2418-
} else if us.payment_preimages.get(&htlc.payment_hash).is_some() {
2442+
} else if us.payment_preimages.contains_key(&htlc.payment_hash) {
24192443
inbound_claiming_htlc_rounded_msat += rounded_value_msat;
24202444
if htlc.transaction_output_index.is_some() {
24212445
claimable_inbound_htlc_value_sat += htlc.amount_msat / 1000;
@@ -2570,7 +2594,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
25702594
res
25712595
}
25722596

2573-
pub(crate) fn get_stored_preimages(&self) -> HashMap<PaymentHash, PaymentPreimage> {
2597+
pub(crate) fn get_stored_preimages(&self) -> HashMap<PaymentHash, (PaymentPreimage, Vec<PaymentClaimDetails>)> {
25742598
self.inner.lock().unwrap().payment_preimages.clone()
25752599
}
25762600
}
@@ -2929,14 +2953,27 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
29292953

29302954
/// Provides a payment_hash->payment_preimage mapping. Will be automatically pruned when all
29312955
/// commitment_tx_infos which contain the payment hash have been revoked.
2956+
///
2957+
/// Note that this is often called multiple times for the same payment and must be idempotent.
29322958
fn provide_payment_preimage<B: Deref, F: Deref, L: Deref>(
2933-
&mut self, payment_hash: &PaymentHash, payment_preimage: &PaymentPreimage, broadcaster: &B,
2959+
&mut self, payment_hash: &PaymentHash, payment_preimage: &PaymentPreimage,
2960+
payment_info: &Option<PaymentClaimDetails>, broadcaster: &B,
29342961
fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &WithChannelMonitor<L>)
29352962
where B::Target: BroadcasterInterface,
29362963
F::Target: FeeEstimator,
29372964
L::Target: Logger,
29382965
{
2939-
self.payment_preimages.insert(payment_hash.clone(), payment_preimage.clone());
2966+
self.payment_preimages.entry(payment_hash.clone())
2967+
.and_modify(|(_, payment_infos)| {
2968+
if let Some(payment_info) = payment_info {
2969+
if !payment_infos.contains(&payment_info) {
2970+
payment_infos.push(payment_info.clone());
2971+
}
2972+
}
2973+
})
2974+
.or_insert_with(|| {
2975+
(payment_preimage.clone(), payment_info.clone().into_iter().collect())
2976+
});
29402977

29412978
let confirmed_spend_txid = self.funding_spend_confirmed.or_else(|| {
29422979
self.onchain_events_awaiting_threshold_conf.iter().find_map(|event| match event.event {
@@ -3139,9 +3176,9 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
31393176
log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info");
31403177
self.provide_latest_counterparty_commitment_tx(*commitment_txid, htlc_outputs.clone(), *commitment_number, *their_per_commitment_point, logger)
31413178
},
3142-
ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } => {
3179+
ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage, payment_info } => {
31433180
log_trace!(logger, "Updating ChannelMonitor with payment preimage");
3144-
self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).to_byte_array()), &payment_preimage, broadcaster, &bounded_fee_estimator, logger)
3181+
self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).to_byte_array()), &payment_preimage, payment_info, broadcaster, &bounded_fee_estimator, logger)
31453182
},
31463183
ChannelMonitorUpdateStep::CommitmentSecret { idx, secret } => {
31473184
log_trace!(logger, "Updating ChannelMonitor with commitment secret");
@@ -3593,7 +3630,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
35933630
return (claimable_outpoints, to_counterparty_output_info);
35943631
}
35953632
}
3596-
let preimage = if htlc.offered { if let Some(p) = self.payment_preimages.get(&htlc.payment_hash) { Some(*p) } else { None } } else { None };
3633+
let preimage = if htlc.offered { if let Some((p, _)) = self.payment_preimages.get(&htlc.payment_hash) { Some(*p) } else { None } } else { None };
35973634
if preimage.is_some() || !htlc.offered {
35983635
let counterparty_htlc_outp = if htlc.offered {
35993636
PackageSolvingData::CounterpartyOfferedHTLCOutput(
@@ -3681,7 +3718,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
36813718
);
36823719
(htlc_output, conf_height)
36833720
} else {
3684-
let payment_preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) {
3721+
let payment_preimage = if let Some((preimage, _)) = self.payment_preimages.get(&htlc.payment_hash) {
36853722
preimage.clone()
36863723
} else {
36873724
// We can't build an HTLC-Success transaction without the preimage
@@ -3835,7 +3872,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
38353872
for htlc in self.current_holder_commitment_tx.htlc_outputs.iter() {
38363873
if let Some(vout) = htlc.0.transaction_output_index {
38373874
let preimage = if !htlc.0.offered {
3838-
if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(preimage.clone()) } else {
3875+
if let Some((preimage, _)) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(preimage.clone()) } else {
38393876
// We can't build an HTLC-Success transaction without the preimage
38403877
continue;
38413878
}
@@ -4808,7 +4845,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
48084845
for _ in 0..payment_preimages_len {
48094846
let preimage: PaymentPreimage = Readable::read(reader)?;
48104847
let hash = PaymentHash(Sha256::hash(&preimage.0[..]).to_byte_array());
4811-
if let Some(_) = payment_preimages.insert(hash, preimage) {
4848+
if let Some(_) = payment_preimages.insert(hash, (preimage, Vec::new())) {
48124849
return Err(DecodeError::InvalidValue);
48134850
}
48144851
}
@@ -4891,6 +4928,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
48914928
let mut balances_empty_height = None;
48924929
let mut channel_id = None;
48934930
let mut holder_pays_commitment_tx_fee = None;
4931+
let mut payment_preimages_with_info: Option<HashMap<_, _>> = None;
48944932
read_tlv_fields!(reader, {
48954933
(1, funding_spend_confirmed, option),
48964934
(3, htlcs_resolved_on_chain, optional_vec),
@@ -4904,7 +4942,24 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
49044942
(19, channel_id, option),
49054943
(21, balances_empty_height, option),
49064944
(23, holder_pays_commitment_tx_fee, option),
4945+
(25, payment_preimages_with_info, option),
49074946
});
4947+
if let Some(payment_preimages_with_info) = payment_preimages_with_info {
4948+
if payment_preimages_with_info.len() != payment_preimages.len() {
4949+
return Err(DecodeError::InvalidValue);
4950+
}
4951+
for (payment_hash, (payment_preimage, _)) in payment_preimages.iter() {
4952+
// Note that because `payment_preimages` is built back from preimages directly,
4953+
// checking that the two maps have the same hash -> preimage pairs also checks that
4954+
// the payment hashes in `payment_preimages_with_info`'s preimages match its
4955+
// hashes.
4956+
let new_preimage = payment_preimages_with_info.get(payment_hash).map(|(p, _)| p);
4957+
if new_preimage != Some(payment_preimage) {
4958+
return Err(DecodeError::InvalidValue);
4959+
}
4960+
}
4961+
payment_preimages = payment_preimages_with_info;
4962+
}
49084963

49094964
// `HolderForceClosedWithInfo` replaced `HolderForceClosed` in v0.0.122. If we have both
49104965
// events, we can remove the `HolderForceClosed` event and just keep the `HolderForceClosedWithInfo`.
@@ -5097,8 +5152,12 @@ mod tests {
50975152
assert_eq!(replay_update.updates.len(), 1);
50985153
if let ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. } = replay_update.updates[0] {
50995154
} else { panic!(); }
5100-
replay_update.updates.push(ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage: payment_preimage_1 });
5101-
replay_update.updates.push(ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage: payment_preimage_2 });
5155+
replay_update.updates.push(ChannelMonitorUpdateStep::PaymentPreimage {
5156+
payment_preimage: payment_preimage_1, payment_info: None,
5157+
});
5158+
replay_update.updates.push(ChannelMonitorUpdateStep::PaymentPreimage {
5159+
payment_preimage: payment_preimage_2, payment_info: None,
5160+
});
51025161

51035162
let broadcaster = TestBroadcaster::with_blocks(Arc::clone(&nodes[1].blocks));
51045163
assert!(
@@ -5228,7 +5287,9 @@ mod tests {
52285287
preimages_slice_to_htlc_outputs!(preimages[15..20]), 281474976710654, dummy_key, &logger);
52295288
for &(ref preimage, ref hash) in preimages.iter() {
52305289
let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&fee_estimator);
5231-
monitor.provide_payment_preimage(hash, preimage, &broadcaster, &bounded_fee_estimator, &logger);
5290+
monitor.provide_payment_preimage_unsafe_legacy(
5291+
hash, preimage, &broadcaster, &bounded_fee_estimator, &logger
5292+
);
52325293
}
52335294

52345295
// Now provide a secret, pruning preimages 10-15

0 commit comments

Comments
 (0)