Skip to content

Commit 1deaf26

Browse files
committed
Qualify the BOLT 11 semantic error type
A previous commit qualified the BOLT 12 semantic error type. Qualify the BOLT 11 semantic error type for consistency.
1 parent edf15c2 commit 1deaf26

File tree

3 files changed

+46
-46
lines changed

3 files changed

+46
-46
lines changed

lightning-invoice/src/de.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use secp256k1::ecdsa::{RecoveryId, RecoverableSignature};
2424
use secp256k1::PublicKey;
2525

2626
use super::{Bolt11Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp,
27-
SemanticError, PrivateRoute, Bolt11ParseError, ParseOrSemanticError, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawBolt11Invoice,
27+
Bolt11SemanticError, PrivateRoute, Bolt11ParseError, ParseOrSemanticError, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawBolt11Invoice,
2828
constants, SignedRawBolt11Invoice, RawDataPart, InvoiceFeatures};
2929

3030
use self::hrp_sm::parse_hrp;
@@ -715,8 +715,8 @@ impl From<Bolt11ParseError> for ParseOrSemanticError {
715715
}
716716
}
717717

718-
impl From<crate::SemanticError> for ParseOrSemanticError {
719-
fn from(e: SemanticError) -> Self {
718+
impl From<crate::Bolt11SemanticError> for ParseOrSemanticError {
719+
fn from(e: Bolt11SemanticError) -> Self {
720720
ParseOrSemanticError::SemanticError(e)
721721
}
722722
}

lightning-invoice/src/lib.rs

+40-40
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ pub enum ParseOrSemanticError {
139139
ParseError(Bolt11ParseError),
140140

141141
/// The invoice could be decoded but violates the BOLT11 standard
142-
SemanticError(crate::SemanticError),
142+
SemanticError(crate::Bolt11SemanticError),
143143
}
144144

145145
/// The number of bits used to represent timestamps as defined in BOLT 11.
@@ -1154,16 +1154,16 @@ impl Bolt11Invoice {
11541154
}
11551155

11561156
/// Check that all mandatory fields are present
1157-
fn check_field_counts(&self) -> Result<(), SemanticError> {
1157+
fn check_field_counts(&self) -> Result<(), Bolt11SemanticError> {
11581158
// "A writer MUST include exactly one p field […]."
11591159
let payment_hash_cnt = self.tagged_fields().filter(|&tf| match *tf {
11601160
TaggedField::PaymentHash(_) => true,
11611161
_ => false,
11621162
}).count();
11631163
if payment_hash_cnt < 1 {
1164-
return Err(SemanticError::NoPaymentHash);
1164+
return Err(Bolt11SemanticError::NoPaymentHash);
11651165
} else if payment_hash_cnt > 1 {
1166-
return Err(SemanticError::MultiplePaymentHashes);
1166+
return Err(Bolt11SemanticError::MultiplePaymentHashes);
11671167
}
11681168

11691169
// "A writer MUST include either exactly one d or exactly one h field."
@@ -1172,9 +1172,9 @@ impl Bolt11Invoice {
11721172
_ => false,
11731173
}).count();
11741174
if description_cnt < 1 {
1175-
return Err(SemanticError::NoDescription);
1175+
return Err(Bolt11SemanticError::NoDescription);
11761176
} else if description_cnt > 1 {
1177-
return Err(SemanticError::MultipleDescriptions);
1177+
return Err(Bolt11SemanticError::MultipleDescriptions);
11781178
}
11791179

11801180
self.check_payment_secret()?;
@@ -1183,33 +1183,33 @@ impl Bolt11Invoice {
11831183
}
11841184

11851185
/// Checks that there is exactly one payment secret field
1186-
fn check_payment_secret(&self) -> Result<(), SemanticError> {
1186+
fn check_payment_secret(&self) -> Result<(), Bolt11SemanticError> {
11871187
// "A writer MUST include exactly one `s` field."
11881188
let payment_secret_count = self.tagged_fields().filter(|&tf| match *tf {
11891189
TaggedField::PaymentSecret(_) => true,
11901190
_ => false,
11911191
}).count();
11921192
if payment_secret_count < 1 {
1193-
return Err(SemanticError::NoPaymentSecret);
1193+
return Err(Bolt11SemanticError::NoPaymentSecret);
11941194
} else if payment_secret_count > 1 {
1195-
return Err(SemanticError::MultiplePaymentSecrets);
1195+
return Err(Bolt11SemanticError::MultiplePaymentSecrets);
11961196
}
11971197

11981198
Ok(())
11991199
}
12001200

12011201
/// Check that amount is a whole number of millisatoshis
1202-
fn check_amount(&self) -> Result<(), SemanticError> {
1202+
fn check_amount(&self) -> Result<(), Bolt11SemanticError> {
12031203
if let Some(amount_pico_btc) = self.amount_pico_btc() {
12041204
if amount_pico_btc % 10 != 0 {
1205-
return Err(SemanticError::ImpreciseAmount);
1205+
return Err(Bolt11SemanticError::ImpreciseAmount);
12061206
}
12071207
}
12081208
Ok(())
12091209
}
12101210

12111211
/// Check that feature bits are set as required
1212-
fn check_feature_bits(&self) -> Result<(), SemanticError> {
1212+
fn check_feature_bits(&self) -> Result<(), Bolt11SemanticError> {
12131213
self.check_payment_secret()?;
12141214

12151215
// "A writer MUST set an s field if and only if the payment_secret feature is set."
@@ -1220,12 +1220,12 @@ impl Bolt11Invoice {
12201220
_ => false,
12211221
});
12221222
match features {
1223-
None => Err(SemanticError::InvalidFeatures),
1223+
None => Err(Bolt11SemanticError::InvalidFeatures),
12241224
Some(TaggedField::Features(features)) => {
12251225
if features.requires_unknown_bits() {
1226-
Err(SemanticError::InvalidFeatures)
1226+
Err(Bolt11SemanticError::InvalidFeatures)
12271227
} else if !features.supports_payment_secret() {
1228-
Err(SemanticError::InvalidFeatures)
1228+
Err(Bolt11SemanticError::InvalidFeatures)
12291229
} else {
12301230
Ok(())
12311231
}
@@ -1235,18 +1235,18 @@ impl Bolt11Invoice {
12351235
}
12361236

12371237
/// Check that the invoice is signed correctly and that key recovery works
1238-
pub fn check_signature(&self) -> Result<(), SemanticError> {
1238+
pub fn check_signature(&self) -> Result<(), Bolt11SemanticError> {
12391239
match self.signed_invoice.recover_payee_pub_key() {
12401240
Err(secp256k1::Error::InvalidRecoveryId) =>
1241-
return Err(SemanticError::InvalidRecoveryId),
1241+
return Err(Bolt11SemanticError::InvalidRecoveryId),
12421242
Err(secp256k1::Error::InvalidSignature) =>
1243-
return Err(SemanticError::InvalidSignature),
1243+
return Err(Bolt11SemanticError::InvalidSignature),
12441244
Err(e) => panic!("no other error may occur, got {:?}", e),
12451245
Ok(_) => {},
12461246
}
12471247

12481248
if !self.signed_invoice.check_signature() {
1249-
return Err(SemanticError::InvalidSignature);
1249+
return Err(Bolt11SemanticError::InvalidSignature);
12501250
}
12511251

12521252
Ok(())
@@ -1272,7 +1272,7 @@ impl Bolt11Invoice {
12721272
///
12731273
/// assert!(Bolt11Invoice::from_signed(signed).is_ok());
12741274
/// ```
1275-
pub fn from_signed(signed_invoice: SignedRawBolt11Invoice) -> Result<Self, SemanticError> {
1275+
pub fn from_signed(signed_invoice: SignedRawBolt11Invoice) -> Result<Self, Bolt11SemanticError> {
12761276
let invoice = Bolt11Invoice {
12771277
signed_invoice,
12781278
};
@@ -1654,7 +1654,7 @@ impl std::error::Error for CreationError { }
16541654
/// Errors that may occur when converting a [`RawBolt11Invoice`] to a [`Bolt11Invoice`]. They relate to
16551655
/// the requirements sections in BOLT #11
16561656
#[derive(Eq, PartialEq, Debug, Clone)]
1657-
pub enum SemanticError {
1657+
pub enum Bolt11SemanticError {
16581658
/// The invoice is missing the mandatory payment hash
16591659
NoPaymentHash,
16601660

@@ -1687,25 +1687,25 @@ pub enum SemanticError {
16871687
ImpreciseAmount,
16881688
}
16891689

1690-
impl Display for SemanticError {
1690+
impl Display for Bolt11SemanticError {
16911691
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
16921692
match self {
1693-
SemanticError::NoPaymentHash => f.write_str("The invoice is missing the mandatory payment hash"),
1694-
SemanticError::MultiplePaymentHashes => f.write_str("The invoice has multiple payment hashes which isn't allowed"),
1695-
SemanticError::NoDescription => f.write_str("No description or description hash are part of the invoice"),
1696-
SemanticError::MultipleDescriptions => f.write_str("The invoice contains multiple descriptions and/or description hashes which isn't allowed"),
1697-
SemanticError::NoPaymentSecret => f.write_str("The invoice is missing the mandatory payment secret"),
1698-
SemanticError::MultiplePaymentSecrets => f.write_str("The invoice contains multiple payment secrets"),
1699-
SemanticError::InvalidFeatures => f.write_str("The invoice's features are invalid"),
1700-
SemanticError::InvalidRecoveryId => f.write_str("The recovery id doesn't fit the signature/pub key"),
1701-
SemanticError::InvalidSignature => f.write_str("The invoice's signature is invalid"),
1702-
SemanticError::ImpreciseAmount => f.write_str("The invoice's amount was not a whole number of millisatoshis"),
1693+
Bolt11SemanticError::NoPaymentHash => f.write_str("The invoice is missing the mandatory payment hash"),
1694+
Bolt11SemanticError::MultiplePaymentHashes => f.write_str("The invoice has multiple payment hashes which isn't allowed"),
1695+
Bolt11SemanticError::NoDescription => f.write_str("No description or description hash are part of the invoice"),
1696+
Bolt11SemanticError::MultipleDescriptions => f.write_str("The invoice contains multiple descriptions and/or description hashes which isn't allowed"),
1697+
Bolt11SemanticError::NoPaymentSecret => f.write_str("The invoice is missing the mandatory payment secret"),
1698+
Bolt11SemanticError::MultiplePaymentSecrets => f.write_str("The invoice contains multiple payment secrets"),
1699+
Bolt11SemanticError::InvalidFeatures => f.write_str("The invoice's features are invalid"),
1700+
Bolt11SemanticError::InvalidRecoveryId => f.write_str("The recovery id doesn't fit the signature/pub key"),
1701+
Bolt11SemanticError::InvalidSignature => f.write_str("The invoice's signature is invalid"),
1702+
Bolt11SemanticError::ImpreciseAmount => f.write_str("The invoice's amount was not a whole number of millisatoshis"),
17031703
}
17041704
}
17051705
}
17061706

17071707
#[cfg(feature = "std")]
1708-
impl std::error::Error for SemanticError { }
1708+
impl std::error::Error for Bolt11SemanticError { }
17091709

17101710
/// When signing using a fallible method either an user-supplied `SignError` or a [`CreationError`]
17111711
/// may occur.
@@ -1867,7 +1867,7 @@ mod test {
18671867
use secp256k1::Secp256k1;
18681868
use secp256k1::SecretKey;
18691869
use crate::{Bolt11Invoice, RawBolt11Invoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp,
1870-
SemanticError};
1870+
Bolt11SemanticError};
18711871

18721872
let private_key = SecretKey::from_slice(&[42; 32]).unwrap();
18731873
let payment_secret = lightning::ln::PaymentSecret([21; 32]);
@@ -1898,7 +1898,7 @@ mod test {
18981898
invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
18991899
invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)))
19001900
}.unwrap();
1901-
assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::InvalidFeatures));
1901+
assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::InvalidFeatures));
19021902

19031903
// Missing feature bits
19041904
let invoice = {
@@ -1907,7 +1907,7 @@ mod test {
19071907
invoice.data.tagged_fields.push(Features(InvoiceFeatures::empty()).into());
19081908
invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)))
19091909
}.unwrap();
1910-
assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::InvalidFeatures));
1910+
assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::InvalidFeatures));
19111911

19121912
let mut payment_secret_features = InvoiceFeatures::empty();
19131913
payment_secret_features.set_payment_secret_required();
@@ -1926,23 +1926,23 @@ mod test {
19261926
let invoice = invoice_template.clone();
19271927
invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)))
19281928
}.unwrap();
1929-
assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret));
1929+
assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::NoPaymentSecret));
19301930

19311931
// No payment secret or feature bits
19321932
let invoice = {
19331933
let mut invoice = invoice_template.clone();
19341934
invoice.data.tagged_fields.push(Features(InvoiceFeatures::empty()).into());
19351935
invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)))
19361936
}.unwrap();
1937-
assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret));
1937+
assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::NoPaymentSecret));
19381938

19391939
// Missing payment secret
19401940
let invoice = {
19411941
let mut invoice = invoice_template.clone();
19421942
invoice.data.tagged_fields.push(Features(payment_secret_features).into());
19431943
invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)))
19441944
}.unwrap();
1945-
assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret));
1945+
assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::NoPaymentSecret));
19461946

19471947
// Multiple payment secrets
19481948
let invoice = {
@@ -1951,7 +1951,7 @@ mod test {
19511951
invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
19521952
invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)))
19531953
}.unwrap();
1954-
assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::MultiplePaymentSecrets));
1954+
assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::MultiplePaymentSecrets));
19551955
}
19561956

19571957
#[test]

lightning-invoice/tests/ser_de.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ fn test_bolt_invalid_invoices() {
421421
// Tests the BOLT 11 invalid invoice test vectors
422422
assert_eq!(Bolt11Invoice::from_str(
423423
"lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q4psqqqqqqqqqqqqqqqqsgqtqyx5vggfcsll4wu246hz02kp85x4katwsk9639we5n5yngc3yhqkm35jnjw4len8vrnqnf5ejh0mzj9n3vz2px97evektfm2l6wqccp3y7372"
424-
), Err(ParseOrSemanticError::SemanticError(SemanticError::InvalidFeatures)));
424+
), Err(ParseOrSemanticError::SemanticError(Bolt11SemanticError::InvalidFeatures)));
425425
assert_eq!(Bolt11Invoice::from_str(
426426
"lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrnt"
427427
), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::Bech32Error(bech32::Error::InvalidChecksum))));
@@ -433,7 +433,7 @@ fn test_bolt_invalid_invoices() {
433433
), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::Bech32Error(bech32::Error::MixedCase))));
434434
assert_eq!(Bolt11Invoice::from_str(
435435
"lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgqwgt7mcn5yqw3yx0w94pswkpq6j9uh6xfqqqtsk4tnarugeektd4hg5975x9am52rz4qskukxdmjemg92vvqz8nvmsye63r5ykel43pgz7zq0g2"
436-
), Err(ParseOrSemanticError::SemanticError(SemanticError::InvalidSignature)));
436+
), Err(ParseOrSemanticError::SemanticError(Bolt11SemanticError::InvalidSignature)));
437437
assert_eq!(Bolt11Invoice::from_str(
438438
"lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6na6hlh"
439439
), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::TooShortDataPart)));
@@ -442,5 +442,5 @@ fn test_bolt_invalid_invoices() {
442442
), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::UnknownSiPrefix)));
443443
assert_eq!(Bolt11Invoice::from_str(
444444
"lnbc2500000001p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgq0lzc236j96a95uv0m3umg28gclm5lqxtqqwk32uuk4k6673k6n5kfvx3d2h8s295fad45fdhmusm8sjudfhlf6dcsxmfvkeywmjdkxcp99202x"
445-
), Err(ParseOrSemanticError::SemanticError(SemanticError::ImpreciseAmount)));
445+
), Err(ParseOrSemanticError::SemanticError(Bolt11SemanticError::ImpreciseAmount)));
446446
}

0 commit comments

Comments
 (0)