projects
/
rust-lightning
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Remove unused imports in static_invoice.rs
[rust-lightning]
/
lightning
/
src
/
offers
/
offer.rs
diff --git
a/lightning/src/offers/offer.rs
b/lightning/src/offers/offer.rs
index baac949515a3de0f180814fa3d25b31b46b35501..dd58c75cec27e600e803122d72d92036665b0976 100644
(file)
--- a/
lightning/src/offers/offer.rs
+++ b/
lightning/src/offers/offer.rs
@@
-24,7
+24,7
@@
//! use core::num::NonZeroU64;
//! use core::time::Duration;
//!
//! use core::num::NonZeroU64;
//! use core::time::Duration;
//!
-//! use bitcoin::secp256k1::{Key
P
air, PublicKey, Secp256k1, SecretKey};
+//! use bitcoin::secp256k1::{Key
p
air, PublicKey, Secp256k1, SecretKey};
//! use lightning::offers::offer::{Offer, OfferBuilder, Quantity};
//! use lightning::offers::parse::Bolt12ParseError;
//! use lightning::util::ser::{Readable, Writeable};
//! use lightning::offers::offer::{Offer, OfferBuilder, Quantity};
//! use lightning::offers::parse::Bolt12ParseError;
//! use lightning::util::ser::{Readable, Writeable};
@@
-39,7
+39,7
@@
//! # #[cfg(feature = "std")]
//! # fn build() -> Result<(), Bolt12ParseError> {
//! let secp_ctx = Secp256k1::new();
//! # #[cfg(feature = "std")]
//! # fn build() -> Result<(), Bolt12ParseError> {
//! let secp_ctx = Secp256k1::new();
-//! let keys = Key
P
air::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
+//! let keys = Key
p
air::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
//! let pubkey = PublicKey::from(keys);
//!
//! let expiration = SystemTime::now() + Duration::from_secs(24 * 60 * 60);
//! let pubkey = PublicKey::from(keys);
//!
//! let expiration = SystemTime::now() + Duration::from_secs(24 * 60 * 60);
@@
-78,8
+78,8
@@
//! [`ChannelManager::create_offer_builder`]: crate::ln::channelmanager::ChannelManager::create_offer_builder
use bitcoin::blockdata::constants::ChainHash;
//! [`ChannelManager::create_offer_builder`]: crate::ln::channelmanager::ChannelManager::create_offer_builder
use bitcoin::blockdata::constants::ChainHash;
-use bitcoin::network::
constants::
Network;
-use bitcoin::secp256k1::{Key
P
air, PublicKey, Secp256k1, self};
+use bitcoin::network::Network;
+use bitcoin::secp256k1::{Key
p
air, PublicKey, Secp256k1, self};
use core::hash::{Hash, Hasher};
use core::num::NonZeroU64;
use core::ops::Deref;
use core::hash::{Hash, Hasher};
use core::num::NonZeroU64;
use core::ops::Deref;
@@
-163,10
+163,9
@@
pub struct OfferBuilder<'a, M: MetadataStrategy, T: secp256k1::Signing> {
///
/// See [module-level documentation] for usage.
///
///
/// See [module-level documentation] for usage.
///
-/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
-///
/// [module-level documentation]: self
#[cfg(c_bindings)]
/// [module-level documentation]: self
#[cfg(c_bindings)]
+#[derive(Clone)]
pub struct OfferWithExplicitMetadataBuilder<'a> {
offer: OfferContents,
metadata_strategy: core::marker::PhantomData<ExplicitMetadata>,
pub struct OfferWithExplicitMetadataBuilder<'a> {
offer: OfferContents,
metadata_strategy: core::marker::PhantomData<ExplicitMetadata>,
@@
-177,10
+176,9
@@
pub struct OfferWithExplicitMetadataBuilder<'a> {
///
/// See [module-level documentation] for usage.
///
///
/// See [module-level documentation] for usage.
///
-/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
-///
/// [module-level documentation]: self
#[cfg(c_bindings)]
/// [module-level documentation]: self
#[cfg(c_bindings)]
+#[derive(Clone)]
pub struct OfferWithDerivedMetadataBuilder<'a> {
offer: OfferContents,
metadata_strategy: core::marker::PhantomData<DerivedMetadata>,
pub struct OfferWithDerivedMetadataBuilder<'a> {
offer: OfferContents,
metadata_strategy: core::marker::PhantomData<DerivedMetadata>,
@@
-209,9
+207,8
@@
impl MetadataStrategy for DerivedMetadata {}
macro_rules! offer_explicit_metadata_builder_methods { (
$self: ident, $self_type: ty, $return_type: ty, $return_value: expr
) => {
macro_rules! offer_explicit_metadata_builder_methods { (
$self: ident, $self_type: ty, $return_type: ty, $return_value: expr
) => {
- /// Creates a new builder for an offer setting an empty [`Offer::description`] and using the
- /// [`Offer::signing_pubkey`] for signing invoices. The associated secret key must be remembered
- /// while the offer is valid.
+ /// Creates a new builder for an offer using the [`Offer::signing_pubkey`] for signing invoices.
+ /// The associated secret key must be remembered while the offer is valid.
///
/// Use a different pubkey per offer to avoid correlating offers.
///
///
/// Use a different pubkey per offer to avoid correlating offers.
///
@@
-225,7
+222,7
@@
macro_rules! offer_explicit_metadata_builder_methods { (
pub fn new(signing_pubkey: PublicKey) -> Self {
Self {
offer: OfferContents {
pub fn new(signing_pubkey: PublicKey) -> Self {
Self {
offer: OfferContents {
- chains: None, metadata: None, amount: None, description:
String::new()
,
+ chains: None, metadata: None, amount: None, description:
None
,
features: OfferFeatures::empty(), absolute_expiry: None, issuer: None, paths: None,
supported_quantity: Quantity::One, signing_pubkey: Some(signing_pubkey),
},
features: OfferFeatures::empty(), absolute_expiry: None, issuer: None, paths: None,
supported_quantity: Quantity::One, signing_pubkey: Some(signing_pubkey),
},
@@
-264,7
+261,7
@@
macro_rules! offer_derived_metadata_builder_methods { ($secp_context: ty) => {
let metadata = Metadata::DerivedSigningPubkey(derivation_material);
Self {
offer: OfferContents {
let metadata = Metadata::DerivedSigningPubkey(derivation_material);
Self {
offer: OfferContents {
- chains: None, metadata: Some(metadata), amount: None, description:
String::new()
,
+ chains: None, metadata: Some(metadata), amount: None, description:
None
,
features: OfferFeatures::empty(), absolute_expiry: None, issuer: None, paths: None,
supported_quantity: Quantity::One, signing_pubkey: Some(node_id),
},
features: OfferFeatures::empty(), absolute_expiry: None, issuer: None, paths: None,
supported_quantity: Quantity::One, signing_pubkey: Some(node_id),
},
@@
-330,7
+327,7
@@
macro_rules! offer_builder_methods { (
///
/// Successive calls to this method will override the previous setting.
pub fn description($($self_mut)* $self: $self_type, description: String) -> $return_type {
///
/// Successive calls to this method will override the previous setting.
pub fn description($($self_mut)* $self: $self_type, description: String) -> $return_type {
- $self.offer.description =
description
;
+ $self.offer.description =
Some(description)
;
$return_value
}
$return_value
}
@@
-373,6
+370,10
@@
macro_rules! offer_builder_methods { (
None => {},
}
None => {},
}
+ if $self.offer.amount.is_some() && $self.offer.description.is_none() {
+ $self.offer.description = Some(String::new());
+ }
+
if let Some(chains) = &$self.offer.chains {
if chains.len() == 1 && chains[0] == $self.offer.implied_chain() {
$self.offer.chains = None;
if let Some(chains) = &$self.offer.chains {
if chains.len() == 1 && chains[0] == $self.offer.implied_chain() {
$self.offer.chains = None;
@@
-551,7
+552,7
@@
pub(super) struct OfferContents {
chains: Option<Vec<ChainHash>>,
metadata: Option<Metadata>,
amount: Option<Amount>,
chains: Option<Vec<ChainHash>>,
metadata: Option<Metadata>,
amount: Option<Amount>,
- description:
String
,
+ description:
Option<String>
,
features: OfferFeatures,
absolute_expiry: Option<Duration>,
issuer: Option<String>,
features: OfferFeatures,
absolute_expiry: Option<Duration>,
issuer: Option<String>,
@@
-579,13
+580,13
@@
macro_rules! offer_accessors { ($self: ident, $contents: expr) => {
}
/// The minimum amount required for a successful payment of a single item.
}
/// The minimum amount required for a successful payment of a single item.
- pub fn amount(&$self) -> Option<
&
$crate::offers::offer::Amount> {
+ pub fn amount(&$self) -> Option<$crate::offers::offer::Amount> {
$contents.amount()
}
/// A complete description of the purpose of the payment. Intended to be displayed to the user
/// but with the caveat that it has not been verified in any way.
$contents.amount()
}
/// A complete description of the purpose of the payment. Intended to be displayed to the user
/// but with the caveat that it has not been verified in any way.
- pub fn description(&$self) ->
$crate::util::string::PrintableString
{
+ pub fn description(&$self) ->
Option<$crate::util::string::PrintableString>
{
$contents.description()
}
$contents.description()
}
@@
-663,6
+664,12
@@
impl Offer {
pub fn expects_quantity(&self) -> bool {
self.contents.expects_quantity()
}
pub fn expects_quantity(&self) -> bool {
self.contents.expects_quantity()
}
+
+ pub(super) fn verify<T: secp256k1::Signing>(
+ &self, key: &ExpandedKey, secp_ctx: &Secp256k1<T>
+ ) -> Result<(OfferId, Option<Keypair>), ()> {
+ self.contents.verify(&self.bytes, key, secp_ctx)
+ }
}
macro_rules! request_invoice_derived_payer_id { ($self: ident, $builder: ty) => {
}
macro_rules! request_invoice_derived_payer_id { ($self: ident, $builder: ty) => {
@@
-805,12
+812,12
@@
impl OfferContents {
self.metadata.as_ref().and_then(|metadata| metadata.as_bytes())
}
self.metadata.as_ref().and_then(|metadata| metadata.as_bytes())
}
- pub fn amount(&self) -> Option<
&
Amount> {
- self.amount
.as_ref()
+ pub fn amount(&self) -> Option<Amount> {
+ self.amount
}
}
- pub fn description(&self) ->
PrintableString
{
-
PrintableString(&self.description
)
+ pub fn description(&self) ->
Option<PrintableString>
{
+
self.description.as_ref().map(|description| PrintableString(description)
)
}
pub fn features(&self) -> &OfferFeatures {
}
pub fn features(&self) -> &OfferFeatures {
@@
-908,7
+915,7
@@
impl OfferContents {
/// Verifies that the offer metadata was produced from the offer in the TLV stream.
pub(super) fn verify<T: secp256k1::Signing>(
&self, bytes: &[u8], key: &ExpandedKey, secp_ctx: &Secp256k1<T>
/// Verifies that the offer metadata was produced from the offer in the TLV stream.
pub(super) fn verify<T: secp256k1::Signing>(
&self, bytes: &[u8], key: &ExpandedKey, secp_ctx: &Secp256k1<T>
- ) -> Result<(OfferId, Option<Key
P
air>), ()> {
+ ) -> Result<(OfferId, Option<Key
p
air>), ()> {
match self.metadata() {
Some(metadata) => {
let tlv_stream = TlvStream::new(bytes).range(OFFER_TYPES).filter(|record| {
match self.metadata() {
Some(metadata) => {
let tlv_stream = TlvStream::new(bytes).range(OFFER_TYPES).filter(|record| {
@@
-954,7
+961,7
@@
impl OfferContents {
metadata: self.metadata(),
currency,
amount,
metadata: self.metadata(),
currency,
amount,
- description:
Some(&self.description
),
+ description:
self.description.as_ref(
),
features,
absolute_expiry: self.absolute_expiry.map(|duration| duration.as_secs()),
paths: self.paths.as_ref(),
features,
absolute_expiry: self.absolute_expiry.map(|duration| duration.as_secs()),
paths: self.paths.as_ref(),
@@
-965,6
+972,13
@@
impl OfferContents {
}
}
}
}
+impl Readable for Offer {
+ fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
+ let bytes: WithoutLength<Vec<u8>> = Readable::read(reader)?;
+ Self::try_from(bytes.0).map_err(|_| DecodeError::InvalidValue)
+ }
+}
+
impl Writeable for Offer {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
WithoutLength(&self.bytes).write(writer)
impl Writeable for Offer {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
WithoutLength(&self.bytes).write(writer)
@@
-979,7
+993,7
@@
impl Writeable for OfferContents {
/// The minimum amount required for an item in an [`Offer`], denominated in either bitcoin or
/// another currency.
/// The minimum amount required for an item in an [`Offer`], denominated in either bitcoin or
/// another currency.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone,
Copy,
Debug, PartialEq)]
pub enum Amount {
/// An amount of bitcoin.
Bitcoin {
pub enum Amount {
/// An amount of bitcoin.
Bitcoin {
@@
-1092,10
+1106,9
@@
impl TryFrom<OfferTlvStream> for OfferContents {
(Some(iso4217_code), Some(amount)) => Some(Amount::Currency { iso4217_code, amount }),
};
(Some(iso4217_code), Some(amount)) => Some(Amount::Currency { iso4217_code, amount }),
};
- let description = match description {
- None => return Err(Bolt12SemanticError::MissingDescription),
- Some(description) => description,
- };
+ if amount.is_some() && description.is_none() {
+ return Err(Bolt12SemanticError::MissingDescription);
+ }
let features = features.unwrap_or_else(OfferFeatures::empty);
let features = features.unwrap_or_else(OfferFeatures::empty);
@@
-1140,7
+1153,7
@@
mod tests {
};
use bitcoin::blockdata::constants::ChainHash;
};
use bitcoin::blockdata::constants::ChainHash;
- use bitcoin::network::
constants::
Network;
+ use bitcoin::network::Network;
use bitcoin::secp256k1::Secp256k1;
use core::num::NonZeroU64;
use core::time::Duration;
use bitcoin::secp256k1::Secp256k1;
use core::num::NonZeroU64;
use core::time::Duration;
@@
-1166,7
+1179,7
@@
mod tests {
assert!(offer.supports_chain(ChainHash::using_genesis_block(Network::Bitcoin)));
assert_eq!(offer.metadata(), None);
assert_eq!(offer.amount(), None);
assert!(offer.supports_chain(ChainHash::using_genesis_block(Network::Bitcoin)));
assert_eq!(offer.metadata(), None);
assert_eq!(offer.amount(), None);
- assert_eq!(offer.description(),
PrintableString("")
);
+ assert_eq!(offer.description(),
None
);
assert_eq!(offer.offer_features(), &OfferFeatures::empty());
assert_eq!(offer.absolute_expiry(), None);
#[cfg(feature = "std")]
assert_eq!(offer.offer_features(), &OfferFeatures::empty());
assert_eq!(offer.absolute_expiry(), None);
#[cfg(feature = "std")]
@@
-1174,6
+1187,7
@@
mod tests {
assert_eq!(offer.paths(), &[]);
assert_eq!(offer.issuer(), None);
assert_eq!(offer.supported_quantity(), Quantity::One);
assert_eq!(offer.paths(), &[]);
assert_eq!(offer.issuer(), None);
assert_eq!(offer.supported_quantity(), Quantity::One);
+ assert!(!offer.expects_quantity());
assert_eq!(offer.signing_pubkey(), Some(pubkey(42)));
assert_eq!(
assert_eq!(offer.signing_pubkey(), Some(pubkey(42)));
assert_eq!(
@@
-1183,7
+1197,7
@@
mod tests {
metadata: None,
currency: None,
amount: None,
metadata: None,
currency: None,
amount: None,
- description:
Some(&String::from(""))
,
+ description:
None
,
features: None,
absolute_expiry: None,
paths: None,
features: None,
absolute_expiry: None,
paths: None,
@@
-1379,7
+1393,7
@@
mod tests {
.build()
.unwrap();
let tlv_stream = offer.as_tlv_stream();
.build()
.unwrap();
let tlv_stream = offer.as_tlv_stream();
- assert_eq!(offer.amount(), Some(
&
bitcoin_amount));
+ assert_eq!(offer.amount(), Some(bitcoin_amount));
assert_eq!(tlv_stream.amount, Some(1000));
assert_eq!(tlv_stream.currency, None);
assert_eq!(tlv_stream.amount, Some(1000));
assert_eq!(tlv_stream.currency, None);
@@
-1421,7
+1435,7
@@
mod tests {
.description("foo".into())
.build()
.unwrap();
.description("foo".into())
.build()
.unwrap();
- assert_eq!(offer.description(),
PrintableString("foo"
));
+ assert_eq!(offer.description(),
Some(PrintableString("foo")
));
assert_eq!(offer.as_tlv_stream().description, Some(&String::from("foo")));
let offer = OfferBuilder::new(pubkey(42))
assert_eq!(offer.as_tlv_stream().description, Some(&String::from("foo")));
let offer = OfferBuilder::new(pubkey(42))
@@
-1429,8
+1443,15
@@
mod tests {
.description("bar".into())
.build()
.unwrap();
.description("bar".into())
.build()
.unwrap();
- assert_eq!(offer.description(),
PrintableString("bar"
));
+ assert_eq!(offer.description(),
Some(PrintableString("bar")
));
assert_eq!(offer.as_tlv_stream().description, Some(&String::from("bar")));
assert_eq!(offer.as_tlv_stream().description, Some(&String::from("bar")));
+
+ let offer = OfferBuilder::new(pubkey(42))
+ .amount_msats(1000)
+ .build()
+ .unwrap();
+ assert_eq!(offer.description(), Some(PrintableString("")));
+ assert_eq!(offer.as_tlv_stream().description, Some(&String::from("")));
}
#[test]
}
#[test]
@@
-1541,6
+1562,7
@@
mod tests {
.build()
.unwrap();
let tlv_stream = offer.as_tlv_stream();
.build()
.unwrap();
let tlv_stream = offer.as_tlv_stream();
+ assert!(!offer.expects_quantity());
assert_eq!(offer.supported_quantity(), Quantity::One);
assert_eq!(tlv_stream.quantity_max, None);
assert_eq!(offer.supported_quantity(), Quantity::One);
assert_eq!(tlv_stream.quantity_max, None);
@@
-1549,6
+1571,7
@@
mod tests {
.build()
.unwrap();
let tlv_stream = offer.as_tlv_stream();
.build()
.unwrap();
let tlv_stream = offer.as_tlv_stream();
+ assert!(offer.expects_quantity());
assert_eq!(offer.supported_quantity(), Quantity::Unbounded);
assert_eq!(tlv_stream.quantity_max, Some(0));
assert_eq!(offer.supported_quantity(), Quantity::Unbounded);
assert_eq!(tlv_stream.quantity_max, Some(0));
@@
-1557,6
+1580,7
@@
mod tests {
.build()
.unwrap();
let tlv_stream = offer.as_tlv_stream();
.build()
.unwrap();
let tlv_stream = offer.as_tlv_stream();
+ assert!(offer.expects_quantity());
assert_eq!(offer.supported_quantity(), Quantity::Bounded(ten));
assert_eq!(tlv_stream.quantity_max, Some(10));
assert_eq!(offer.supported_quantity(), Quantity::Bounded(ten));
assert_eq!(tlv_stream.quantity_max, Some(10));
@@
-1565,6
+1589,7
@@
mod tests {
.build()
.unwrap();
let tlv_stream = offer.as_tlv_stream();
.build()
.unwrap();
let tlv_stream = offer.as_tlv_stream();
+ assert!(offer.expects_quantity());
assert_eq!(offer.supported_quantity(), Quantity::Bounded(one));
assert_eq!(tlv_stream.quantity_max, Some(1));
assert_eq!(offer.supported_quantity(), Quantity::Bounded(one));
assert_eq!(tlv_stream.quantity_max, Some(1));
@@
-1574,6
+1599,7
@@
mod tests {
.build()
.unwrap();
let tlv_stream = offer.as_tlv_stream();
.build()
.unwrap();
let tlv_stream = offer.as_tlv_stream();
+ assert!(!offer.expects_quantity());
assert_eq!(offer.supported_quantity(), Quantity::One);
assert_eq!(tlv_stream.quantity_max, None);
}
assert_eq!(offer.supported_quantity(), Quantity::One);
assert_eq!(tlv_stream.quantity_max, None);
}
@@
-1655,6
+1681,14
@@
mod tests {
panic!("error parsing offer: {:?}", e);
}
panic!("error parsing offer: {:?}", e);
}
+ let offer = OfferBuilder::new(pubkey(42))
+ .description("foo".to_string())
+ .amount_msats(1000)
+ .build().unwrap();
+ if let Err(e) = offer.to_string().parse::<Offer>() {
+ panic!("error parsing offer: {:?}", e);
+ }
+
let mut tlv_stream = offer.as_tlv_stream();
tlv_stream.description = None;
let mut tlv_stream = offer.as_tlv_stream();
tlv_stream.description = None;
@@
-1845,6
+1879,9
@@
mod bolt12_tests {
// with blinded path via Bob (0x424242...), blinding 020202...
"lno1pgx9getnwss8vetrw3hhyucs5ypjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qzqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgqpqqqqqqqqqqqqqqqqqqqqqqqqqqqzqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqqzq3zyg3zyg3zyg3vggzamrjghtt05kvkvpcp0a79gmy3nt6jsn98ad2xs8de6sl9qmgvcvs",
// with blinded path via Bob (0x424242...), blinding 020202...
"lno1pgx9getnwss8vetrw3hhyucs5ypjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qzqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgqpqqqqqqqqqqqqqqqqqqqqqqqqqqqzqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqqzq3zyg3zyg3zyg3vggzamrjghtt05kvkvpcp0a79gmy3nt6jsn98ad2xs8de6sl9qmgvcvs",
+ // ... and with sciddir introduction node
+ "lno1pgx9getnwss8vetrw3hhyucs3yqqqqqqqqqqqqp2qgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqqyqqqqqqqqqqqqqqqqqqqqqqqqqqqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqqgzyg3zyg3zyg3z93pqthvwfzadd7jejes8q9lhc4rvjxd022zv5l44g6qah82ru5rdpnpj",
+
// ... and with second blinded path via Carol (0x434343...), blinding 020202...
"lno1pgx9getnwss8vetrw3hhyucsl5q5yqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trspqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqqsqqqqqqqqqqqqqqqqqqqqqqqqqqpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsqpqg3zyg3zyg3zygz0uc7h32x9s0aecdhxlk075kn046aafpuuyw8f5j652t3vha2yqrsyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsqzqqqqqqqqqqqqqqqqqqqqqqqqqqqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqqyzyg3zyg3zyg3zzcss9mk8y3wkklfvevcrszlmu23kfrxh49px20665dqwmn4p72pksese",
// ... and with second blinded path via Carol (0x434343...), blinding 020202...
"lno1pgx9getnwss8vetrw3hhyucsl5q5yqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trspqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqqsqqqqqqqqqqqqqqqqqqqqqqqqqqpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsqpqg3zyg3zyg3zygz0uc7h32x9s0aecdhxlk075kn046aafpuuyw8f5j652t3vha2yqrsyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqsqzqqqqqqqqqqqqqqqqqqqqqqqqqqqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqqyzyg3zyg3zyg3zzcss9mk8y3wkklfvevcrszlmu23kfrxh49px20665dqwmn4p72pksese",
@@
-1875,7
+1912,7
@@
mod bolt12_tests {
// Malformed: empty
assert_eq!(
"lno1".parse::<Offer>(),
// Malformed: empty
assert_eq!(
"lno1".parse::<Offer>(),
- Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::Missing
Description
)),
+ Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::Missing
SigningPubkey
)),
);
// Malformed: truncated at type
);
// Malformed: truncated at type
@@
-2000,7
+2037,8
@@
mod bolt12_tests {
// Missing offer_description
assert_eq!(
// Missing offer_description
assert_eq!(
- "lno1zcss9mk8y3wkklfvevcrszlmu23kfrxh49px20665dqwmn4p72pksese".parse::<Offer>(),
+ // TODO: Match the spec once it is updated.
+ "lno1pqpq86qkyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxg".parse::<Offer>(),
Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingDescription)),
);
Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingDescription)),
);