Skip to content

Commit 46df35b

Browse files
committed
Add a new AwaitingOffer outbound payment state for BIP 353
1 parent a39e274 commit 46df35b

File tree

2 files changed

+60
-25
lines changed

2 files changed

+60
-25
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3605,11 +3605,11 @@ where
36053605
pub fn list_recent_payments(&self) -> Vec<RecentPaymentDetails> {
36063606
self.pending_outbound_payments.pending_outbound_payments.lock().unwrap().iter()
36073607
.filter_map(|(payment_id, pending_outbound_payment)| match pending_outbound_payment {
3608-
PendingOutboundPayment::AwaitingInvoice { .. } => {
3609-
Some(RecentPaymentDetails::AwaitingInvoice { payment_id: *payment_id })
3610-
},
3611-
// InvoiceReceived is an intermediate state and doesn't need to be exposed
3612-
PendingOutboundPayment::InvoiceReceived { .. } => {
3608+
PendingOutboundPayment::AwaitingInvoice { .. }
3609+
| PendingOutboundPayment::AwaitingOffer { .. }
3610+
// InvoiceReceived is an intermediate state and doesn't need to be exposed
3611+
| PendingOutboundPayment::InvoiceReceived { .. } =>
3612+
{
36133613
Some(RecentPaymentDetails::AwaitingInvoice { payment_id: *payment_id })
36143614
},
36153615
PendingOutboundPayment::StaticInvoiceReceived { .. } => {
@@ -12254,6 +12254,7 @@ where
1225412254
}
1225512255
}
1225612256
PendingOutboundPayment::AwaitingInvoice { .. } => {},
12257+
PendingOutboundPayment::AwaitingOffer { .. } => {},
1225712258
PendingOutboundPayment::InvoiceReceived { .. } => {},
1225812259
PendingOutboundPayment::StaticInvoiceReceived { .. } => {},
1225912260
PendingOutboundPayment::Fulfilled { .. } => {},

lightning/src/ln/outbound_payment.rs

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ pub(crate) enum PendingOutboundPayment {
5858
Legacy {
5959
session_privs: HashSet<[u8; 32]>,
6060
},
61+
/// Used when we are waiting for an Offer to come back from a BIP 353 resolution
62+
AwaitingOffer {
63+
expiration: StaleExpiration,
64+
retry_strategy: Retry,
65+
max_total_routing_fee_msat: Option<u64>,
66+
/// Human Readable Names-originated payments should always specify an explicit amount to
67+
/// send up-front, which we track here and enforce once we receive the offer.
68+
amount_msats: u64,
69+
},
6170
AwaitingInvoice {
6271
expiration: StaleExpiration,
6372
retry_strategy: Retry,
@@ -201,6 +210,7 @@ impl PendingOutboundPayment {
201210
fn payment_hash(&self) -> Option<PaymentHash> {
202211
match self {
203212
PendingOutboundPayment::Legacy { .. } => None,
213+
PendingOutboundPayment::AwaitingOffer { .. } => None,
204214
PendingOutboundPayment::AwaitingInvoice { .. } => None,
205215
PendingOutboundPayment::InvoiceReceived { payment_hash, .. } => Some(*payment_hash),
206216
PendingOutboundPayment::StaticInvoiceReceived { payment_hash, .. } => Some(*payment_hash),
@@ -217,7 +227,8 @@ impl PendingOutboundPayment {
217227
PendingOutboundPayment::Retryable { session_privs, .. } |
218228
PendingOutboundPayment::Fulfilled { session_privs, .. } |
219229
PendingOutboundPayment::Abandoned { session_privs, .. } => session_privs,
220-
PendingOutboundPayment::AwaitingInvoice { .. } |
230+
PendingOutboundPayment::AwaitingOffer { .. } |
231+
PendingOutboundPayment::AwaitingInvoice { .. } |
221232
PendingOutboundPayment::InvoiceReceived { .. } |
222233
PendingOutboundPayment::StaticInvoiceReceived { .. } => { debug_assert!(false); return; },
223234
});
@@ -258,7 +269,8 @@ impl PendingOutboundPayment {
258269
PendingOutboundPayment::Abandoned { session_privs, .. } => {
259270
session_privs.remove(session_priv)
260271
},
261-
PendingOutboundPayment::AwaitingInvoice { .. } |
272+
PendingOutboundPayment::AwaitingOffer { .. } |
273+
PendingOutboundPayment::AwaitingInvoice { .. } |
262274
PendingOutboundPayment::InvoiceReceived { .. } |
263275
PendingOutboundPayment::StaticInvoiceReceived { .. } => { debug_assert!(false); false },
264276
};
@@ -288,7 +300,8 @@ impl PendingOutboundPayment {
288300
PendingOutboundPayment::Retryable { session_privs, .. } => {
289301
session_privs.insert(session_priv)
290302
},
291-
PendingOutboundPayment::AwaitingInvoice { .. } |
303+
PendingOutboundPayment::AwaitingOffer { .. } |
304+
PendingOutboundPayment::AwaitingInvoice { .. } |
292305
PendingOutboundPayment::InvoiceReceived { .. } |
293306
PendingOutboundPayment::StaticInvoiceReceived { .. } => { debug_assert!(false); false },
294307
PendingOutboundPayment::Fulfilled { .. } => false,
@@ -322,6 +335,7 @@ impl PendingOutboundPayment {
322335
session_privs.len()
323336
},
324337
PendingOutboundPayment::AwaitingInvoice { .. } => 0,
338+
PendingOutboundPayment::AwaitingOffer { .. } => 0,
325339
PendingOutboundPayment::InvoiceReceived { .. } => 0,
326340
PendingOutboundPayment::StaticInvoiceReceived { .. } => 0,
327341
}
@@ -416,8 +430,9 @@ impl Display for PaymentAttempts {
416430
}
417431
}
418432

419-
/// How long before a [`PendingOutboundPayment::AwaitingInvoice`] should be considered stale and
420-
/// candidate for removal in [`OutboundPayments::remove_stale_payments`].
433+
/// How long before a [`PendingOutboundPayment::AwaitingInvoice`] or
434+
/// [`PendingOutboundPayment::AwaitingOffer`] should be considered stale and candidate for removal
435+
/// in [`OutboundPayments::remove_stale_payments`].
421436
#[derive(Clone, Copy)]
422437
pub(crate) enum StaleExpiration {
423438
/// Number of times [`OutboundPayments::remove_stale_payments`] is called.
@@ -1388,7 +1403,9 @@ impl OutboundPayments {
13881403
log_error!(logger, "Unable to retry payments that were initially sent on LDK versions prior to 0.0.102");
13891404
return
13901405
},
1391-
PendingOutboundPayment::AwaitingInvoice { .. } => {
1406+
PendingOutboundPayment::AwaitingInvoice { .. }
1407+
| PendingOutboundPayment::AwaitingOffer { .. } =>
1408+
{
13921409
log_error!(logger, "Payment not yet sent");
13931410
debug_assert!(false);
13941411
return
@@ -1910,7 +1927,9 @@ impl OutboundPayments {
19101927
true
19111928
}
19121929
},
1913-
PendingOutboundPayment::AwaitingInvoice { expiration, .. } => {
1930+
PendingOutboundPayment::AwaitingInvoice { expiration, .. }
1931+
| PendingOutboundPayment::AwaitingOffer { expiration, .. } =>
1932+
{
19141933
let is_stale = match expiration {
19151934
StaleExpiration::AbsoluteTimeout(absolute_expiry) => {
19161935
*absolute_expiry <= duration_since_epoch
@@ -2096,22 +2115,28 @@ impl OutboundPayments {
20962115
let mut outbounds = self.pending_outbound_payments.lock().unwrap();
20972116
if let hash_map::Entry::Occupied(mut payment) = outbounds.entry(payment_id) {
20982117
payment.get_mut().mark_abandoned(reason);
2099-
if let PendingOutboundPayment::Abandoned { payment_hash, reason, .. } = payment.get() {
2100-
if payment.get().remaining_parts() == 0 {
2118+
match payment.get() {
2119+
PendingOutboundPayment::Abandoned { payment_hash, reason, .. } => {
2120+
if payment.get().remaining_parts() == 0 {
2121+
pending_events.lock().unwrap().push_back((events::Event::PaymentFailed {
2122+
payment_id,
2123+
payment_hash: Some(*payment_hash),
2124+
reason: *reason,
2125+
}, None));
2126+
payment.remove();
2127+
}
2128+
},
2129+
PendingOutboundPayment::AwaitingInvoice { .. }
2130+
| PendingOutboundPayment::AwaitingOffer { .. } =>
2131+
{
21012132
pending_events.lock().unwrap().push_back((events::Event::PaymentFailed {
21022133
payment_id,
2103-
payment_hash: Some(*payment_hash),
2104-
reason: *reason,
2134+
payment_hash: None,
2135+
reason: Some(reason),
21052136
}, None));
21062137
payment.remove();
2107-
}
2108-
} else if let PendingOutboundPayment::AwaitingInvoice { .. } = payment.get() {
2109-
pending_events.lock().unwrap().push_back((events::Event::PaymentFailed {
2110-
payment_id,
2111-
payment_hash: None,
2112-
reason: Some(reason),
2113-
}, None));
2114-
payment.remove();
2138+
},
2139+
_ => {},
21152140
}
21162141
}
21172142
}
@@ -2183,7 +2208,8 @@ impl OutboundPayments {
21832208
match self.pending_outbound_payments.lock().unwrap().entry(payment_id) {
21842209
hash_map::Entry::Occupied(mut entry) => {
21852210
let newly_added = match entry.get() {
2186-
PendingOutboundPayment::AwaitingInvoice { .. } |
2211+
PendingOutboundPayment::AwaitingOffer { .. } |
2212+
PendingOutboundPayment::AwaitingInvoice { .. } |
21872213
PendingOutboundPayment::InvoiceReceived { .. } |
21882214
PendingOutboundPayment::StaticInvoiceReceived { .. } =>
21892215
{
@@ -2285,6 +2311,14 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
22852311
(6, route_params, required),
22862312
(8, invoice_request, required),
22872313
},
2314+
// Added in 0.1. Prior versions will drop these outbounds on downgrade, which is safe because
2315+
// no HTLCs are in-flight.
2316+
(11, AwaitingOffer) => {
2317+
(0, expiration, required),
2318+
(2, retry_strategy, required),
2319+
(4, max_total_routing_fee_msat, option),
2320+
(6, amount_msats, required),
2321+
},
22882322
);
22892323

22902324
#[cfg(test)]

0 commit comments

Comments
 (0)