unsigned_tlv_stream.write(&mut bytes).unwrap();
let pubkey = self.invoice_request.payer_id;
- let signature = Some(merkle::sign_message(sign, SIGNATURE_TAG, &bytes, pubkey)?);
+ let signature = merkle::sign_message(sign, SIGNATURE_TAG, &bytes, pubkey)?;
// Append the signature TLV record to the bytes.
let signature_tlv_stream = SignatureTlvStreamRef {
- signature: signature.as_ref(),
+ signature: Some(&signature),
};
signature_tlv_stream.write(&mut bytes).unwrap();
pub struct InvoiceRequest {
pub(super) bytes: Vec<u8>,
contents: InvoiceRequestContents,
- signature: Option<Signature>,
+ signature: Signature,
}
/// The contents of an [`InvoiceRequest`], which may be shared with an `Invoice`.
/// Signature of the invoice request using [`payer_id`].
///
/// [`payer_id`]: Self::payer_id
- pub fn signature(&self) -> Option<Signature> {
+ pub fn signature(&self) -> Signature {
self.signature
}
let (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream) =
self.contents.as_tlv_stream();
let signature_tlv_stream = SignatureTlvStreamRef {
- signature: self.signature.as_ref(),
+ signature: Some(&self.signature),
};
(payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, signature_tlv_stream)
}
(payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
)?;
- if let Some(signature) = &signature {
- merkle::verify_signature(signature, SIGNATURE_TAG, &bytes, contents.payer_id)?;
- }
+ let signature = match signature {
+ None => return Err(ParseError::InvalidSemantics(SemanticError::MissingSignature)),
+ Some(signature) => signature,
+ };
+ merkle::verify_signature(&signature, SIGNATURE_TAG, &bytes, contents.payer_id)?;
Ok(InvoiceRequest { bytes, contents, signature })
}
#[cfg(test)]
mod tests {
- use super::{InvoiceRequest, InvoiceRequestTlvStreamRef};
+ use super::{InvoiceRequest, InvoiceRequestTlvStreamRef, SIGNATURE_TAG};
use bitcoin::blockdata::constants::ChainHash;
use bitcoin::network::constants::Network;
use core::time::Duration;
use crate::ln::features::InvoiceRequestFeatures;
use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
- use crate::offers::merkle::{SignError, SignatureTlvStreamRef};
+ use crate::offers::merkle::{SignError, SignatureTlvStreamRef, self};
use crate::offers::offer::{Amount, OfferBuilder, OfferTlvStreamRef, Quantity};
use crate::offers::parse::{ParseError, SemanticError};
use crate::offers::payer::PayerTlvStreamRef;
assert_eq!(invoice_request.quantity(), None);
assert_eq!(invoice_request.payer_id(), payer_pubkey());
assert_eq!(invoice_request.payer_note(), None);
- assert!(invoice_request.signature().is_some());
+ assert!(
+ merkle::verify_signature(
+ &invoice_request.signature, SIGNATURE_TAG, &invoice_request.bytes, payer_pubkey()
+ ).is_ok()
+ );
assert_eq!(
invoice_request.as_tlv_stream(),
payer_id: Some(&payer_pubkey()),
payer_note: None,
},
- SignatureTlvStreamRef { signature: invoice_request.signature().as_ref() },
+ SignatureTlvStreamRef { signature: Some(&invoice_request.signature()) },
),
);
}
#[test]
- fn parses_invoice_request_without_signature() {
+ fn fails_parsing_invoice_request_without_signature() {
let mut buffer = Vec::new();
OfferBuilder::new("foo".into(), recipient_pubkey())
.amount_msats(1000)
.invoice_request
.write(&mut buffer).unwrap();
- if let Err(e) = InvoiceRequest::try_from(buffer) {
- panic!("error parsing invoice_request: {:?}", e);
+ match InvoiceRequest::try_from(buffer) {
+ Ok(_) => panic!("expected error"),
+ Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingSignature)),
}
}