Merge pull request #2161 from benthecarman/prune-stale-channels-rgs
[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_FEATURES =>
464                                 Ok(TaggedField::Features(InvoiceFeatures::from_base32(field_data)?)),
465                         _ => {
466                                 // "A reader MUST skip over unknown fields"
467                                 Err(ParseError::Skip)
468                         }
469                 }
470         }
471 }
472
473 impl FromBase32 for Sha256 {
474         type Err = ParseError;
475
476         fn from_base32(field_data: &[u5]) -> Result<Sha256, ParseError> {
477                 if field_data.len() != 52 {
478                         // "A reader MUST skip over […] a p, [or] h […] field that does not have data_length 52 […]."
479                         Err(ParseError::Skip)
480                 } else {
481                         Ok(Sha256(sha256::Hash::from_slice(&Vec::<u8>::from_base32(field_data)?)
482                                 .expect("length was checked before (52 u5 -> 32 u8)")))
483                 }
484         }
485 }
486
487 impl FromBase32 for Description {
488         type Err = ParseError;
489
490         fn from_base32(field_data: &[u5]) -> Result<Description, ParseError> {
491                 let bytes = Vec::<u8>::from_base32(field_data)?;
492                 let description = String::from(str::from_utf8(&bytes)?);
493                 Ok(Description::new(description).expect(
494                         "Max len is 639=floor(1023*5/8) since the len field is only 10bits long"
495                 ))
496         }
497 }
498
499 impl FromBase32 for PayeePubKey {
500         type Err = ParseError;
501
502         fn from_base32(field_data: &[u5]) -> Result<PayeePubKey, ParseError> {
503                 if field_data.len() != 53 {
504                         // "A reader MUST skip over […] a n […] field that does not have data_length 53 […]."
505                         Err(ParseError::Skip)
506                 } else {
507                         let data_bytes = Vec::<u8>::from_base32(field_data)?;
508                         let pub_key = PublicKey::from_slice(&data_bytes)?;
509                         Ok(pub_key.into())
510                 }
511         }
512 }
513
514 impl FromBase32 for ExpiryTime {
515         type Err = ParseError;
516
517         fn from_base32(field_data: &[u5]) -> Result<ExpiryTime, ParseError> {
518                 match parse_int_be::<u64, u5>(field_data, 32)
519                         .map(ExpiryTime::from_seconds)
520                 {
521                         Some(t) => Ok(t),
522                         None => Err(ParseError::IntegerOverflowError),
523                 }
524         }
525 }
526
527 impl FromBase32 for MinFinalCltvExpiryDelta {
528         type Err = ParseError;
529
530         fn from_base32(field_data: &[u5]) -> Result<MinFinalCltvExpiryDelta, ParseError> {
531                 let expiry = parse_int_be::<u64, u5>(field_data, 32);
532                 if let Some(expiry) = expiry {
533                         Ok(MinFinalCltvExpiryDelta(expiry))
534                 } else {
535                         Err(ParseError::IntegerOverflowError)
536                 }
537         }
538 }
539
540 impl FromBase32 for Fallback {
541         type Err = ParseError;
542
543         fn from_base32(field_data: &[u5]) -> Result<Fallback, ParseError> {
544                 if field_data.is_empty() {
545                         return Err(ParseError::UnexpectedEndOfTaggedFields);
546                 }
547
548                 let version = field_data[0];
549                 let bytes = Vec::<u8>::from_base32(&field_data[1..])?;
550
551                 match version.to_u8() {
552                         0..=16 => {
553                                 if bytes.len() < 2 || bytes.len() > 40 {
554                                         return Err(ParseError::InvalidSegWitProgramLength);
555                                 }
556                                 let version = WitnessVersion::try_from(version).expect("0 through 16 are valid SegWit versions");
557                                 Ok(Fallback::SegWitProgram {
558                                         version,
559                                         program: bytes
560                                 })
561                         },
562                         17 => {
563                                 let pkh = match PubkeyHash::from_slice(&bytes) {
564                                         Ok(pkh) => pkh,
565                                         Err(bitcoin_hashes::Error::InvalidLength(_, _)) => return Err(ParseError::InvalidPubKeyHashLength),
566                                 };
567                                 Ok(Fallback::PubKeyHash(pkh))
568                         }
569                         18 => {
570                                 let sh = match ScriptHash::from_slice(&bytes) {
571                                         Ok(sh) => sh,
572                                         Err(bitcoin_hashes::Error::InvalidLength(_, _)) => return Err(ParseError::InvalidScriptHashLength),
573                                 };
574                                 Ok(Fallback::ScriptHash(sh))
575                         }
576                         _ => Err(ParseError::Skip)
577                 }
578         }
579 }
580
581 impl FromBase32 for PrivateRoute {
582         type Err = ParseError;
583
584         fn from_base32(field_data: &[u5]) -> Result<PrivateRoute, ParseError> {
585                 let bytes = Vec::<u8>::from_base32(field_data)?;
586
587                 if bytes.len() % 51 != 0 {
588                         return Err(ParseError::UnexpectedEndOfTaggedFields);
589                 }
590
591                 let mut route_hops = Vec::<RouteHintHop>::new();
592
593                 let mut bytes = bytes.as_slice();
594                 while !bytes.is_empty() {
595                         let hop_bytes = &bytes[0..51];
596                         bytes = &bytes[51..];
597
598                         let mut channel_id: [u8; 8] = Default::default();
599                         channel_id.copy_from_slice(&hop_bytes[33..41]);
600
601                         let hop = RouteHintHop {
602                                 src_node_id: PublicKey::from_slice(&hop_bytes[0..33])?,
603                                 short_channel_id: parse_int_be(&channel_id, 256).expect("short chan ID slice too big?"),
604                                 fees: RoutingFees {
605                                         base_msat: parse_int_be(&hop_bytes[41..45], 256).expect("slice too big?"),
606                                         proportional_millionths: parse_int_be(&hop_bytes[45..49], 256).expect("slice too big?"),
607                                 },
608                                 cltv_expiry_delta: parse_int_be(&hop_bytes[49..51], 256).expect("slice too big?"),
609                                 htlc_minimum_msat: None,
610                                 htlc_maximum_msat: None,
611                         };
612
613                         route_hops.push(hop);
614                 }
615
616                 Ok(PrivateRoute(RouteHint(route_hops)))
617         }
618 }
619
620 impl Display for ParseError {
621         fn fmt(&self, f: &mut Formatter) -> fmt::Result {
622                 match *self {
623                         // TODO: find a way to combine the first three arms (e as error::Error?)
624                         ParseError::Bech32Error(ref e) => {
625                                 write!(f, "Invalid bech32: {}", e)
626                         }
627                         ParseError::ParseAmountError(ref e) => {
628                                 write!(f, "Invalid amount in hrp ({})", e)
629                         }
630                         ParseError::MalformedSignature(ref e) => {
631                                 write!(f, "Invalid secp256k1 signature: {}", e)
632                         }
633                         ParseError::DescriptionDecodeError(ref e) => {
634                                 write!(f, "Description is not a valid utf-8 string: {}", e)
635                         }
636                         ParseError::InvalidSliceLength(ref function) => {
637                                 write!(f, "Slice in function {} had the wrong length", function)
638                         }
639                         ParseError::BadPrefix => f.write_str("did not begin with 'ln'"),
640                         ParseError::UnknownCurrency => f.write_str("currency code unknown"),
641                         ParseError::UnknownSiPrefix => f.write_str("unknown SI prefix"),
642                         ParseError::MalformedHRP => f.write_str("malformed human readable part"),
643                         ParseError::TooShortDataPart => {
644                                 f.write_str("data part too short (should be at least 111 bech32 chars long)")
645                         },
646                         ParseError::UnexpectedEndOfTaggedFields => {
647                                 f.write_str("tagged fields part ended unexpectedly")
648                         },
649                         ParseError::PaddingError => f.write_str("some data field had bad padding"),
650                         ParseError::IntegerOverflowError => {
651                                 f.write_str("parsed integer doesn't fit into receiving type")
652                         },
653                         ParseError::InvalidSegWitProgramLength => {
654                                 f.write_str("fallback SegWit program is too long or too short")
655                         },
656                         ParseError::InvalidPubKeyHashLength => {
657                                 f.write_str("fallback public key hash has a length unequal 20 bytes")
658                         },
659                         ParseError::InvalidScriptHashLength => {
660                                 f.write_str("fallback script hash has a length unequal 32 bytes")
661                         },
662                         ParseError::InvalidRecoveryId => {
663                                 f.write_str("recovery id is out of range (should be in [0,3])")
664                         },
665                         ParseError::Skip => {
666                                 f.write_str("the tagged field has to be skipped because of an unexpected, but allowed property")
667                         },
668                 }
669         }
670 }
671
672 impl Display for ParseOrSemanticError {
673         fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
674                 match self {
675                         ParseOrSemanticError::ParseError(err) => err.fmt(f),
676                         ParseOrSemanticError::SemanticError(err) => err.fmt(f),
677                 }
678         }
679 }
680
681 #[cfg(feature = "std")]
682 impl error::Error for ParseError {}
683
684 #[cfg(feature = "std")]
685 impl error::Error for ParseOrSemanticError {}
686
687 macro_rules! from_error {
688     ($my_error:expr, $extern_error:ty) => {
689         impl From<$extern_error> for ParseError {
690             fn from(e: $extern_error) -> Self {
691                 $my_error(e)
692             }
693         }
694     }
695 }
696
697 from_error!(ParseError::MalformedSignature, secp256k1::Error);
698 from_error!(ParseError::ParseAmountError, ParseIntError);
699 from_error!(ParseError::DescriptionDecodeError, str::Utf8Error);
700
701 impl From<bech32::Error> for ParseError {
702         fn from(e: bech32::Error) -> Self {
703                 match e {
704                         bech32::Error::InvalidPadding => ParseError::PaddingError,
705                         _ => ParseError::Bech32Error(e)
706                 }
707         }
708 }
709
710 impl From<ParseError> for ParseOrSemanticError {
711         fn from(e: ParseError) -> Self {
712                 ParseOrSemanticError::ParseError(e)
713         }
714 }
715
716 impl From<crate::SemanticError> for ParseOrSemanticError {
717         fn from(e: SemanticError) -> Self {
718                 ParseOrSemanticError::SemanticError(e)
719         }
720 }
721
722 #[cfg(test)]
723 mod test {
724         use crate::de::ParseError;
725         use secp256k1::PublicKey;
726         use bech32::u5;
727         use bitcoin_hashes::hex::FromHex;
728         use bitcoin_hashes::sha256;
729
730         const CHARSET_REV: [i8; 128] = [
731                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
732                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
733                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
734                 15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1,
735                 -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
736                 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -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         ];
740
741         fn from_bech32(bytes_5b: &[u8]) -> Vec<u5> {
742                 bytes_5b
743                         .iter()
744                         .map(|c| u5::try_from_u8(CHARSET_REV[*c as usize] as u8).unwrap())
745                         .collect()
746         }
747
748         #[test]
749         fn test_parse_currency_prefix() {
750                 use crate::Currency;
751
752                 assert_eq!("bc".parse::<Currency>(), Ok(Currency::Bitcoin));
753                 assert_eq!("tb".parse::<Currency>(), Ok(Currency::BitcoinTestnet));
754                 assert_eq!("bcrt".parse::<Currency>(), Ok(Currency::Regtest));
755                 assert_eq!("sb".parse::<Currency>(), Ok(Currency::Simnet));
756                 assert_eq!("tbs".parse::<Currency>(), Ok(Currency::Signet));
757                 assert_eq!("something_else".parse::<Currency>(), Err(ParseError::UnknownCurrency))
758         }
759
760         #[test]
761         fn test_parse_int_from_bytes_be() {
762                 use crate::de::parse_int_be;
763
764                 assert_eq!(parse_int_be::<u32, u8>(&[1, 2, 3, 4], 256), Some(16909060));
765                 assert_eq!(parse_int_be::<u32, u8>(&[1, 3], 32), Some(35));
766                 assert_eq!(parse_int_be::<u32, u8>(&[255, 255, 255, 255], 256), Some(4294967295));
767                 assert_eq!(parse_int_be::<u32, u8>(&[1, 0, 0, 0, 0], 256), None);
768         }
769
770         #[test]
771         fn test_parse_sha256_hash() {
772                 use crate::Sha256;
773                 use bech32::FromBase32;
774
775                 let input = from_bech32(
776                         "qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypq".as_bytes()
777                 );
778
779                 let hash = sha256::Hash::from_hex(
780                         "0001020304050607080900010203040506070809000102030405060708090102"
781                 ).unwrap();
782                 let expected = Ok(Sha256(hash));
783
784                 assert_eq!(Sha256::from_base32(&input), expected);
785
786                 // make sure hashes of unknown length get skipped
787                 let input_unexpected_length = from_bech32(
788                         "qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypyq".as_bytes()
789                 );
790                 assert_eq!(Sha256::from_base32(&input_unexpected_length), Err(ParseError::Skip));
791         }
792
793         #[test]
794         fn test_parse_description() {
795                 use crate::Description;
796                 use bech32::FromBase32;
797
798                 let input = from_bech32("xysxxatsyp3k7enxv4js".as_bytes());
799                 let expected = Ok(Description::new("1 cup coffee".to_owned()).unwrap());
800                 assert_eq!(Description::from_base32(&input), expected);
801         }
802
803         #[test]
804         fn test_parse_payee_pub_key() {
805                 use crate::PayeePubKey;
806                 use bech32::FromBase32;
807
808                 let input = from_bech32("q0n326hr8v9zprg8gsvezcch06gfaqqhde2aj730yg0durunfhv66".as_bytes());
809                 let pk_bytes = [
810                         0x03, 0xe7, 0x15, 0x6a, 0xe3, 0x3b, 0x0a, 0x20, 0x8d, 0x07, 0x44, 0x19, 0x91, 0x63,
811                         0x17, 0x7e, 0x90, 0x9e, 0x80, 0x17, 0x6e, 0x55, 0xd9, 0x7a, 0x2f, 0x22, 0x1e, 0xde,
812                         0x0f, 0x93, 0x4d, 0xd9, 0xad
813                 ];
814                 let expected = Ok(PayeePubKey(
815                         PublicKey::from_slice(&pk_bytes[..]).unwrap()
816                 ));
817
818                 assert_eq!(PayeePubKey::from_base32(&input), expected);
819
820                 // expects 33 bytes
821                 let input_unexpected_length = from_bech32(
822                         "q0n326hr8v9zprg8gsvezcch06gfaqqhde2aj730yg0durunfhvq".as_bytes()
823                 );
824                 assert_eq!(PayeePubKey::from_base32(&input_unexpected_length), Err(ParseError::Skip));
825         }
826
827         #[test]
828         fn test_parse_expiry_time() {
829                 use crate::ExpiryTime;
830                 use bech32::FromBase32;
831
832                 let input = from_bech32("pu".as_bytes());
833                 let expected = Ok(ExpiryTime::from_seconds(60));
834                 assert_eq!(ExpiryTime::from_base32(&input), expected);
835
836                 let input_too_large = from_bech32("sqqqqqqqqqqqq".as_bytes());
837                 assert_eq!(ExpiryTime::from_base32(&input_too_large), Err(ParseError::IntegerOverflowError));
838         }
839
840         #[test]
841         fn test_parse_min_final_cltv_expiry_delta() {
842                 use crate::MinFinalCltvExpiryDelta;
843                 use bech32::FromBase32;
844
845                 let input = from_bech32("pr".as_bytes());
846                 let expected = Ok(MinFinalCltvExpiryDelta(35));
847
848                 assert_eq!(MinFinalCltvExpiryDelta::from_base32(&input), expected);
849         }
850
851         #[test]
852         fn test_parse_fallback() {
853                 use crate::Fallback;
854                 use bech32::FromBase32;
855                 use bitcoin::{PubkeyHash, ScriptHash};
856                 use bitcoin::util::address::WitnessVersion;
857                 use bitcoin_hashes::Hash;
858
859                 let cases = vec![
860                         (
861                                 from_bech32("3x9et2e20v6pu37c5d9vax37wxq72un98".as_bytes()),
862                                 Ok(Fallback::PubKeyHash(PubkeyHash::from_slice(&[
863                                         0x31, 0x72, 0xb5, 0x65, 0x4f, 0x66, 0x83, 0xc8, 0xfb, 0x14, 0x69, 0x59, 0xd3,
864                                         0x47, 0xce, 0x30, 0x3c, 0xae, 0x4c, 0xa7
865                                 ]).unwrap()))
866                         ),
867                         (
868                                 from_bech32("j3a24vwu6r8ejrss3axul8rxldph2q7z9".as_bytes()),
869                                 Ok(Fallback::ScriptHash(ScriptHash::from_slice(&[
870                                         0x8f, 0x55, 0x56, 0x3b, 0x9a, 0x19, 0xf3, 0x21, 0xc2, 0x11, 0xe9, 0xb9, 0xf3,
871                                         0x8c, 0xdf, 0x68, 0x6e, 0xa0, 0x78, 0x45
872                                 ]).unwrap()))
873                         ),
874                         (
875                                 from_bech32("qw508d6qejxtdg4y5r3zarvary0c5xw7k".as_bytes()),
876                                 Ok(Fallback::SegWitProgram {
877                                         version: WitnessVersion::V0,
878                                         program: Vec::from(&[
879                                                 0x75u8, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 0x1c, 0x45,
880                                                 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6
881                                         ][..])
882                                 })
883                         ),
884                         (
885                                 vec![u5::try_from_u8(21).unwrap(); 41],
886                                 Err(ParseError::Skip)
887                         ),
888                         (
889                                 vec![],
890                                 Err(ParseError::UnexpectedEndOfTaggedFields)
891                         ),
892                         (
893                                 vec![u5::try_from_u8(1).unwrap(); 81],
894                                 Err(ParseError::InvalidSegWitProgramLength)
895                         ),
896                         (
897                                 vec![u5::try_from_u8(17).unwrap(); 1],
898                                 Err(ParseError::InvalidPubKeyHashLength)
899                         ),
900                         (
901                                 vec![u5::try_from_u8(18).unwrap(); 1],
902                                 Err(ParseError::InvalidScriptHashLength)
903                         )
904                 ];
905
906                 for (input, expected) in cases.into_iter() {
907                         assert_eq!(Fallback::from_base32(&input), expected);
908                 }
909         }
910
911         #[test]
912         fn test_parse_route() {
913                 use lightning::routing::gossip::RoutingFees;
914                 use lightning::routing::router::{RouteHint, RouteHintHop};
915                 use crate::PrivateRoute;
916                 use bech32::FromBase32;
917                 use crate::de::parse_int_be;
918
919                 let input = from_bech32(
920                         "q20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqpqqqqq9qqqvpeuqa\
921                         fqxu92d8lr6fvg0r5gv0heeeqgcrqlnm6jhphu9y00rrhy4grqszsvpcgpy9qqqqqqgqqqqq7qqzq".as_bytes()
922                 );
923
924                 let mut expected = Vec::<RouteHintHop>::new();
925                 expected.push(RouteHintHop {
926                         src_node_id: PublicKey::from_slice(
927                                 &[
928                                         0x02u8, 0x9e, 0x03, 0xa9, 0x01, 0xb8, 0x55, 0x34, 0xff, 0x1e, 0x92, 0xc4, 0x3c,
929                                         0x74, 0x43, 0x1f, 0x7c, 0xe7, 0x20, 0x46, 0x06, 0x0f, 0xcf, 0x7a, 0x95, 0xc3,
930                                         0x7e, 0x14, 0x8f, 0x78, 0xc7, 0x72, 0x55
931                                 ][..]
932                         ).unwrap(),
933                         short_channel_id: parse_int_be(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08], 256).expect("short chan ID slice too big?"),
934                         fees: RoutingFees {
935                                 base_msat: 1,
936                                 proportional_millionths: 20,
937                         },
938                         cltv_expiry_delta: 3,
939                         htlc_minimum_msat: None,
940                         htlc_maximum_msat: None
941                 });
942                 expected.push(RouteHintHop {
943                         src_node_id: PublicKey::from_slice(
944                                 &[
945                                         0x03u8, 0x9e, 0x03, 0xa9, 0x01, 0xb8, 0x55, 0x34, 0xff, 0x1e, 0x92, 0xc4, 0x3c,
946                                         0x74, 0x43, 0x1f, 0x7c, 0xe7, 0x20, 0x46, 0x06, 0x0f, 0xcf, 0x7a, 0x95, 0xc3,
947                                         0x7e, 0x14, 0x8f, 0x78, 0xc7, 0x72, 0x55
948                                 ][..]
949                         ).unwrap(),
950                         short_channel_id: parse_int_be(&[0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a], 256).expect("short chan ID slice too big?"),
951                         fees: RoutingFees {
952                                 base_msat: 2,
953                                 proportional_millionths: 30,
954                         },
955                         cltv_expiry_delta: 4,
956                         htlc_minimum_msat: None,
957                         htlc_maximum_msat: None
958                 });
959
960                 assert_eq!(PrivateRoute::from_base32(&input), Ok(PrivateRoute(RouteHint(expected))));
961
962                 assert_eq!(
963                         PrivateRoute::from_base32(&[u5::try_from_u8(0).unwrap(); 40][..]),
964                         Err(ParseError::UnexpectedEndOfTaggedFields)
965                 );
966         }
967
968         #[test]
969         fn test_payment_secret_and_features_de_and_ser() {
970                 use lightning::ln::features::InvoiceFeatures;
971                 use secp256k1::ecdsa::{RecoveryId, RecoverableSignature};
972                 use crate::TaggedField::*;
973                 use crate::{SiPrefix, SignedRawInvoice, InvoiceSignature, RawInvoice, RawHrp, RawDataPart,
974                                  Currency, Sha256, PositiveTimestamp};
975
976                 // Feature bits 9, 15, and 99 are set.
977                 let expected_features = InvoiceFeatures::from_le_bytes(vec![0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8]);
978                 let invoice_str = "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q5sqqqqqqqqqqqqqqqpqsq67gye39hfg3zd8rgc80k32tvy9xk2xunwm5lzexnvpx6fd77en8qaq424dxgt56cag2dpt359k3ssyhetktkpqh24jqnjyw6uqd08sgptq44qu";
979                 let invoice = SignedRawInvoice {
980                                         raw_invoice: RawInvoice {
981                                                 hrp: RawHrp {
982                                                         currency: Currency::Bitcoin,
983                                                         raw_amount: Some(25),
984                                                         si_prefix: Some(SiPrefix::Milli)
985                                                 },
986                                                 data: RawDataPart {
987                                                         timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
988                                                         tagged_fields: vec ! [
989                                                                 PaymentHash(Sha256(sha256::Hash::from_hex(
990                                                                         "0001020304050607080900010203040506070809000102030405060708090102"
991                                                                 ).unwrap())).into(),
992                                                                 Description(crate::Description::new("coffee beans".to_owned()).unwrap()).into(),
993                                                                 PaymentSecret(crate::PaymentSecret([17; 32])).into(),
994                                                                 Features(expected_features).into()]}
995                                                                 },
996                                         hash: [0xb1, 0x96, 0x46, 0xc3, 0xbc, 0x56, 0x76, 0x1d, 0x20, 0x65, 0x6e, 0x0e, 0x32,
997                                                                         0xec, 0xd2, 0x69, 0x27, 0xb7, 0x62, 0x6e, 0x2a, 0x8b, 0xe6, 0x97, 0x71, 0x9f,
998                                                                         0xf8, 0x7e, 0x44, 0x54, 0x55, 0xb9],
999                                         signature: InvoiceSignature(RecoverableSignature::from_compact(
1000                                                                                 &[0xd7, 0x90, 0x4c, 0xc4, 0xb7, 0x4a, 0x22, 0x26, 0x9c, 0x68, 0xc1, 0xdf, 0x68,
1001                                                                                         0xa9, 0x6c, 0x21, 0x4d, 0x65, 0x1b, 0x93, 0x76, 0xe9, 0xf1, 0x64, 0xd3, 0x60,
1002                                                                                         0x4d, 0xa4, 0xb7, 0xde, 0xcc, 0xce, 0x0e, 0x82, 0xaa, 0xab, 0x4c, 0x85, 0xd3,
1003                                                                                         0x58, 0xea, 0x14, 0xd0, 0xae, 0x34, 0x2d, 0xa3, 0x08, 0x12, 0xf9, 0x5d, 0x97,
1004                                                                                         0x60, 0x82, 0xea, 0xac, 0x81, 0x39, 0x11, 0xda, 0xe0, 0x1a, 0xf3, 0xc1],
1005                                                                                 RecoveryId::from_i32(1).unwrap()
1006                                                                 ).unwrap()),
1007                         };
1008                 assert_eq!(invoice_str, invoice.to_string());
1009                 assert_eq!(
1010                         invoice_str.parse(),
1011                         Ok(invoice)
1012                 );
1013         }
1014
1015         #[test]
1016         fn test_raw_signed_invoice_deserialization() {
1017                 use crate::TaggedField::*;
1018                 use secp256k1::ecdsa::{RecoveryId, RecoverableSignature};
1019                 use crate::{SignedRawInvoice, InvoiceSignature, RawInvoice, RawHrp, RawDataPart, Currency, Sha256,
1020                          PositiveTimestamp};
1021
1022                 assert_eq!(
1023                         "lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmw\
1024                         wd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq8rkx3yf5tcsyz3d73gafnh3cax9rn449d9p5uxz9\
1025                         ezhhypd0elx87sjle52x86fux2ypatgddc6k63n7erqz25le42c4u4ecky03ylcqca784w".parse(),
1026                         Ok(SignedRawInvoice {
1027                                 raw_invoice: RawInvoice {
1028                                         hrp: RawHrp {
1029                                                 currency: Currency::Bitcoin,
1030                                                 raw_amount: None,
1031                                                 si_prefix: None,
1032                                         },
1033                                         data: RawDataPart {
1034                                         timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(),
1035                                         tagged_fields: vec ! [
1036                                                 PaymentHash(Sha256(sha256::Hash::from_hex(
1037                                                         "0001020304050607080900010203040506070809000102030405060708090102"
1038                                                 ).unwrap())).into(),
1039                                                 Description(
1040                                                         crate::Description::new(
1041                                                                 "Please consider supporting this project".to_owned()
1042                                                         ).unwrap()
1043                                                 ).into(),
1044                                         ],
1045                                         },
1046                                         },
1047                                 hash: [
1048                                         0xc3, 0xd4, 0xe8, 0x3f, 0x64, 0x6f, 0xa7, 0x9a, 0x39, 0x3d, 0x75, 0x27,
1049                                         0x7b, 0x1d, 0x85, 0x8d, 0xb1, 0xd1, 0xf7, 0xab, 0x71, 0x37, 0xdc, 0xb7,
1050                                         0x83, 0x5d, 0xb2, 0xec, 0xd5, 0x18, 0xe1, 0xc9
1051                                 ],
1052                                 signature: InvoiceSignature(RecoverableSignature::from_compact(
1053                                         & [
1054                                                 0x38u8, 0xec, 0x68, 0x91, 0x34, 0x5e, 0x20, 0x41, 0x45, 0xbe, 0x8a,
1055                                                 0x3a, 0x99, 0xde, 0x38, 0xe9, 0x8a, 0x39, 0xd6, 0xa5, 0x69, 0x43,
1056                                                 0x4e, 0x18, 0x45, 0xc8, 0xaf, 0x72, 0x05, 0xaf, 0xcf, 0xcc, 0x7f,
1057                                                 0x42, 0x5f, 0xcd, 0x14, 0x63, 0xe9, 0x3c, 0x32, 0x88, 0x1e, 0xad,
1058                                                 0x0d, 0x6e, 0x35, 0x6d, 0x46, 0x7e, 0xc8, 0xc0, 0x25, 0x53, 0xf9,
1059                                                 0xaa, 0xb1, 0x5e, 0x57, 0x38, 0xb1, 0x1f, 0x12, 0x7f
1060                                         ],
1061                                         RecoveryId::from_i32(0).unwrap()
1062                                 ).unwrap()),
1063                                 }
1064                         )
1065                 )
1066         }
1067 }