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