Skip to content

Commit 4be3adb

Browse files
committed
Track MPP data while receiving keysends
This commit adds the field `payment_data: FinalOnionHopData` to `ReceiveKeysend` which will allow us to check for payment secrets and total amounts which is needed to support receiving MPP keysends. This field is non-backwards compatible since we wouldn't be able to handle an MPP keysend properly if we were to downgrade to a prior version. We also no longer reject keysends with payment secrets if we support MPP keysend.
1 parent 07def92 commit 4be3adb

File tree

1 file changed

+30
-20
lines changed

1 file changed

+30
-20
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ pub(super) enum PendingHTLCRouting {
112112
phantom_shared_secret: Option<[u8; 32]>,
113113
},
114114
ReceiveKeysend {
115+
/// This was added in 0.0.116 and will break deserialization on downgrades.
116+
payment_data: Option<msgs::FinalOnionHopData>,
115117
payment_preimage: PaymentPreimage,
116118
payment_metadata: Option<Vec<u8>>,
117119
incoming_cltv_expiry: u32, // Used to track when we should expire pending HTLCs that go unclaimed
@@ -2342,20 +2344,7 @@ where
23422344
});
23432345
},
23442346
msgs::OnionHopDataFormat::FinalNode { payment_data, keysend_preimage, payment_metadata } => {
2345-
if payment_data.is_some() && keysend_preimage.is_some() {
2346-
return Err(ReceiveError {
2347-
err_code: 0x4000|22,
2348-
err_data: Vec::new(),
2349-
msg: "We don't support MPP keysend payments",
2350-
});
2351-
} else if let Some(data) = payment_data {
2352-
PendingHTLCRouting::Receive {
2353-
payment_data: data,
2354-
payment_metadata,
2355-
incoming_cltv_expiry: hop_data.outgoing_cltv_value,
2356-
phantom_shared_secret,
2357-
}
2358-
} else if let Some(payment_preimage) = keysend_preimage {
2347+
if let Some(payment_preimage) = keysend_preimage {
23592348
// We need to check that the sender knows the keysend preimage before processing this
23602349
// payment further. Otherwise, an intermediary routing hop forwarding non-keysend-HTLC X
23612350
// could discover the final destination of X, by probing the adjacent nodes on the route
@@ -2369,12 +2358,26 @@ where
23692358
msg: "Payment preimage didn't match payment hash",
23702359
});
23712360
}
2372-
2361+
if !self.default_configuration.accept_mpp_keysend && payment_data.is_some() {
2362+
return Err(ReceiveError {
2363+
err_code: 0x4000|22,
2364+
err_data: Vec::new(),
2365+
msg: "We don't support MPP keysend payments",
2366+
});
2367+
}
23732368
PendingHTLCRouting::ReceiveKeysend {
2369+
payment_data,
23742370
payment_preimage,
23752371
payment_metadata,
23762372
incoming_cltv_expiry: hop_data.outgoing_cltv_value,
23772373
}
2374+
} else if let Some(data) = payment_data {
2375+
PendingHTLCRouting::Receive {
2376+
payment_data: data,
2377+
payment_metadata,
2378+
incoming_cltv_expiry: hop_data.outgoing_cltv_value,
2379+
phantom_shared_secret,
2380+
}
23782381
} else {
23792382
return Err(ReceiveError {
23802383
err_code: 0x4000|0x2000|3,
@@ -3490,10 +3493,13 @@ where
34903493
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data },
34913494
Some(payment_data), phantom_shared_secret, onion_fields)
34923495
},
3493-
PendingHTLCRouting::ReceiveKeysend { payment_preimage, payment_metadata, incoming_cltv_expiry } => {
3494-
let onion_fields = RecipientOnionFields { payment_secret: None, payment_metadata };
3496+
PendingHTLCRouting::ReceiveKeysend { payment_data, payment_preimage, payment_metadata, incoming_cltv_expiry } => {
3497+
let onion_fields = RecipientOnionFields {
3498+
payment_secret: payment_data.as_ref().map(|data| data.payment_secret),
3499+
payment_metadata
3500+
};
34953501
(incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage),
3496-
None, None, onion_fields)
3502+
payment_data, None, onion_fields)
34973503
},
34983504
_ => {
34993505
panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive");
@@ -7058,6 +7064,7 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
70587064
(0, payment_preimage, required),
70597065
(2, incoming_cltv_expiry, required),
70607066
(3, payment_metadata, option),
7067+
(4, payment_data, option), // Added in 0.0.116
70617068
},
70627069
;);
70637070

@@ -8704,10 +8711,13 @@ mod tests {
87048711

87058712
#[test]
87068713
fn test_keysend_msg_with_secret_err() {
8707-
// Test that we error as expected if we receive a keysend payment that includes a payment secret.
8714+
// Test that we error as expected if we receive a keysend payment that includes a payment
8715+
// secret when we don't support MPP keysend.
8716+
let mut reject_mpp_keysend_cfg = test_default_channel_config();
8717+
reject_mpp_keysend_cfg.accept_mpp_keysend = false;
87088718
let chanmon_cfgs = create_chanmon_cfgs(2);
87098719
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
8710-
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
8720+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, Some(reject_mpp_keysend_cfg)]);
87118721
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
87128722

87138723
let payer_pubkey = nodes[0].node.get_our_node_id();

0 commit comments

Comments
 (0)