Skip to content

Commit 694a8b9

Browse files
Fail out-of-PaymentContext inbound keysends
Here we bubble up the payment context into PendingHTLCRouting::ReceiveKeysend and check it when receiving a spontaneous payment prior to generating a claimable event. Prior to this patch, we would have accepted out-of-context keysends sent over blinded paths taken from our BOLT 12 invoices. As a side effect of this, our blinded keysend success test cases now fail, so those tests are now removed. Their coverage is re-added in future commits when we add support for async receive, meaning we're able to receive blinded keysends in the correct payment context. While we could avoid storing the payment context for the purposes of this bugfix, we go ahead and store it now because it will be needed when support for receiving async payments is added.
1 parent ec8472e commit 694a8b9

File tree

4 files changed

+82
-172
lines changed

4 files changed

+82
-172
lines changed

Diff for: lightning/src/ln/async_payments_tests.rs

+1-168
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@
99

1010
use crate::blinded_path::message::{MessageContext, OffersContext};
1111
use crate::events::{Event, HTLCDestination, MessageSendEventsProvider, PaymentFailureReason};
12-
use crate::ln::blinded_payment_tests::{blinded_payment_path, get_blinded_route_parameters};
13-
use crate::ln::channelmanager;
12+
use crate::ln::blinded_payment_tests::get_blinded_route_parameters;
1413
use crate::ln::channelmanager::{PaymentId, RecipientOnionFields};
1514
use crate::ln::functional_test_utils::*;
16-
use crate::ln::inbound_payment;
1715
use crate::ln::msgs::ChannelMessageHandler;
1816
use crate::ln::msgs::OnionMessageHandler;
1917
use crate::ln::offers_tests;
@@ -29,11 +27,8 @@ use crate::onion_message::messenger::{Destination, MessageRouter, MessageSendIns
2927
use crate::onion_message::offers::OffersMessage;
3028
use crate::onion_message::packet::ParsedOnionMessageContents;
3129
use crate::prelude::*;
32-
use crate::routing::router::{PaymentParameters, RouteParameters};
33-
use crate::sign::NodeSigner;
3430
use crate::types::features::Bolt12InvoiceFeatures;
3531
use crate::types::payment::{PaymentPreimage, PaymentSecret};
36-
use crate::util::config::UserConfig;
3732
use bitcoin::secp256k1;
3833
use bitcoin::secp256k1::Secp256k1;
3934

@@ -67,168 +62,6 @@ fn create_static_invoice<T: secp256k1::Signing + secp256k1::Verification>(
6762
(offer, static_invoice)
6863
}
6964

70-
#[test]
71-
fn blinded_keysend() {
72-
let chanmon_cfgs = create_chanmon_cfgs(3);
73-
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
74-
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
75-
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
76-
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0);
77-
let chan_upd_1_2 =
78-
create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 0).0.contents;
79-
80-
let inbound_payment_key = nodes[2].keys_manager.get_inbound_payment_key();
81-
let payment_secret = inbound_payment::create_for_spontaneous_payment(
82-
&inbound_payment_key,
83-
None,
84-
u32::MAX,
85-
nodes[2].node.duration_since_epoch().as_secs(),
86-
None,
87-
)
88-
.unwrap();
89-
90-
let amt_msat = 5000;
91-
let keysend_preimage = PaymentPreimage([42; 32]);
92-
let route_params = get_blinded_route_parameters(
93-
amt_msat,
94-
payment_secret,
95-
1,
96-
1_0000_0000,
97-
nodes.iter().skip(1).map(|n| n.node.get_our_node_id()).collect(),
98-
&[&chan_upd_1_2],
99-
&chanmon_cfgs[2].keys_manager,
100-
);
101-
102-
let payment_hash = nodes[0]
103-
.node
104-
.send_spontaneous_payment(
105-
Some(keysend_preimage),
106-
RecipientOnionFields::spontaneous_empty(),
107-
PaymentId(keysend_preimage.0),
108-
route_params,
109-
Retry::Attempts(0),
110-
)
111-
.unwrap();
112-
check_added_monitors(&nodes[0], 1);
113-
114-
let expected_route: &[&[&Node]] = &[&[&nodes[1], &nodes[2]]];
115-
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
116-
assert_eq!(events.len(), 1);
117-
118-
let ev = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &mut events);
119-
pass_along_path(
120-
&nodes[0],
121-
expected_route[0],
122-
amt_msat,
123-
payment_hash,
124-
Some(payment_secret),
125-
ev.clone(),
126-
true,
127-
Some(keysend_preimage),
128-
);
129-
claim_payment_along_route(ClaimAlongRouteArgs::new(
130-
&nodes[0],
131-
expected_route,
132-
keysend_preimage,
133-
));
134-
}
135-
136-
#[test]
137-
fn blinded_mpp_keysend() {
138-
let chanmon_cfgs = create_chanmon_cfgs(4);
139-
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
140-
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
141-
let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
142-
143-
create_announced_chan_between_nodes(&nodes, 0, 1);
144-
create_announced_chan_between_nodes(&nodes, 0, 2);
145-
let chan_1_3 = create_announced_chan_between_nodes(&nodes, 1, 3);
146-
let chan_2_3 = create_announced_chan_between_nodes(&nodes, 2, 3);
147-
148-
let inbound_payment_key = nodes[3].keys_manager.get_inbound_payment_key();
149-
let payment_secret = inbound_payment::create_for_spontaneous_payment(
150-
&inbound_payment_key,
151-
None,
152-
u32::MAX,
153-
nodes[3].node.duration_since_epoch().as_secs(),
154-
None,
155-
)
156-
.unwrap();
157-
158-
let amt_msat = 15_000_000;
159-
let keysend_preimage = PaymentPreimage([42; 32]);
160-
let route_params = {
161-
let pay_params = PaymentParameters::blinded(vec![
162-
blinded_payment_path(
163-
payment_secret,
164-
1,
165-
1_0000_0000,
166-
vec![nodes[1].node.get_our_node_id(), nodes[3].node.get_our_node_id()],
167-
&[&chan_1_3.0.contents],
168-
&chanmon_cfgs[3].keys_manager,
169-
),
170-
blinded_payment_path(
171-
payment_secret,
172-
1,
173-
1_0000_0000,
174-
vec![nodes[2].node.get_our_node_id(), nodes[3].node.get_our_node_id()],
175-
&[&chan_2_3.0.contents],
176-
&chanmon_cfgs[3].keys_manager,
177-
),
178-
])
179-
.with_bolt12_features(channelmanager::provided_bolt12_invoice_features(
180-
&UserConfig::default(),
181-
))
182-
.unwrap();
183-
RouteParameters::from_payment_params_and_value(pay_params, amt_msat)
184-
};
185-
186-
let payment_hash = nodes[0]
187-
.node
188-
.send_spontaneous_payment(
189-
Some(keysend_preimage),
190-
RecipientOnionFields::spontaneous_empty(),
191-
PaymentId(keysend_preimage.0),
192-
route_params,
193-
Retry::Attempts(0),
194-
)
195-
.unwrap();
196-
check_added_monitors!(nodes[0], 2);
197-
198-
let expected_route: &[&[&Node]] = &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]];
199-
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
200-
assert_eq!(events.len(), 2);
201-
202-
let ev = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &mut events);
203-
pass_along_path(
204-
&nodes[0],
205-
expected_route[0],
206-
amt_msat,
207-
payment_hash.clone(),
208-
Some(payment_secret),
209-
ev.clone(),
210-
false,
211-
Some(keysend_preimage),
212-
);
213-
214-
let ev = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut events);
215-
pass_along_path(
216-
&nodes[0],
217-
expected_route[1],
218-
amt_msat,
219-
payment_hash.clone(),
220-
Some(payment_secret),
221-
ev.clone(),
222-
true,
223-
Some(keysend_preimage),
224-
);
225-
claim_payment_along_route(ClaimAlongRouteArgs::new(
226-
&nodes[0],
227-
expected_route,
228-
keysend_preimage,
229-
));
230-
}
231-
23265
#[test]
23366
fn invalid_keysend_payment_secret() {
23467
let chanmon_cfgs = create_chanmon_cfgs(3);

Diff for: lightning/src/ln/channelmanager.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,11 @@ pub enum PendingHTLCRouting {
240240
/// [`PaymentSecret`] and should verify it using our
241241
/// [`NodeSigner::get_inbound_payment_key`].
242242
has_recipient_created_payment_secret: bool,
243+
/// The context of the payment included by the recipient in a blinded path, or `None` if a
244+
/// blinded path was not used.
245+
///
246+
/// Used in part to determine the [`events::PaymentPurpose`].
247+
payment_context: Option<PaymentContext>,
243248
},
244249
}
245250

@@ -6051,15 +6056,16 @@ where
60516056
PendingHTLCRouting::ReceiveKeysend {
60526057
payment_data, payment_preimage, payment_metadata,
60536058
incoming_cltv_expiry, custom_tlvs, requires_blinded_error: _,
6054-
has_recipient_created_payment_secret,
6059+
has_recipient_created_payment_secret, payment_context,
60556060
} => {
60566061
let onion_fields = RecipientOnionFields {
60576062
payment_secret: payment_data.as_ref().map(|data| data.payment_secret),
60586063
payment_metadata,
60596064
custom_tlvs,
60606065
};
60616066
(incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage),
6062-
payment_data, None, None, onion_fields, has_recipient_created_payment_secret)
6067+
payment_data, payment_context, None, onion_fields,
6068+
has_recipient_created_payment_secret)
60636069
},
60646070
_ => {
60656071
panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive");
@@ -6256,6 +6262,12 @@ where
62566262
check_total_value!(purpose);
62576263
},
62586264
OnionPayload::Spontaneous(preimage) => {
6265+
if payment_context.is_some() {
6266+
if !matches!(payment_context, Some(PaymentContext::AsyncBolt12Offer(_))) {
6267+
log_trace!(self.logger, "Failing new HTLC with payment_hash {}: received a keysend payment to a non-async payments context {:#?}", payment_hash, payment_context);
6268+
}
6269+
fail_htlc!(claimable_htlc, payment_hash);
6270+
}
62596271
let purpose = events::PaymentPurpose::SpontaneousPayment(preimage);
62606272
check_total_value!(purpose);
62616273
}
@@ -12452,6 +12464,7 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
1245212464
(4, payment_data, option), // Added in 0.0.116
1245312465
(5, custom_tlvs, optional_vec),
1245412466
(7, has_recipient_created_payment_secret, (default_value, false)),
12467+
(9, payment_context, option),
1245512468
},
1245612469
);
1245712470

Diff for: lightning/src/ln/offers_tests.rs

+65-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ use crate::blinded_path::IntroductionNode;
4747
use crate::blinded_path::message::BlindedMessagePath;
4848
use crate::blinded_path::payment::{Bolt12OfferContext, Bolt12RefundContext, PaymentContext};
4949
use crate::blinded_path::message::{MessageContext, OffersContext};
50-
use crate::events::{ClosureReason, Event, MessageSendEventsProvider, PaymentFailureReason, PaymentPurpose};
51-
use crate::ln::channelmanager::{Bolt12PaymentError, MAX_SHORT_LIVED_RELATIVE_EXPIRY, PaymentId, RecentPaymentDetails, Retry, self};
50+
use crate::events::{ClosureReason, Event, HTLCDestination, MessageSendEventsProvider, PaymentFailureReason, PaymentPurpose};
51+
use crate::ln::channelmanager::{Bolt12PaymentError, MAX_SHORT_LIVED_RELATIVE_EXPIRY, PaymentId, RecentPaymentDetails, RecipientOnionFields, Retry, self};
5252
use crate::types::features::Bolt12InvoiceFeatures;
5353
use crate::ln::functional_test_utils::*;
5454
use crate::ln::msgs::{ChannelMessageHandler, Init, NodeAnnouncement, OnionMessage, OnionMessageHandler, RoutingMessageHandler, SocketAddress, UnsignedGossipMessage, UnsignedNodeAnnouncement};
@@ -62,6 +62,7 @@ use crate::onion_message::messenger::{Destination, PeeledOnion, MessageSendInstr
6262
use crate::onion_message::offers::OffersMessage;
6363
use crate::onion_message::packet::ParsedOnionMessageContents;
6464
use crate::routing::gossip::{NodeAlias, NodeId};
65+
use crate::routing::router::{PaymentParameters, RouteParameters};
6566
use crate::sign::{NodeSigner, Recipient};
6667
use crate::util::ser::Writeable;
6768

@@ -2255,6 +2256,68 @@ fn fails_paying_invoice_with_unknown_required_features() {
22552256
}
22562257
}
22572258

2259+
#[test]
2260+
fn rejects_keysend_to_non_static_invoice_path() {
2261+
// Test that we'll fail a keysend payment that was sent over a non-static BOLT 12 invoice path.
2262+
let chanmon_cfgs = create_chanmon_cfgs(2);
2263+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
2264+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
2265+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
2266+
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0);
2267+
2268+
// First pay the offer and save the payment preimage and invoice.
2269+
let offer = nodes[1].node.create_offer_builder(None).unwrap().build().unwrap();
2270+
let amt_msat = 5000;
2271+
let payment_id = PaymentId([1; 32]);
2272+
nodes[0].node.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(1), None).unwrap();
2273+
let invreq_om = nodes[0].onion_messenger.next_onion_message_for_peer(nodes[1].node.get_our_node_id()).unwrap();
2274+
nodes[1].onion_messenger.handle_onion_message(nodes[0].node.get_our_node_id(), &invreq_om);
2275+
let invoice_om = nodes[1].onion_messenger.next_onion_message_for_peer(nodes[0].node.get_our_node_id()).unwrap();
2276+
let invoice = extract_invoice(&nodes[0], &invoice_om).0;
2277+
nodes[0].onion_messenger.handle_onion_message(nodes[1].node.get_our_node_id(), &invoice_om);
2278+
2279+
route_bolt12_payment(&nodes[0], &[&nodes[1]], &invoice);
2280+
expect_recent_payment!(nodes[0], RecentPaymentDetails::Pending, payment_id);
2281+
2282+
let payment_preimage = match get_event!(nodes[1], Event::PaymentClaimable) {
2283+
Event::PaymentClaimable { purpose, .. } => purpose.preimage().unwrap(),
2284+
_ => panic!()
2285+
};
2286+
2287+
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage);
2288+
expect_recent_payment!(&nodes[0], RecentPaymentDetails::Fulfilled, payment_id);
2289+
2290+
// Time out the payment from recent payments so we can attempt to pay it again via keysend.
2291+
for _ in 0..=IDEMPOTENCY_TIMEOUT_TICKS {
2292+
nodes[0].node.timer_tick_occurred();
2293+
nodes[1].node.timer_tick_occurred();
2294+
}
2295+
2296+
// Pay the invoice via keysend now that we have the preimage and make sure the recipient fails it
2297+
// due to incorrect payment context.
2298+
let pay_params = PaymentParameters::from_bolt12_invoice(&invoice);
2299+
let route_params = RouteParameters::from_payment_params_and_value(pay_params, amt_msat);
2300+
let keysend_payment_id = PaymentId([2; 32]);
2301+
let payment_hash = nodes[0].node.send_spontaneous_payment(
2302+
Some(payment_preimage), RecipientOnionFields::spontaneous_empty(), keysend_payment_id,
2303+
route_params, Retry::Attempts(0)
2304+
).unwrap();
2305+
check_added_monitors!(nodes[0], 1);
2306+
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
2307+
assert_eq!(events.len(), 1);
2308+
let ev = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &mut events);
2309+
let route: &[&[&Node]] = &[&[&nodes[1]]];
2310+
2311+
let args = PassAlongPathArgs::new(&nodes[0], route[0], amt_msat, payment_hash, ev)
2312+
.with_payment_preimage(payment_preimage)
2313+
.expect_failure(HTLCDestination::FailedPayment { payment_hash });
2314+
do_pass_along_path(args);
2315+
let mut updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
2316+
nodes[0].node.handle_update_fail_htlc(nodes[1].node.get_our_node_id(), &updates.update_fail_htlcs[0]);
2317+
do_commitment_signed_dance(&nodes[0], &nodes[1], &updates.commitment_signed, false, false);
2318+
expect_payment_failed_conditions(&nodes[0], payment_hash, true, PaymentFailedConditions::new());
2319+
}
2320+
22582321
#[test]
22592322
fn no_double_pay_with_stale_channelmanager() {
22602323
// This tests the following bug:

Diff for: lightning/src/ln/onion_payment.rs

+1
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ pub(super) fn create_recv_pending_htlc_info(
235235
custom_tlvs,
236236
requires_blinded_error,
237237
has_recipient_created_payment_secret,
238+
payment_context,
238239
}
239240
} else if let Some(data) = payment_data {
240241
PendingHTLCRouting::Receive {

0 commit comments

Comments
 (0)