invoice: Use PaymentHash in raw invoice types
What changed, and why it matters
This commit is a straightforward internal code cleanup in the Lightning Dev Kit's invoice handling. It replaces the use of a generic SHA-256 hash type with a dedicated PaymentHash type when representing payment hashes inside BOLT11 invoices. There is no indication this fixes a security vulnerability; it is a type-safety and consistency refactor that touches many test files and a few production call sites.
No security action required. Treat as a normal refactor. If reviewing, verify that all former sha256::Hash -> PaymentHash conversions preserve byte ordering and that the new base32 length check does not reject valid invoices (it should not, because PaymentHash is a 32-byte array).
Security signals we found
No security-relevant keywords in commit title or message
Refactor-only: type substitution with equivalent semantics
New base32 length validation mirrors existing 32-byte fixed-array requirement
No changes to cryptographic operations, parsing bounds, or trust assumptions
No vendor or researcher attribution for a security issue
Evidence from the diff
The change refactors lightning-invoice so that TaggedField::PaymentHash and related APIs use lightning_types::payment::PaymentHash instead of bitcoin::hashes::sha256::Hash (wrapped in the local Sha256 newtype). It adds FromBase32/Base32Iterable implementations for PaymentHash, updates InvoiceBuilder::payment_hash, RawBolt11Invoice::payment_hash, and Bolt11Invoice::payment_hash, and converts callers/tests to construct PaymentHash directly. The only behavioral addition is a length check during base32 decoding (52 characters / 32 bytes), which is already enforced by the underlying fixed-size array conversion. No vulnerability or security fix is described in the commit message or diff.
Changed components
lightning-invoice/src/de.rslightning-invoice/src/lib.rslightning-invoice/src/ser.rslightning-invoice/src/test_ser_de.rslightning-invoice/tests/ser_de.rslightning-liquidity/tests/lsps2_integration_tests.rslightning/src/ln/bolt11_payment_tests.rslightning/src/ln/channelmanager.rslightning/src/ln/invoice_utils.rsInspect captured patch +351 / −189
diff --git a/lightning-invoice/src/de.rs b/lightning-invoice/src/de.rs
index 0747015..f1bbe29 100644
--- a/lightning-invoice/src/de.rs
+++ b/lightning-invoice/src/de.rs
@@ -16,7 +16,7 @@ use crate::Bolt11Bech32;
use bitcoin::hashes::sha256;
use bitcoin::hashes::Hash;
use bitcoin::{PubkeyHash, ScriptHash, WitnessVersion};
-use lightning_types::payment::PaymentSecret;
+use lightning_types::payment::{PaymentHash, PaymentSecret};
use lightning_types::routing::{RouteHint, RouteHintHop, RoutingFees};
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, RecoveryId};
@@ -89,6 +89,18 @@ impl FromBase32 for PaymentSecret {
}
}
+impl FromBase32 for PaymentHash {
+ type Err = Bolt11ParseError;
+
+ fn from_base32(field_data: &[Fe32]) -> Result<Self, Self::Err> {
+ if field_data.len() != 52 {
+ return Err(Bolt11ParseError::InvalidSliceLength(field_data.len(), 52, "PaymentHash"));
+ }
+ let data_bytes = <[u8; 32]>::from_base32(field_data)?;
+ Ok(PaymentHash(data_bytes))
+ }
+}
+
impl FromBase32 for Bolt11InvoiceFeatures {
type Err = Bolt11ParseError;
@@ -540,7 +552,7 @@ impl FromBase32 for TaggedField {
match tag.to_u8() {
constants::TAG_PAYMENT_HASH => {
- Ok(TaggedField::PaymentHash(Sha256::from_base32(field_data)?))
+ Ok(TaggedField::PaymentHash(PaymentHash::from_base32(field_data)?))
},
constants::TAG_DESCRIPTION => {
Ok(TaggedField::Description(Description::from_base32(field_data)?))
@@ -1068,8 +1080,9 @@ mod test {
use crate::TaggedField::*;
use crate::{
Bolt11InvoiceSignature, Currency, PositiveTimestamp, RawBolt11Invoice, RawDataPart,
- RawHrp, Sha256, SiPrefix, SignedRawBolt11Invoice,
+ RawHrp, SiPrefix, SignedRawBolt11Invoice,
};
+ use bitcoin::hex::FromHex;
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, RecoveryId};
use lightning_types::features::Bolt11InvoiceFeatures;
@@ -1077,45 +1090,51 @@ mod test {
let expected_features =
Bolt11InvoiceFeatures::from_le_bytes(vec![0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8]);
let invoice_str = "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q5sqqqqqqqqqqqqqqqpqsq67gye39hfg3zd8rgc80k32tvy9xk2xunwm5lzexnvpx6fd77en8qaq424dxgt56cag2dpt359k3ssyhetktkpqh24jqnjyw6uqd08sgptq44qu";
- let invoice =
- SignedRawBolt11Invoice {
- raw_invoice: RawBolt11Invoice {
- hrp: RawHrp {
- currency: Currency::Bitcoin,
- raw_amount: Some(25),
- si_prefix: Some(SiPrefix::Milli),
- },
- data: RawDataPart {
- timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
- tagged_fields: vec ! [
- PaymentHash(Sha256(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())).into(),
+ let invoice = SignedRawBolt11Invoice {
+ raw_invoice: RawBolt11Invoice {
+ hrp: RawHrp {
+ currency: Currency::Bitcoin,
+ raw_amount: Some(25),
+ si_prefix: Some(SiPrefix::Milli),
+ },
+ data: RawDataPart {
+ timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
+ tagged_fields: vec ! [
+ crate::TaggedField::PaymentHash(crate::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
+ .into(),
Description(crate::Description::new("coffee beans".to_owned()).unwrap()).into(),
PaymentSecret(crate::PaymentSecret([17; 32])).into(),
Features(expected_features).into()],
- },
},
- hash: [
- 0xb1, 0x96, 0x46, 0xc3, 0xbc, 0x56, 0x76, 0x1d, 0x20, 0x65, 0x6e, 0x0e, 0x32,
- 0xec, 0xd2, 0x69, 0x27, 0xb7, 0x62, 0x6e, 0x2a, 0x8b, 0xe6, 0x97, 0x71, 0x9f,
- 0xf8, 0x7e, 0x44, 0x54, 0x55, 0xb9,
- ],
- signature: Bolt11InvoiceSignature(
- RecoverableSignature::from_compact(
- &[
- 0xd7, 0x90, 0x4c, 0xc4, 0xb7, 0x4a, 0x22, 0x26, 0x9c, 0x68, 0xc1, 0xdf,
- 0x68, 0xa9, 0x6c, 0x21, 0x4d, 0x65, 0x1b, 0x93, 0x76, 0xe9, 0xf1, 0x64,
- 0xd3, 0x60, 0x4d, 0xa4, 0xb7, 0xde, 0xcc, 0xce, 0x0e, 0x82, 0xaa, 0xab,
- 0x4c, 0x85, 0xd3, 0x58, 0xea, 0x14, 0xd0, 0xae, 0x34, 0x2d, 0xa3, 0x08,
- 0x12, 0xf9, 0x5d, 0x97, 0x60, 0x82, 0xea, 0xac, 0x81, 0x39, 0x11, 0xda,
- 0xe0, 0x1a, 0xf3, 0xc1,
- ],
- RecoveryId::from_i32(1).unwrap(),
- )
- .unwrap(),
- ),
- };
+ },
+ hash: [
+ 0xb1, 0x96, 0x46, 0xc3, 0xbc, 0x56, 0x76, 0x1d, 0x20, 0x65, 0x6e, 0x0e, 0x32, 0xec,
+ 0xd2, 0x69, 0x27, 0xb7, 0x62, 0x6e, 0x2a, 0x8b, 0xe6, 0x97, 0x71, 0x9f, 0xf8, 0x7e,
+ 0x44, 0x54, 0x55, 0xb9,
+ ],
+ signature: Bolt11InvoiceSignature(
+ RecoverableSignature::from_compact(
+ &[
+ 0xd7, 0x90, 0x4c, 0xc4, 0xb7, 0x4a, 0x22, 0x26, 0x9c, 0x68, 0xc1, 0xdf,
+ 0x68, 0xa9, 0x6c, 0x21, 0x4d, 0x65, 0x1b, 0x93, 0x76, 0xe9, 0xf1, 0x64,
+ 0xd3, 0x60, 0x4d, 0xa4, 0xb7, 0xde, 0xcc, 0xce, 0x0e, 0x82, 0xaa, 0xab,
+ 0x4c, 0x85, 0xd3, 0x58, 0xea, 0x14, 0xd0, 0xae, 0x34, 0x2d, 0xa3, 0x08,
+ 0x12, 0xf9, 0x5d, 0x97, 0x60, 0x82, 0xea, 0xac, 0x81, 0x39, 0x11, 0xda,
+ 0xe0, 0x1a, 0xf3, 0xc1,
+ ],
+ RecoveryId::from_i32(1).unwrap(),
+ )
+ .unwrap(),
+ ),
+ };
assert_eq!(invoice_str, invoice.to_string());
assert_eq!(invoice_str.parse(), Ok(invoice));
}
@@ -1125,8 +1144,9 @@ mod test {
use crate::TaggedField::*;
use crate::{
Bolt11InvoiceSignature, Currency, PositiveTimestamp, RawBolt11Invoice, RawDataPart,
- RawHrp, Sha256, SignedRawBolt11Invoice,
+ RawHrp, SignedRawBolt11Invoice,
};
+ use bitcoin::hex::FromHex;
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, RecoveryId};
assert_eq!(
@@ -1143,9 +1163,16 @@ mod test {
data: RawDataPart {
timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
tagged_fields: vec ! [
- PaymentHash(Sha256(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())).into(),
+ crate::TaggedField::PaymentHash(crate::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
+ .into(),
Description(
crate::Description::new(
"Please consider supporting this project".to_owned()
@@ -1289,9 +1316,10 @@ mod test {
use crate::TaggedField::*;
use crate::{
Bolt11Invoice, Bolt11InvoiceFeatures, Bolt11InvoiceSignature, Currency,
- PositiveTimestamp, RawBolt11Invoice, RawDataPart, RawHrp, RawTaggedField, Sha256,
+ PositiveTimestamp, RawBolt11Invoice, RawDataPart, RawHrp, RawTaggedField,
SignedRawBolt11Invoice,
};
+ use bitcoin::hex::FromHex;
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, RecoveryId};
use bitcoin::secp256k1::PublicKey;
use lightning_types::routing::{RouteHint, RouteHintHop, RoutingFees};
@@ -1310,10 +1338,13 @@ mod test {
}
// Invoice fields
- let payment_hash = sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102",
- )
- .unwrap();
+ let payment_hash = crate::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex("0001020304050607080900010203040506070809000102030405060708090102")
+ .unwrap(),
+ )
+ .unwrap(),
+ );
let description = "A".repeat(639);
let fallback_addr = crate::Fallback::SegWitProgram {
version: bitcoin::WitnessVersion::V0,
@@ -1346,7 +1377,7 @@ mod test {
data: RawDataPart {
timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
tagged_fields: vec![
- PaymentHash(Sha256(payment_hash)).into(),
+ crate::TaggedField::PaymentHash(payment_hash).into(),
Description(crate::Description::new(description).unwrap()).into(),
PayeePubKey(crate::PayeePubKey(payee_pk)).into(),
ExpiryTime(crate::ExpiryTime(std::time::Duration::from_secs(u64::MAX))).into(),
@@ -1414,4 +1445,18 @@ mod test {
assert!(parse_is_code_length_err(&too_long));
assert!(!parse_is_code_length_err(&too_long[..too_long.len() - 1]));
}
+
+ #[test]
+ fn test_payment_hash_from_base32_invalid_len() {
+ use crate::PaymentHash;
+
+ // PaymentHash must be 52 base32 characters (32 bytes).
+ // Test with 51 characters (too short).
+ let input = vec![Fe32::try_from(0).unwrap(); 51];
+ assert!(PaymentHash::from_base32(&input).is_err());
+
+ // Test with 53 characters (too long).
+ let input = vec![Fe32::try_from(0).unwrap(); 53];
+ assert!(PaymentHash::from_base32(&input).is_err());
+ }
}
diff --git a/lightning-invoice/src/lib.rs b/lightning-invoice/src/lib.rs
index a83130a..4ee9acb 100644
--- a/lightning-invoice/src/lib.rs
+++ b/lightning-invoice/src/lib.rs
@@ -189,7 +189,7 @@ impl Checksum for Bolt11Bech32 {
///
/// use lightning_types::payment::PaymentSecret;
///
-/// use lightning_invoice::{Currency, InvoiceBuilder};
+/// use lightning_invoice::{Currency, InvoiceBuilder, PaymentHash};
///
/// # #[cfg(not(feature = "std"))]
/// # fn main() {}
@@ -203,7 +203,7 @@ impl Checksum for Bolt11Bech32 {
/// ][..]
/// ).unwrap();
///
-/// let payment_hash = sha256::Hash::from_slice(&[0; 32][..]).unwrap();
+/// let payment_hash = PaymentHash([0; 32]);
/// let payment_secret = PaymentSecret([42u8; 32]);
///
/// let invoice = InvoiceBuilder::new(Currency::Bitcoin)
@@ -521,7 +521,7 @@ impl Ord for RawTaggedField {
#[allow(missing_docs)]
#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub enum TaggedField {
- PaymentHash(Sha256),
+ PaymentHash(PaymentHash),
Description(Description),
PayeePubKey(PayeePubKey),
DescriptionHash(Sha256),
@@ -793,8 +793,8 @@ impl<D: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool, M: tb::Bool>
InvoiceBuilder<D, tb::False, T, C, S, M>
{
/// Set the payment hash. This function is only available if no payment hash was set.
- pub fn payment_hash(mut self, hash: sha256::Hash) -> InvoiceBuilder<D, tb::True, T, C, S, M> {
- self.tagged_fields.push(TaggedField::PaymentHash(Sha256(hash)));
+ pub fn payment_hash(mut self, hash: PaymentHash) -> InvoiceBuilder<D, tb::True, T, C, S, M> {
+ self.tagged_fields.push(TaggedField::PaymentHash(hash));
self.set_flags()
}
}
@@ -1158,7 +1158,7 @@ impl RawBolt11Invoice {
self.data.tagged_fields.iter().filter_map(match_raw)
}
- pub fn payment_hash(&self) -> Option<&Sha256> {
+ pub fn payment_hash(&self) -> Option<&PaymentHash> {
find_extract!(self.known_tagged_fields(), TaggedField::PaymentHash(ref x), x)
}
@@ -1461,8 +1461,7 @@ impl Bolt11Invoice {
/// Returns the hash to which we will receive the preimage on completion of the payment
pub fn payment_hash(&self) -> PaymentHash {
- let hash = self.signed_invoice.payment_hash().expect("checked by constructor").0;
- PaymentHash(hash.to_byte_array())
+ *self.signed_invoice.payment_hash().expect("checked by constructor")
}
/// Return the description or a hash of it for longer ones
@@ -1925,10 +1924,7 @@ impl<'de> Deserialize<'de> for Bolt11Invoice {
#[cfg(test)]
mod test {
- use bitcoin::hashes::sha256;
use bitcoin::ScriptBuf;
- use std::str::FromStr;
-
#[test]
fn test_system_time_bounds_assumptions() {
assert_eq!(
@@ -1940,16 +1936,22 @@ mod test {
#[test]
fn test_calc_invoice_hash() {
use crate::TaggedField::*;
- use crate::{Currency, PositiveTimestamp, RawBolt11Invoice, RawDataPart, RawHrp};
+ use crate::{
+ Currency, PaymentHash, PositiveTimestamp, RawBolt11Invoice, RawDataPart, RawHrp,
+ };
+ use bitcoin::hex::FromHex;
let invoice = RawBolt11Invoice {
hrp: RawHrp { currency: Currency::Bitcoin, raw_amount: None, si_prefix: None },
data: RawDataPart {
timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
tagged_fields: vec![
- PaymentHash(crate::Sha256(
- sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102",
+ crate::TaggedField::PaymentHash(PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
)
.unwrap(),
))
@@ -1978,51 +1980,58 @@ mod test {
fn test_check_signature() {
use crate::TaggedField::*;
use crate::{
- Bolt11InvoiceSignature, Currency, PositiveTimestamp, RawBolt11Invoice, RawDataPart,
- RawHrp, Sha256, SignedRawBolt11Invoice,
+ Bolt11InvoiceSignature, Currency, PaymentHash, PositiveTimestamp, RawBolt11Invoice,
+ RawDataPart, RawHrp, SignedRawBolt11Invoice,
};
+ use bitcoin::hex::FromHex;
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, RecoveryId};
use bitcoin::secp256k1::Secp256k1;
use bitcoin::secp256k1::{PublicKey, SecretKey};
- let invoice =
- SignedRawBolt11Invoice {
- raw_invoice: RawBolt11Invoice {
- hrp: RawHrp { currency: Currency::Bitcoin, raw_amount: None, si_prefix: None },
- data: RawDataPart {
- timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
- tagged_fields: vec ! [
- PaymentHash(Sha256(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())).into(),
+ let invoice = SignedRawBolt11Invoice {
+ raw_invoice: RawBolt11Invoice {
+ hrp: RawHrp { currency: Currency::Bitcoin, raw_amount: None, si_prefix: None },
+ data: RawDataPart {
+ timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
+ tagged_fields: vec ! [
+ crate::TaggedField::PaymentHash(PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
+ .into(),
Description(
crate::Description::new(
"Please consider supporting this project".to_owned()
).unwrap()
).into(),
],
- },
},
- hash: [
- 0xc3, 0xd4, 0xe8, 0x3f, 0x64, 0x6f, 0xa7, 0x9a, 0x39, 0x3d, 0x75, 0x27, 0x7b,
- 0x1d, 0x85, 0x8d, 0xb1, 0xd1, 0xf7, 0xab, 0x71, 0x37, 0xdc, 0xb7, 0x83, 0x5d,
- 0xb2, 0xec, 0xd5, 0x18, 0xe1, 0xc9,
- ],
- signature: Bolt11InvoiceSignature(
- RecoverableSignature::from_compact(
- &[
- 0x38u8, 0xec, 0x68, 0x91, 0x34, 0x5e, 0x20, 0x41, 0x45, 0xbe, 0x8a,
- 0x3a, 0x99, 0xde, 0x38, 0xe9, 0x8a, 0x39, 0xd6, 0xa5, 0x69, 0x43, 0x4e,
- 0x18, 0x45, 0xc8, 0xaf, 0x72, 0x05, 0xaf, 0xcf, 0xcc, 0x7f, 0x42, 0x5f,
- 0xcd, 0x14, 0x63, 0xe9, 0x3c, 0x32, 0x88, 0x1e, 0xad, 0x0d, 0x6e, 0x35,
- 0x6d, 0x46, 0x7e, 0xc8, 0xc0, 0x25, 0x53, 0xf9, 0xaa, 0xb1, 0x5e, 0x57,
- 0x38, 0xb1, 0x1f, 0x12, 0x7f,
- ],
- RecoveryId::from_i32(0).unwrap(),
- )
- .unwrap(),
- ),
- };
+ },
+ hash: [
+ 0xc3, 0xd4, 0xe8, 0x3f, 0x64, 0x6f, 0xa7, 0x9a, 0x39, 0x3d, 0x75, 0x27, 0x7b, 0x1d,
+ 0x85, 0x8d, 0xb1, 0xd1, 0xf7, 0xab, 0x71, 0x37, 0xdc, 0xb7, 0x83, 0x5d, 0xb2, 0xec,
+ 0xd5, 0x18, 0xe1, 0xc9,
+ ],
+ signature: Bolt11InvoiceSignature(
+ RecoverableSignature::from_compact(
+ &[
+ 0x38u8, 0xec, 0x68, 0x91, 0x34, 0x5e, 0x20, 0x41, 0x45, 0xbe, 0x8a, 0x3a,
+ 0x99, 0xde, 0x38, 0xe9, 0x8a, 0x39, 0xd6, 0xa5, 0x69, 0x43, 0x4e, 0x18,
+ 0x45, 0xc8, 0xaf, 0x72, 0x05, 0xaf, 0xcf, 0xcc, 0x7f, 0x42, 0x5f, 0xcd,
+ 0x14, 0x63, 0xe9, 0x3c, 0x32, 0x88, 0x1e, 0xad, 0x0d, 0x6e, 0x35, 0x6d,
+ 0x46, 0x7e, 0xc8, 0xc0, 0x25, 0x53, 0xf9, 0xaa, 0xb1, 0x5e, 0x57, 0x38,
+ 0xb1, 0x1f, 0x12, 0x7f,
+ ],
+ RecoveryId::from_i32(0).unwrap(),
+ )
+ .unwrap(),
+ ),
+ };
assert!(invoice.check_signature());
@@ -2050,9 +2059,10 @@ mod test {
fn test_check_feature_bits() {
use crate::TaggedField::*;
use crate::{
- Bolt11Invoice, Bolt11SemanticError, Currency, PositiveTimestamp, RawBolt11Invoice,
- RawDataPart, RawHrp, Sha256,
+ Bolt11Invoice, Bolt11SemanticError, Currency, PaymentHash, PositiveTimestamp,
+ RawBolt11Invoice, RawDataPart, RawHrp,
};
+ use bitcoin::hex::FromHex;
use bitcoin::secp256k1::Secp256k1;
use bitcoin::secp256k1::SecretKey;
use lightning_types::features::Bolt11InvoiceFeatures;
@@ -2064,9 +2074,12 @@ mod test {
data: RawDataPart {
timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
tagged_fields: vec![
- PaymentHash(Sha256(
- sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102",
+ crate::TaggedField::PaymentHash(PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
)
.unwrap(),
))
@@ -2174,7 +2187,7 @@ mod test {
let builder = InvoiceBuilder::new(Currency::Bitcoin)
.description("Test".into())
- .payment_hash(sha256::Hash::from_slice(&[0; 32][..]).unwrap())
+ .payment_hash(PaymentHash([0; 32]))
.duration_since_epoch(Duration::from_secs(1234567));
let invoice = builder.clone().amount_milli_satoshis(1500).build_raw().unwrap();
@@ -2196,7 +2209,7 @@ mod test {
use std::iter::FromIterator;
let builder = InvoiceBuilder::new(Currency::Bitcoin)
- .payment_hash(sha256::Hash::from_slice(&[0; 32][..]).unwrap())
+ .payment_hash(PaymentHash([0; 32]))
.duration_since_epoch(Duration::from_secs(1234567))
.min_final_cltv_expiry_delta(144);
@@ -2300,7 +2313,7 @@ mod test {
.private_route(route_1.clone())
.private_route(route_2.clone())
.description_hash(sha256::Hash::from_slice(&[3; 32][..]).unwrap())
- .payment_hash(sha256::Hash::from_slice(&[21; 32][..]).unwrap())
+ .payment_hash(PaymentHash([21; 32]))
.payment_secret(PaymentSecret([42; 32]))
.basic_mpp();
@@ -2361,7 +2374,7 @@ mod test {
let signed_invoice = InvoiceBuilder::new(Currency::Bitcoin)
.description("Test".into())
- .payment_hash(sha256::Hash::from_slice(&[0; 32][..]).unwrap())
+ .payment_hash(PaymentHash([0; 32]))
.payment_secret(PaymentSecret([0; 32]))
.duration_since_epoch(Duration::from_secs(1234567))
.build_raw()
@@ -2387,7 +2400,7 @@ mod test {
let signed_invoice = InvoiceBuilder::new(Currency::Bitcoin)
.description("Test".into())
- .payment_hash(sha256::Hash::from_slice(&[0; 32][..]).unwrap())
+ .payment_hash(PaymentHash([0; 32]))
.payment_secret(PaymentSecret([0; 32]))
.duration_since_epoch(Duration::from_secs(1234567))
.build_raw()
@@ -2428,13 +2441,13 @@ mod test {
#[test]
fn raw_tagged_field_ordering() {
- use crate::{
- sha256, Description, Fe32, RawTaggedField, Sha256, TaggedField, UntrustedString,
- };
+ use crate::{Description, Fe32, PaymentHash, RawTaggedField, TaggedField, UntrustedString};
+ use bitcoin::hex::FromHex;
- let field10 = RawTaggedField::KnownSemantics(TaggedField::PaymentHash(Sha256(
- sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102",
+ let field10 = RawTaggedField::KnownSemantics(crate::TaggedField::PaymentHash(PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex("0001020304050607080900010203040506070809000102030405060708090102")
+ .unwrap(),
)
.unwrap(),
)));
diff --git a/lightning-invoice/src/ser.rs b/lightning-invoice/src/ser.rs
index 853accd..35d5dc0 100644
--- a/lightning-invoice/src/ser.rs
+++ b/lightning-invoice/src/ser.rs
@@ -7,9 +7,9 @@ use bech32::{ByteIterExt, Fe32, Fe32IterExt};
use super::{
constants, Bolt11Invoice, Bolt11InvoiceFeatures, Bolt11InvoiceSignature, Currency, Description,
- ExpiryTime, Fallback, MinFinalCltvExpiryDelta, PayeePubKey, PaymentSecret, PositiveTimestamp,
- PrivateRoute, RawDataPart, RawHrp, RawTaggedField, RouteHintHop, Sha256, SiPrefix,
- SignedRawBolt11Invoice, TaggedField,
+ ExpiryTime, Fallback, MinFinalCltvExpiryDelta, PayeePubKey, PaymentHash, PaymentSecret,
+ PositiveTimestamp, PrivateRoute, RawDataPart, RawHrp, RawTaggedField, RouteHintHop, Sha256,
+ SiPrefix, SignedRawBolt11Invoice, TaggedField,
};
macro_rules! define_iterator_enum {
@@ -95,6 +95,18 @@ impl Base32Len for PaymentSecret {
}
}
+impl Base32Iterable for PaymentHash {
+ fn fe_iter<'s>(&'s self) -> impl Iterator<Item = Fe32> + 's {
+ self.0[..].fe_iter()
+ }
+}
+
+impl Base32Len for PaymentHash {
+ fn base32_len(&self) -> usize {
+ 52
+ }
+}
+
impl Base32Iterable for Bolt11InvoiceFeatures {
/// Convert to 5-bit values, by unpacking the 5 bit groups,
/// putting the bytes from right-to-left,
diff --git a/lightning-invoice/src/test_ser_de.rs b/lightning-invoice/src/test_ser_de.rs
index e2e4d76..efeed83 100644
--- a/lightning-invoice/src/test_ser_de.rs
+++ b/lightning-invoice/src/test_ser_de.rs
@@ -1,7 +1,11 @@
use crate::de::FromBase32;
use crate::ser::{Base32Iterable, Base32Len};
-use crate::{sha256, PayeePubKey, PaymentSecret, PositiveTimestamp, RawDataPart, Sha256};
+use crate::{
+ sha256, PayeePubKey, PaymentHash, PaymentSecret, PositiveTimestamp, RawDataPart,
+ RawTaggedField, Sha256, TaggedField,
+};
use bech32::Fe32;
+use bitcoin::hex::FromHex;
use core::fmt::Debug;
use std::str::FromStr;
@@ -173,11 +177,12 @@ fn bolt11_invoice_features() {
#[test]
fn raw_tagged_field() {
- use crate::TaggedField::PaymentHash;
-
- let field = PaymentHash(Sha256(
- sha256::Hash::from_str("0001020304050607080900010203040506070809000102030405060708090102")
- .unwrap(),
+ let field = TaggedField::PaymentHash(PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex("0001020304050607080900010203040506070809000102030405060708090102")
+ .unwrap(),
+ )
+ .unwrap(),
));
ser_de_test(field, "pp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypq");
}
@@ -202,17 +207,15 @@ fn description() {
#[test]
fn raw_data_part() {
- use crate::TaggedField::PaymentHash;
-
let raw_data_part = RawDataPart {
timestamp: PositiveTimestamp::from_unix_timestamp(10000).unwrap(),
- tagged_fields: vec![PaymentHash(Sha256(
- sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102",
+ tagged_fields: vec![RawTaggedField::KnownSemantics(TaggedField::PaymentHash(PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex("0001020304050607080900010203040506070809000102030405060708090102")
+ .unwrap(),
)
.unwrap(),
- ))
- .into()],
+ )))],
};
ser_de_test(raw_data_part, "qqqqfcspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypq");
}
diff --git a/lightning-invoice/tests/ser_de.rs b/lightning-invoice/tests/ser_de.rs
index b4d3fa7..353878a 100644
--- a/lightning-invoice/tests/ser_de.rs
+++ b/lightning-invoice/tests/ser_de.rs
@@ -18,9 +18,15 @@ fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
InvoiceBuilder::new(Currency::Bitcoin)
.duration_since_epoch(Duration::from_secs(1496314658))
.payment_secret(PaymentSecret([0x11; 32]))
- .payment_hash(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())
+ .payment_hash(lightning_invoice::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
.description("Please consider supporting this project".to_owned())
.build_raw()
.unwrap()
@@ -39,9 +45,15 @@ fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
.amount_milli_satoshis(250_000_000)
.duration_since_epoch(Duration::from_secs(1496314658))
.payment_secret(PaymentSecret([0x11; 32]))
- .payment_hash(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())
+ .payment_hash(lightning_invoice::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
.description("1 cup coffee".to_owned())
.expiry_time(Duration::from_secs(60))
.build_raw()
@@ -61,9 +73,15 @@ fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
.amount_milli_satoshis(250_000_000)
.duration_since_epoch(Duration::from_secs(1496314658))
.payment_secret(PaymentSecret([0x11; 32]))
- .payment_hash(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())
+ .payment_hash(lightning_invoice::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
.description("ナンセンス 1杯".to_owned())
.expiry_time(Duration::from_secs(60))
.build_raw()
@@ -84,9 +102,15 @@ fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
.duration_since_epoch(Duration::from_secs(1496314658))
.description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
.payment_secret(PaymentSecret([0x11; 32]))
- .payment_hash(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())
+ .payment_hash(lightning_invoice::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
.build_raw()
.unwrap()
.sign(|_| {
@@ -105,9 +129,15 @@ fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
.duration_since_epoch(Duration::from_secs(1496314658))
.description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
.payment_secret(PaymentSecret([0x11; 32]))
- .payment_hash(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())
+ .payment_hash(lightning_invoice::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
.fallback(Fallback::PubKeyHash(PubkeyHash::from_slice(&[49, 114, 181, 101, 79, 102, 131, 200, 251, 20, 105, 89, 211, 71, 206, 48, 60, 174, 76, 167]).unwrap()))
.build_raw()
.unwrap()
@@ -127,9 +157,15 @@ fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
.duration_since_epoch(Duration::from_secs(1496314658))
.description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
.payment_secret(PaymentSecret([0x11; 32]))
- .payment_hash(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())
+ .payment_hash(lightning_invoice::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
.fallback(Fallback::PubKeyHash(PubkeyHash::from_slice(&[4, 182, 31, 125, 193, 234, 13, 201, 148, 36, 70, 76, 196, 6, 77, 197, 100, 217, 30, 137]).unwrap()))
.private_route(RouteHint(vec![RouteHintHop {
src_node_id: PublicKey::from_slice(&<Vec<u8>>::from_hex(
@@ -166,9 +202,15 @@ fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
.duration_since_epoch(Duration::from_secs(1496314658))
.description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
.payment_secret(PaymentSecret([0x11; 32]))
- .payment_hash(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())
+ .payment_hash(lightning_invoice::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
.fallback(Fallback::ScriptHash(ScriptHash::from_slice(&[143, 85, 86, 59, 154, 25, 243, 33, 194, 17, 233, 185, 243, 140, 223, 104, 110, 160, 120, 69]).unwrap()))
.build_raw()
.unwrap()
@@ -188,9 +230,15 @@ fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
.duration_since_epoch(Duration::from_secs(1496314658))
.description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
.payment_secret(PaymentSecret([0x11; 32]))
- .payment_hash(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())
+ .payment_hash(lightning_invoice::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
.fallback(Fallback::SegWitProgram { version: WitnessVersion::V0,
program: vec![117, 30, 118, 232, 25, 145, 150, 212, 84, 148, 28, 69, 209, 179, 163, 35, 241, 67, 59, 214]
})
@@ -212,9 +260,15 @@ fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
.duration_since_epoch(Duration::from_secs(1496314658))
.description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
.payment_secret(PaymentSecret([0x11; 32]))
- .payment_hash(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())
+ .payment_hash(lightning_invoice::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
.fallback(Fallback::SegWitProgram { version: WitnessVersion::V0,
program: vec![24, 99, 20, 60, 20, 197, 22, 104, 4, 189, 25, 32, 51, 86, 218, 19, 108, 152, 86, 120, 205, 77, 39, 161, 184, 198, 50, 150, 4, 144, 50, 98]
})
@@ -235,9 +289,15 @@ fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
.amount_milli_satoshis(967878534)
.duration_since_epoch(Duration::from_secs(1572468703))
.payment_secret(PaymentSecret([0x11; 32]))
- .payment_hash(sha256::Hash::from_str(
- "462264ede7e14047e9b249da94fefc47f41f7d02ee9b091815a5506bc8abf75f"
- ).unwrap())
+ .payment_hash(lightning_invoice::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "462264ede7e14047e9b249da94fefc47f41f7d02ee9b091815a5506bc8abf75f",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
.expiry_time(Duration::from_secs(604800))
.min_final_cltv_expiry_delta(10)
.description("Blockstream Store: 88.85 USD for Blockstream Ledger Nano S x 1, \"Back In My Day\" Sticker x 2, \"I Got Lightning Working\" Sticker x 2 and 1 more items".to_owned())
@@ -267,9 +327,15 @@ fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
.amount_milli_satoshis(2_500_000_000)
.duration_since_epoch(Duration::from_secs(1496314658))
.payment_secret(PaymentSecret([0x11; 32]))
- .payment_hash(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())
+ .payment_hash(lightning_invoice::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
.description("coffee beans".to_owned())
.build_raw()
.unwrap()
@@ -288,9 +354,15 @@ fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
.amount_milli_satoshis(2_500_000_000)
.duration_since_epoch(Duration::from_secs(1496314658))
.payment_secret(PaymentSecret([0x11; 32]))
- .payment_hash(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())
+ .payment_hash(lightning_invoice::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
.description("coffee beans".to_owned())
.build_raw()
.unwrap()
@@ -309,9 +381,15 @@ fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
.amount_milli_satoshis(2_500_000_000)
.duration_since_epoch(Duration::from_secs(1496314658))
.payment_secret(PaymentSecret([0x11; 32]))
- .payment_hash(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())
+ .payment_hash(lightning_invoice::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
.description("coffee beans".to_owned())
.build_raw()
.unwrap()
@@ -329,9 +407,15 @@ fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
InvoiceBuilder::new(Currency::Bitcoin)
.amount_milli_satoshis(1_000_000_000)
.duration_since_epoch(Duration::from_secs(1496314658))
- .payment_hash(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())
+ .payment_hash(lightning_invoice::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
.description("payment metadata inside".to_owned())
.payment_metadata(<Vec<u8>>::from_hex("01fafaf0").unwrap())
.require_payment_metadata()
@@ -355,9 +439,15 @@ fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
InvoiceBuilder::new(Currency::Bitcoin)
.amount_milli_satoshis(1_000_000_000)
.duration_since_epoch(Duration::from_secs(1496314658))
- .payment_hash(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())
+ .payment_hash(lightning_invoice::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
.description("payment metadata inside".to_owned())
.payment_metadata(<Vec<u8>>::from_hex("01fafaf0").unwrap())
.require_payment_metadata()
@@ -378,9 +468,15 @@ fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
InvoiceBuilder::new(Currency::Bitcoin)
.duration_since_epoch(Duration::from_secs(1496314658))
.payment_secret(PaymentSecret([0x11; 32]))
- .payment_hash(sha256::Hash::from_str(
- "0001020304050607080900010203040506070809000102030405060708090102"
- ).unwrap())
+ .payment_hash(lightning_invoice::PaymentHash(
+ <[u8; 32]>::try_from(
+ Vec::from_hex(
+ "0001020304050607080900010203040506070809000102030405060708090102",
+ )
+ .unwrap(),
+ )
+ .unwrap(),
+ ))
.description("Please consider supporting this project".to_owned())
.build_raw()
.unwrap()
diff --git a/lightning-liquidity/tests/lsps2_integration_tests.rs b/lightning-liquidity/tests/lsps2_integration_tests.rs
index 45c2891..42195ac 100644
--- a/lightning-liquidity/tests/lsps2_integration_tests.rs
+++ b/lightning-liquidity/tests/lsps2_integration_tests.rs
@@ -47,7 +47,6 @@ use lightning_invoice::{Bolt11Invoice, InvoiceBuilder, RoutingFees};
use lightning_types::payment::PaymentHash;
-use bitcoin::hashes::{sha256, Hash};
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
use bitcoin::Network;
use lightning_types::payment::PaymentPreimage;
@@ -138,10 +137,6 @@ fn create_jit_invoice(
htlc_maximum_msat: None,
}]);
- let payment_hash = sha256::Hash::from_slice(&payment_hash.0).map_err(|e| {
- log_error!(node.logger, "Invalid payment hash: {:?}", e);
- })?;
-
let currency = Network::Bitcoin.into();
let mut invoice_builder = InvoiceBuilder::new(currency)
.description(description.to_string())
diff --git a/lightning/src/ln/bolt11_payment_tests.rs b/lightning/src/ln/bolt11_payment_tests.rs
index 63c5576..63861f9 100644
--- a/lightning/src/ln/bolt11_payment_tests.rs
+++ b/lightning/src/ln/bolt11_payment_tests.rs
@@ -16,8 +16,6 @@ use crate::ln::msgs::ChannelMessageHandler;
use crate::ln::outbound_payment::Bolt11PaymentError;
use crate::routing::router::RouteParametersConfig;
use crate::sign::{NodeSigner, Recipient};
-use bitcoin::hashes::sha256::Hash as Sha256;
-use bitcoin::hashes::Hash;
use lightning_invoice::{Bolt11Invoice, Currency, InvoiceBuilder};
use std::time::SystemTime;
@@ -39,7 +37,7 @@ fn payment_metadata_end_to_end_for_invoice_with_amount() {
let timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
let invoice = InvoiceBuilder::new(Currency::Bitcoin)
.description("test".into())
- .payment_hash(Sha256::from_slice(&payment_hash.0).unwrap())
+ .payment_hash(payment_hash)
.payment_secret(payment_secret)
.duration_since_epoch(timestamp)
.min_final_cltv_expiry_delta(144)
@@ -108,7 +106,7 @@ fn payment_metadata_end_to_end_for_invoice_with_no_amount() {
let timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
let invoice = InvoiceBuilder::new(Currency::Bitcoin)
.description("test".into())
- .payment_hash(Sha256::from_slice(&payment_hash.0).unwrap())
+ .payment_hash(payment_hash)
.payment_secret(payment_secret)
.duration_since_epoch(timestamp)
.min_final_cltv_expiry_delta(144)
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index 0f9adfc..41d49be 100644
--- a/lightning/src/ln/channelmanager.rs
+++ b/lightning/src/ln/channelmanager.rs
@@ -13309,7 +13309,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
let mut invoice = invoice
.duration_since_epoch(duration_since_epoch)
.payee_pub_key(self.get_our_node_id())
- .payment_hash(Hash::from_slice(&payment_hash.0).unwrap())
+ .payment_hash(payment_hash)
.payment_secret(payment_secret)
.basic_mpp()
.min_final_cltv_expiry_delta(
diff --git a/lightning/src/ln/invoice_utils.rs b/lightning/src/ln/invoice_utils.rs
index e72ea45..2cf3233 100644
--- a/lightning/src/ln/invoice_utils.rs
+++ b/lightning/src/ln/invoice_utils.rs
@@ -18,7 +18,6 @@ use crate::sign::{EntropySource, NodeSigner, Recipient};
use crate::types::payment::PaymentHash;
use crate::util::logger::{Logger, Record};
use alloc::collections::{btree_map, BTreeMap};
-use bitcoin::hashes::Hash;
use bitcoin::secp256k1::PublicKey;
#[cfg(not(feature = "std"))]
use core::iter::Iterator;
@@ -228,7 +227,7 @@ where
let mut invoice = invoice
.duration_since_epoch(duration_since_epoch)
- .payment_hash(Hash::from_slice(&payment_hash.0).unwrap())
+ .payment_hash(payment_hash)
.payment_secret(payment_secret)
.min_final_cltv_expiry_delta(
// Add a buffer of 3 to the delta if present, otherwise use LDK's minimum.
@@ -1257,7 +1256,8 @@ mod test {
Duration::from_secs(genesis_timestamp),
)
.unwrap();
- let (payment_hash, payment_secret) = (invoice.payment_hash(), *invoice.payment_secret());
+ let payment_hash = invoice.payment_hash();
+ let payment_secret = *invoice.payment_secret();
let payment_preimage = if user_generated_pmt_hash {
user_payment_preimage
} else {
Why this scored 20/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.