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