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