Skip to content

Commit 9cf178f

Browse files
committed
Add parsing tests for experimental invreq TLVs
1 parent e217c62 commit 9cf178f

File tree

1 file changed

+121
-2
lines changed

1 file changed

+121
-2
lines changed

lightning/src/offers/invoice_request.rs

Lines changed: 121 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,7 +1361,7 @@ impl Readable for InvoiceRequestFields {
13611361

13621362
#[cfg(test)]
13631363
mod tests {
1364-
use super::{ExperimentalInvoiceRequestTlvStreamRef, INVOICE_REQUEST_TYPES, InvoiceRequest, InvoiceRequestFields, InvoiceRequestTlvStreamRef, PAYER_NOTE_LIMIT, SIGNATURE_TAG, UnsignedInvoiceRequest};
1364+
use super::{EXPERIMENTAL_INVOICE_REQUEST_TYPES, ExperimentalInvoiceRequestTlvStreamRef, INVOICE_REQUEST_TYPES, InvoiceRequest, InvoiceRequestFields, InvoiceRequestTlvStreamRef, PAYER_NOTE_LIMIT, SIGNATURE_TAG, UnsignedInvoiceRequest};
13651365

13661366
use bitcoin::constants::ChainHash;
13671367
use bitcoin::network::Network;
@@ -1375,7 +1375,7 @@ mod tests {
13751375
use crate::ln::inbound_payment::ExpandedKey;
13761376
use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
13771377
use crate::offers::invoice::{Bolt12Invoice, SIGNATURE_TAG as INVOICE_SIGNATURE_TAG};
1378-
use crate::offers::merkle::{SignError, SignatureTlvStreamRef, TaggedHash, self};
1378+
use crate::offers::merkle::{SignError, SignatureTlvStreamRef, TaggedHash, TlvStream, self};
13791379
use crate::offers::nonce::Nonce;
13801380
use crate::offers::offer::{Amount, ExperimentalOfferTlvStreamRef, OfferTlvStreamRef, Quantity};
13811381
#[cfg(not(c_bindings))]
@@ -2525,10 +2525,118 @@ mod tests {
25252525
}
25262526
}
25272527

2528+
#[test]
2529+
fn parses_invoice_request_with_experimental_tlv_records() {
2530+
const UNKNOWN_ODD_TYPE: u64 = EXPERIMENTAL_INVOICE_REQUEST_TYPES.start + 1;
2531+
assert!(UNKNOWN_ODD_TYPE % 2 == 1);
2532+
2533+
let secp_ctx = Secp256k1::new();
2534+
let keys = Keypair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
2535+
let mut unsigned_invoice_request = OfferBuilder::new(keys.public_key())
2536+
.amount_msats(1000)
2537+
.build().unwrap()
2538+
.request_invoice(vec![1; 32], keys.public_key()).unwrap()
2539+
.build().unwrap();
2540+
2541+
let mut unknown_bytes = Vec::new();
2542+
BigSize(UNKNOWN_ODD_TYPE).write(&mut unknown_bytes).unwrap();
2543+
BigSize(32).write(&mut unknown_bytes).unwrap();
2544+
[42u8; 32].write(&mut unknown_bytes).unwrap();
2545+
2546+
unsigned_invoice_request.bytes.reserve_exact(
2547+
unsigned_invoice_request.bytes.capacity()
2548+
- unsigned_invoice_request.bytes.len()
2549+
+ unknown_bytes.len(),
2550+
);
2551+
unsigned_invoice_request.experimental_bytes.extend_from_slice(&unknown_bytes);
2552+
2553+
let tlv_stream = TlvStream::new(&unsigned_invoice_request.bytes)
2554+
.chain(TlvStream::new(&unsigned_invoice_request.experimental_bytes));
2555+
unsigned_invoice_request.tagged_hash =
2556+
TaggedHash::from_tlv_stream(SIGNATURE_TAG, tlv_stream);
2557+
2558+
let invoice_request = unsigned_invoice_request
2559+
.sign(|message: &UnsignedInvoiceRequest|
2560+
Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2561+
)
2562+
.unwrap();
2563+
2564+
let mut encoded_invoice_request = Vec::new();
2565+
invoice_request.write(&mut encoded_invoice_request).unwrap();
2566+
2567+
match InvoiceRequest::try_from(encoded_invoice_request.clone()) {
2568+
Ok(invoice_request) => assert_eq!(invoice_request.bytes, encoded_invoice_request),
2569+
Err(e) => panic!("error parsing invoice_request: {:?}", e),
2570+
}
2571+
2572+
const UNKNOWN_EVEN_TYPE: u64 = EXPERIMENTAL_INVOICE_REQUEST_TYPES.start;
2573+
assert!(UNKNOWN_EVEN_TYPE % 2 == 0);
2574+
2575+
let mut unsigned_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+
2581+
let mut unknown_bytes = Vec::new();
2582+
BigSize(UNKNOWN_EVEN_TYPE).write(&mut unknown_bytes).unwrap();
2583+
BigSize(32).write(&mut unknown_bytes).unwrap();
2584+
[42u8; 32].write(&mut unknown_bytes).unwrap();
2585+
2586+
unsigned_invoice_request.bytes.reserve_exact(
2587+
unsigned_invoice_request.bytes.capacity()
2588+
- unsigned_invoice_request.bytes.len()
2589+
+ unknown_bytes.len(),
2590+
);
2591+
unsigned_invoice_request.experimental_bytes.extend_from_slice(&unknown_bytes);
2592+
2593+
let tlv_stream = TlvStream::new(&unsigned_invoice_request.bytes)
2594+
.chain(TlvStream::new(&unsigned_invoice_request.experimental_bytes));
2595+
unsigned_invoice_request.tagged_hash =
2596+
TaggedHash::from_tlv_stream(SIGNATURE_TAG, tlv_stream);
2597+
2598+
let invoice_request = unsigned_invoice_request
2599+
.sign(|message: &UnsignedInvoiceRequest|
2600+
Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2601+
)
2602+
.unwrap();
2603+
2604+
let mut encoded_invoice_request = Vec::new();
2605+
invoice_request.write(&mut encoded_invoice_request).unwrap();
2606+
2607+
match InvoiceRequest::try_from(encoded_invoice_request) {
2608+
Ok(_) => panic!("expected error"),
2609+
Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::UnknownRequiredFeature)),
2610+
}
2611+
2612+
let invoice_request = OfferBuilder::new(keys.public_key())
2613+
.amount_msats(1000)
2614+
.build().unwrap()
2615+
.request_invoice(vec![1; 32], keys.public_key()).unwrap()
2616+
.build().unwrap()
2617+
.sign(|message: &UnsignedInvoiceRequest|
2618+
Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
2619+
)
2620+
.unwrap();
2621+
2622+
let mut encoded_invoice_request = Vec::new();
2623+
invoice_request.write(&mut encoded_invoice_request).unwrap();
2624+
2625+
BigSize(UNKNOWN_ODD_TYPE).write(&mut encoded_invoice_request).unwrap();
2626+
BigSize(32).write(&mut encoded_invoice_request).unwrap();
2627+
[42u8; 32].write(&mut encoded_invoice_request).unwrap();
2628+
2629+
match InvoiceRequest::try_from(encoded_invoice_request) {
2630+
Ok(_) => panic!("expected error"),
2631+
Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSignature(secp256k1::Error::IncorrectSignature)),
2632+
}
2633+
}
2634+
25282635
#[test]
25292636
fn fails_parsing_invoice_request_with_out_of_range_tlv_records() {
25302637
let secp_ctx = Secp256k1::new();
25312638
let keys = Keypair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
2639+
25322640
let invoice_request = OfferBuilder::new(keys.public_key())
25332641
.amount_msats(1000)
25342642
.build().unwrap()
@@ -2549,6 +2657,17 @@ mod tests {
25492657
Ok(_) => panic!("expected error"),
25502658
Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)),
25512659
}
2660+
2661+
let mut encoded_invoice_request = Vec::new();
2662+
invoice_request.write(&mut encoded_invoice_request).unwrap();
2663+
BigSize(EXPERIMENTAL_INVOICE_REQUEST_TYPES.end).write(&mut encoded_invoice_request).unwrap();
2664+
BigSize(32).write(&mut encoded_invoice_request).unwrap();
2665+
[42u8; 32].write(&mut encoded_invoice_request).unwrap();
2666+
2667+
match InvoiceRequest::try_from(encoded_invoice_request) {
2668+
Ok(_) => panic!("expected error"),
2669+
Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)),
2670+
}
25522671
}
25532672

25542673
#[test]

0 commit comments

Comments
 (0)