From: Jeffrey Czyz Date: Fri, 9 Dec 2022 20:45:56 +0000 (-0600) Subject: Check entire TLV stream instead of by field X-Git-Tag: v0.0.114-beta~83^2~6 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=04d64f08087788d2ceafd842fe1e7e2ef4e8f275;p=rust-lightning Check entire TLV stream instead of by field This causes a compilation error if a new field is added but missed in the tests. --- diff --git a/lightning/src/offers/invoice_request.rs b/lightning/src/offers/invoice_request.rs index 90f6c183c..69dc616eb 100644 --- a/lightning/src/offers/invoice_request.rs +++ b/lightning/src/offers/invoice_request.rs @@ -471,7 +471,7 @@ impl TryFrom for InvoiceRequestContents { #[cfg(test)] mod tests { - use super::InvoiceRequest; + use super::{InvoiceRequest, InvoiceRequestTlvStreamRef}; use bitcoin::blockdata::constants::ChainHash; use bitcoin::network::constants::Network; @@ -483,9 +483,10 @@ mod tests { use core::time::Duration; use crate::ln::features::InvoiceRequestFeatures; use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT}; - use crate::offers::merkle::SignError; - use crate::offers::offer::{Amount, OfferBuilder, Quantity}; + use crate::offers::merkle::{SignError, SignatureTlvStreamRef}; + use crate::offers::offer::{Amount, OfferBuilder, OfferTlvStreamRef, Quantity}; use crate::offers::parse::{ParseError, SemanticError}; + use crate::offers::payer::PayerTlvStreamRef; use crate::util::ser::{BigSize, Writeable}; use crate::util::string::PrintableString; @@ -517,14 +518,13 @@ mod tests { #[test] fn builds_invoice_request_with_defaults() { - let offer = OfferBuilder::new("foo".into(), recipient_pubkey()) + let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey()) .amount_msats(1000) - .build().unwrap(); - let invoice_request = offer.request_invoice(vec![1; 32], payer_pubkey()).unwrap() - .build().unwrap().sign(payer_sign).unwrap(); + .build().unwrap() + .request_invoice(vec![1; 32], payer_pubkey()).unwrap() + .build().unwrap() + .sign(payer_sign).unwrap(); - let (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, signature_tlv_stream) = - invoice_request.as_tlv_stream(); let mut buffer = Vec::new(); invoice_request.write(&mut buffer).unwrap(); @@ -538,25 +538,34 @@ mod tests { assert_eq!(invoice_request.payer_note(), None); assert!(invoice_request.signature().is_some()); - assert_eq!(payer_tlv_stream.metadata, Some(&vec![1; 32])); - assert_eq!(offer_tlv_stream.chains, None); - assert_eq!(offer_tlv_stream.metadata, None); - assert_eq!(offer_tlv_stream.currency, None); - assert_eq!(offer_tlv_stream.amount, Some(1000)); - assert_eq!(offer_tlv_stream.description, Some(&String::from("foo"))); - assert_eq!(offer_tlv_stream.features, None); - assert_eq!(offer_tlv_stream.absolute_expiry, None); - assert_eq!(offer_tlv_stream.paths, None); - assert_eq!(offer_tlv_stream.issuer, None); - assert_eq!(offer_tlv_stream.quantity_max, None); - assert_eq!(offer_tlv_stream.node_id, Some(&recipient_pubkey())); - assert_eq!(invoice_request_tlv_stream.chain, None); - assert_eq!(invoice_request_tlv_stream.amount, None); - assert_eq!(invoice_request_tlv_stream.features, None); - assert_eq!(invoice_request_tlv_stream.quantity, None); - assert_eq!(invoice_request_tlv_stream.payer_id, Some(&payer_pubkey())); - assert_eq!(invoice_request_tlv_stream.payer_note, None); - assert!(signature_tlv_stream.signature.is_some()); + assert_eq!( + invoice_request.as_tlv_stream(), + ( + PayerTlvStreamRef { metadata: Some(&vec![1; 32]) }, + OfferTlvStreamRef { + chains: None, + metadata: None, + currency: None, + amount: Some(1000), + description: Some(&String::from("foo")), + features: None, + absolute_expiry: None, + paths: None, + issuer: None, + quantity_max: None, + node_id: Some(&recipient_pubkey()), + }, + InvoiceRequestTlvStreamRef { + chain: None, + amount: None, + features: None, + quantity: None, + payer_id: Some(&payer_pubkey()), + payer_note: None, + }, + SignatureTlvStreamRef { signature: invoice_request.signature().as_ref() }, + ), + ); if let Err(e) = InvoiceRequest::try_from(buffer) { panic!("error parsing invoice request: {:?}", e); diff --git a/lightning/src/offers/offer.rs b/lightning/src/offers/offer.rs index 680f40941..a401ec1cc 100644 --- a/lightning/src/offers/offer.rs +++ b/lightning/src/offers/offer.rs @@ -653,7 +653,7 @@ impl core::fmt::Display for Offer { #[cfg(test)] mod tests { - use super::{Amount, Offer, OfferBuilder, Quantity}; + use super::{Amount, Offer, OfferBuilder, OfferTlvStreamRef, Quantity}; use bitcoin::blockdata::constants::ChainHash; use bitcoin::network::constants::Network; @@ -680,7 +680,7 @@ mod tests { #[test] fn builds_offer_with_defaults() { let offer = OfferBuilder::new("foo".into(), pubkey(42)).build().unwrap(); - let tlv_stream = offer.as_tlv_stream(); + let mut buffer = Vec::new(); offer.write(&mut buffer).unwrap(); @@ -699,17 +699,22 @@ mod tests { assert_eq!(offer.supported_quantity(), Quantity::one()); assert_eq!(offer.signing_pubkey(), pubkey(42)); - assert_eq!(tlv_stream.chains, None); - assert_eq!(tlv_stream.metadata, None); - assert_eq!(tlv_stream.currency, None); - assert_eq!(tlv_stream.amount, None); - assert_eq!(tlv_stream.description, Some(&String::from("foo"))); - assert_eq!(tlv_stream.features, None); - assert_eq!(tlv_stream.absolute_expiry, None); - assert_eq!(tlv_stream.paths, None); - assert_eq!(tlv_stream.issuer, None); - assert_eq!(tlv_stream.quantity_max, None); - assert_eq!(tlv_stream.node_id, Some(&pubkey(42))); + assert_eq!( + offer.as_tlv_stream(), + OfferTlvStreamRef { + chains: None, + metadata: None, + currency: None, + amount: None, + description: Some(&String::from("foo")), + features: None, + absolute_expiry: None, + paths: None, + issuer: None, + quantity_max: None, + node_id: Some(&pubkey(42)), + }, + ); if let Err(e) = Offer::try_from(buffer) { panic!("error parsing offer: {:?}", e); diff --git a/lightning/src/util/ser_macros.rs b/lightning/src/util/ser_macros.rs index 231320ac1..df504cc2a 100644 --- a/lightning/src/util/ser_macros.rs +++ b/lightning/src/util/ser_macros.rs @@ -510,6 +510,7 @@ macro_rules! tlv_stream { )* } + #[derive(Debug, PartialEq)] pub(super) struct $nameref<'a> { $( pub(super) $field: Option,