Skip to content

Commit fd66adb

Browse files
committed
Add parsing tests for experimental invreq TLVs
1 parent 6e89432 commit fd66adb

File tree

1 file changed

+82
-2
lines changed

1 file changed

+82
-2
lines changed

lightning/src/offers/invoice_request.rs

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,7 +1334,7 @@ impl Readable for InvoiceRequestFields {
13341334

13351335
#[cfg(test)]
13361336
mod tests {
1337-
use super::{ExperimentalInvoiceRequestTlvStreamRef, INVOICE_REQUEST_TYPES, InvoiceRequest, InvoiceRequestFields, InvoiceRequestTlvStreamRef, PAYER_NOTE_LIMIT, SIGNATURE_TAG, UnsignedInvoiceRequest};
1337+
use super::{EXPERIMENTAL_INVOICE_REQUEST_TYPES, ExperimentalInvoiceRequestTlvStreamRef, INVOICE_REQUEST_TYPES, InvoiceRequest, InvoiceRequestFields, InvoiceRequestTlvStreamRef, PAYER_NOTE_LIMIT, SIGNATURE_TAG, UnsignedInvoiceRequest};
13381338

13391339
use bitcoin::constants::ChainHash;
13401340
use bitcoin::network::Network;
@@ -1348,7 +1348,7 @@ mod tests {
13481348
use crate::ln::inbound_payment::ExpandedKey;
13491349
use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
13501350
use crate::offers::invoice::{Bolt12Invoice, SIGNATURE_TAG as INVOICE_SIGNATURE_TAG};
1351-
use crate::offers::merkle::{SignError, SignatureTlvStreamRef, TaggedHash, self};
1351+
use crate::offers::merkle::{SignError, SignatureTlvStreamRef, TaggedHash, TlvStream, self};
13521352
use crate::offers::nonce::Nonce;
13531353
use crate::offers::offer::{Amount, ExperimentalOfferTlvStreamRef, OfferTlvStreamRef, Quantity};
13541354
#[cfg(not(c_bindings))]
@@ -2483,10 +2483,79 @@ mod tests {
24832483
}
24842484
}
24852485

2486+
#[test]
2487+
fn parses_invoice_request_with_experimental_tlv_records() {
2488+
const UNKNOWN_ODD_TYPE: u64 = EXPERIMENTAL_INVOICE_REQUEST_TYPES.start + 1;
2489+
assert!(UNKNOWN_ODD_TYPE % 2 == 1);
2490+
2491+
let secp_ctx = Secp256k1::new();
2492+
let keys = Keypair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
2493+
let mut unsigned_invoice_request = OfferBuilder::new(keys.public_key())
2494+
.amount_msats(1000)
2495+
.build().unwrap()
2496+
.request_invoice(vec![1; 32], keys.public_key()).unwrap()
2497+
.build().unwrap();
2498+
2499+
BigSize(UNKNOWN_ODD_TYPE).write(&mut unsigned_invoice_request.experimental_bytes).unwrap();
2500+
BigSize(32).write(&mut unsigned_invoice_request.experimental_bytes).unwrap();
2501+
[42u8; 32].write(&mut unsigned_invoice_request.experimental_bytes).unwrap();
2502+
2503+
let tlv_stream = TlvStream::new(&unsigned_invoice_request.bytes)
2504+
.chain(TlvStream::new(&unsigned_invoice_request.experimental_bytes));
2505+
unsigned_invoice_request.tagged_hash =
2506+
TaggedHash::from_tlv_stream(SIGNATURE_TAG, tlv_stream);
2507+
2508+
let invoice_request = unsigned_invoice_request
2509+
.sign(|message: &UnsignedInvoiceRequest|
2510+
Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2511+
)
2512+
.unwrap();
2513+
2514+
let mut encoded_invoice_request = Vec::new();
2515+
invoice_request.write(&mut encoded_invoice_request).unwrap();
2516+
2517+
if let Err(e) = InvoiceRequest::try_from(encoded_invoice_request) {
2518+
panic!("error parsing invoice_request: {:?}", e);
2519+
}
2520+
2521+
const UNKNOWN_EVEN_TYPE: u64 = EXPERIMENTAL_INVOICE_REQUEST_TYPES.start;
2522+
assert!(UNKNOWN_EVEN_TYPE % 2 == 0);
2523+
2524+
let mut unsigned_invoice_request = OfferBuilder::new(keys.public_key())
2525+
.amount_msats(1000)
2526+
.build().unwrap()
2527+
.request_invoice(vec![1; 32], keys.public_key()).unwrap()
2528+
.build().unwrap();
2529+
2530+
BigSize(UNKNOWN_EVEN_TYPE).write(&mut unsigned_invoice_request.experimental_bytes).unwrap();
2531+
BigSize(32).write(&mut unsigned_invoice_request.experimental_bytes).unwrap();
2532+
[42u8; 32].write(&mut unsigned_invoice_request.experimental_bytes).unwrap();
2533+
2534+
let tlv_stream = TlvStream::new(&unsigned_invoice_request.bytes)
2535+
.chain(TlvStream::new(&unsigned_invoice_request.experimental_bytes));
2536+
unsigned_invoice_request.tagged_hash =
2537+
TaggedHash::from_tlv_stream(SIGNATURE_TAG, tlv_stream);
2538+
2539+
let invoice_request = unsigned_invoice_request
2540+
.sign(|message: &UnsignedInvoiceRequest|
2541+
Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2542+
)
2543+
.unwrap();
2544+
2545+
let mut encoded_invoice_request = Vec::new();
2546+
invoice_request.write(&mut encoded_invoice_request).unwrap();
2547+
2548+
match InvoiceRequest::try_from(encoded_invoice_request) {
2549+
Ok(_) => panic!("expected error"),
2550+
Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::UnknownRequiredFeature)),
2551+
}
2552+
}
2553+
24862554
#[test]
24872555
fn fails_parsing_invoice_request_with_out_of_range_tlv_records() {
24882556
let secp_ctx = Secp256k1::new();
24892557
let keys = Keypair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
2558+
24902559
let invoice_request = OfferBuilder::new(keys.public_key())
24912560
.amount_msats(1000)
24922561
.build().unwrap()
@@ -2507,6 +2576,17 @@ mod tests {
25072576
Ok(_) => panic!("expected error"),
25082577
Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)),
25092578
}
2579+
2580+
let mut encoded_invoice_request = Vec::new();
2581+
invoice_request.write(&mut encoded_invoice_request).unwrap();
2582+
BigSize(EXPERIMENTAL_INVOICE_REQUEST_TYPES.end).write(&mut encoded_invoice_request).unwrap();
2583+
BigSize(32).write(&mut encoded_invoice_request).unwrap();
2584+
[42u8; 32].write(&mut encoded_invoice_request).unwrap();
2585+
2586+
match InvoiceRequest::try_from(encoded_invoice_request) {
2587+
Ok(_) => panic!("expected error"),
2588+
Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)),
2589+
}
25102590
}
25112591

25122592
#[test]

0 commit comments

Comments
 (0)