Skip to content

Commit ad638a5

Browse files
committed
Add parsing tests for experimental invreq TLVs
1 parent cc749b8 commit ad638a5

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
@@ -1335,7 +1335,7 @@ impl Readable for InvoiceRequestFields {
13351335

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

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

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

25132593
#[test]

0 commit comments

Comments
 (0)