Skip to content

Commit 435be66

Browse files
committed
Add parsing tests for experimental invreq TLVs
1 parent b79e74d commit 435be66

File tree

1 file changed

+105
-2
lines changed

1 file changed

+105
-2
lines changed

lightning/src/offers/invoice_request.rs

Lines changed: 105 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,7 +1354,7 @@ impl Readable for InvoiceRequestFields {
13541354

13551355
#[cfg(test)]
13561356
mod tests {
1357-
use super::{ExperimentalInvoiceRequestTlvStreamRef, INVOICE_REQUEST_TYPES, InvoiceRequest, InvoiceRequestFields, InvoiceRequestTlvStreamRef, PAYER_NOTE_LIMIT, SIGNATURE_TAG, UnsignedInvoiceRequest};
1357+
use super::{EXPERIMENTAL_INVOICE_REQUEST_TYPES, ExperimentalInvoiceRequestTlvStreamRef, INVOICE_REQUEST_TYPES, InvoiceRequest, InvoiceRequestFields, InvoiceRequestTlvStreamRef, PAYER_NOTE_LIMIT, SIGNATURE_TAG, UnsignedInvoiceRequest};
13581358

13591359
use bitcoin::constants::ChainHash;
13601360
use bitcoin::network::Network;
@@ -1368,7 +1368,7 @@ mod tests {
13681368
use crate::ln::inbound_payment::ExpandedKey;
13691369
use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
13701370
use crate::offers::invoice::{Bolt12Invoice, SIGNATURE_TAG as INVOICE_SIGNATURE_TAG};
1371-
use crate::offers::merkle::{SignError, SignatureTlvStreamRef, TaggedHash, self};
1371+
use crate::offers::merkle::{SignError, SignatureTlvStreamRef, TaggedHash, TlvStream, self};
13721372
use crate::offers::nonce::Nonce;
13731373
use crate::offers::offer::{Amount, ExperimentalOfferTlvStreamRef, OfferTlvStreamRef, Quantity};
13741374
#[cfg(not(c_bindings))]
@@ -2504,10 +2504,102 @@ mod tests {
25042504
}
25052505
}
25062506

2507+
#[test]
2508+
fn parses_invoice_request_with_experimental_tlv_records() {
2509+
const UNKNOWN_ODD_TYPE: u64 = EXPERIMENTAL_INVOICE_REQUEST_TYPES.start + 1;
2510+
assert!(UNKNOWN_ODD_TYPE % 2 == 1);
2511+
2512+
let secp_ctx = Secp256k1::new();
2513+
let keys = Keypair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
2514+
let mut unsigned_invoice_request = OfferBuilder::new(keys.public_key())
2515+
.amount_msats(1000)
2516+
.build().unwrap()
2517+
.request_invoice(vec![1; 32], keys.public_key()).unwrap()
2518+
.build().unwrap();
2519+
2520+
BigSize(UNKNOWN_ODD_TYPE).write(&mut unsigned_invoice_request.experimental_bytes).unwrap();
2521+
BigSize(32).write(&mut unsigned_invoice_request.experimental_bytes).unwrap();
2522+
[42u8; 32].write(&mut unsigned_invoice_request.experimental_bytes).unwrap();
2523+
2524+
let tlv_stream = TlvStream::new(&unsigned_invoice_request.bytes)
2525+
.chain(TlvStream::new(&unsigned_invoice_request.experimental_bytes));
2526+
unsigned_invoice_request.tagged_hash =
2527+
TaggedHash::from_tlv_stream(SIGNATURE_TAG, tlv_stream);
2528+
2529+
let invoice_request = unsigned_invoice_request
2530+
.sign(|message: &UnsignedInvoiceRequest|
2531+
Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2532+
)
2533+
.unwrap();
2534+
2535+
let mut encoded_invoice_request = Vec::new();
2536+
invoice_request.write(&mut encoded_invoice_request).unwrap();
2537+
2538+
match InvoiceRequest::try_from(encoded_invoice_request.clone()) {
2539+
Ok(invoice_request) => assert_eq!(invoice_request.bytes, encoded_invoice_request),
2540+
Err(e) => panic!("error parsing invoice_request: {:?}", e),
2541+
}
2542+
2543+
const UNKNOWN_EVEN_TYPE: u64 = EXPERIMENTAL_INVOICE_REQUEST_TYPES.start;
2544+
assert!(UNKNOWN_EVEN_TYPE % 2 == 0);
2545+
2546+
let mut unsigned_invoice_request = OfferBuilder::new(keys.public_key())
2547+
.amount_msats(1000)
2548+
.build().unwrap()
2549+
.request_invoice(vec![1; 32], keys.public_key()).unwrap()
2550+
.build().unwrap();
2551+
2552+
BigSize(UNKNOWN_EVEN_TYPE).write(&mut unsigned_invoice_request.experimental_bytes).unwrap();
2553+
BigSize(32).write(&mut unsigned_invoice_request.experimental_bytes).unwrap();
2554+
[42u8; 32].write(&mut unsigned_invoice_request.experimental_bytes).unwrap();
2555+
2556+
let tlv_stream = TlvStream::new(&unsigned_invoice_request.bytes)
2557+
.chain(TlvStream::new(&unsigned_invoice_request.experimental_bytes));
2558+
unsigned_invoice_request.tagged_hash =
2559+
TaggedHash::from_tlv_stream(SIGNATURE_TAG, tlv_stream);
2560+
2561+
let invoice_request = unsigned_invoice_request
2562+
.sign(|message: &UnsignedInvoiceRequest|
2563+
Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2564+
)
2565+
.unwrap();
2566+
2567+
let mut encoded_invoice_request = Vec::new();
2568+
invoice_request.write(&mut encoded_invoice_request).unwrap();
2569+
2570+
match InvoiceRequest::try_from(encoded_invoice_request) {
2571+
Ok(_) => panic!("expected error"),
2572+
Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::UnknownRequiredFeature)),
2573+
}
2574+
2575+
let invoice_request = OfferBuilder::new(keys.public_key())
2576+
.amount_msats(1000)
2577+
.build().unwrap()
2578+
.request_invoice(vec![1; 32], keys.public_key()).unwrap()
2579+
.build().unwrap()
2580+
.sign(|message: &UnsignedInvoiceRequest|
2581+
Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2582+
)
2583+
.unwrap();
2584+
2585+
let mut encoded_invoice_request = Vec::new();
2586+
invoice_request.write(&mut encoded_invoice_request).unwrap();
2587+
2588+
BigSize(UNKNOWN_ODD_TYPE).write(&mut encoded_invoice_request).unwrap();
2589+
BigSize(32).write(&mut encoded_invoice_request).unwrap();
2590+
[42u8; 32].write(&mut encoded_invoice_request).unwrap();
2591+
2592+
match InvoiceRequest::try_from(encoded_invoice_request) {
2593+
Ok(_) => panic!("expected error"),
2594+
Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSignature(secp256k1::Error::IncorrectSignature)),
2595+
}
2596+
}
2597+
25072598
#[test]
25082599
fn fails_parsing_invoice_request_with_out_of_range_tlv_records() {
25092600
let secp_ctx = Secp256k1::new();
25102601
let keys = Keypair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
2602+
25112603
let invoice_request = OfferBuilder::new(keys.public_key())
25122604
.amount_msats(1000)
25132605
.build().unwrap()
@@ -2528,6 +2620,17 @@ mod tests {
25282620
Ok(_) => panic!("expected error"),
25292621
Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)),
25302622
}
2623+
2624+
let mut encoded_invoice_request = Vec::new();
2625+
invoice_request.write(&mut encoded_invoice_request).unwrap();
2626+
BigSize(EXPERIMENTAL_INVOICE_REQUEST_TYPES.end).write(&mut encoded_invoice_request).unwrap();
2627+
BigSize(32).write(&mut encoded_invoice_request).unwrap();
2628+
[42u8; 32].write(&mut encoded_invoice_request).unwrap();
2629+
2630+
match InvoiceRequest::try_from(encoded_invoice_request) {
2631+
Ok(_) => panic!("expected error"),
2632+
Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)),
2633+
}
25312634
}
25322635

25332636
#[test]

0 commit comments

Comments
 (0)