Skip to content

Commit 0e21ae5

Browse files
committed
Generate a PaymentForwarded event when a forwarded HTLC is claimed
It is useful for accounting and informational reasons for users to be informed when a payment has been successfully forwarded. Thus, when an HTLC which represents a forwarded leg is claimed, we generate a new `PaymentForwarded` event. This requires some additional plumbing to return HTLC values from `OnchainEvent`s. Further, when we have to go on-chain to claim the inbound side of the payment, we do not inform the user of the fee reward, as we cannot calculate it until we see what is confirmed on-chain. Substantial code structure rewrites by: Valentine Wallace <[email protected]>
1 parent f438778 commit 0e21ae5

11 files changed

+207
-68
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
# 0.0.100 - WIP
2+
3+
## Serialization Compatibility
4+
* HTLCs which were in the process of being claimed on-chain when a pre-0.0.100
5+
`ChannelMonitor` was serialized may generate `PaymentForwarded` events with
6+
spurious `fee_earned_msat` values. This only applies to payments which were
7+
unresolved at the time of the upgrade.
8+
* 0.0.100 clients with pending PaymentForwarded events at serialization-time
9+
will generate serialized `ChannelManager` objects which 0.0.99 and earlier
10+
clients cannot read. The likelihood of this can be reduced by ensuring you
11+
process all pending events immediately before serialization (as is done by
12+
the `lightning-background-processor` crate).
13+
14+
115
# 0.0.99 - 2021-07-09
216

317
## API Updates

fuzz/src/chanmon_consistency.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
805805
},
806806
events::Event::PaymentSent { .. } => {},
807807
events::Event::PaymentFailed { .. } => {},
808+
events::Event::PaymentForwarded { .. } if $node == 1 => {},
808809
events::Event::PendingHTLCsForwardable { .. } => {
809810
nodes[$node].process_pending_htlc_forwards();
810811
},

fuzz/src/full_stack.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -596,12 +596,10 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
596596
//TODO: enhance by fetching random amounts from fuzz input?
597597
payments_received.push(payment_hash);
598598
},
599-
Event::PaymentSent {..} => {},
600-
Event::PaymentFailed {..} => {},
601599
Event::PendingHTLCsForwardable {..} => {
602600
should_forward = true;
603601
},
604-
Event::SpendableOutputs {..} => {},
602+
_ => {},
605603
}
606604
}
607605
}

lightning/src/chain/channelmonitor.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,12 @@ pub enum MonitorEvent {
199199
pub struct HTLCUpdate {
200200
pub(crate) payment_hash: PaymentHash,
201201
pub(crate) payment_preimage: Option<PaymentPreimage>,
202-
pub(crate) source: HTLCSource
202+
pub(crate) source: HTLCSource,
203+
pub(crate) onchain_value_satoshis: Option<u64>,
203204
}
204205
impl_writeable_tlv_based!(HTLCUpdate, {
205206
(0, payment_hash, required),
207+
(1, onchain_value_satoshis, option),
206208
(2, source, required),
207209
(4, payment_preimage, option),
208210
});
@@ -385,6 +387,7 @@ enum OnchainEvent {
385387
HTLCUpdate {
386388
source: HTLCSource,
387389
payment_hash: PaymentHash,
390+
onchain_value_satoshis: Option<u64>,
388391
},
389392
MaturingOutput {
390393
descriptor: SpendableOutputDescriptor,
@@ -400,6 +403,7 @@ impl_writeable_tlv_based!(OnchainEventEntry, {
400403
impl_writeable_tlv_based_enum!(OnchainEvent,
401404
(0, HTLCUpdate) => {
402405
(0, source, required),
406+
(1, onchain_value_satoshis, option),
403407
(2, payment_hash, required),
404408
},
405409
(1, MaturingOutput) => {
@@ -1574,6 +1578,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
15741578
event: OnchainEvent::HTLCUpdate {
15751579
source: (**source).clone(),
15761580
payment_hash: htlc.payment_hash.clone(),
1581+
onchain_value_satoshis: Some(htlc.amount_msat / 1000),
15771582
},
15781583
};
15791584
log_info!(logger, "Failing HTLC with payment_hash {} from {} counterparty commitment tx due to broadcast of revoked counterparty commitment transaction, waiting for confirmation (at height {})", log_bytes!(htlc.payment_hash.0), $commitment_tx, entry.confirmation_threshold());
@@ -1641,6 +1646,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
16411646
event: OnchainEvent::HTLCUpdate {
16421647
source: (**source).clone(),
16431648
payment_hash: htlc.payment_hash.clone(),
1649+
onchain_value_satoshis: Some(htlc.amount_msat / 1000),
16441650
},
16451651
});
16461652
}
@@ -1825,6 +1831,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
18251831
height,
18261832
event: OnchainEvent::HTLCUpdate {
18271833
source: source.clone(), payment_hash: htlc.payment_hash,
1834+
onchain_value_satoshis: Some(htlc.amount_msat / 1000)
18281835
},
18291836
};
18301837
log_trace!(logger, "Failing HTLC with payment_hash {} from {} holder commitment tx due to broadcast of transaction, waiting confirmation (at height{})",
@@ -2087,7 +2094,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
20872094
// Produce actionable events from on-chain events having reached their threshold.
20882095
for entry in onchain_events_reaching_threshold_conf.drain(..) {
20892096
match entry.event {
2090-
OnchainEvent::HTLCUpdate { ref source, payment_hash } => {
2097+
OnchainEvent::HTLCUpdate { ref source, payment_hash, onchain_value_satoshis } => {
20912098
// Check for duplicate HTLC resolutions.
20922099
#[cfg(debug_assertions)]
20932100
{
@@ -2106,9 +2113,10 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
21062113

21072114
log_debug!(logger, "HTLC {} failure update has got enough confirmations to be passed upstream", log_bytes!(payment_hash.0));
21082115
self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate {
2109-
payment_hash: payment_hash,
2116+
payment_hash,
21102117
payment_preimage: None,
21112118
source: source.clone(),
2119+
onchain_value_satoshis,
21122120
}));
21132121
},
21142122
OnchainEvent::MaturingOutput { descriptor } => {
@@ -2325,7 +2333,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
23252333
if pending_htlc.payment_hash == $htlc_output.payment_hash && pending_htlc.amount_msat == $htlc_output.amount_msat {
23262334
if let &Some(ref source) = pending_source {
23272335
log_claim!("revoked counterparty commitment tx", false, pending_htlc, true);
2328-
payment_data = Some(((**source).clone(), $htlc_output.payment_hash));
2336+
payment_data = Some(((**source).clone(), $htlc_output.payment_hash, $htlc_output.amount_msat));
23292337
break;
23302338
}
23312339
}
@@ -2345,7 +2353,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
23452353
// transaction. This implies we either learned a preimage, the HTLC
23462354
// has timed out, or we screwed up. In any case, we should now
23472355
// resolve the source HTLC with the original sender.
2348-
payment_data = Some(((*source).clone(), htlc_output.payment_hash));
2356+
payment_data = Some(((*source).clone(), htlc_output.payment_hash, htlc_output.amount_msat));
23492357
} else if !$holder_tx {
23502358
check_htlc_valid_counterparty!(self.current_counterparty_commitment_txid, htlc_output);
23512359
if payment_data.is_none() {
@@ -2378,7 +2386,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
23782386

23792387
// Check that scan_commitment, above, decided there is some source worth relaying an
23802388
// HTLC resolution backwards to and figure out whether we learned a preimage from it.
2381-
if let Some((source, payment_hash)) = payment_data {
2389+
if let Some((source, payment_hash, amount_msat)) = payment_data {
23822390
let mut payment_preimage = PaymentPreimage([0; 32]);
23832391
if accepted_preimage_claim {
23842392
if !self.pending_monitor_events.iter().any(
@@ -2387,7 +2395,8 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
23872395
self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate {
23882396
source,
23892397
payment_preimage: Some(payment_preimage),
2390-
payment_hash
2398+
payment_hash,
2399+
onchain_value_satoshis: Some(amount_msat / 1000),
23912400
}));
23922401
}
23932402
} else if offered_preimage_claim {
@@ -2399,7 +2408,8 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
23992408
self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate {
24002409
source,
24012410
payment_preimage: Some(payment_preimage),
2402-
payment_hash
2411+
payment_hash,
2412+
onchain_value_satoshis: Some(amount_msat / 1000),
24032413
}));
24042414
}
24052415
} else {
@@ -2415,7 +2425,10 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
24152425
let entry = OnchainEventEntry {
24162426
txid: tx.txid(),
24172427
height,
2418-
event: OnchainEvent::HTLCUpdate { source: source, payment_hash: payment_hash },
2428+
event: OnchainEvent::HTLCUpdate {
2429+
source, payment_hash,
2430+
onchain_value_satoshis: Some(amount_msat / 1000),
2431+
},
24192432
};
24202433
log_info!(logger, "Failing HTLC with payment_hash {} timeout by a spend tx, waiting for confirmation (at height {})", log_bytes!(payment_hash.0), entry.confirmation_threshold());
24212434
self.onchain_events_awaiting_threshold_conf.push(entry);

lightning/src/ln/chanmon_update_fail_tests.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,7 @@ fn test_monitor_update_fail_reestablish() {
11591159
assert!(updates.update_fee.is_none());
11601160
assert_eq!(updates.update_fulfill_htlcs.len(), 1);
11611161
nodes[1].node.handle_update_fulfill_htlc(&nodes[2].node.get_our_node_id(), &updates.update_fulfill_htlcs[0]);
1162+
expect_payment_forwarded!(nodes[1], Some(1000), false);
11621163
check_added_monitors!(nodes[1], 1);
11631164
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
11641165
commitment_signed_dance!(nodes[1], nodes[2], updates.commitment_signed, false);
@@ -2317,6 +2318,7 @@ fn do_test_reconnect_dup_htlc_claims(htlc_status: HTLCStatusAtDupClaim, second_f
23172318
assert_eq!(fulfill_msg, cs_updates.update_fulfill_htlcs[0]);
23182319
}
23192320
nodes[1].node.handle_update_fulfill_htlc(&nodes[2].node.get_our_node_id(), &fulfill_msg);
2321+
expect_payment_forwarded!(nodes[1], Some(1000), false);
23202322
check_added_monitors!(nodes[1], 1);
23212323

23222324
let mut bs_updates = None;

lightning/src/ln/channel.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ pub struct CounterpartyForwardingInfo {
306306
enum UpdateFulfillFetch {
307307
NewClaim {
308308
monitor_update: ChannelMonitorUpdate,
309+
htlc_value_msat: u64,
309310
msg: Option<msgs::UpdateFulfillHTLC>,
310311
},
311312
DuplicateClaim {},
@@ -319,6 +320,8 @@ pub enum UpdateFulfillCommitFetch {
319320
NewClaim {
320321
/// The ChannelMonitorUpdate which places the new payment preimage in the channel monitor
321322
monitor_update: ChannelMonitorUpdate,
323+
/// The value of the HTLC which was claimed, in msat.
324+
htlc_value_msat: u64,
322325
/// The update_fulfill message and commitment_signed message (if the claim was not placed
323326
/// in the holding cell).
324327
msgs: Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)>,
@@ -336,6 +339,9 @@ pub enum UpdateFulfillCommitFetch {
336339
// Holder designates channel data owned for the benefice of the user client.
337340
// Counterparty designates channel data owned by the another channel participant entity.
338341
pub(super) struct Channel<Signer: Sign> {
342+
#[cfg(any(test, feature = "_test_utils"))]
343+
pub(crate) config: ChannelConfig,
344+
#[cfg(not(any(test, feature = "_test_utils")))]
339345
config: ChannelConfig,
340346

341347
user_id: u64,
@@ -1275,6 +1281,7 @@ impl<Signer: Sign> Channel<Signer> {
12751281
// these, but for now we just have to treat them as normal.
12761282

12771283
let mut pending_idx = core::usize::MAX;
1284+
let mut htlc_value_msat = 0;
12781285
for (idx, htlc) in self.pending_inbound_htlcs.iter().enumerate() {
12791286
if htlc.htlc_id == htlc_id_arg {
12801287
assert_eq!(htlc.payment_hash, payment_hash_calc);
@@ -1294,6 +1301,7 @@ impl<Signer: Sign> Channel<Signer> {
12941301
}
12951302
}
12961303
pending_idx = idx;
1304+
htlc_value_msat = htlc.amount_msat;
12971305
break;
12981306
}
12991307
}
@@ -1335,7 +1343,7 @@ impl<Signer: Sign> Channel<Signer> {
13351343
// TODO: We may actually be able to switch to a fulfill here, though its
13361344
// rare enough it may not be worth the complexity burden.
13371345
debug_assert!(false, "Tried to fulfill an HTLC that was already failed");
1338-
return UpdateFulfillFetch::NewClaim { monitor_update, msg: None };
1346+
return UpdateFulfillFetch::NewClaim { monitor_update, htlc_value_msat, msg: None };
13391347
}
13401348
},
13411349
_ => {}
@@ -1347,7 +1355,7 @@ impl<Signer: Sign> Channel<Signer> {
13471355
});
13481356
#[cfg(any(test, feature = "fuzztarget"))]
13491357
self.historical_inbound_htlc_fulfills.insert(htlc_id_arg);
1350-
return UpdateFulfillFetch::NewClaim { monitor_update, msg: None };
1358+
return UpdateFulfillFetch::NewClaim { monitor_update, htlc_value_msat, msg: None };
13511359
}
13521360
#[cfg(any(test, feature = "fuzztarget"))]
13531361
self.historical_inbound_htlc_fulfills.insert(htlc_id_arg);
@@ -1357,14 +1365,15 @@ impl<Signer: Sign> Channel<Signer> {
13571365
if let InboundHTLCState::Committed = htlc.state {
13581366
} else {
13591367
debug_assert!(false, "Have an inbound HTLC we tried to claim before it was fully committed to");
1360-
return UpdateFulfillFetch::NewClaim { monitor_update, msg: None };
1368+
return UpdateFulfillFetch::NewClaim { monitor_update, htlc_value_msat, msg: None };
13611369
}
13621370
log_trace!(logger, "Upgrading HTLC {} to LocalRemoved with a Fulfill in channel {}!", log_bytes!(htlc.payment_hash.0), log_bytes!(self.channel_id));
13631371
htlc.state = InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::Fulfill(payment_preimage_arg.clone()));
13641372
}
13651373

13661374
UpdateFulfillFetch::NewClaim {
13671375
monitor_update,
1376+
htlc_value_msat,
13681377
msg: Some(msgs::UpdateFulfillHTLC {
13691378
channel_id: self.channel_id(),
13701379
htlc_id: htlc_id_arg,
@@ -1375,7 +1384,7 @@ impl<Signer: Sign> Channel<Signer> {
13751384

13761385
pub fn get_update_fulfill_htlc_and_commit<L: Deref>(&mut self, htlc_id: u64, payment_preimage: PaymentPreimage, logger: &L) -> Result<UpdateFulfillCommitFetch, (ChannelError, ChannelMonitorUpdate)> where L::Target: Logger {
13771386
match self.get_update_fulfill_htlc(htlc_id, payment_preimage, logger) {
1378-
UpdateFulfillFetch::NewClaim { mut monitor_update, msg: Some(update_fulfill_htlc) } => {
1387+
UpdateFulfillFetch::NewClaim { mut monitor_update, htlc_value_msat, msg: Some(update_fulfill_htlc) } => {
13791388
let (commitment, mut additional_update) = match self.send_commitment_no_status_check(logger) {
13801389
Err(e) => return Err((e, monitor_update)),
13811390
Ok(res) => res
@@ -1384,9 +1393,10 @@ impl<Signer: Sign> Channel<Signer> {
13841393
// strictly increasing by one, so decrement it here.
13851394
self.latest_monitor_update_id = monitor_update.update_id;
13861395
monitor_update.updates.append(&mut additional_update.updates);
1387-
Ok(UpdateFulfillCommitFetch::NewClaim { monitor_update, msgs: Some((update_fulfill_htlc, commitment)) })
1396+
Ok(UpdateFulfillCommitFetch::NewClaim { monitor_update, htlc_value_msat, msgs: Some((update_fulfill_htlc, commitment)) })
13881397
},
1389-
UpdateFulfillFetch::NewClaim { monitor_update, msg: None } => Ok(UpdateFulfillCommitFetch::NewClaim { monitor_update, msgs: None }),
1398+
UpdateFulfillFetch::NewClaim { monitor_update, htlc_value_msat, msg: None } =>
1399+
Ok(UpdateFulfillCommitFetch::NewClaim { monitor_update, htlc_value_msat, msgs: None }),
13901400
UpdateFulfillFetch::DuplicateClaim {} => Ok(UpdateFulfillCommitFetch::DuplicateClaim {}),
13911401
}
13921402
}
@@ -2163,7 +2173,7 @@ impl<Signer: Sign> Channel<Signer> {
21632173

21642174
/// Marks an outbound HTLC which we have received update_fail/fulfill/malformed
21652175
#[inline]
2166-
fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, check_preimage: Option<PaymentHash>, fail_reason: Option<HTLCFailReason>) -> Result<&HTLCSource, ChannelError> {
2176+
fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, check_preimage: Option<PaymentHash>, fail_reason: Option<HTLCFailReason>) -> Result<&OutboundHTLCOutput, ChannelError> {
21672177
for htlc in self.pending_outbound_htlcs.iter_mut() {
21682178
if htlc.htlc_id == htlc_id {
21692179
match check_preimage {
@@ -2182,13 +2192,13 @@ impl<Signer: Sign> Channel<Signer> {
21822192
OutboundHTLCState::AwaitingRemoteRevokeToRemove(_) | OutboundHTLCState::AwaitingRemovedRemoteRevoke(_) | OutboundHTLCState::RemoteRemoved(_) =>
21832193
return Err(ChannelError::Close(format!("Remote tried to fulfill/fail HTLC ({}) that they'd already fulfilled/failed", htlc_id))),
21842194
}
2185-
return Ok(&htlc.source);
2195+
return Ok(htlc);
21862196
}
21872197
}
21882198
Err(ChannelError::Close("Remote tried to fulfill/fail an HTLC we couldn't find".to_owned()))
21892199
}
21902200

2191-
pub fn update_fulfill_htlc(&mut self, msg: &msgs::UpdateFulfillHTLC) -> Result<HTLCSource, ChannelError> {
2201+
pub fn update_fulfill_htlc(&mut self, msg: &msgs::UpdateFulfillHTLC) -> Result<(HTLCSource, u64), ChannelError> {
21922202
if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
21932203
return Err(ChannelError::Close("Got fulfill HTLC message when channel was not in an operational state".to_owned()));
21942204
}
@@ -2197,7 +2207,7 @@ impl<Signer: Sign> Channel<Signer> {
21972207
}
21982208

21992209
let payment_hash = PaymentHash(Sha256::hash(&msg.payment_preimage.0[..]).into_inner());
2200-
self.mark_outbound_htlc_removed(msg.htlc_id, Some(payment_hash), None).map(|source| source.clone())
2210+
self.mark_outbound_htlc_removed(msg.htlc_id, Some(payment_hash), None).map(|htlc| (htlc.source.clone(), htlc.amount_msat))
22012211
}
22022212

22032213
pub fn update_fail_htlc(&mut self, msg: &msgs::UpdateFailHTLC, fail_reason: HTLCFailReason) -> Result<(), ChannelError> {
@@ -2496,7 +2506,7 @@ impl<Signer: Sign> Channel<Signer> {
24962506
// in it hitting the holding cell again and we cannot change the state of a
24972507
// holding cell HTLC from fulfill to anything else.
24982508
let (update_fulfill_msg_option, mut additional_monitor_update) =
2499-
if let UpdateFulfillFetch::NewClaim { msg, monitor_update } = self.get_update_fulfill_htlc(htlc_id, *payment_preimage, logger) {
2509+
if let UpdateFulfillFetch::NewClaim { msg, monitor_update, .. } = self.get_update_fulfill_htlc(htlc_id, *payment_preimage, logger) {
25002510
(msg, monitor_update)
25012511
} else { unreachable!() };
25022512
update_fulfill_htlcs.push(update_fulfill_msg_option.unwrap());

0 commit comments

Comments
 (0)