Refactor handling of InvoiceRequest
[rust-lightning] / lightning / src / offers / invoice_error.rs
index e843264b4e3ed851afc5642fc1e8b5d0869854e5..5ae5f457a84822172d970035286a562be0d67973 100644 (file)
 
 use crate::io;
 use crate::ln::msgs::DecodeError;
-use crate::offers::parse::SemanticError;
+use crate::offers::merkle::SignError;
+use crate::offers::parse::Bolt12SemanticError;
 use crate::util::ser::{HighZeroBytesDroppedBigSize, Readable, WithoutLength, Writeable, Writer};
 use crate::util::string::UntrustedString;
 
+#[allow(unused_imports)]
 use crate::prelude::*;
 
-/// An error in response to an [`InvoiceRequest`] or an [`Invoice`].
+/// An error in response to an [`InvoiceRequest`] or an [`Bolt12Invoice`].
 ///
 /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
-/// [`Invoice`]: crate::offers::invoice::Invoice
+/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
 #[derive(Clone, Debug)]
 #[cfg_attr(test, derive(PartialEq))]
 pub struct InvoiceError {
-       /// The field in the [`InvoiceRequest`] or the [`Invoice`] that contained an error.
+       /// The field in the [`InvoiceRequest`] or the [`Bolt12Invoice`] that contained an error.
        ///
        /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
-       /// [`Invoice`]: crate::offers::invoice::Invoice
+       /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
        pub erroneous_field: Option<ErroneousField>,
 
        /// An explanation of the error.
        pub message: UntrustedString,
 }
 
-/// The field in the [`InvoiceRequest`] or the [`Invoice`] that contained an error.
+/// The field in the [`InvoiceRequest`] or the [`Bolt12Invoice`] that contained an error.
 ///
 /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
-/// [`Invoice`]: crate::offers::invoice::Invoice
+/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
 #[derive(Clone, Debug)]
 #[cfg_attr(test, derive(PartialEq))]
 pub struct ErroneousField {
@@ -48,6 +50,16 @@ pub struct ErroneousField {
        pub suggested_value: Option<Vec<u8>>,
 }
 
+impl InvoiceError {
+       /// Creates an [`InvoiceError`] with the given message.
+       pub fn from_string(s: String) -> Self {
+               Self {
+                       erroneous_field: None,
+                       message: UntrustedString(s),
+               }
+       }
+}
+
 impl core::fmt::Display for InvoiceError {
        fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
                self.message.fmt(f)
@@ -70,7 +82,7 @@ impl Writeable for InvoiceError {
 
 impl Readable for InvoiceError {
        fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
-               _init_and_read_tlv_fields!(reader, {
+               _init_and_read_len_prefixed_tlv_fields!(reader, {
                        (1, erroneous_field, (option, encoding: (u64, HighZeroBytesDroppedBigSize))),
                        (3, suggested_value, (option, encoding: (Vec<u8>, WithoutLength))),
                        (5, error, (option, encoding: (UntrustedString, WithoutLength))),
@@ -93,8 +105,8 @@ impl Readable for InvoiceError {
        }
 }
 
-impl From<SemanticError> for InvoiceError {
-       fn from(error: SemanticError) -> Self {
+impl From<Bolt12SemanticError> for InvoiceError {
+       fn from(error: Bolt12SemanticError) -> Self {
                InvoiceError {
                        erroneous_field: None,
                        message: UntrustedString(format!("{:?}", error)),
@@ -102,6 +114,19 @@ impl From<SemanticError> for InvoiceError {
        }
 }
 
+impl From<SignError> for InvoiceError {
+       fn from(error: SignError) -> Self {
+               let message = match error {
+                       SignError::Signing => "Failed signing invoice",
+                       SignError::Verification(_) => "Failed invoice signature verification",
+               };
+               InvoiceError {
+                       erroneous_field: None,
+                       message: UntrustedString(message.to_string()),
+               }
+       }
+}
+
 #[cfg(test)]
 mod tests {
        use super::{ErroneousField, InvoiceError};