Skip to content

Commit 68d4717

Browse files
committed
Move BOLT 12 invoice method implementations
1 parent 85c471a commit 68d4717

File tree

1 file changed

+95
-65
lines changed

1 file changed

+95
-65
lines changed

lightning/src/offers/invoice.rs

Lines changed: 95 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -501,106 +501,50 @@ impl Bolt12Invoice {
501501
/// This is not exported to bindings users as slices with non-reference types cannot be ABI
502502
/// matched in another language.
503503
pub fn payment_paths(&self) -> &[(BlindedPayInfo, BlindedPath)] {
504-
&self.contents.fields().payment_paths[..]
504+
self.contents.payment_paths()
505505
}
506506

507507
/// Duration since the Unix epoch when the invoice was created.
508508
pub fn created_at(&self) -> Duration {
509-
self.contents.fields().created_at
509+
self.contents.created_at()
510510
}
511511

512512
/// Duration since [`Bolt12Invoice::created_at`] when the invoice has expired and therefore
513513
/// should no longer be paid.
514514
pub fn relative_expiry(&self) -> Duration {
515-
self.contents.fields().relative_expiry.unwrap_or(DEFAULT_RELATIVE_EXPIRY)
515+
self.contents.relative_expiry()
516516
}
517517

518518
/// Whether the invoice has expired.
519519
#[cfg(feature = "std")]
520520
pub fn is_expired(&self) -> bool {
521-
let absolute_expiry = self.created_at().checked_add(self.relative_expiry());
522-
match absolute_expiry {
523-
Some(seconds_from_epoch) => match SystemTime::UNIX_EPOCH.elapsed() {
524-
Ok(elapsed) => elapsed > seconds_from_epoch,
525-
Err(_) => false,
526-
},
527-
None => false,
528-
}
521+
self.contents.is_expired()
529522
}
530523

531524
/// SHA256 hash of the payment preimage that will be given in return for paying the invoice.
532525
pub fn payment_hash(&self) -> PaymentHash {
533-
self.contents.fields().payment_hash
526+
self.contents.payment_hash()
534527
}
535528

536529
/// The minimum amount required for a successful payment of the invoice.
537530
pub fn amount_msats(&self) -> u64 {
538-
self.contents.fields().amount_msats
531+
self.contents.amount_msats()
539532
}
540533

541534
/// Fallback addresses for paying the invoice on-chain, in order of most-preferred to
542535
/// least-preferred.
543536
pub fn fallbacks(&self) -> Vec<Address> {
544-
let network = match self.network() {
545-
None => return Vec::new(),
546-
Some(network) => network,
547-
};
548-
549-
let to_valid_address = |address: &FallbackAddress| {
550-
let version = match WitnessVersion::try_from(address.version) {
551-
Ok(version) => version,
552-
Err(_) => return None,
553-
};
554-
555-
let program = &address.program;
556-
if program.len() < 2 || program.len() > 40 {
557-
return None;
558-
}
559-
560-
let address = Address {
561-
payload: Payload::WitnessProgram {
562-
version,
563-
program: address.program.clone(),
564-
},
565-
network,
566-
};
567-
568-
if !address.is_standard() && version == WitnessVersion::V0 {
569-
return None;
570-
}
571-
572-
Some(address)
573-
};
574-
575-
self.contents.fields().fallbacks
576-
.as_ref()
577-
.map(|fallbacks| fallbacks.iter().filter_map(to_valid_address).collect())
578-
.unwrap_or_else(Vec::new)
579-
}
580-
581-
fn network(&self) -> Option<Network> {
582-
let chain = self.contents.chain();
583-
if chain == ChainHash::using_genesis_block(Network::Bitcoin) {
584-
Some(Network::Bitcoin)
585-
} else if chain == ChainHash::using_genesis_block(Network::Testnet) {
586-
Some(Network::Testnet)
587-
} else if chain == ChainHash::using_genesis_block(Network::Signet) {
588-
Some(Network::Signet)
589-
} else if chain == ChainHash::using_genesis_block(Network::Regtest) {
590-
Some(Network::Regtest)
591-
} else {
592-
None
593-
}
537+
self.contents.fallbacks()
594538
}
595539

596540
/// Features pertaining to paying an invoice.
597541
pub fn features(&self) -> &Bolt12InvoiceFeatures {
598-
&self.contents.fields().features
542+
self.contents.features()
599543
}
600544

601545
/// The public key corresponding to the key used to sign the invoice.
602546
pub fn signing_pubkey(&self) -> PublicKey {
603-
self.contents.fields().signing_pubkey
547+
self.contents.signing_pubkey()
604548
}
605549

606550
/// Signature of the invoice verified using [`Bolt12Invoice::signing_pubkey`].
@@ -659,6 +603,92 @@ impl InvoiceContents {
659603
}
660604
}
661605

606+
fn payment_paths(&self) -> &[(BlindedPayInfo, BlindedPath)] {
607+
&self.fields().payment_paths[..]
608+
}
609+
610+
fn created_at(&self) -> Duration {
611+
self.fields().created_at
612+
}
613+
614+
fn relative_expiry(&self) -> Duration {
615+
self.fields().relative_expiry.unwrap_or(DEFAULT_RELATIVE_EXPIRY)
616+
}
617+
618+
#[cfg(feature = "std")]
619+
fn is_expired(&self) -> bool {
620+
let absolute_expiry = self.created_at().checked_add(self.relative_expiry());
621+
match absolute_expiry {
622+
Some(seconds_from_epoch) => match SystemTime::UNIX_EPOCH.elapsed() {
623+
Ok(elapsed) => elapsed > seconds_from_epoch,
624+
Err(_) => false,
625+
},
626+
None => false,
627+
}
628+
}
629+
630+
fn payment_hash(&self) -> PaymentHash {
631+
self.fields().payment_hash
632+
}
633+
634+
fn amount_msats(&self) -> u64 {
635+
self.fields().amount_msats
636+
}
637+
638+
fn fallbacks(&self) -> Vec<Address> {
639+
let chain = self.chain();
640+
let network = if chain == ChainHash::using_genesis_block(Network::Bitcoin) {
641+
Network::Bitcoin
642+
} else if chain == ChainHash::using_genesis_block(Network::Testnet) {
643+
Network::Testnet
644+
} else if chain == ChainHash::using_genesis_block(Network::Signet) {
645+
Network::Signet
646+
} else if chain == ChainHash::using_genesis_block(Network::Regtest) {
647+
Network::Regtest
648+
} else {
649+
return Vec::new()
650+
};
651+
652+
let to_valid_address = |address: &FallbackAddress| {
653+
let version = match WitnessVersion::try_from(address.version) {
654+
Ok(version) => version,
655+
Err(_) => return None,
656+
};
657+
658+
let program = &address.program;
659+
if program.len() < 2 || program.len() > 40 {
660+
return None;
661+
}
662+
663+
let address = Address {
664+
payload: Payload::WitnessProgram {
665+
version,
666+
program: program.clone(),
667+
},
668+
network,
669+
};
670+
671+
if !address.is_standard() && version == WitnessVersion::V0 {
672+
return None;
673+
}
674+
675+
Some(address)
676+
};
677+
678+
self.fields().fallbacks
679+
.as_ref()
680+
.map(|fallbacks| fallbacks.iter().filter_map(to_valid_address).collect())
681+
.unwrap_or_else(Vec::new)
682+
}
683+
684+
fn features(&self) -> &Bolt12InvoiceFeatures {
685+
&self.fields().features
686+
}
687+
688+
fn signing_pubkey(&self) -> PublicKey {
689+
self.fields().signing_pubkey
690+
}
691+
662692
fn fields(&self) -> &InvoiceFields {
663693
match self {
664694
InvoiceContents::ForOffer { fields, .. } => fields,

0 commit comments

Comments
 (0)