Support reading the new `payment_metadata` field in invoices
[rust-lightning] / lightning-invoice / src / de.rs
1 #[cfg(feature = "std")]
2 use std::error;
3 use core::convert::TryFrom;
4 use core::fmt;
5 use core::fmt::{Display, Formatter};
6 use core::num::ParseIntError;
7 use core::str;
8 use core::str::FromStr;
9
10 use bech32::{u5, FromBase32};
11
12 use bitcoin::{PubkeyHash, ScriptHash};
13 use bitcoin::util::address::WitnessVersion;
14 use bitcoin_hashes::Hash;
15 use bitcoin_hashes::sha256;
16 use crate::prelude::*;
17 use lightning::ln::PaymentSecret;
18 use lightning::routing::gossip::RoutingFees;
19 use lightning::routing::router::{RouteHint, RouteHintHop};
20
21 use num_traits::{CheckedAdd, CheckedMul};
22
23 use secp256k1::ecdsa::{RecoveryId, RecoverableSignature};
24 use secp256k1::PublicKey;
25
26 use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp,
27         SemanticError, PrivateRoute, ParseError, ParseOrSemanticError, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawInvoice,
28         constants, SignedRawInvoice, RawDataPart, InvoiceFeatures};
29
30 use self::hrp_sm::parse_hrp;
31
32 /// State machine to parse the hrp
33 mod hrp_sm {
34         use core::ops::Range;
35
36         #[derive(PartialEq, Eq, Debug)]
37         enum States {
38                 Start,
39                 ParseL,
40                 ParseN,
41                 ParseCurrencyPrefix,
42                 ParseAmountNumber,
43                 ParseAmountSiPrefix,
44         }
45
46         impl States {
47                 fn next_state(&self, read_symbol: char) -> Result<States, super::ParseError> {
48                         match *self {
49                                 States::Start => {
50                                         if read_symbol == 'l' {
51                                                 Ok(States::ParseL)
52                                         } else {
53                                                 Err(super::ParseError::MalformedHRP)
54                                         }
55                                 }
56                                 States::ParseL => {
57                                         if read_symbol == 'n' {
58                                                 Ok(States::ParseN)
59                                         } else {
60                                                 Err(super::ParseError::MalformedHRP)
61                                         }
62                                 },
63                                 States::ParseN => {
64                                         if !read_symbol.is_numeric() {
65                                                 Ok(States::ParseCurrencyPrefix)
66                                         } else {
67                                                 Ok(States::ParseAmountNumber)
68                                         }
69                                 },
70                                 States::ParseCurrencyPrefix => {
71                                         if !read_symbol.is_numeric() {
72                                                 Ok(States::ParseCurrencyPrefix)
73                                         } else {
74                                                 Ok(States::ParseAmountNumber)
75                                         }
76                                 },
77                                 States::ParseAmountNumber => {
78                                         if read_symbol.is_numeric() {
79                                                 Ok(States::ParseAmountNumber)
80                                         } else if ['m', 'u', 'n', 'p'].contains(&read_symbol) {
81                                                 Ok(States::ParseAmountSiPrefix)
82                                         } else {
83                                                 Err(super::ParseError::UnknownSiPrefix)
84                                         }
85                                 },
86                                 States::ParseAmountSiPrefix => Err(super::ParseError::MalformedHRP),
87                         }
88                 }
89
90                 fn is_final(&self) -> bool {
91                         !(*self == States::ParseL || *self == States::ParseN)
92                 }
93         }
94
95
96         struct StateMachine {
97                 state: States,
98                 position: usize,
99                 currency_prefix: Option<Range<usize>>,
100                 amount_number: Option<Range<usize>>,
101                 amount_si_prefix: Option<Range<usize>>,
102         }
103
104         impl StateMachine {
105                 fn new() -> StateMachine {
106                         StateMachine {
107                                 state: States::Start,
108                                 position: 0,
109                                 currency_prefix: None,
110                                 amount_number: None,
111                                 amount_si_prefix: None,
112                         }
113                 }
114
115                 fn update_range(range: &mut Option<Range<usize>>, position: usize) {
116                         let new_range = match *range {
117                                 None => Range {start: position, end: position + 1},
118                                 Some(ref r) => Range {start: r.start, end: r.end + 1},
119                         };
120                         *range = Some(new_range);
121                 }
122
123                 fn step(&mut self, c: char) -> Result<(), super::ParseError> {
124                         let next_state = self.state.next_state(c)?;
125                         match next_state {
126                                 States::ParseCurrencyPrefix => {
127                                         StateMachine::update_range(&mut self.currency_prefix, self.position)
128                                 }
129                                 States::ParseAmountNumber => {
130                                         StateMachine::update_range(&mut self.amount_number, self.position)
131                                 },
132                                 States::ParseAmountSiPrefix => {
133                                         StateMachine::update_range(&mut self.amount_si_prefix, self.position)
134                                 },
135                                 _ => {}
136                         }
137
138                         self.position += 1;
139                         self.state = next_state;
140                         Ok(())
141                 }
142
143                 fn is_final(&self) -> bool {
144                         self.state.is_final()
145                 }
146
147                 fn currency_prefix(&self) -> &Option<Range<usize>> {
148                         &self.currency_prefix
149                 }
150
151                 fn amount_number(&self) -> &Option<Range<usize>> {
152                         &self.amount_number
153                 }
154
155                 fn amount_si_prefix(&self) -> &Option<Range<usize>> {
156                         &self.amount_si_prefix
157                 }
158         }
159
160         pub fn parse_hrp(input: &str) -> Result<(&str, &str, &str), super::ParseError> {
161                 let mut sm = StateMachine::new();
162                 for c in input.chars() {
163                         sm.step(c)?;
164                 }
165
166                 if !sm.is_final() {
167                         return Err(super::ParseError::MalformedHRP);
168                 }
169
170                 let currency = sm.currency_prefix().clone()
171                         .map(|r| &input[r]).unwrap_or("");
172                 let amount = sm.amount_number().clone()
173                         .map(|r| &input[r]).unwrap_or("");
174                 let si = sm.amount_si_prefix().clone()
175                         .map(|r| &input[r]).unwrap_or("");
176
177                 Ok((currency, amount, si))
178         }
179 }
180
181
182 impl FromStr for super::Currency {
183         type Err = ParseError;
184
185         fn from_str(currency_prefix: &str) -> Result<Self, ParseError> {
186                 match currency_prefix {
187                         "bc" => Ok(Currency::Bitcoin),
188                         "tb" => Ok(Currency::BitcoinTestnet),
189                         "bcrt" => Ok(Currency::Regtest),
190                         "sb" => Ok(Currency::Simnet),
191                         "tbs" => Ok(Currency::Signet),
192                         _ => Err(ParseError::UnknownCurrency)
193                 }
194         }
195 }
196
197 impl FromStr for SiPrefix {
198         type Err = ParseError;
199
200         fn from_str(currency_prefix: &str) -> Result<Self, ParseError> {
201                 use crate::SiPrefix::*;
202                 match currency_prefix {
203                         "m" => Ok(Milli),
204                         "u" => Ok(Micro),
205                         "n" => Ok(Nano),
206                         "p" => Ok(Pico),
207                         _ => Err(ParseError::UnknownSiPrefix)
208                 }
209         }
210 }
211
212 /// ```
213 /// use lightning_invoice::Invoice;
214 ///
215 ///
216 /// let invoice = "lnbc100p1psj9jhxdqud3jxktt5w46x7unfv9kz6mn0v3jsnp4q0d3p2sfluzdx45tqcs\
217 /// h2pu5qc7lgq0xs578ngs6s0s68ua4h7cvspp5q6rmq35js88zp5dvwrv9m459tnk2zunwj5jalqtyxqulh0l\
218 /// 5gflssp5nf55ny5gcrfl30xuhzj3nphgj27rstekmr9fw3ny5989s300gyus9qyysgqcqpcrzjqw2sxwe993\
219 /// h5pcm4dxzpvttgza8zhkqxpgffcrf5v25nwpr3cmfg7z54kuqq8rgqqqqqqqq2qqqqq9qq9qrzjqd0ylaqcl\
220 /// j9424x9m8h2vcukcgnm6s56xfgu3j78zyqzhgs4hlpzvznlugqq9vsqqqqqqqlgqqqqqeqq9qrzjqwldmj9d\
221 /// ha74df76zhx6l9we0vjdquygcdt3kssupehe64g6yyp5yz5rhuqqwccqqyqqqqlgqqqqjcqq9qrzjqf9e58a\
222 /// guqr0rcun0ajlvmzq3ek63cw2w282gv3z5uupmuwvgjtq2z55qsqqg6qqqyqqqrtnqqqzq3cqygrzjqvphms\
223 /// ywntrrhqjcraumvc4y6r8v4z5v593trte429v4hredj7ms5z52usqq9ngqqqqqqqlgqqqqqqgq9qrzjq2v0v\
224 /// p62g49p7569ev48cmulecsxe59lvaw3wlxm7r982zxa9zzj7z5l0cqqxusqqyqqqqlgqqqqqzsqygarl9fh3\
225 /// 8s0gyuxjjgux34w75dnc6xp2l35j7es3jd4ugt3lu0xzre26yg5m7ke54n2d5sym4xcmxtl8238xxvw5h5h5\
226 /// j5r6drg6k6zcqj0fcwg";
227 ///
228 /// assert!(invoice.parse::<Invoice>().is_ok());
229 /// ```
230 impl FromStr for Invoice {
231         type Err = ParseOrSemanticError;
232
233         fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
234                 let signed = s.parse::<SignedRawInvoice>()?;
235                 Ok(Invoice::from_signed(signed)?)
236         }
237 }
238
239 /// ```
240 /// use lightning_invoice::*;
241 ///
242 /// let invoice = "lnbc100p1psj9jhxdqud3jxktt5w46x7unfv9kz6mn0v3jsnp4q0d3p2sfluzdx45tqcs\
243 /// h2pu5qc7lgq0xs578ngs6s0s68ua4h7cvspp5q6rmq35js88zp5dvwrv9m459tnk2zunwj5jalqtyxqulh0l\
244 /// 5gflssp5nf55ny5gcrfl30xuhzj3nphgj27rstekmr9fw3ny5989s300gyus9qyysgqcqpcrzjqw2sxwe993\
245 /// h5pcm4dxzpvttgza8zhkqxpgffcrf5v25nwpr3cmfg7z54kuqq8rgqqqqqqqq2qqqqq9qq9qrzjqd0ylaqcl\
246 /// j9424x9m8h2vcukcgnm6s56xfgu3j78zyqzhgs4hlpzvznlugqq9vsqqqqqqqlgqqqqqeqq9qrzjqwldmj9d\
247 /// ha74df76zhx6l9we0vjdquygcdt3kssupehe64g6yyp5yz5rhuqqwccqqyqqqqlgqqqqjcqq9qrzjqf9e58a\
248 /// guqr0rcun0ajlvmzq3ek63cw2w282gv3z5uupmuwvgjtq2z55qsqqg6qqqyqqqrtnqqqzq3cqygrzjqvphms\
249 /// ywntrrhqjcraumvc4y6r8v4z5v593trte429v4hredj7ms5z52usqq9ngqqqqqqqlgqqqqqqgq9qrzjq2v0v\
250 /// p62g49p7569ev48cmulecsxe59lvaw3wlxm7r982zxa9zzj7z5l0cqqxusqqyqqqqlgqqqqqzsqygarl9fh3\
251 /// 8s0gyuxjjgux34w75dnc6xp2l35j7es3jd4ugt3lu0xzre26yg5m7ke54n2d5sym4xcmxtl8238xxvw5h5h5\
252 /// j5r6drg6k6zcqj0fcwg";
253 ///
254 /// let parsed_1 = invoice.parse::<Invoice>();
255 ///
256 /// let parsed_2 = match invoice.parse::<SignedRawInvoice>() {
257 ///     Ok(signed) => match Invoice::from_signed(signed) {
258 ///             Ok(invoice) => Ok(invoice),
259 ///             Err(e) => Err(ParseOrSemanticError::SemanticError(e)),
260 ///     },
261 ///     Err(e) => Err(ParseOrSemanticError::ParseError(e)),
262 /// };
263 ///
264 /// assert!(parsed_1.is_ok());
265 /// assert_eq!(parsed_1, parsed_2);
266 /// ```
267 impl FromStr for SignedRawInvoice {
268         type Err = ParseError;
269
270         fn from_str(s: &str) -> Result<Self, Self::Err> {
271                 let (hrp, data, var) = bech32::decode(s)?;
272
273                 if var == bech32::Variant::Bech32m {
274                         // Consider Bech32m addresses to be "Invalid Checksum", since that is what we'd get if
275                         // we didn't support Bech32m (which lightning does not use).
276                         return Err(ParseError::Bech32Error(bech32::Error::InvalidChecksum));
277                 }
278
279                 if data.len() < 104 {
280                         return Err(ParseError::TooShortDataPart);
281                 }
282
283                 let raw_hrp: RawHrp = hrp.parse()?;
284                 let data_part = RawDataPart::from_base32(&data[..data.len()-104])?;
285
286                 Ok(SignedRawInvoice {
287                         raw_invoice: RawInvoice {
288                                 hrp: raw_hrp,
289                                 data: data_part,
290                         },
291                         hash: RawInvoice::hash_from_parts(
292                                 hrp.as_bytes(),
293                                 &data[..data.len()-104]
294                         ),
295                         signature: InvoiceSignature::from_base32(&data[data.len()-104..])?,
296                 })
297         }
298 }
299
300 impl FromStr for RawHrp {
301         type Err = ParseError;
302
303         fn from_str(hrp: &str) -> Result<Self, <Self as FromStr>::Err> {
304                 let parts = parse_hrp(hrp)?;
305
306                 let currency = parts.0.parse::<Currency>()?;
307
308                 let amount = if !parts.1.is_empty() {
309                         Some(parts.1.parse::<u64>()?)
310                 } else {
311                         None
312                 };
313
314                 let si_prefix: Option<SiPrefix> = if parts.2.is_empty() {
315                         None
316                 } else {
317                         let si: SiPrefix = parts.2.parse()?;
318                         if let Some(amt) = amount {
319                                 if amt.checked_mul(si.multiplier()).is_none() {
320                                         return Err(ParseError::IntegerOverflowError);
321                                 }
322                         }
323                         Some(si)
324                 };
325
326                 Ok(RawHrp {
327                         currency,
328                         raw_amount: amount,
329                         si_prefix,
330                 })
331         }
332 }
333
334 impl FromBase32 for RawDataPart {
335         type Err = ParseError;
336
337         fn from_base32(data: &[u5]) -> Result<Self, Self::Err> {
338                 if data.len() < 7 { // timestamp length
339                         return Err(ParseError::TooShortDataPart);
340                 }
341
342                 let timestamp = PositiveTimestamp::from_base32(&data[0..7])?;
343                 let tagged = parse_tagged_parts(&data[7..])?;
344
345                 Ok(RawDataPart {
346                         timestamp,
347                         tagged_fields: tagged,
348                 })
349         }
350 }
351
352 impl FromBase32 for PositiveTimestamp {
353         type Err = ParseError;
354
355         fn from_base32(b32: &[u5]) -> Result<Self, Self::Err> {
356                 if b32.len() != 7 {
357                         return Err(ParseError::InvalidSliceLength("PositiveTimestamp::from_base32()".into()));
358                 }
359                 let timestamp: u64 = parse_int_be(b32, 32)
360                         .expect("7*5bit < 64bit, no overflow possible");
361                 match PositiveTimestamp::from_unix_timestamp(timestamp) {
362                         Ok(t) => Ok(t),
363                         Err(_) => unreachable!(),
364                 }
365         }
366 }
367
368 impl FromBase32 for InvoiceSignature {
369         type Err = ParseError;
370         fn from_base32(signature: &[u5]) -> Result<Self, Self::Err> {
371                 if signature.len() != 104 {
372                         return Err(ParseError::InvalidSliceLength("InvoiceSignature::from_base32()".into()));
373                 }
374                 let recoverable_signature_bytes = Vec::<u8>::from_base32(signature)?;
375                 let signature = &recoverable_signature_bytes[0..64];
376                 let recovery_id = RecoveryId::from_i32(recoverable_signature_bytes[64] as i32)?;
377
378                 Ok(InvoiceSignature(RecoverableSignature::from_compact(
379                         signature,
380                         recovery_id
381                 )?))
382         }
383 }
384
385 pub(crate) fn parse_int_be<T, U>(digits: &[U], base: T) -> Option<T>
386         where T: CheckedAdd + CheckedMul + From<u8> + Default,
387               U: Into<u8> + Copy
388 {
389         digits.iter().fold(Some(Default::default()), |acc, b|
390                 acc
391                         .and_then(|x| x.checked_mul(&base))
392                         .and_then(|x| x.checked_add(&(Into::<u8>::into(*b)).into()))
393         )
394 }
395
396 fn parse_tagged_parts(data: &[u5]) -> Result<Vec<RawTaggedField>, ParseError> {
397         let mut parts = Vec::<RawTaggedField>::new();
398         let mut data = data;
399
400         while !data.is_empty() {
401                 if data.len() < 3 {
402                         return Err(ParseError::UnexpectedEndOfTaggedFields);
403                 }
404
405                 // Ignore tag at data[0], it will be handled in the TaggedField parsers and
406                 // parse the length to find the end of the tagged field's data
407                 let len = parse_int_be(&data[1..3], 32).expect("can't overflow");
408                 let last_element = 3 + len;
409
410                 if data.len() < last_element {
411                         return Err(ParseError::UnexpectedEndOfTaggedFields);
412                 }
413
414                 // Get the tagged field's data slice
415                 let field = &data[0..last_element];
416
417                 // Set data slice to remaining data
418                 data = &data[last_element..];
419
420                 match TaggedField::from_base32(field) {
421                         Ok(field) => {
422                                 parts.push(RawTaggedField::KnownSemantics(field))
423                         },
424                         Err(ParseError::Skip)|Err(ParseError::Bech32Error(bech32::Error::InvalidLength)) => {
425                                 parts.push(RawTaggedField::UnknownSemantics(field.into()))
426                         },
427                         Err(e) => {return Err(e)}
428                 }
429         }
430         Ok(parts)
431 }
432
433 impl FromBase32 for TaggedField {
434         type Err = ParseError;
435
436         fn from_base32(field: &[u5]) -> Result<TaggedField, ParseError> {
437                 if field.len() < 3 {
438                         return Err(ParseError::UnexpectedEndOfTaggedFields);
439                 }
440
441                 let tag = field[0];
442                 let field_data =  &field[3..];
443
444                 match tag.to_u8() {
445                         constants::TAG_PAYMENT_HASH =>
446                                 Ok(TaggedField::PaymentHash(Sha256::from_base32(field_data)?)),
447                         constants::TAG_DESCRIPTION =>
448                                 Ok(TaggedField::Description(Description::from_base32(field_data)?)),
449                         constants::TAG_PAYEE_PUB_KEY =>
450                                 Ok(TaggedField::PayeePubKey(PayeePubKey::from_base32(field_data)?)),
451                         constants::TAG_DESCRIPTION_HASH =>
452                                 Ok(TaggedField::DescriptionHash(Sha256::from_base32(field_data)?)),
453                         constants::TAG_EXPIRY_TIME =>
454                                 Ok(TaggedField::ExpiryTime(ExpiryTime::from_base32(field_data)?)),
455                         constants::TAG_MIN_FINAL_CLTV_EXPIRY_DELTA =>
456                                 Ok(TaggedField::MinFinalCltvExpiryDelta(MinFinalCltvExpiryDelta::from_base32(field_data)?)),
457                         constants::TAG_FALLBACK =>
458                                 Ok(TaggedField::Fallback(Fallback::from_base32(field_data)?)),
459                         constants::TAG_PRIVATE_ROUTE =>
460                                 Ok(TaggedField::PrivateRoute(PrivateRoute::from_base32(field_data)?)),
461                         constants::TAG_PAYMENT_SECRET =>
462                                 Ok(TaggedField::PaymentSecret(PaymentSecret::from_base32(field_data)?)),
463                         constants::TAG_PAYMENT_METADATA =>
464                                 Ok(TaggedField::PaymentMetadata(Vec::<u8>::from_base32(field_data)?)),
465                         constants::TAG_FEATURES =>
466                                 Ok(TaggedField::Features(InvoiceFeatures::from_base32(field_data)?)),
467                         _ => {
468                                 // "A reader MUST skip over unknown fields"
469                                 Err(ParseError::Skip)
470                         }
471                 }
472         }
473 }
474
475 impl FromBase32 for Sha256 {
476         type Err = ParseError;
477
478         fn from_base32(field_data: &[u5]) -> Result<Sha256, ParseError> {
479                 if field_data.len() != 52 {
480                         // "A reader MUST skip over […] a p, [or] h […] field that does not have data_length 52 […]."
481                         Err(ParseError::Skip)
482                 } else {
483                         Ok(Sha256(sha256::Hash::from_slice(&Vec::<u8>::from_base32(field_data)?)
484                                 .expect("length was checked before (52 u5 -> 32 u8)")))
485                 }
486         }
487 }
488
489 impl FromBase32 for Description {
490         type Err = ParseError;
491
492         fn from_base32(field_data: &[u5]) -> Result<Description, ParseError> {
493                 let bytes = Vec::<u8>::from_base32(field_data)?;
494                 let description = String::from(str::from_utf8(&bytes)?);
495                 Ok(Description::new(description).expect(
496                         "Max len is 639=floor(1023*5/8) since the len field is only 10bits long"
497                 ))
498         }
499 }
500
501 impl FromBase32 for PayeePubKey {
502         type Err = ParseError;
503
504         fn from_base32(field_data: &[u5]) -> Result<PayeePubKey, ParseError> {
505                 if field_data.len() != 53 {
506                         // "A reader MUST skip over […] a n […] field that does not have data_length 53 […]."
507                         Err(ParseError::Skip)
508                 } else {
509                         let data_bytes = Vec::<u8>::from_base32(field_data)?;
510                         let pub_key = PublicKey::from_slice(&data_bytes)?;
511                         Ok(pub_key.into())
512                 }
513         }
514 }
515
516 impl FromBase32 for ExpiryTime {
517         type Err = ParseError;
518
519         fn from_base32(field_data: &[u5]) -> Result<ExpiryTime, ParseError> {
520                 match parse_int_be::<u64, u5>(field_data, 32)
521                         .map(ExpiryTime::from_seconds)
522                 {
523                         Some(t) => Ok(t),
524                         None => Err(ParseError::IntegerOverflowError),
525                 }
526         }
527 }
528
529 impl FromBase32 for MinFinalCltvExpiryDelta {
530         type Err = ParseError;
531
532         fn from_base32(field_data: &[u5]) -> Result<MinFinalCltvExpiryDelta, ParseError> {
533                 let expiry = parse_int_be::<u64, u5>(field_data, 32);
534                 if let Some(expiry) = expiry {
535                         Ok(MinFinalCltvExpiryDelta(expiry))
536                 } else {
537                         Err(ParseError::IntegerOverflowError)
538                 }
539         }
540 }
541
542 impl FromBase32 for Fallback {
543         type Err = ParseError;
544
545         fn from_base32(field_data: &[u5]) -> Result<Fallback, ParseError> {
546                 if field_data.is_empty() {
547                         return Err(ParseError::UnexpectedEndOfTaggedFields);
548                 }
549
550                 let version = field_data[0];
551                 let bytes = Vec::<u8>::from_base32(&field_data[1..])?;
552
553                 match version.to_u8() {
554                         0..=16 => {
555                                 if bytes.len() < 2 || bytes.len() > 40 {
556                                         return Err(ParseError::InvalidSegWitProgramLength);
557                                 }
558                                 let version = WitnessVersion::try_from(version).expect("0 through 16 are valid SegWit versions");
559                                 Ok(Fallback::SegWitProgram {
560                                         version,
561                                         program: bytes
562                                 })
563                         },
564                         17 => {
565                                 let pkh = match PubkeyHash::from_slice(&bytes) {
566                                         Ok(pkh) => pkh,
567                                         Err(bitcoin_hashes::Error::InvalidLength(_, _)) => return Err(ParseError::InvalidPubKeyHashLength),
568                                 };
569                                 Ok(Fallback::PubKeyHash(pkh))
570                         }
571                         18 => {
572                                 let sh = match ScriptHash::from_slice(&bytes) {
573                                         Ok(sh) => sh,
574                                         Err(bitcoin_hashes::Error::InvalidLength(_, _)) => return Err(ParseError::InvalidScriptHashLength),
575                                 };
576                                 Ok(Fallback::ScriptHash(sh))
577                         }
578                         _ => Err(ParseError::Skip)
579                 }
580         }
581 }
582
583 impl FromBase32 for PrivateRoute {
584         type Err = ParseError;
585
586         fn from_base32(field_data: &[u5]) -> Result<PrivateRoute, ParseError> {
587                 let bytes = Vec::<u8>::from_base32(field_data)?;
588
589                 if bytes.len() % 51 != 0 {
590                         return Err(ParseError::UnexpectedEndOfTaggedFields);
591                 }
592
593                 let mut route_hops = Vec::<RouteHintHop>::new();
594
595                 let mut bytes = bytes.as_slice();
596                 while !bytes.is_empty() {
597                         let hop_bytes = &bytes[0..51];
598                         bytes = &bytes[51..];
599
600                         let mut channel_id: [u8; 8] = Default::default();
601                         channel_id.copy_from_slice(&hop_bytes[33..41]);
602
603                         let hop = RouteHintHop {
604                                 src_node_id: PublicKey::from_slice(&hop_bytes[0..33])?,
605                                 short_channel_id: parse_int_be(&channel_id, 256).expect("short chan ID slice too big?"),
606                                 fees: RoutingFees {
607                                         base_msat: parse_int_be(&hop_bytes[41..45], 256).expect("slice too big?"),
608                                         proportional_millionths: parse_int_be(&hop_bytes[45..49], 256).expect("slice too big?"),
609                                 },
610                                 cltv_expiry_delta: parse_int_be(&hop_bytes[49..51], 256).expect("slice too big?"),
611                                 htlc_minimum_msat: None,
612                                 htlc_maximum_msat: None,
613                         };
614
615                         route_hops.push(hop);
616                 }
617
618                 Ok(PrivateRoute(RouteHint(route_hops)))
619         }
620 }
621
622 impl Display for ParseError {
623         fn fmt(&self, f: &mut Formatter) -> fmt::Result {
624                 match *self {
625                         // TODO: find a way to combine the first three arms (e as error::Error?)
626                         ParseError::Bech32Error(ref e) => {
627                                 write!(f, "Invalid bech32: {}", e)
628                         }
629                         ParseError::ParseAmountError(ref e) => {
630                                 write!(f, "Invalid amount in hrp ({})", e)
631                         }
632                         ParseError::MalformedSignature(ref e) => {
633                                 write!(f, "Invalid secp256k1 signature: {}", e)
634                         }
635                         ParseError::DescriptionDecodeError(ref e) => {
636                                 write!(f, "Description is not a valid utf-8 string: {}", e)
637                         }
638                         ParseError::InvalidSliceLength(ref function) => {
639                                 write!(f, "Slice in function {} had the wrong length", function)
640                         }
641                         ParseError::BadPrefix => f.write_str("did not begin with 'ln'"),
642                         ParseError::UnknownCurrency => f.write_str("currency code unknown"),
643                         ParseError::UnknownSiPrefix => f.write_str("unknown SI prefix"),
644                         ParseError::MalformedHRP => f.write_str("malformed human readable part"),
645                         ParseError::TooShortDataPart => {
646                                 f.write_str("data part too short (should be at least 111 bech32 chars long)")
647                         },
648                         ParseError::UnexpectedEndOfTaggedFields => {
649                                 f.write_str("tagged fields part ended unexpectedly")
650                         },
651                         ParseError::PaddingError => f.write_str("some data field had bad padding"),
652                         ParseError::IntegerOverflowError => {
653                                 f.write_str("parsed integer doesn't fit into receiving type")
654                         },
655                         ParseError::InvalidSegWitProgramLength => {
656                                 f.write_str("fallback SegWit program is too long or too short")
657                         },
658                         ParseError::InvalidPubKeyHashLength => {
659                                 f.write_str("fallback public key hash has a length unequal 20 bytes")
660                         },
661                         ParseError::InvalidScriptHashLength => {
662                                 f.write_str("fallback script hash has a length unequal 32 bytes")
663                         },
664                         ParseError::InvalidRecoveryId => {
665                                 f.write_str("recovery id is out of range (should be in [0,3])")
666                         },
667                         ParseError::Skip => {
668                                 f.write_str("the tagged field has to be skipped because of an unexpected, but allowed property")
669                         },
670                 }
671         }
672 }
673
674 impl Display for ParseOrSemanticError {
675         fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
676                 match self {
677                         ParseOrSemanticError::ParseError(err) => err.fmt(f),
678                         ParseOrSemanticError::SemanticError(err) => err.fmt(f),
679                 }
680         }
681 }
682
683 #[cfg(feature = "std")]
684 impl error::Error for ParseError {}
685
686 #[cfg(feature = "std")]
687 impl error::Error for ParseOrSemanticError {}
688
689 macro_rules! from_error {
690     ($my_error:expr, $extern_error:ty) => {
691         impl From<$extern_error> for ParseError {
692             fn from(e: $extern_error) -> Self {
693                 $my_error(e)
694             }
695         }
696     }
697 }
698
699 from_error!(ParseError::MalformedSignature, secp256k1::Error);
700 from_error!(ParseError::ParseAmountError, ParseIntError);
701 from_error!(ParseError::DescriptionDecodeError, str::Utf8Error);
702
703 impl From<bech32::Error> for ParseError {
704         fn from(e: bech32::Error) -> Self {
705                 match e {
706                         bech32::Error::InvalidPadding => ParseError::PaddingError,
707                         _ => ParseError::Bech32Error(e)
708                 }
709         }
710 }
711
712 impl From<ParseError> for ParseOrSemanticError {
713         fn from(e: ParseError) -> Self {
714                 ParseOrSemanticError::ParseError(e)
715         }
716 }
717
718 impl From<crate::SemanticError> for ParseOrSemanticError {
719         fn from(e: SemanticError) -> Self {
720                 ParseOrSemanticError::SemanticError(e)
721         }
722 }
723
724 #[cfg(test)]
725 mod test {
726         use crate::de::ParseError;
727         use secp256k1::PublicKey;
728         use bech32::u5;
729         use bitcoin_hashes::hex::FromHex;
730         use bitcoin_hashes::sha256;
731
732         const CHARSET_REV: [i8; 128] = [
733                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
734                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
735                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
736                 15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1,
737                 -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
738                 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1,
739                 -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
740                 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1
741         ];
742
743         fn from_bech32(bytes_5b: &[u8]) -> Vec<u5> {
744                 bytes_5b
745                         .iter()
746                         .map(|c| u5::try_from_u8(CHARSET_REV[*c as usize] as u8).unwrap())
747                         .collect()
748         }
749
750         #[test]
751         fn test_parse_currency_prefix() {
752                 use crate::Currency;
753
754                 assert_eq!("bc".parse::<Currency>(), Ok(Currency::Bitcoin));
755                 assert_eq!("tb".parse::<Currency>(), Ok(Currency::BitcoinTestnet));
756                 assert_eq!("bcrt".parse::<Currency>(), Ok(Currency::Regtest));
757                 assert_eq!("sb".parse::<Currency>(), Ok(Currency::Simnet));
758                 assert_eq!("tbs".parse::<Currency>(), Ok(Currency::Signet));
759                 assert_eq!("something_else".parse::<Currency>(), Err(ParseError::UnknownCurrency))
760         }
761
762         #[test]
763         fn test_parse_int_from_bytes_be() {
764                 use crate::de::parse_int_be;
765
766                 assert_eq!(parse_int_be::<u32, u8>(&[1, 2, 3, 4], 256), Some(16909060));
767                 assert_eq!(parse_int_be::<u32, u8>(&[1, 3], 32), Some(35));
768                 assert_eq!(parse_int_be::<u32, u8>(&[255, 255, 255, 255], 256), Some(4294967295));
769                 assert_eq!(parse_int_be::<u32, u8>(&[1, 0, 0, 0, 0], 256), None);
770         }
771
772         #[test]
773         fn test_parse_sha256_hash() {
774                 use crate::Sha256;
775                 use bech32::FromBase32;
776
777                 let input = from_bech32(
778                         "qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypq".as_bytes()
779                 );
780
781                 let hash = sha256::Hash::from_hex(
782                         "0001020304050607080900010203040506070809000102030405060708090102"
783                 ).unwrap();
784                 let expected = Ok(Sha256(hash));
785
786                 assert_eq!(Sha256::from_base32(&input), expected);
787
788                 // make sure hashes of unknown length get skipped
789                 let input_unexpected_length = from_bech32(
790                         "qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypyq".as_bytes()
791                 );
792                 assert_eq!(Sha256::from_base32(&input_unexpected_length), Err(ParseError::Skip));
793         }
794
795         #[test]
796         fn test_parse_description() {
797                 use crate::Description;
798                 use bech32::FromBase32;
799
800                 let input = from_bech32("xysxxatsyp3k7enxv4js".as_bytes());
801                 let expected = Ok(Description::new("1 cup coffee".to_owned()).unwrap());
802                 assert_eq!(Description::from_base32(&input), expected);
803         }
804
805         #[test]
806         fn test_parse_payee_pub_key() {
807                 use crate::PayeePubKey;
808                 use bech32::FromBase32;
809
810                 let input = from_bech32("q0n326hr8v9zprg8gsvezcch06gfaqqhde2aj730yg0durunfhv66".as_bytes());
811                 let pk_bytes = [
812                         0x03, 0xe7, 0x15, 0x6a, 0xe3, 0x3b, 0x0a, 0x20, 0x8d, 0x07, 0x44, 0x19, 0x91, 0x63,
813                         0x17, 0x7e, 0x90, 0x9e, 0x80, 0x17, 0x6e, 0x55, 0xd9, 0x7a, 0x2f, 0x22, 0x1e, 0xde,
814                         0x0f, 0x93, 0x4d, 0xd9, 0xad
815                 ];
816                 let expected = Ok(PayeePubKey(
817                         PublicKey::from_slice(&pk_bytes[..]).unwrap()
818                 ));
819
820                 assert_eq!(PayeePubKey::from_base32(&input), expected);
821
822                 // expects 33 bytes
823                 let input_unexpected_length = from_bech32(
824                         "q0n326hr8v9zprg8gsvezcch06gfaqqhde2aj730yg0durunfhvq".as_bytes()
825                 );
826                 assert_eq!(PayeePubKey::from_base32(&input_unexpected_length), Err(ParseError::Skip));
827         }
828
829         #[test]
830         fn test_parse_expiry_time() {
831                 use crate::ExpiryTime;
832                 use bech32::FromBase32;
833
834                 let input = from_bech32("pu".as_bytes());
835                 let expected = Ok(ExpiryTime::from_seconds(60));
836                 assert_eq!(ExpiryTime::from_base32(&input), expected);
837
838                 let input_too_large = from_bech32("sqqqqqqqqqqqq".as_bytes());
839                 assert_eq!(ExpiryTime::from_base32(&input_too_large), Err(ParseError::IntegerOverflowError));
840         }
841
842         #[test]
843         fn test_parse_min_final_cltv_expiry_delta() {
844                 use crate::MinFinalCltvExpiryDelta;
845                 use bech32::FromBase32;
846
847                 let input = from_bech32("pr".as_bytes());
848                 let expected = Ok(MinFinalCltvExpiryDelta(35));
849
850                 assert_eq!(MinFinalCltvExpiryDelta::from_base32(&input), expected);
851         }
852
853         #[test]
854         fn test_parse_fallback() {
855                 use crate::Fallback;
856                 use bech32::FromBase32;
857                 use bitcoin::{PubkeyHash, ScriptHash};
858                 use bitcoin::util::address::WitnessVersion;
859                 use bitcoin_hashes::Hash;
860
861                 let cases = vec![
862                         (
863                                 from_bech32("3x9et2e20v6pu37c5d9vax37wxq72un98".as_bytes()),
864                                 Ok(Fallback::PubKeyHash(PubkeyHash::from_slice(&[
865                                         0x31, 0x72, 0xb5, 0x65, 0x4f, 0x66, 0x83, 0xc8, 0xfb, 0x14, 0x69, 0x59, 0xd3,
866                                         0x47, 0xce, 0x30, 0x3c, 0xae, 0x4c, 0xa7
867                                 ]).unwrap()))
868                         ),
869                         (
870                                 from_bech32("j3a24vwu6r8ejrss3axul8rxldph2q7z9".as_bytes()),
871                                 Ok(Fallback::ScriptHash(ScriptHash::from_slice(&[
872                                         0x8f, 0x55, 0x56, 0x3b, 0x9a, 0x19, 0xf3, 0x21, 0xc2, 0x11, 0xe9, 0xb9, 0xf3,
873                                         0x8c, 0xdf, 0x68, 0x6e, 0xa0, 0x78, 0x45
874                                 ]).unwrap()))
875                         ),
876                         (
877                                 from_bech32("qw508d6qejxtdg4y5r3zarvary0c5xw7k".as_bytes()),
878                                 Ok(Fallback::SegWitProgram {
879                                         version: WitnessVersion::V0,
880                                         program: Vec::from(&[
881                                                 0x75u8, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 0x1c, 0x45,
882                                                 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6
883                                         ][..])
884                                 })
885                         ),
886                         (
887                                 vec![u5::try_from_u8(21).unwrap(); 41],
888                                 Err(ParseError::Skip)
889                         ),
890                         (
891                                 vec![],
892                                 Err(ParseError::UnexpectedEndOfTaggedFields)
893                         ),
894                         (
895                                 vec![u5::try_from_u8(1).unwrap(); 81],
896                                 Err(ParseError::InvalidSegWitProgramLength)
897                         ),
898                         (
899                                 vec![u5::try_from_u8(17).unwrap(); 1],
900                                 Err(ParseError::InvalidPubKeyHashLength)
901                         ),
902                         (
903                                 vec![u5::try_from_u8(18).unwrap(); 1],
904                                 Err(ParseError::InvalidScriptHashLength)
905                         )
906                 ];
907
908                 for (input, expected) in cases.into_iter() {
909                         assert_eq!(Fallback::from_base32(&input), expected);
910                 }
911         }
912
913         #[test]
914         fn test_parse_route() {
915                 use lightning::routing::gossip::RoutingFees;
916                 use lightning::routing::router::{RouteHint, RouteHintHop};
917                 use crate::PrivateRoute;
918                 use bech32::FromBase32;
919                 use crate::de::parse_int_be;
920
921                 let input = from_bech32(
922                         "q20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqpqqqqq9qqqvpeuqa\
923                         fqxu92d8lr6fvg0r5gv0heeeqgcrqlnm6jhphu9y00rrhy4grqszsvpcgpy9qqqqqqgqqqqq7qqzq".as_bytes()
924                 );
925
926                 let mut expected = Vec::<RouteHintHop>::new();
927                 expected.push(RouteHintHop {
928                         src_node_id: PublicKey::from_slice(
929                                 &[
930                                         0x02u8, 0x9e, 0x03, 0xa9, 0x01, 0xb8, 0x55, 0x34, 0xff, 0x1e, 0x92, 0xc4, 0x3c,
931                                         0x74, 0x43, 0x1f, 0x7c, 0xe7, 0x20, 0x46, 0x06, 0x0f, 0xcf, 0x7a, 0x95, 0xc3,
932                                         0x7e, 0x14, 0x8f, 0x78, 0xc7, 0x72, 0x55
933                                 ][..]
934                         ).unwrap(),
935                         short_channel_id: parse_int_be(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08], 256).expect("short chan ID slice too big?"),
936                         fees: RoutingFees {
937                                 base_msat: 1,
938                                 proportional_millionths: 20,
939                         },
940                         cltv_expiry_delta: 3,
941                         htlc_minimum_msat: None,
942                         htlc_maximum_msat: None
943                 });
944                 expected.push(RouteHintHop {
945                         src_node_id: PublicKey::from_slice(
946                                 &[
947                                         0x03u8, 0x9e, 0x03, 0xa9, 0x01, 0xb8, 0x55, 0x34, 0xff, 0x1e, 0x92, 0xc4, 0x3c,
948                                         0x74, 0x43, 0x1f, 0x7c, 0xe7, 0x20, 0x46, 0x06, 0x0f, 0xcf, 0x7a, 0x95, 0xc3,
949                                         0x7e, 0x14, 0x8f, 0x78, 0xc7, 0x72, 0x55
950                                 ][..]
951                         ).unwrap(),
952                         short_channel_id: parse_int_be(&[0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a], 256).expect("short chan ID slice too big?"),
953                         fees: RoutingFees {
954                                 base_msat: 2,
955                                 proportional_millionths: 30,
956                         },
957                         cltv_expiry_delta: 4,
958                         htlc_minimum_msat: None,
959                         htlc_maximum_msat: None
960                 });
961
962                 assert_eq!(PrivateRoute::from_base32(&input), Ok(PrivateRoute(RouteHint(expected))));
963
964                 assert_eq!(
965                         PrivateRoute::from_base32(&[u5::try_from_u8(0).unwrap(); 40][..]),
966                         Err(ParseError::UnexpectedEndOfTaggedFields)
967                 );
968         }
969
970         #[test]
971         fn test_payment_secret_and_features_de_and_ser() {
972                 use lightning::ln::features::InvoiceFeatures;
973                 use secp256k1::ecdsa::{RecoveryId, RecoverableSignature};
974                 use crate::TaggedField::*;
975                 use crate::{SiPrefix, SignedRawInvoice, InvoiceSignature, RawInvoice, RawHrp, RawDataPart,
976                                  Currency, Sha256, PositiveTimestamp};
977
978                 // Feature bits 9, 15, and 99 are set.
979                 let expected_features = InvoiceFeatures::from_le_bytes(vec![0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8]);
980                 let invoice_str = "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q5sqqqqqqqqqqqqqqqpqsq67gye39hfg3zd8rgc80k32tvy9xk2xunwm5lzexnvpx6fd77en8qaq424dxgt56cag2dpt359k3ssyhetktkpqh24jqnjyw6uqd08sgptq44qu";
981                 let invoice = SignedRawInvoice {
982                                         raw_invoice: RawInvoice {
983                                                 hrp: RawHrp {
984                                                         currency: Currency::Bitcoin,
985                                                         raw_amount: Some(25),
986                                                         si_prefix: Some(SiPrefix::Milli)
987                                                 },
988                                                 data: RawDataPart {
989                                                         timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
990                                                         tagged_fields: vec ! [
991                                                                 PaymentHash(Sha256(sha256::Hash::from_hex(
992                                                                         "0001020304050607080900010203040506070809000102030405060708090102"
993                                                                 ).unwrap())).into(),
994                                                                 Description(crate::Description::new("coffee beans".to_owned()).unwrap()).into(),
995                                                                 PaymentSecret(crate::PaymentSecret([17; 32])).into(),
996                                                                 Features(expected_features).into()]}
997                                                                 },
998                                         hash: [0xb1, 0x96, 0x46, 0xc3, 0xbc, 0x56, 0x76, 0x1d, 0x20, 0x65, 0x6e, 0x0e, 0x32,
999                                                                         0xec, 0xd2, 0x69, 0x27, 0xb7, 0x62, 0x6e, 0x2a, 0x8b, 0xe6, 0x97, 0x71, 0x9f,
1000                                                                         0xf8, 0x7e, 0x44, 0x54, 0x55, 0xb9],
1001                                         signature: InvoiceSignature(RecoverableSignature::from_compact(
1002                                                                                 &[0xd7, 0x90, 0x4c, 0xc4, 0xb7, 0x4a, 0x22, 0x26, 0x9c, 0x68, 0xc1, 0xdf, 0x68,
1003                                                                                         0xa9, 0x6c, 0x21, 0x4d, 0x65, 0x1b, 0x93, 0x76, 0xe9, 0xf1, 0x64, 0xd3, 0x60,
1004                                                                                         0x4d, 0xa4, 0xb7, 0xde, 0xcc, 0xce, 0x0e, 0x82, 0xaa, 0xab, 0x4c, 0x85, 0xd3,
1005                                                                                         0x58, 0xea, 0x14, 0xd0, 0xae, 0x34, 0x2d, 0xa3, 0x08, 0x12, 0xf9, 0x5d, 0x97,
1006                                                                                         0x60, 0x82, 0xea, 0xac, 0x81, 0x39, 0x11, 0xda, 0xe0, 0x1a, 0xf3, 0xc1],
1007                                                                                 RecoveryId::from_i32(1).unwrap()
1008                                                                 ).unwrap()),
1009                         };
1010                 assert_eq!(invoice_str, invoice.to_string());
1011                 assert_eq!(
1012                         invoice_str.parse(),
1013                         Ok(invoice)
1014                 );
1015         }
1016
1017         #[test]
1018         fn test_raw_signed_invoice_deserialization() {
1019                 use crate::TaggedField::*;
1020                 use secp256k1::ecdsa::{RecoveryId, RecoverableSignature};
1021                 use crate::{SignedRawInvoice, InvoiceSignature, RawInvoice, RawHrp, RawDataPart, Currency, Sha256,
1022                          PositiveTimestamp};
1023
1024                 assert_eq!(
1025                         "lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmw\
1026                         wd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq8rkx3yf5tcsyz3d73gafnh3cax9rn449d9p5uxz9\
1027                         ezhhypd0elx87sjle52x86fux2ypatgddc6k63n7erqz25le42c4u4ecky03ylcqca784w".parse(),
1028                         Ok(SignedRawInvoice {
1029                                 raw_invoice: RawInvoice {
1030                                         hrp: RawHrp {
1031                                                 currency: Currency::Bitcoin,
1032                                                 raw_amount: None,
1033                                                 si_prefix: None,
1034                                         },
1035                                         data: RawDataPart {
1036                                         timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
1037                                         tagged_fields: vec ! [
1038                                                 PaymentHash(Sha256(sha256::Hash::from_hex(
1039                                                         "0001020304050607080900010203040506070809000102030405060708090102"
1040                                                 ).unwrap())).into(),
1041                                                 Description(
1042                                                         crate::Description::new(
1043                                                                 "Please consider supporting this project".to_owned()
1044                                                         ).unwrap()
1045                                                 ).into(),
1046                                         ],
1047                                         },
1048                                         },
1049                                 hash: [
1050                                         0xc3, 0xd4, 0xe8, 0x3f, 0x64, 0x6f, 0xa7, 0x9a, 0x39, 0x3d, 0x75, 0x27,
1051                                         0x7b, 0x1d, 0x85, 0x8d, 0xb1, 0xd1, 0xf7, 0xab, 0x71, 0x37, 0xdc, 0xb7,
1052                                         0x83, 0x5d, 0xb2, 0xec, 0xd5, 0x18, 0xe1, 0xc9
1053                                 ],
1054                                 signature: InvoiceSignature(RecoverableSignature::from_compact(
1055                                         & [
1056                                                 0x38u8, 0xec, 0x68, 0x91, 0x34, 0x5e, 0x20, 0x41, 0x45, 0xbe, 0x8a,
1057                                                 0x3a, 0x99, 0xde, 0x38, 0xe9, 0x8a, 0x39, 0xd6, 0xa5, 0x69, 0x43,
1058                                                 0x4e, 0x18, 0x45, 0xc8, 0xaf, 0x72, 0x05, 0xaf, 0xcf, 0xcc, 0x7f,
1059                                                 0x42, 0x5f, 0xcd, 0x14, 0x63, 0xe9, 0x3c, 0x32, 0x88, 0x1e, 0xad,
1060                                                 0x0d, 0x6e, 0x35, 0x6d, 0x46, 0x7e, 0xc8, 0xc0, 0x25, 0x53, 0xf9,
1061                                                 0xaa, 0xb1, 0x5e, 0x57, 0x38, 0xb1, 0x1f, 0x12, 0x7f
1062                                         ],
1063                                         RecoveryId::from_i32(0).unwrap()
1064                                 ).unwrap()),
1065                                 }
1066                         )
1067                 )
1068         }
1069 }