@@ -18,10 +18,9 @@ use lightning::events::bump_transaction::BumpTransactionEvent;
1818#[ cfg( not( feature = "uniffi" ) ) ]
1919use lightning:: events:: PaidBolt12Invoice ;
2020use lightning:: events:: {
21- ClosureReason , Event as LdkEvent , FundingInfo , PaymentFailureReason , PaymentPurpose ,
22- ReplayEvent ,
21+ ClosureReason , Event as LdkEvent , FundingInfo , HTLCLocator as LdkHtlcLocator ,
22+ PaymentFailureReason , PaymentPurpose , ReplayEvent ,
2323} ;
24- use lightning:: impl_writeable_tlv_based_enum;
2524use lightning:: ln:: channelmanager:: { PaymentId , TrustedChannelFeatures } ;
2625use lightning:: ln:: types:: ChannelId ;
2726use lightning:: routing:: gossip:: NodeId ;
@@ -30,6 +29,7 @@ use lightning::util::config::{ChannelConfigOverrides, ChannelConfigUpdate};
3029use lightning:: util:: errors:: APIError ;
3130use lightning:: util:: persist:: KVStore ;
3231use lightning:: util:: ser:: { Readable , ReadableArgs , Writeable , Writer } ;
32+ use lightning:: { impl_writeable_tlv_based, impl_writeable_tlv_based_enum} ;
3333use lightning_liquidity:: lsps2:: utils:: compute_opening_fee;
3434use lightning_types:: payment:: { PaymentHash , PaymentPreimage } ;
3535
@@ -59,6 +59,40 @@ use crate::{
5959 UserChannelId ,
6060} ;
6161
62+ /// Identifies the channel and counterparty that a HTLC was processed with.
63+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
64+ #[ cfg_attr( feature = "uniffi" , derive( uniffi:: Record ) ) ]
65+ pub struct HTLCLocator {
66+ /// The channel that the HTLC was sent or received on.
67+ pub channel_id : ChannelId ,
68+ /// The `user_channel_id` for the channel.
69+ ///
70+ /// Will only be `None` for events serialized with LDK Node v0.3.0 or prior, or if the
71+ /// payment was settled via an on-chain transaction.
72+ pub user_channel_id : Option < UserChannelId > ,
73+ /// The node id of the counterparty for this HTLC.
74+ ///
75+ /// This is only `None` for HTLCs received prior to LDK Node v0.5 or for events serialized by
76+ /// versions prior to v0.5.
77+ pub node_id : Option < PublicKey > ,
78+ }
79+
80+ impl_writeable_tlv_based ! ( HTLCLocator , {
81+ ( 1 , channel_id, required) ,
82+ ( 3 , user_channel_id, option) ,
83+ ( 5 , node_id, option) ,
84+ } ) ;
85+
86+ impl From < LdkHtlcLocator > for HTLCLocator {
87+ fn from ( value : LdkHtlcLocator ) -> Self {
88+ HTLCLocator {
89+ channel_id : value. channel_id ,
90+ user_channel_id : value. user_channel_id . map ( |u| UserChannelId ( u) ) ,
91+ node_id : value. node_id ,
92+ }
93+ }
94+ }
95+
6296/// An event emitted by [`Node`], which should be handled by the user.
6397///
6498/// [`Node`]: [`crate::Node`]
@@ -126,29 +160,14 @@ pub enum Event {
126160 } ,
127161 /// A payment has been forwarded.
128162 PaymentForwarded {
129- /// The channel id of the incoming channel between the previous node and us.
130- prev_channel_id : ChannelId ,
131- /// The channel id of the outgoing channel between the next node and us.
132- next_channel_id : ChannelId ,
133- /// The `user_channel_id` of the incoming channel between the previous node and us.
134- ///
135- /// Will only be `None` for events serialized with LDK Node v0.3.0 or prior.
136- prev_user_channel_id : Option < UserChannelId > ,
137- /// The `user_channel_id` of the outgoing channel between the next node and us.
138- ///
139- /// This will be `None` if the payment was settled via an on-chain transaction. See the
140- /// caveat described for the `total_fee_earned_msat` field.
141- next_user_channel_id : Option < UserChannelId > ,
142- /// The node id of the previous node.
143- ///
144- /// This is only `None` for HTLCs received prior to LDK Node v0.5 or for events serialized by
145- /// versions prior to v0.5.
146- prev_node_id : Option < PublicKey > ,
147- /// The node id of the next node.
148- ///
149- /// This is only `None` for HTLCs received prior to LDK Node v0.5 or for events serialized by
150- /// versions prior to v0.5.
151- next_node_id : Option < PublicKey > ,
163+ /// The set of incoming HTLCs that were forwarded to our node. Contains a single HTLC for
164+ /// source-routed payments, and may contain multiple HTLCs when we acted as a trampoline
165+ /// router.
166+ prev_htlcs : Vec < HTLCLocator > ,
167+ /// The set of outgoing HTLCs forwarded by our node. Contains a single HTLC for regular
168+ /// source-routed payments, and may contain multiple HTLCs when we acted as a trampoline
169+ /// router.
170+ next_htlcs : Vec < HTLCLocator > ,
152171 /// The total fee, in milli-satoshis, which was earned as a result of the payment.
153172 ///
154173 /// Note that if we force-closed the channel over which we forwarded an HTLC while the HTLC
@@ -321,16 +340,27 @@ impl_writeable_tlv_based_enum!(Event,
321340 ( 7 , custom_records, optional_vec) ,
322341 } ,
323342 ( 7 , PaymentForwarded ) => {
324- ( 0 , prev_channel_id, required) ,
325- ( 1 , prev_node_id, option) ,
326- ( 2 , next_channel_id, required) ,
327- ( 3 , next_node_id, option) ,
328- ( 4 , prev_user_channel_id, option) ,
329- ( 6 , next_user_channel_id, option) ,
343+ // Legacy fields: read from old data, never written.
344+ ( 0 , legacy_prev_channel_id, ( legacy, ChannelId , |_| Ok ( ( ) ) , |_: & Event | None :: <Option <ChannelId >>) ) ,
345+ ( 1 , legacy_prev_node_id, ( legacy, PublicKey , |_| Ok ( ( ) ) , |_: & Event | None :: <Option <PublicKey >>) ) ,
346+ ( 2 , legacy_next_channel_id, ( legacy, ChannelId , |_| Ok ( ( ) ) , |_: & Event | None :: <Option <ChannelId >>) ) ,
347+ ( 3 , legacy_next_node_id, ( legacy, PublicKey , |_| Ok ( ( ) ) , |_: & Event | None :: <Option <PublicKey >>) ) ,
348+ ( 4 , legacy_prev_user_channel_id, ( legacy, u128 , |_| Ok ( ( ) ) , |_: & Event | None :: <Option <u128 >>) ) ,
349+ ( 6 , legacy_next_user_channel_id, ( legacy, u128 , |_| Ok ( ( ) ) , |_: & Event | None :: <Option <u128 >>) ) ,
330350 ( 8 , total_fee_earned_msat, option) ,
331351 ( 10 , skimmed_fee_msat, option) ,
332352 ( 12 , claim_from_onchain_tx, required) ,
333353 ( 14 , outbound_amount_forwarded_msat, option) ,
354+ ( 15 , prev_htlcs, ( default_value_vec, vec![ HTLCLocator {
355+ channel_id: legacy_prev_channel_id. ok_or( lightning:: ln:: msgs:: DecodeError :: InvalidValue ) ?,
356+ user_channel_id: legacy_prev_user_channel_id. map( UserChannelId ) ,
357+ node_id: legacy_prev_node_id,
358+ } ] ) ) ,
359+ ( 17 , next_htlcs, ( default_value_vec, vec![ HTLCLocator {
360+ channel_id: legacy_next_channel_id. ok_or( lightning:: ln:: msgs:: DecodeError :: InvalidValue ) ?,
361+ user_channel_id: legacy_next_user_channel_id. map( UserChannelId ) ,
362+ node_id: legacy_next_node_id,
363+ } ] ) ) ,
334364 } ,
335365 ( 8 , SplicePending ) => {
336366 ( 1 , channel_id, required) ,
@@ -1403,32 +1433,29 @@ where
14031433 }
14041434 }
14051435
1406- // We only allow multiple HTLCs in/out for trampoline forwards, which have not yet
1407- // been fully implemented in LDK, so we do not lose any information by just
1408- // reporting the first HTLC in each vec.
1409- debug_assert_eq ! ( prev_htlcs. len( ) , 1 , "unexpected number of prev_htlcs" ) ;
1410- debug_assert_eq ! ( next_htlcs. len( ) , 1 , "unexpected number of next_htlcs" ) ;
1411- let prev_htlc = prev_htlcs
1412- . first ( )
1413- . expect ( "we expect at least one prev_htlc for PaymentForwarded" ) ;
1414- let next_htlc = next_htlcs
1415- . first ( )
1416- . expect ( "we expect at least one next_htlc for PaymentForwarded" ) ;
1417-
1436+ // We only expect multiple next_htlcs when we have a trampoline forward, and we do
1437+ // not support JIT channels in combination with trampoline. We're not at risk of
1438+ // double-reporting a skimmed fee when we have multiple next_htlcs because we
1439+ // expect our skimmed fee to be zero.
1440+ if skimmed_fee_msat. is_some ( ) {
1441+ debug_assert_eq ! (
1442+ next_htlcs. len( ) ,
1443+ 1 ,
1444+ "unexpected skimmed fee for trampoline forward, fee may be double counted"
1445+ ) ;
1446+ }
14181447 if let Some ( liquidity_source) = self . liquidity_source . as_ref ( ) {
14191448 let skimmed_fee_msat = skimmed_fee_msat. unwrap_or ( 0 ) ;
1420- liquidity_source
1421- . handle_payment_forwarded ( Some ( next_htlc. channel_id ) , skimmed_fee_msat)
1422- . await ;
1449+ for next_htlc in next_htlcs. iter ( ) {
1450+ liquidity_source
1451+ . handle_payment_forwarded ( Some ( next_htlc. channel_id ) , skimmed_fee_msat)
1452+ . await ;
1453+ }
14231454 }
14241455
14251456 let event = Event :: PaymentForwarded {
1426- prev_channel_id : prev_htlc. channel_id ,
1427- next_channel_id : next_htlc. channel_id ,
1428- prev_user_channel_id : prev_htlc. user_channel_id . map ( UserChannelId ) ,
1429- next_user_channel_id : next_htlc. user_channel_id . map ( UserChannelId ) ,
1430- prev_node_id : prev_htlc. node_id ,
1431- next_node_id : next_htlc. node_id ,
1457+ prev_htlcs : prev_htlcs. into_iter ( ) . map ( HTLCLocator :: from) . collect ( ) ,
1458+ next_htlcs : next_htlcs. into_iter ( ) . map ( HTLCLocator :: from) . collect ( ) ,
14321459 total_fee_earned_msat,
14331460 skimmed_fee_msat,
14341461 claim_from_onchain_tx,
0 commit comments