Skip to content

Commit 6d44db1

Browse files
committed
Expose {prev,next}_user_channel_id fields in PaymentForwarded
This is useful for users that track channels by `user_channel_id`. For example, in `lightning-liquidity` we currently keep a full `HashMap<ChanelId, u128>` around *just* to be able to associate `PaymentForwarded` events with the channels otherwise tracked by `user_channel_id`.
1 parent 7a35bf8 commit 6d44db1

File tree

3 files changed

+57
-22
lines changed

3 files changed

+57
-22
lines changed

lightning/src/events/mod.rs

+31-11
Original file line numberDiff line numberDiff line change
@@ -797,12 +797,24 @@ pub enum Event {
797797
/// This event is generated when a payment has been successfully forwarded through us and a
798798
/// forwarding fee earned.
799799
PaymentForwarded {
800-
/// The incoming channel between the previous node and us. This is only `None` for events
801-
/// generated or serialized by versions prior to 0.0.107.
800+
/// The channel id of the incoming channel between the previous node and us.
801+
///
802+
/// This is only `None` for events generated or serialized by versions prior to 0.0.107.
802803
prev_channel_id: Option<ChannelId>,
803-
/// The outgoing channel between the next node and us. This is only `None` for events
804-
/// generated or serialized by versions prior to 0.0.107.
804+
/// The channel id of the outgoing channel between the next node and us.
805+
///
806+
/// This is only `None` for events generated or serialized by versions prior to 0.0.107.
805807
next_channel_id: Option<ChannelId>,
808+
/// The `user_channel_id` of the incoming channel between the previous node and us.
809+
///
810+
/// This is only `None` for events generated or serialized by versions prior to 0.0.122.
811+
prev_user_channel_id: Option<u128>,
812+
/// The `user_channel_id` of the outgoing channel between the next node and us.
813+
///
814+
/// This will be `None` if the payment was settled via an on-chain transaction. See the
815+
/// caveat described for the `total_fee_earned_msat` field. Moreover it will be `None` for
816+
/// events generated or serialized by versions prior to 0.0.122.
817+
next_user_channel_id: Option<u128>,
806818
/// The total fee, in milli-satoshis, which was earned as a result of the payment.
807819
///
808820
/// Note that if we force-closed the channel over which we forwarded an HTLC while the HTLC
@@ -1121,8 +1133,9 @@ impl Writeable for Event {
11211133
});
11221134
}
11231135
&Event::PaymentForwarded {
1124-
total_fee_earned_msat, prev_channel_id, claim_from_onchain_tx,
1125-
next_channel_id, outbound_amount_forwarded_msat, skimmed_fee_msat,
1136+
prev_channel_id, next_channel_id, prev_user_channel_id, next_user_channel_id,
1137+
total_fee_earned_msat, skimmed_fee_msat, claim_from_onchain_tx,
1138+
outbound_amount_forwarded_msat,
11261139
} => {
11271140
7u8.write(writer)?;
11281141
write_tlv_fields!(writer, {
@@ -1132,6 +1145,8 @@ impl Writeable for Event {
11321145
(3, next_channel_id, option),
11331146
(5, outbound_amount_forwarded_msat, option),
11341147
(7, skimmed_fee_msat, option),
1148+
(9, prev_user_channel_id, option),
1149+
(11, next_user_channel_id, option),
11351150
});
11361151
},
11371152
&Event::ChannelClosed { ref channel_id, ref user_channel_id, ref reason,
@@ -1427,23 +1442,28 @@ impl MaybeReadable for Event {
14271442
},
14281443
7u8 => {
14291444
let f = || {
1430-
let mut total_fee_earned_msat = None;
14311445
let mut prev_channel_id = None;
1432-
let mut claim_from_onchain_tx = false;
14331446
let mut next_channel_id = None;
1434-
let mut outbound_amount_forwarded_msat = None;
1447+
let mut prev_user_channel_id = None;
1448+
let mut next_user_channel_id = None;
1449+
let mut total_fee_earned_msat = None;
14351450
let mut skimmed_fee_msat = None;
1451+
let mut claim_from_onchain_tx = false;
1452+
let mut outbound_amount_forwarded_msat = None;
14361453
read_tlv_fields!(reader, {
14371454
(0, total_fee_earned_msat, option),
14381455
(1, prev_channel_id, option),
14391456
(2, claim_from_onchain_tx, required),
14401457
(3, next_channel_id, option),
14411458
(5, outbound_amount_forwarded_msat, option),
14421459
(7, skimmed_fee_msat, option),
1460+
(9, prev_user_channel_id, option),
1461+
(11, next_user_channel_id, option),
14431462
});
14441463
Ok(Some(Event::PaymentForwarded {
1445-
total_fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id,
1446-
outbound_amount_forwarded_msat, skimmed_fee_msat,
1464+
prev_channel_id, next_channel_id, prev_user_channel_id,
1465+
next_user_channel_id, total_fee_earned_msat, skimmed_fee_msat,
1466+
claim_from_onchain_tx, outbound_amount_forwarded_msat,
14471467
}))
14481468
};
14491469
f()

lightning/src/ln/channelmanager.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -5733,7 +5733,7 @@ where
57335733
fn claim_funds_internal(&self, source: HTLCSource, payment_preimage: PaymentPreimage,
57345734
forwarded_htlc_value_msat: Option<u64>, skimmed_fee_msat: Option<u64>, from_onchain: bool,
57355735
startup_replay: bool, next_channel_counterparty_node_id: Option<PublicKey>,
5736-
next_channel_outpoint: OutPoint, next_channel_id: ChannelId,
5736+
next_channel_outpoint: OutPoint, next_channel_id: ChannelId, next_user_channel_id: Option<u128>,
57375737
) {
57385738
match source {
57395739
HTLCSource::OutboundRoute { session_priv, payment_id, path, .. } => {
@@ -5752,6 +5752,7 @@ where
57525752
},
57535753
HTLCSource::PreviousHopData(hop_data) => {
57545754
let prev_channel_id = hop_data.channel_id;
5755+
let prev_user_channel_id = hop_data.user_channel_id;
57555756
let completed_blocker = RAAMonitorUpdateBlockingAction::from_prev_hop_data(&hop_data);
57565757
#[cfg(debug_assertions)]
57575758
let claiming_chan_funding_outpoint = hop_data.outpoint;
@@ -5838,12 +5839,14 @@ where
58385839
"skimmed_fee_msat must always be included in total_fee_earned_msat");
58395840
Some(MonitorUpdateCompletionAction::EmitEventAndFreeOtherChannel {
58405841
event: events::Event::PaymentForwarded {
5841-
total_fee_earned_msat,
5842-
claim_from_onchain_tx: from_onchain,
58435842
prev_channel_id: Some(prev_channel_id),
58445843
next_channel_id: Some(next_channel_id),
5845-
outbound_amount_forwarded_msat: forwarded_htlc_value_msat,
5844+
prev_user_channel_id,
5845+
next_user_channel_id,
5846+
total_fee_earned_msat,
58465847
skimmed_fee_msat,
5848+
claim_from_onchain_tx: from_onchain,
5849+
outbound_amount_forwarded_msat: forwarded_htlc_value_msat,
58475850
},
58485851
downstream_counterparty_and_funding_outpoint: chan_to_release,
58495852
})
@@ -6817,6 +6820,7 @@ where
68176820

68186821
fn internal_update_fulfill_htlc(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFulfillHTLC) -> Result<(), MsgHandleErrInternal> {
68196822
let funding_txo;
6823+
let next_user_channel_id;
68206824
let (htlc_source, forwarded_htlc_value, skimmed_fee_msat) = {
68216825
let per_peer_state = self.per_peer_state.read().unwrap();
68226826
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
@@ -6846,6 +6850,7 @@ where
68466850
// outbound HTLC is claimed. This is guaranteed to all complete before we
68476851
// process the RAA as messages are processed from single peers serially.
68486852
funding_txo = chan.context.get_funding_txo().expect("We won't accept a fulfill until funded");
6853+
next_user_channel_id = chan.context.get_user_id();
68496854
res
68506855
} else {
68516856
return try_chan_phase_entry!(self, Err(ChannelError::Close(
@@ -6857,7 +6862,7 @@ where
68576862
};
68586863
self.claim_funds_internal(htlc_source, msg.payment_preimage.clone(),
68596864
Some(forwarded_htlc_value), skimmed_fee_msat, false, false, Some(*counterparty_node_id),
6860-
funding_txo, msg.channel_id
6865+
funding_txo, msg.channel_id, Some(next_user_channel_id),
68616866
);
68626867

68636868
Ok(())
@@ -7359,7 +7364,7 @@ where
73597364
log_trace!(logger, "Claiming HTLC with preimage {} from our monitor", preimage);
73607365
self.claim_funds_internal(htlc_update.source, preimage,
73617366
htlc_update.htlc_value_satoshis.map(|v| v * 1000), None, true,
7362-
false, counterparty_node_id, funding_outpoint, channel_id);
7367+
false, counterparty_node_id, funding_outpoint, channel_id, None);
73637368
} else {
73647369
log_trace!(logger, "Failing HTLC with hash {} from our monitor", &htlc_update.payment_hash);
73657370
let receiver = HTLCDestination::NextHopChannel { node_id: counterparty_node_id, channel_id };
@@ -11319,7 +11324,9 @@ where
1131911324
// don't remember in the `ChannelMonitor` where we got a preimage from, but if the
1132011325
// channel is closed we just assume that it probably came from an on-chain claim.
1132111326
channel_manager.claim_funds_internal(source, preimage, Some(downstream_value), None,
11322-
downstream_closed, true, downstream_node_id, downstream_funding, downstream_channel_id);
11327+
downstream_closed, true, downstream_node_id, downstream_funding,
11328+
downstream_channel_id, None
11329+
);
1132311330
}
1132411331

1132511332
//TODO: Broadcast channel update for closed channels, but only after we've made a

lightning/src/ln/functional_test_utils.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -2230,8 +2230,8 @@ pub fn expect_payment_forwarded<CM: AChannelManager, H: NodeHolder<CM=CM>>(
22302230
) {
22312231
match event {
22322232
Event::PaymentForwarded {
2233-
total_fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id,
2234-
outbound_amount_forwarded_msat: _, skimmed_fee_msat
2233+
prev_channel_id, next_channel_id, prev_user_channel_id, next_user_channel_id,
2234+
total_fee_earned_msat, skimmed_fee_msat, claim_from_onchain_tx, ..
22352235
} => {
22362236
assert_eq!(total_fee_earned_msat, expected_fee);
22372237

@@ -2240,12 +2240,20 @@ pub fn expect_payment_forwarded<CM: AChannelManager, H: NodeHolder<CM=CM>>(
22402240
assert!(skimmed_fee_msat == expected_extra_fees_msat);
22412241
if !upstream_force_closed {
22422242
// Is the event prev_channel_id in one of the channels between the two nodes?
2243-
assert!(node.node().list_channels().iter().any(|x| x.counterparty.node_id == prev_node.node().get_our_node_id() && x.channel_id == prev_channel_id.unwrap()));
2243+
assert!(node.node().list_channels().iter().any(|x|
2244+
x.counterparty.node_id == prev_node.node().get_our_node_id() &&
2245+
x.channel_id == prev_channel_id.unwrap() &&
2246+
x.user_channel_id == prev_user_channel_id.unwrap()
2247+
));
22442248
}
22452249
// We check for force closures since a force closed channel is removed from the
22462250
// node's channel list
22472251
if !downstream_force_closed {
2248-
assert!(node.node().list_channels().iter().any(|x| x.counterparty.node_id == next_node.node().get_our_node_id() && x.channel_id == next_channel_id.unwrap()));
2252+
assert!(node.node().list_channels().iter().any(|x|
2253+
x.counterparty.node_id == next_node.node().get_our_node_id() &&
2254+
x.channel_id == next_channel_id.unwrap() &&
2255+
x.user_channel_id == next_user_channel_id.unwrap()
2256+
));
22492257
}
22502258
assert_eq!(claim_from_onchain_tx, downstream_force_closed);
22512259
},

0 commit comments

Comments
 (0)