Skip to content

Commit 5cd6351

Browse files
committed
Add min_final_cltv_expiry parameter to invoice utils
1 parent 7635dea commit 5cd6351

File tree

5 files changed

+77
-35
lines changed

5 files changed

+77
-35
lines changed

lightning-invoice/src/de.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use secp256k1;
2222
use secp256k1::ecdsa::{RecoveryId, RecoverableSignature};
2323
use secp256k1::PublicKey;
2424

25-
use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiry, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp,
25+
use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp,
2626
SemanticError, PrivateRoute, ParseError, ParseOrSemanticError, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawInvoice,
2727
constants, SignedRawInvoice, RawDataPart, InvoiceFeatures};
2828

@@ -452,7 +452,7 @@ impl FromBase32 for TaggedField {
452452
constants::TAG_EXPIRY_TIME =>
453453
Ok(TaggedField::ExpiryTime(ExpiryTime::from_base32(field_data)?)),
454454
constants::TAG_MIN_FINAL_CLTV_EXPIRY_DELTA =>
455-
Ok(TaggedField::MinFinalCltvExpiry(MinFinalCltvExpiry::from_base32(field_data)?)),
455+
Ok(TaggedField::MinFinalCltvExpiryDelta(MinFinalCltvExpiryDelta::from_base32(field_data)?)),
456456
constants::TAG_FALLBACK =>
457457
Ok(TaggedField::Fallback(Fallback::from_base32(field_data)?)),
458458
constants::TAG_PRIVATE_ROUTE =>
@@ -523,13 +523,13 @@ impl FromBase32 for ExpiryTime {
523523
}
524524
}
525525

526-
impl FromBase32 for MinFinalCltvExpiry {
526+
impl FromBase32 for MinFinalCltvExpiryDelta {
527527
type Err = ParseError;
528528

529-
fn from_base32(field_data: &[u5]) -> Result<MinFinalCltvExpiry, ParseError> {
529+
fn from_base32(field_data: &[u5]) -> Result<MinFinalCltvExpiryDelta, ParseError> {
530530
let expiry = parse_int_be::<u64, u5>(field_data, 32);
531531
if let Some(expiry) = expiry {
532-
Ok(MinFinalCltvExpiry(expiry))
532+
Ok(MinFinalCltvExpiryDelta(expiry))
533533
} else {
534534
Err(ParseError::IntegerOverflowError)
535535
}
@@ -841,13 +841,13 @@ mod test {
841841

842842
#[test]
843843
fn test_parse_min_final_cltv_expiry_delta() {
844-
use crate::MinFinalCltvExpiry;
844+
use crate::MinFinalCltvExpiryDelta;
845845
use bech32::FromBase32;
846846

847847
let input = from_bech32("pr".as_bytes());
848-
let expected = Ok(MinFinalCltvExpiry(35));
848+
let expected = Ok(MinFinalCltvExpiryDelta(35));
849849

850-
assert_eq!(MinFinalCltvExpiry::from_base32(&input), expected);
850+
assert_eq!(MinFinalCltvExpiryDelta::from_base32(&input), expected);
851851
}
852852

853853
#[test]

lightning-invoice/src/lib.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ pub enum TaggedField {
410410
PayeePubKey(PayeePubKey),
411411
DescriptionHash(Sha256),
412412
ExpiryTime(ExpiryTime),
413-
MinFinalCltvExpiry(MinFinalCltvExpiry),
413+
MinFinalCltvExpiryDelta(MinFinalCltvExpiryDelta),
414414
Fallback(Fallback),
415415
PrivateRoute(PrivateRoute),
416416
PaymentSecret(PaymentSecret),
@@ -440,7 +440,7 @@ pub struct ExpiryTime(Duration);
440440

441441
/// `min_final_cltv_expiry_delta` to use for the last HTLC in the route
442442
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
443-
pub struct MinFinalCltvExpiry(pub u64);
443+
pub struct MinFinalCltvExpiryDelta(pub u64);
444444

445445
// TODO: better types instead onf byte arrays
446446
/// Fallback address in case no LN payment is possible
@@ -656,7 +656,7 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
656656
impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, T, tb::False, S> {
657657
/// Sets `min_final_cltv_expiry_delta`.
658658
pub fn min_final_cltv_expiry_delta(mut self, min_final_cltv_expiry_delta: u64) -> InvoiceBuilder<D, H, T, tb::True, S> {
659-
self.tagged_fields.push(TaggedField::MinFinalCltvExpiry(MinFinalCltvExpiry(min_final_cltv_expiry_delta)));
659+
self.tagged_fields.push(TaggedField::MinFinalCltvExpiryDelta(MinFinalCltvExpiryDelta(min_final_cltv_expiry_delta)));
660660
self.set_flags()
661661
}
662662
}
@@ -925,8 +925,8 @@ impl RawInvoice {
925925
find_extract!(self.known_tagged_fields(), TaggedField::ExpiryTime(ref x), x)
926926
}
927927

928-
pub fn min_final_cltv_expiry_delta(&self) -> Option<&MinFinalCltvExpiry> {
929-
find_extract!(self.known_tagged_fields(), TaggedField::MinFinalCltvExpiry(ref x), x)
928+
pub fn min_final_cltv_expiry_delta(&self) -> Option<&MinFinalCltvExpiryDelta> {
929+
find_extract!(self.known_tagged_fields(), TaggedField::MinFinalCltvExpiryDelta(ref x), x)
930930
}
931931

932932
pub fn payment_secret(&self) -> Option<&PaymentSecret> {
@@ -1297,7 +1297,7 @@ impl TaggedField {
12971297
TaggedField::PayeePubKey(_) => constants::TAG_PAYEE_PUB_KEY,
12981298
TaggedField::DescriptionHash(_) => constants::TAG_DESCRIPTION_HASH,
12991299
TaggedField::ExpiryTime(_) => constants::TAG_EXPIRY_TIME,
1300-
TaggedField::MinFinalCltvExpiry(_) => constants::TAG_MIN_FINAL_CLTV_EXPIRY_DELTA,
1300+
TaggedField::MinFinalCltvExpiryDelta(_) => constants::TAG_MIN_FINAL_CLTV_EXPIRY_DELTA,
13011301
TaggedField::Fallback(_) => constants::TAG_FALLBACK,
13021302
TaggedField::PrivateRoute(_) => constants::TAG_PRIVATE_ROUTE,
13031303
TaggedField::PaymentSecret(_) => constants::TAG_PAYMENT_SECRET,
@@ -1444,6 +1444,9 @@ pub enum CreationError {
14441444
///
14451445
/// [phantom invoices]: crate::utils::create_phantom_invoice
14461446
MissingRouteHints,
1447+
1448+
/// The provided `min_final_cltv_expiry_delta` was less than `MIN_FINAL_CLTV_EXPIRY_DELTA`.
1449+
MinFinalCltvExpiryDeltaTooShort,
14471450
}
14481451

14491452
impl Display for CreationError {
@@ -1454,6 +1457,8 @@ impl Display for CreationError {
14541457
CreationError::TimestampOutOfBounds => f.write_str("The Unix timestamp of the supplied date is less than zero or greater than 35-bits"),
14551458
CreationError::InvalidAmount => f.write_str("The supplied millisatoshi amount was greater than the total bitcoin supply"),
14561459
CreationError::MissingRouteHints => f.write_str("The invoice required route hints and they weren't provided"),
1460+
CreationError::MinFinalCltvExpiryDeltaTooShort => f.write_str(
1461+
"The supplied final CLTV expiry delta was less than LDK's `MIN_FINAL_CLTV_EXPIRY_DELTA`"),
14571462
}
14581463
}
14591464
}

lightning-invoice/src/payment.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2113,7 +2113,7 @@ mod tests {
21132113

21142114
assert!(invoice_payer.pay_invoice(&create_invoice_from_channelmanager_and_duration_since_epoch(
21152115
&nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::Bitcoin,
2116-
Some(100_010_000), "Invoice".to_string(), duration_since_epoch(), 3600).unwrap())
2116+
Some(100_010_000), "Invoice".to_string(), duration_since_epoch(), 3600, None).unwrap())
21172117
.is_ok());
21182118
let htlc_msgs = nodes[0].node.get_and_clear_pending_msg_events();
21192119
assert_eq!(htlc_msgs.len(), 2);
@@ -2158,7 +2158,7 @@ mod tests {
21582158

21592159
assert!(invoice_payer.pay_invoice(&create_invoice_from_channelmanager_and_duration_since_epoch(
21602160
&nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::Bitcoin,
2161-
Some(100_010_000), "Invoice".to_string(), duration_since_epoch(), 3600).unwrap())
2161+
Some(100_010_000), "Invoice".to_string(), duration_since_epoch(), 3600, None).unwrap())
21622162
.is_ok());
21632163
let htlc_msgs = nodes[0].node.get_and_clear_pending_msg_events();
21642164
assert_eq!(htlc_msgs.len(), 2);
@@ -2239,7 +2239,7 @@ mod tests {
22392239

22402240
assert!(invoice_payer.pay_invoice(&create_invoice_from_channelmanager_and_duration_since_epoch(
22412241
&nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::Bitcoin,
2242-
Some(100_010_000), "Invoice".to_string(), duration_since_epoch(), 3600).unwrap())
2242+
Some(100_010_000), "Invoice".to_string(), duration_since_epoch(), 3600, None).unwrap())
22432243
.is_ok());
22442244
let htlc_updates = SendEvent::from_node(&nodes[0]);
22452245
check_added_monitors!(nodes[0], 1);

lightning-invoice/src/ser.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use core::fmt::{Display, Formatter};
33
use bech32::{ToBase32, u5, WriteBase32, Base32Len};
44
use crate::prelude::*;
55

6-
use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiry, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp,
6+
use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp,
77
PrivateRoute, Description, RawTaggedField, Currency, RawHrp, SiPrefix, constants, SignedRawInvoice, RawDataPart};
88

99
/// Converts a stream of bytes written to it to base32. On finalization the according padding will
@@ -313,13 +313,13 @@ impl Base32Len for ExpiryTime {
313313
}
314314
}
315315

316-
impl ToBase32 for MinFinalCltvExpiry {
316+
impl ToBase32 for MinFinalCltvExpiryDelta {
317317
fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
318318
writer.write(&encode_int_be_base32(self.0))
319319
}
320320
}
321321

322-
impl Base32Len for MinFinalCltvExpiry {
322+
impl Base32Len for MinFinalCltvExpiryDelta {
323323
fn base32_len(&self) -> usize {
324324
encoded_int_be_base32_size(self.0)
325325
}
@@ -434,7 +434,7 @@ impl ToBase32 for TaggedField {
434434
TaggedField::ExpiryTime(ref duration) => {
435435
write_tagged_field(writer, constants::TAG_EXPIRY_TIME, duration)
436436
},
437-
TaggedField::MinFinalCltvExpiry(ref expiry) => {
437+
TaggedField::MinFinalCltvExpiryDelta(ref expiry) => {
438438
write_tagged_field(writer, constants::TAG_MIN_FINAL_CLTV_EXPIRY_DELTA, expiry)
439439
},
440440
TaggedField::Fallback(ref fallback_address) => {

lightning-invoice/src/utils.rs

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,12 @@ where
235235
///
236236
/// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for
237237
/// in excess of the current time.
238+
/// You can specify a custom `min_final_cltv_expiry_delta`, or let LDK default it to
239+
/// `MIN_FINAL_CLTV_EXPIRY_DELTA`. The provided expiry must be at least `MIN_FINAL_CLTV_EXPIRY_DELTA`.
238240
pub fn create_invoice_from_channelmanager<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
239241
channelmanager: &ChannelManager<M, T, K, F, L>, keys_manager: K, logger: L,
240-
network: Currency, amt_msat: Option<u64>, description: String, invoice_expiry_delta_secs: u32
242+
network: Currency, amt_msat: Option<u64>, description: String, invoice_expiry_delta_secs: u32,
243+
min_final_cltv_expiry_delta: Option<u32>,
241244
) -> Result<Invoice, SignOrCreationError<()>>
242245
where
243246
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
@@ -251,7 +254,7 @@ where
251254
.expect("for the foreseeable future this shouldn't happen");
252255
create_invoice_from_channelmanager_and_duration_since_epoch(
253256
channelmanager, keys_manager, logger, network, amt_msat, description, duration,
254-
invoice_expiry_delta_secs
257+
invoice_expiry_delta_secs, min_final_cltv_expiry_delta,
255258
)
256259
}
257260

@@ -268,7 +271,7 @@ where
268271
pub fn create_invoice_from_channelmanager_with_description_hash<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
269272
channelmanager: &ChannelManager<M, T, K, F, L>, keys_manager: K, logger: L,
270273
network: Currency, amt_msat: Option<u64>, description_hash: Sha256,
271-
invoice_expiry_delta_secs: u32
274+
invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option<u32>,
272275
) -> Result<Invoice, SignOrCreationError<()>>
273276
where
274277
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
@@ -285,7 +288,7 @@ where
285288

286289
create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch(
287290
channelmanager, keys_manager, logger, network, amt_msat,
288-
description_hash, duration, invoice_expiry_delta_secs
291+
description_hash, duration, invoice_expiry_delta_secs, min_final_cltv_expiry_delta,
289292
)
290293
}
291294

@@ -295,7 +298,7 @@ where
295298
pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
296299
channelmanager: &ChannelManager<M, T, K, F, L>, keys_manager: K, logger: L,
297300
network: Currency, amt_msat: Option<u64>, description_hash: Sha256,
298-
duration_since_epoch: Duration, invoice_expiry_delta_secs: u32
301+
duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option<u32>,
299302
) -> Result<Invoice, SignOrCreationError<()>>
300303
where
301304
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
@@ -307,7 +310,7 @@ where
307310
_create_invoice_from_channelmanager_and_duration_since_epoch(
308311
channelmanager, keys_manager, logger, network, amt_msat,
309312
InvoiceDescription::Hash(&description_hash),
310-
duration_since_epoch, invoice_expiry_delta_secs
313+
duration_since_epoch, invoice_expiry_delta_secs, min_final_cltv_expiry_delta,
311314
)
312315
}
313316

@@ -317,7 +320,7 @@ where
317320
pub fn create_invoice_from_channelmanager_and_duration_since_epoch<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
318321
channelmanager: &ChannelManager<M, T, K, F, L>, keys_manager: K, logger: L,
319322
network: Currency, amt_msat: Option<u64>, description: String, duration_since_epoch: Duration,
320-
invoice_expiry_delta_secs: u32
323+
invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option<u32>,
321324
) -> Result<Invoice, SignOrCreationError<()>>
322325
where
323326
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
@@ -331,14 +334,14 @@ where
331334
InvoiceDescription::Direct(
332335
&Description::new(description).map_err(SignOrCreationError::CreationError)?,
333336
),
334-
duration_since_epoch, invoice_expiry_delta_secs
337+
duration_since_epoch, invoice_expiry_delta_secs, min_final_cltv_expiry_delta,
335338
)
336339
}
337340

338341
fn _create_invoice_from_channelmanager_and_duration_since_epoch<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
339342
channelmanager: &ChannelManager<M, T, K, F, L>, keys_manager: K, logger: L,
340343
network: Currency, amt_msat: Option<u64>, description: InvoiceDescription,
341-
duration_since_epoch: Duration, invoice_expiry_delta_secs: u32
344+
duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option<u32>,
342345
) -> Result<Invoice, SignOrCreationError<()>>
343346
where
344347
M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
@@ -347,6 +350,10 @@ where
347350
F::Target: FeeEstimator,
348351
L::Target: Logger,
349352
{
353+
if min_final_cltv_expiry_delta.is_some() && min_final_cltv_expiry_delta.unwrap() < MIN_FINAL_CLTV_EXPIRY_DELTA {
354+
return Err(SignOrCreationError::CreationError(CreationError::MinFinalCltvExpiryDeltaTooShort));
355+
}
356+
350357
// `create_inbound_payment` only returns an error if the amount is greater than the total bitcoin
351358
// supply.
352359
let (payment_hash, payment_secret) = channelmanager
@@ -370,7 +377,7 @@ where
370377
.payment_hash(Hash::from_slice(&payment_hash.0).unwrap())
371378
.payment_secret(payment_secret)
372379
.basic_mpp()
373-
.min_final_cltv_expiry_delta(MIN_FINAL_CLTV_EXPIRY_DELTA.into())
380+
.min_final_cltv_expiry_delta(min_final_cltv_expiry_delta.unwrap_or(MIN_FINAL_CLTV_EXPIRY_DELTA).into())
374381
.expiry_time(Duration::from_secs(invoice_expiry_delta_secs.into()));
375382
if let Some(amt) = amt_msat {
376383
invoice = invoice.amount_milli_satoshis(amt);
@@ -683,7 +690,7 @@ impl<'a, S: Score> Score for ScorerAccountingForInFlightHtlcs<'a, S> {
683690
#[cfg(test)]
684691
mod test {
685692
use core::time::Duration;
686-
use crate::{Currency, Description, InvoiceDescription};
693+
use crate::{Currency, Description, InvoiceDescription, SignOrCreationError, CreationError};
687694
use bitcoin_hashes::Hash;
688695
use bitcoin_hashes::sha256::Hash as Sha256;
689696
use lightning::chain::keysinterface::PhantomKeysManager;
@@ -710,8 +717,9 @@ mod test {
710717
let invoice = create_invoice_from_channelmanager_and_duration_since_epoch(
711718
&nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::BitcoinTestnet,
712719
Some(10_000), "test".to_string(), Duration::from_secs(1234567),
713-
non_default_invoice_expiry_secs).unwrap();
720+
non_default_invoice_expiry_secs, None).unwrap();
714721
assert_eq!(invoice.amount_pico_btc(), Some(100_000));
722+
// If no `min_final_cltv_expiry_delta` is specified, then it should be `MIN_FINAL_CLTV_EXPIRY_DELTA`.
715723
assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
716724
assert_eq!(invoice.description(), InvoiceDescription::Direct(&Description("test".to_string())));
717725
assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
@@ -775,7 +783,7 @@ mod test {
775783
let description_hash = crate::Sha256(Hash::hash("Testing description_hash".as_bytes()));
776784
let invoice = crate::utils::create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch(
777785
&nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::BitcoinTestnet,
778-
Some(10_000), description_hash, Duration::from_secs(1234567), 3600
786+
Some(10_000), description_hash, Duration::from_secs(1234567), 3600, None,
779787
).unwrap();
780788
assert_eq!(invoice.amount_pico_btc(), Some(100_000));
781789
assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
@@ -967,7 +975,7 @@ mod test {
967975
let invoice = create_invoice_from_channelmanager_and_duration_since_epoch(
968976
&invoice_node.node, invoice_node.keys_manager, invoice_node.logger,
969977
Currency::BitcoinTestnet, invoice_amt, "test".to_string(), Duration::from_secs(1234567),
970-
3600).unwrap();
978+
3600, None).unwrap();
971979
let hints = invoice.private_routes();
972980

973981
for hint in hints {
@@ -1494,4 +1502,33 @@ mod test {
14941502
}
14951503
assert!(chan_ids_to_match.is_empty(), "Unmatched short channel ids: {:?}", chan_ids_to_match);
14961504
}
1505+
1506+
#[test]
1507+
fn test_create_invoice_with_valid_custom_min_final_cltv_expiry_delta() {
1508+
let chanmon_cfgs = create_chanmon_cfgs(2);
1509+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
1510+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
1511+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
1512+
let invoice = crate::utils::create_invoice_from_channelmanager_and_duration_since_epoch(
1513+
&nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::BitcoinTestnet,
1514+
Some(10_000), "Some description".into(), Duration::from_secs(1234567), 3600, Some(30),
1515+
).unwrap();
1516+
assert_eq!(invoice.min_final_cltv_expiry_delta(), 30 as u64);
1517+
}
1518+
1519+
#[test]
1520+
fn test_create_invoice_fails_with_invalid_custom_min_final_cltv_expiry_delta() {
1521+
let chanmon_cfgs = create_chanmon_cfgs(2);
1522+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
1523+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
1524+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
1525+
let result = crate::utils::create_invoice_from_channelmanager_and_duration_since_epoch(
1526+
&nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::BitcoinTestnet,
1527+
Some(10_000), "Some description".into(), Duration::from_secs(1234567), 3600, Some(MIN_FINAL_CLTV_EXPIRY_DELTA - 1),
1528+
);
1529+
match result {
1530+
Err(SignOrCreationError::CreationError(CreationError::MinFinalCltvExpiryDeltaTooShort)) => {},
1531+
_ => panic!(),
1532+
}
1533+
}
14971534
}

0 commit comments

Comments
 (0)