Use explicit import lists instead of glob imports in invoice
[rust-lightning] / lightning-invoice / src / ser.rs
1 use std::fmt;
2 use std::fmt::{Display, Formatter};
3 use bech32::{ToBase32, u5, WriteBase32, Base32Len};
4
5 use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiry, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp,
6         RouteHint, Description, RawTaggedField, Currency, RawHrp, SiPrefix, constants, SignedRawInvoice, RawDataPart};
7
8 /// Converts a stream of bytes written to it to base32. On finalization the according padding will
9 /// be applied. That means the results of writing two data blocks with one or two `BytesToBase32`
10 /// converters will differ.
11 struct BytesToBase32<'a, W: WriteBase32 + 'a> {
12         /// Target for writing the resulting `u5`s resulting from the written bytes
13         writer: &'a mut W,
14         /// Holds all unwritten bits left over from last round. The bits are stored beginning from
15         /// the most significant bit. E.g. if buffer_bits=3, then the byte with bits a, b and c will
16         /// look as follows: [a, b, c, 0, 0, 0, 0, 0]
17         buffer: u8,
18         /// Amount of bits left over from last round, stored in buffer.
19         buffer_bits: u8,
20 }
21
22 impl<'a, W: WriteBase32> BytesToBase32<'a, W> {
23         /// Create a new bytes-to-base32 converter with `writer` as  a sink for the resulting base32
24         /// data.
25         pub fn new(writer: &'a mut W) -> BytesToBase32<'a, W> {
26                 BytesToBase32 {
27                         writer,
28                         buffer: 0,
29                         buffer_bits: 0,
30                 }
31         }
32
33         /// Add more bytes to the current conversion unit
34         pub fn append(&mut self, bytes: &[u8]) -> Result<(), W::Err> {
35                 for b in bytes {
36                         self.append_u8(*b)?;
37                 }
38                 Ok(())
39         }
40
41         pub fn append_u8(&mut self, byte: u8) -> Result<(), W::Err> {
42                 // Write first u5 if we have to write two u5s this round. That only happens if the
43                 // buffer holds too many bits, so we don't have to combine buffer bits with new bits
44                 // from this rounds byte.
45                 if self.buffer_bits >= 5 {
46                         self.writer.write_u5(
47                                 u5::try_from_u8((self.buffer & 0b11111000) >> 3 ).expect("<32")
48                         )?;
49                         self.buffer = self.buffer << 5;
50                         self.buffer_bits -= 5;
51                 }
52
53                 // Combine all bits from buffer with enough bits from this rounds byte so that they fill
54                 // a u5. Save reamining bits from byte to buffer.
55                 let from_buffer = self.buffer >> 3;
56                 let from_byte = byte >> (3 + self.buffer_bits); // buffer_bits <= 4
57
58                 self.writer.write_u5(u5::try_from_u8(from_buffer | from_byte).expect("<32"))?;
59                 self.buffer = byte << (5 - self.buffer_bits);
60                 self.buffer_bits = 3 + self.buffer_bits;
61
62                 Ok(())
63         }
64
65         pub fn finalize(mut self) ->  Result<(), W::Err> {
66                 self.inner_finalize()?;
67                 std::mem::forget(self);
68                 Ok(())
69         }
70
71         fn inner_finalize(&mut self) -> Result<(), W::Err>{
72                 // There can be at most two u5s left in the buffer after processing all bytes, write them.
73                 if self.buffer_bits >= 5 {
74                         self.writer.write_u5(
75                                 u5::try_from_u8((self.buffer & 0b11111000) >> 3).expect("<32")
76                         )?;
77                         self.buffer = self.buffer << 5;
78                         self.buffer_bits -= 5;
79                 }
80
81                 if self.buffer_bits != 0 {
82                         self.writer.write_u5(u5::try_from_u8(self.buffer >> 3).expect("<32"))?;
83                 }
84
85                 Ok(())
86         }
87 }
88
89 impl<'a, W: WriteBase32> Drop for BytesToBase32<'a, W> {
90         fn drop(&mut self) {
91                 self.inner_finalize()
92                         .expect("Unhandled error when finalizing conversion on drop. User finalize to handle.")
93         }
94 }
95
96 /// Calculates the base32 encoded size of a byte slice
97 fn bytes_size_to_base32_size(byte_size: usize) -> usize {
98         let bits = byte_size * 8;
99         if bits % 5 == 0 {
100                 // without padding bits
101                 bits / 5
102         } else {
103                 // with padding bits
104                 bits / 5 + 1
105         }
106 }
107
108 impl Display for Invoice {
109         fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
110                 self.signed_invoice.fmt(f)
111         }
112 }
113
114 impl Display for SignedRawInvoice {
115         fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
116                 let hrp = self.raw_invoice.hrp.to_string();
117                 let mut data  = self.raw_invoice.data.to_base32();
118                 data.extend_from_slice(&self.signature.to_base32());
119
120                 bech32::encode_to_fmt(f, &hrp, data).expect("HRP is valid")?;
121
122                 Ok(())
123         }
124 }
125
126 impl Display for RawHrp {
127         fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
128                 let amount = match self.raw_amount {
129                         Some(ref amt) => amt.to_string(),
130                         None => String::new(),
131                 };
132
133                 let si_prefix = match self.si_prefix {
134                         Some(ref si) => si.to_string(),
135                         None => String::new(),
136                 };
137
138                 write!(
139                         f,
140                         "ln{}{}{}",
141                         self.currency,
142                         amount,
143                         si_prefix
144                 )
145         }
146 }
147
148 impl Display for Currency {
149         fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
150                 let currency_code = match *self {
151                         Currency::Bitcoin => "bc",
152                         Currency::BitcoinTestnet => "tb",
153                         Currency::Regtest => "bcrt",
154                         Currency::Simnet => "sb",
155                 };
156                 write!(f, "{}", currency_code)
157         }
158 }
159
160 impl Display for SiPrefix {
161         fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
162                 write!(f, "{}",
163                         match *self {
164                                 SiPrefix::Milli => "m",
165                                 SiPrefix::Micro => "u",
166                                 SiPrefix::Nano => "n",
167                                 SiPrefix::Pico => "p",
168                         }
169                 )
170         }
171 }
172
173 fn encode_int_be_base32(int: u64) -> Vec<u5> {
174         let base = 32u64;
175
176         let mut out_vec = Vec::<u5>::new();
177
178         let mut rem_int = int;
179         while rem_int != 0 {
180                 out_vec.push(u5::try_from_u8((rem_int % base) as u8).expect("always <32"));
181                 rem_int /= base;
182         }
183
184         out_vec.reverse();
185         out_vec
186 }
187
188 fn encoded_int_be_base32_size(int: u64) -> usize {
189         for pos in (0..13).rev() {
190                 if int & (0x1f << (5 * pos)) != 0 {
191                         return (pos + 1) as usize;
192                 }
193         }
194         0usize
195 }
196
197 fn encode_int_be_base256<T: Into<u64>>(int: T) -> Vec<u8> {
198         let base = 256u64;
199
200         let mut out_vec = Vec::<u8>::new();
201
202         let mut rem_int: u64 = int.into();
203         while rem_int != 0 {
204                 out_vec.push((rem_int % base) as u8);
205                 rem_int /= base;
206         }
207
208         out_vec.reverse();
209         out_vec
210 }
211
212 /// Appends the default value of `T` to the front of the `in_vec` till it reaches the length
213 /// `target_length`. If `in_vec` already is too lang `None` is returned.
214 fn try_stretch<T>(mut in_vec: Vec<T>, target_len: usize) -> Option<Vec<T>>
215         where T: Default + Copy
216 {
217         if in_vec.len() > target_len {
218                 None
219         } else if in_vec.len() == target_len {
220                 Some(in_vec)
221         } else {
222                 let mut out_vec = Vec::<T>::with_capacity(target_len);
223                 out_vec.append(&mut vec![T::default(); target_len - in_vec.len()]);
224                 out_vec.append(&mut in_vec);
225                 Some(out_vec)
226         }
227 }
228
229 impl ToBase32 for RawDataPart {
230         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
231                 // encode timestamp
232                 self.timestamp.write_base32(writer)?;
233
234                 // encode tagged fields
235                 for tagged_field in self.tagged_fields.iter() {
236                         tagged_field.write_base32(writer)?;
237                 }
238
239                 Ok(())
240         }
241 }
242
243 impl ToBase32 for PositiveTimestamp {
244         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
245                 // FIXME: use writer for int encoding
246                 writer.write(
247                         &try_stretch(encode_int_be_base32(self.as_unix_timestamp()), 7)
248                                 .expect("Can't be longer due than 7 u5s due to timestamp bounds")
249                 )
250         }
251 }
252
253 impl ToBase32 for RawTaggedField {
254         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
255                 match *self {
256                         RawTaggedField::UnknownSemantics(ref content) => {
257                                 writer.write(content)
258                         },
259                         RawTaggedField::KnownSemantics(ref tagged_field) => {
260                                 tagged_field.write_base32(writer)
261                         }
262                 }
263         }
264 }
265
266 impl ToBase32 for Sha256 {
267         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
268                 (&self.0[..]).write_base32(writer)
269         }
270 }
271 impl Base32Len for Sha256 {
272         fn base32_len(&self) -> usize {
273                 (&self.0[..]).base32_len()
274         }
275 }
276
277 impl ToBase32 for Description {
278         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
279                 self.as_bytes().write_base32(writer)
280         }
281 }
282
283 impl Base32Len for Description {
284         fn base32_len(&self) -> usize {
285                 self.0.as_bytes().base32_len()
286         }
287 }
288
289 impl ToBase32 for PayeePubKey {
290         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
291                 (&self.serialize()[..]).write_base32(writer)
292         }
293 }
294
295 impl Base32Len for PayeePubKey {
296         fn base32_len(&self) -> usize {
297                 bytes_size_to_base32_size(secp256k1::constants::PUBLIC_KEY_SIZE)
298         }
299 }
300
301 impl ToBase32 for ExpiryTime {
302         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
303                 writer.write(&encode_int_be_base32(self.as_seconds()))
304         }
305 }
306
307 impl Base32Len for ExpiryTime {
308         fn base32_len(&self) -> usize {
309                 encoded_int_be_base32_size(self.0.as_secs())
310         }
311 }
312
313 impl ToBase32 for MinFinalCltvExpiry {
314         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
315                 writer.write(&encode_int_be_base32(self.0))
316         }
317 }
318
319 impl Base32Len for MinFinalCltvExpiry {
320         fn base32_len(&self) -> usize {
321                 encoded_int_be_base32_size(self.0)
322         }
323 }
324
325 impl ToBase32 for Fallback {
326         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
327                 match *self {
328                         Fallback::SegWitProgram {version: v, program: ref p} => {
329                                 writer.write_u5(v)?;
330                                 p.write_base32(writer)
331                         },
332                         Fallback::PubKeyHash(ref hash) => {
333                                 writer.write_u5(u5::try_from_u8(17).expect("17 < 32"))?;
334                                 (&hash[..]).write_base32(writer)
335                         },
336                         Fallback::ScriptHash(ref hash) => {
337                                 writer.write_u5(u5::try_from_u8(18).expect("18 < 32"))?;
338                                 (&hash[..]).write_base32(writer)
339                         }
340                 }
341         }
342 }
343
344 impl Base32Len for Fallback {
345         fn base32_len(&self) -> usize {
346                 match *self {
347                         Fallback::SegWitProgram {program: ref p, ..} => {
348                                 bytes_size_to_base32_size(p.len()) + 1
349                         },
350                         Fallback::PubKeyHash(_) | Fallback::ScriptHash(_) => {
351                                 33
352                         },
353                 }
354         }
355 }
356
357 impl ToBase32 for RouteHint {
358         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
359                 let mut converter = BytesToBase32::new(writer);
360
361                 for hop in self.iter() {
362                         converter.append(&hop.src_node_id.serialize()[..])?;
363                         let short_channel_id = try_stretch(
364                                 encode_int_be_base256(hop.short_channel_id),
365                                 8
366                         ).expect("sizeof(u64) == 8");
367                         converter.append(&short_channel_id)?;
368
369                         let fee_base_msat = try_stretch(
370                                 encode_int_be_base256(hop.fees.base_msat),
371                                 4
372                         ).expect("sizeof(u32) == 4");
373                         converter.append(&fee_base_msat)?;
374
375                         let fee_proportional_millionths = try_stretch(
376                                 encode_int_be_base256(hop.fees.proportional_millionths),
377                                 4
378                         ).expect("sizeof(u32) == 4");
379                         converter.append(&fee_proportional_millionths)?;
380
381                         let cltv_expiry_delta = try_stretch(
382                                 encode_int_be_base256(hop.cltv_expiry_delta),
383                                 2
384                         ).expect("sizeof(u16) == 2");
385                         converter.append(&cltv_expiry_delta)?;
386                 }
387
388                 converter.finalize()?;
389                 Ok(())
390         }
391 }
392
393 impl Base32Len for RouteHint {
394         fn base32_len(&self) -> usize {
395                 bytes_size_to_base32_size(self.0.len() * 51)
396         }
397 }
398
399 impl ToBase32 for TaggedField {
400         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
401                 /// Writes a tagged field: tag, length and data. `tag` should be in `0..32` otherwise the
402                 /// function will panic.
403                 fn write_tagged_field<W, P>(writer: &mut W, tag: u8, payload: &P) -> Result<(), W::Err>
404                         where W: WriteBase32,
405                                   P: ToBase32 + Base32Len,
406                 {
407                         let len = payload.base32_len();
408                         assert!(len < 1024, "Every tagged field data can be at most 1023 bytes long.");
409
410                         writer.write_u5(u5::try_from_u8(tag).expect("invalid tag, not in 0..32"))?;
411                         writer.write(&try_stretch(
412                                 encode_int_be_base32(len as u64),
413                                 2
414                         ).expect("Can't be longer than 2, see assert above."))?;
415                         payload.write_base32(writer)
416                 }
417
418                 match *self {
419                         TaggedField::PaymentHash(ref hash) => {
420                                 write_tagged_field(writer, constants::TAG_PAYMENT_HASH, hash)
421                         },
422                         TaggedField::Description(ref description) => {
423                                 write_tagged_field(writer, constants::TAG_DESCRIPTION, description)
424                         },
425                         TaggedField::PayeePubKey(ref pub_key) => {
426                                 write_tagged_field(writer, constants::TAG_PAYEE_PUB_KEY, pub_key)
427                         },
428                         TaggedField::DescriptionHash(ref hash) => {
429                                 write_tagged_field(writer, constants::TAG_DESCRIPTION_HASH, hash)
430                         },
431                         TaggedField::ExpiryTime(ref duration) => {
432                                 write_tagged_field(writer, constants::TAG_EXPIRY_TIME, duration)
433                         },
434                         TaggedField::MinFinalCltvExpiry(ref expiry) => {
435                                 write_tagged_field(writer, constants::TAG_MIN_FINAL_CLTV_EXPIRY, expiry)
436                         },
437                         TaggedField::Fallback(ref fallback_address) => {
438                                 write_tagged_field(writer, constants::TAG_FALLBACK, fallback_address)
439                         },
440                         TaggedField::Route(ref route_hops) => {
441                                 write_tagged_field(writer, constants::TAG_ROUTE, route_hops)
442                         },
443                         TaggedField::PaymentSecret(ref payment_secret) => {
444                                   write_tagged_field(writer, constants::TAG_PAYMENT_SECRET, payment_secret)
445                         },
446                         TaggedField::Features(ref features) => {
447                                 write_tagged_field(writer, constants::TAG_FEATURES, features)
448                         },
449                 }
450         }
451 }
452
453 impl ToBase32 for InvoiceSignature {
454         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
455                 let mut converter = BytesToBase32::new(writer);
456                 let (recovery_id, signature) = self.0.serialize_compact();
457                 converter.append(&signature[..])?;
458                 converter.append_u8(recovery_id.to_i32() as u8)?;
459                 converter.finalize()
460         }
461 }
462
463 #[cfg(test)]
464 mod test {
465         use bech32::CheckBase32;
466
467         #[test]
468         fn test_currency_code() {
469                 use Currency;
470
471                 assert_eq!("bc", Currency::Bitcoin.to_string());
472                 assert_eq!("tb", Currency::BitcoinTestnet.to_string());
473                 assert_eq!("bcrt", Currency::Regtest.to_string());
474                 assert_eq!("sb", Currency::Simnet.to_string());
475         }
476
477         #[test]
478         fn test_raw_hrp() {
479                 use ::{Currency, RawHrp, SiPrefix};
480
481                 let hrp = RawHrp {
482                         currency: Currency::Bitcoin,
483                         raw_amount: Some(100),
484                         si_prefix: Some(SiPrefix::Micro),
485                 };
486
487                 assert_eq!(hrp.to_string(), "lnbc100u");
488         }
489
490         #[test]
491         fn test_encode_int_be_base32() {
492                 use ser::encode_int_be_base32;
493
494                 let input: u64 = 33764;
495                 let expected_out = CheckBase32::check_base32(&[1, 0, 31, 4]).unwrap();
496
497                 assert_eq!(expected_out, encode_int_be_base32(input));
498         }
499
500         #[test]
501         fn test_encode_int_be_base256() {
502                 use ser::encode_int_be_base256;
503
504                 let input: u64 = 16842530;
505                 let expected_out = vec![1, 0, 255, 34];
506
507                 assert_eq!(expected_out, encode_int_be_base256(input));
508         }
509 }