Skip to content

Commit 4748e7c

Browse files
authored
Merge branch 'lightningdevkit:main' into fix-ci-oom-error
2 parents 8178ef4 + 27e138c commit 4748e7c

File tree

12 files changed

+880
-517
lines changed

12 files changed

+880
-517
lines changed

CLAUDE.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@ See [README.md](README.md) for the workspace layout and [ARCH.md](ARCH.md) for s
1515
of the full task you might prompt the user whether they want you to run the
1616
full CI tests via `./ci/ci-tests.sh`. Note however that this script will run
1717
for a very long time, so please don't timeout when you do.
18-
- Run `cargo +1.75.0 fmt --all` after every code change
18+
- Run `cargo +1.75.0 fmt --all` before committing code changes. If rust 1.75.0 is
19+
not installed, skip this step.
1920
- Never add new dependencies unless explicitly requested
2021
- Please always disclose the use of any AI tools in commit messages and PR descriptions using a `Co-Authored-By:` line.
2122
- When adding new `.rs` files, please ensure to always add the licensing header as found, e.g., in `lightning/src/lib.rs` and other files.
23+
- When adding comments, do not refer to internal logic in other modules, instead
24+
make sure comments make sense in the context they're in without needing other
25+
context.
26+
- Try to keep code DRY - if new code you add is duplicate with other code,
27+
deduplicate it.

lightning-liquidity/tests/lsps2_integration_tests.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,14 +1331,14 @@ fn client_trusts_lsp_end_to_end_test() {
13311331

13321332
let total_fee_msat = match service_events[0].clone() {
13331333
Event::PaymentForwarded {
1334-
prev_node_id,
1335-
next_node_id,
1334+
ref prev_htlcs,
1335+
ref next_htlcs,
13361336
skimmed_fee_msat,
13371337
total_fee_earned_msat,
13381338
..
13391339
} => {
1340-
assert_eq!(prev_node_id, Some(payer_node_id));
1341-
assert_eq!(next_node_id, Some(client_node_id));
1340+
assert_eq!(prev_htlcs[0].node_id, Some(payer_node_id));
1341+
assert_eq!(next_htlcs[0].node_id, Some(client_node_id));
13421342
service_handler.payment_forwarded(channel_id, skimmed_fee_msat.unwrap_or(0)).unwrap();
13431343
Some(total_fee_earned_msat.unwrap() - skimmed_fee_msat.unwrap())
13441344
},

lightning/src/chain/channelmonitor.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2795,6 +2795,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
27952795
let outbound_payment = match source {
27962796
None => panic!("Outbound HTLCs should have a source"),
27972797
Some(&HTLCSource::PreviousHopData(_)) => false,
2798+
Some(&HTLCSource::TrampolineForward { .. }) => false,
27982799
Some(&HTLCSource::OutboundRoute { .. }) => true,
27992800
};
28002801
return Some(Balance::MaybeTimeoutClaimableHTLC {
@@ -3007,6 +3008,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
30073008
let outbound_payment = match source {
30083009
None => panic!("Outbound HTLCs should have a source"),
30093010
Some(HTLCSource::PreviousHopData(_)) => false,
3011+
Some(HTLCSource::TrampolineForward { .. }) => false,
30103012
Some(HTLCSource::OutboundRoute { .. }) => true,
30113013
};
30123014
if outbound_payment {

lightning/src/events/mod.rs

Lines changed: 128 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,10 @@ pub enum HTLCHandlingFailureType {
584584
/// The payment hash of the payment we attempted to process.
585585
payment_hash: PaymentHash,
586586
},
587+
/// We were responsible for pathfinding and forwarding of a trampoline payment, but failed to
588+
/// do so. An example of such an instance is when we can't find a route to the specified
589+
/// trampoline destination.
590+
TrampolineForward {},
587591
}
588592

589593
impl_writeable_tlv_based_enum_upgradable!(HTLCHandlingFailureType,
@@ -601,6 +605,7 @@ impl_writeable_tlv_based_enum_upgradable!(HTLCHandlingFailureType,
601605
(4, Receive) => {
602606
(0, payment_hash, required),
603607
},
608+
(5, TrampolineForward) => {},
604609
);
605610

606611
/// The reason for HTLC failures in [`Event::HTLCHandlingFailed`].
@@ -738,6 +743,31 @@ pub enum InboundChannelFunds {
738743
DualFunded,
739744
}
740745

746+
/// Identifies the channel and peer committed to a HTLC, used for both incoming and outgoing HTLCs.
747+
#[derive(Clone, Debug, PartialEq, Eq)]
748+
pub struct HTLCLocator {
749+
/// The channel that the HTLC was sent or received on.
750+
pub channel_id: ChannelId,
751+
752+
/// The `user_channel_id` for `channel_id`.
753+
///
754+
/// This will be `None` if the payment was settled via an on-chain transaction. It will also
755+
/// be `None` for events serialized by versions prior to 0.0.122.
756+
pub user_channel_id: Option<u128>,
757+
758+
/// The public key identity of the node that the HTLC was sent to or received from.
759+
///
760+
/// This is only `None` for HTLCs received prior to 0.1 or for events serialized by versions
761+
/// prior to 0.1.
762+
pub node_id: Option<PublicKey>,
763+
}
764+
765+
impl_writeable_tlv_based!(HTLCLocator, {
766+
(1, channel_id, required),
767+
(3, user_channel_id, option),
768+
(5, node_id, option),
769+
});
770+
741771
/// An Event which you should probably take some action in response to.
742772
///
743773
/// Note that while Writeable and Readable are implemented for Event, you probably shouldn't use
@@ -1331,38 +1361,22 @@ pub enum Event {
13311361
/// This event is generated when a payment has been successfully forwarded through us and a
13321362
/// forwarding fee earned.
13331363
///
1364+
/// Note that downgrading from 0.3 and above with pending trampoline forwards that use multipart
1365+
/// payments will produce an event that only provides information about the first htlc that was
1366+
/// received/dispatched.
1367+
///
13341368
/// # Failure Behavior and Persistence
13351369
/// This event will eventually be replayed after failures-to-handle (i.e., the event handler
13361370
/// returning `Err(ReplayEvent ())`) and will be persisted across restarts.
13371371
PaymentForwarded {
1338-
/// The channel id of the incoming channel between the previous node and us.
1339-
///
1340-
/// This is only `None` for events generated or serialized by versions prior to 0.0.107.
1341-
prev_channel_id: Option<ChannelId>,
1342-
/// The channel id of the outgoing channel between the next node and us.
1343-
///
1344-
/// This is only `None` for events generated or serialized by versions prior to 0.0.107.
1345-
next_channel_id: Option<ChannelId>,
1346-
/// The `user_channel_id` of the incoming channel between the previous node and us.
1347-
///
1348-
/// This is only `None` for events generated or serialized by versions prior to 0.0.122.
1349-
prev_user_channel_id: Option<u128>,
1350-
/// The `user_channel_id` of the outgoing channel between the next node and us.
1351-
///
1352-
/// This will be `None` if the payment was settled via an on-chain transaction. See the
1353-
/// caveat described for the `total_fee_earned_msat` field. Moreover it will be `None` for
1354-
/// events generated or serialized by versions prior to 0.0.122.
1355-
next_user_channel_id: Option<u128>,
1356-
/// The node id of the previous node.
1357-
///
1358-
/// This is only `None` for HTLCs received prior to 0.1 or for events serialized by
1359-
/// versions prior to 0.1
1360-
prev_node_id: Option<PublicKey>,
1361-
/// The node id of the next node.
1362-
///
1363-
/// This is only `None` for HTLCs received prior to 0.1 or for events serialized by
1364-
/// versions prior to 0.1
1365-
next_node_id: Option<PublicKey>,
1372+
/// The set of HTLCs forwarded to our node that will be claimed by this forward. Contains a
1373+
/// single HTLC for source-routed payments, and may contain multiple HTLCs when we acted as
1374+
/// a trampoline router, responsible for pathfinding within the route.
1375+
prev_htlcs: Vec<HTLCLocator>,
1376+
/// The set of HTLCs forwarded by our node that have been claimed by this forward. Contains
1377+
/// a single HTLC for regular source-routed payments, and may contain multiple HTLCs when
1378+
/// we acted as a trampoline router, responsible for pathfinding within the route.
1379+
next_htlcs: Vec<HTLCLocator>,
13661380
/// The total fee, in milli-satoshis, which was earned as a result of the payment.
13671381
///
13681382
/// Note that if we force-closed the channel over which we forwarded an HTLC while the HTLC
@@ -1656,12 +1670,17 @@ pub enum Event {
16561670
/// Indicates that the HTLC was accepted, but could not be processed when or after attempting to
16571671
/// forward it.
16581672
///
1673+
/// Note that downgrading from 0.3 with pending trampoline forwards that have incoming multipart
1674+
/// payments will produce an event that only provides information about the first htlc that was
1675+
/// received/dispatched.
1676+
///
16591677
/// # Failure Behavior and Persistence
16601678
/// This event will eventually be replayed after failures-to-handle (i.e., the event handler
16611679
/// returning `Err(ReplayEvent ())`) and will be persisted across restarts.
16621680
HTLCHandlingFailed {
1663-
/// The channel over which the HTLC was received.
1664-
prev_channel_id: ChannelId,
1681+
/// The channel(s) over which the HTLC(s) was received. May contain multiple entries for
1682+
/// trampoline forwards.
1683+
prev_channel_ids: Vec<ChannelId>,
16651684
/// The type of HTLC handling that failed.
16661685
failure_type: HTLCHandlingFailureType,
16671686
/// The reason that the HTLC failed.
@@ -2026,29 +2045,47 @@ impl Writeable for Event {
20262045
});
20272046
},
20282047
&Event::PaymentForwarded {
2029-
prev_channel_id,
2030-
next_channel_id,
2031-
prev_user_channel_id,
2032-
next_user_channel_id,
2033-
prev_node_id,
2034-
next_node_id,
2048+
ref prev_htlcs,
2049+
ref next_htlcs,
20352050
total_fee_earned_msat,
20362051
skimmed_fee_msat,
20372052
claim_from_onchain_tx,
20382053
outbound_amount_forwarded_msat,
20392054
} => {
20402055
7u8.write(writer)?;
2056+
// Fields 1, 3, 9, 11, 13 and 15 are written for backwards compatibility. We don't
2057+
// want to fail writes, so we write garbage data if we don't have at least on htlc.
2058+
debug_assert!(
2059+
!prev_htlcs.is_empty(),
2060+
"at least one prev_htlc required for PaymentForwarded",
2061+
);
2062+
debug_assert!(
2063+
!next_htlcs.is_empty(),
2064+
"at least one next_htlc required for PaymentForwarded",
2065+
);
2066+
let empty_locator = HTLCLocator {
2067+
channel_id: ChannelId::new_zero(),
2068+
user_channel_id: None,
2069+
node_id: None,
2070+
};
2071+
let legacy_prev = prev_htlcs.first().unwrap_or(&empty_locator);
2072+
let legacy_next = next_htlcs.first().unwrap_or(&empty_locator);
20412073
write_tlv_fields!(writer, {
20422074
(0, total_fee_earned_msat, option),
2043-
(1, prev_channel_id, option),
2075+
(1, Some(legacy_prev.channel_id), option),
20442076
(2, claim_from_onchain_tx, required),
2045-
(3, next_channel_id, option),
2077+
(3, Some(legacy_next.channel_id), option),
20462078
(5, outbound_amount_forwarded_msat, option),
20472079
(7, skimmed_fee_msat, option),
2048-
(9, prev_user_channel_id, option),
2049-
(11, next_user_channel_id, option),
2050-
(13, prev_node_id, option),
2051-
(15, next_node_id, option),
2080+
(9, legacy_prev.user_channel_id, option),
2081+
(11, legacy_next.user_channel_id, option),
2082+
(13, legacy_prev.node_id, option),
2083+
(15, legacy_next.node_id, option),
2084+
// HTLCs are written as required, rather than required_vec, so that they can be
2085+
// deserialized using default_value to fill in legacy fields which expects
2086+
// LengthReadable (required_vec is WithoutLength).
2087+
(17, *prev_htlcs, required),
2088+
(19, *next_htlcs, required),
20522089
});
20532090
},
20542091
&Event::ChannelClosed {
@@ -2196,15 +2233,24 @@ impl Writeable for Event {
21962233
})
21972234
},
21982235
&Event::HTLCHandlingFailed {
2199-
ref prev_channel_id,
2236+
ref prev_channel_ids,
22002237
ref failure_type,
22012238
ref failure_reason,
22022239
} => {
22032240
25u8.write(writer)?;
2241+
// Legacy field is written for backwards compatibility. We don't want to fail writes
2242+
// so we write garbage data if we don't have the data we expect.
2243+
debug_assert!(
2244+
!prev_channel_ids.is_empty(),
2245+
"at least one prev_channel_id required for HTLCHandlingFailed"
2246+
);
2247+
let zero_id = ChannelId::new_zero();
2248+
let legacy_chan_id = prev_channel_ids.first().unwrap_or(&zero_id);
22042249
write_tlv_fields!(writer, {
2205-
(0, prev_channel_id, required),
2250+
(0, legacy_chan_id, required),
22062251
(1, failure_reason, option),
22072252
(2, failure_type, required),
2253+
(3, *prev_channel_ids, required),
22082254
})
22092255
},
22102256
&Event::BumpTransaction(ref event) => {
@@ -2548,35 +2594,48 @@ impl MaybeReadable for Event {
25482594
},
25492595
7u8 => {
25502596
let mut f = || {
2551-
let mut prev_channel_id = None;
2552-
let mut next_channel_id = None;
2553-
let mut prev_user_channel_id = None;
2554-
let mut next_user_channel_id = None;
2555-
let mut prev_node_id = None;
2556-
let mut next_node_id = None;
2597+
// Legacy values that have been replaced by prev_htlcs and next_htlcs.
2598+
let mut prev_channel_id_legacy = None;
2599+
let mut next_channel_id_legacy = None;
2600+
let mut prev_user_channel_id_legacy = None;
2601+
let mut next_user_channel_id_legacy = None;
2602+
let mut prev_node_id_legacy = None;
2603+
let mut next_node_id_legacy = None;
2604+
25572605
let mut total_fee_earned_msat = None;
25582606
let mut skimmed_fee_msat = None;
25592607
let mut claim_from_onchain_tx = false;
25602608
let mut outbound_amount_forwarded_msat = None;
2609+
let mut prev_htlcs = vec![];
2610+
let mut next_htlcs = vec![];
25612611
read_tlv_fields!(reader, {
25622612
(0, total_fee_earned_msat, option),
2563-
(1, prev_channel_id, option),
2613+
(1, prev_channel_id_legacy, option),
25642614
(2, claim_from_onchain_tx, required),
2565-
(3, next_channel_id, option),
2615+
(3, next_channel_id_legacy, option),
25662616
(5, outbound_amount_forwarded_msat, option),
25672617
(7, skimmed_fee_msat, option),
2568-
(9, prev_user_channel_id, option),
2569-
(11, next_user_channel_id, option),
2570-
(13, prev_node_id, option),
2571-
(15, next_node_id, option),
2618+
(9, prev_user_channel_id_legacy, option),
2619+
(11, next_user_channel_id_legacy, option),
2620+
(13, prev_node_id_legacy, option),
2621+
(15, next_node_id_legacy, option),
2622+
// We never expect prev/next_channel_id_legacy to be None because this field
2623+
// was only None for versions before 0.0.107 and we do not allow upgrades
2624+
// with pending forwards to 0.1 for any version 0.0.123 or earlier.
2625+
(17, prev_htlcs, (default_value, vec![HTLCLocator{
2626+
channel_id: prev_channel_id_legacy.ok_or(DecodeError::InvalidValue)?,
2627+
user_channel_id: prev_user_channel_id_legacy,
2628+
node_id: prev_node_id_legacy,
2629+
}])),
2630+
(19, next_htlcs, (default_value, vec![HTLCLocator{
2631+
channel_id: next_channel_id_legacy.ok_or(DecodeError::InvalidValue)?,
2632+
user_channel_id: next_user_channel_id_legacy,
2633+
node_id: next_node_id_legacy,
2634+
}])),
25722635
});
25732636
Ok(Some(Event::PaymentForwarded {
2574-
prev_channel_id,
2575-
next_channel_id,
2576-
prev_user_channel_id,
2577-
next_user_channel_id,
2578-
prev_node_id,
2579-
next_node_id,
2637+
prev_htlcs,
2638+
next_htlcs,
25802639
total_fee_earned_msat,
25812640
skimmed_fee_msat,
25822641
claim_from_onchain_tx,
@@ -2766,13 +2825,17 @@ impl MaybeReadable for Event {
27662825
},
27672826
25u8 => {
27682827
let mut f = || {
2769-
let mut prev_channel_id = ChannelId::new_zero();
2828+
let mut prev_channel_id_legacy = ChannelId::new_zero();
27702829
let mut failure_reason = None;
27712830
let mut failure_type_opt = UpgradableRequired(None);
2831+
let mut prev_channel_ids = vec![];
27722832
read_tlv_fields!(reader, {
2773-
(0, prev_channel_id, required),
2833+
(0, prev_channel_id_legacy, required),
27742834
(1, failure_reason, option),
27752835
(2, failure_type_opt, upgradable_required),
2836+
(3, prev_channel_ids, (default_value, vec![
2837+
prev_channel_id_legacy,
2838+
])),
27762839
});
27772840

27782841
// If a legacy HTLCHandlingFailureType::UnknownNextHop was written, upgrade
@@ -2787,7 +2850,7 @@ impl MaybeReadable for Event {
27872850
failure_reason = Some(LocalHTLCFailureReason::UnknownNextPeer.into());
27882851
}
27892852
Ok(Some(Event::HTLCHandlingFailed {
2790-
prev_channel_id,
2853+
prev_channel_ids,
27912854
failure_type: _init_tlv_based_struct_field!(
27922855
failure_type_opt,
27932856
upgradable_required

lightning/src/ln/chanmon_update_fail_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3940,11 +3940,11 @@ fn do_test_durable_preimages_on_closed_channel(
39403940
let evs = nodes[1].node.get_and_clear_pending_events();
39413941
assert_eq!(evs.len(), if close_chans_before_reload { 2 } else { 1 });
39423942
for ev in evs {
3943-
if let Event::PaymentForwarded { claim_from_onchain_tx, next_user_channel_id, .. } = ev {
3943+
if let Event::PaymentForwarded { claim_from_onchain_tx, next_htlcs, .. } = ev {
39443944
if !claim_from_onchain_tx {
39453945
// If the outbound channel is still open, the `next_user_channel_id` should be available.
39463946
// This was previously broken.
3947-
assert!(next_user_channel_id.is_some())
3947+
assert!(next_htlcs[0].user_channel_id.is_some())
39483948
}
39493949
} else {
39503950
panic!();

0 commit comments

Comments
 (0)