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