Upgrade rust-bitcoin to 0.31
[rust-lightning] / lightning-invoice / tests / ser_de.rs
1 extern crate bech32;
2 extern crate lightning;
3 extern crate lightning_invoice;
4 extern crate secp256k1;
5 extern crate hex;
6
7 use bitcoin::{PubkeyHash, ScriptHash, WitnessVersion};
8 use bitcoin::hashes::hex::FromHex;
9 use bitcoin::hashes::{sha256, Hash};
10 use lightning_invoice::*;
11 use secp256k1::PublicKey;
12 use secp256k1::ecdsa::{RecoverableSignature, RecoveryId};
13 use std::collections::HashSet;
14 use std::time::Duration;
15 use std::str::FromStr;
16
17 fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> {
18         vec![
19                 (
20                         "lnbc1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq9qrsgq357wnc5r2ueh7ck6q93dj32dlqnls087fxdwk8qakdyafkq3yap9us6v52vjjsrvywa6rt52cm9r9zqt8r2t7mlcwspyetp5h2tztugp9lfyql".to_owned(),
21                         InvoiceBuilder::new(Currency::Bitcoin)
22                                 .duration_since_epoch(Duration::from_secs(1496314658))
23                                 .payment_secret(PaymentSecret([0x11; 32]))
24                                 .payment_hash(sha256::Hash::from_str(
25                                                 "0001020304050607080900010203040506070809000102030405060708090102"
26                                 ).unwrap())
27                                 .description("Please consider supporting this project".to_owned())
28                                 .build_raw()
29                                 .unwrap()
30                                 .sign(|_| {
31                                         RecoverableSignature::from_compact(
32                                                 &<Vec<u8>>::from_hex("8d3ce9e28357337f62da0162d9454df827f83cfe499aeb1c1db349d4d81127425e434ca29929406c23bba1ae8ac6ca32880b38d4bf6ff874024cac34ba9625f1").unwrap(),
33                                                 RecoveryId::from_i32(1).unwrap()
34                                         )
35                                 }).unwrap(),
36                         false, // Same features as set in InvoiceBuilder
37                         false, // No unknown fields
38                 ),
39                 (
40                         "lnbc2500u1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpu9qrsgquk0rl77nj30yxdy8j9vdx85fkpmdla2087ne0xh8nhedh8w27kyke0lp53ut353s06fv3qfegext0eh0ymjpf39tuven09sam30g4vgpfna3rh".to_owned(),
41                         InvoiceBuilder::new(Currency::Bitcoin)
42                                 .amount_milli_satoshis(250_000_000)
43                                 .duration_since_epoch(Duration::from_secs(1496314658))
44                                 .payment_secret(PaymentSecret([0x11; 32]))
45                                 .payment_hash(sha256::Hash::from_str(
46                                         "0001020304050607080900010203040506070809000102030405060708090102"
47                                 ).unwrap())
48                                 .description("1 cup coffee".to_owned())
49                                 .expiry_time(Duration::from_secs(60))
50                                 .build_raw()
51                                 .unwrap()
52                                 .sign(|_| {
53                                         RecoverableSignature::from_compact(
54                                                 &<Vec<u8>>::from_hex("e59e3ffbd3945e4334879158d31e89b076dff54f3fa7979ae79df2db9dcaf5896cbfe1a478b8d2307e92c88139464cb7e6ef26e414c4abe33337961ddc5e8ab1").unwrap(),
55                                                 RecoveryId::from_i32(1).unwrap()
56                                         )
57                                 }).unwrap(),
58                         false, // Same features as set in InvoiceBuilder
59                         false, // No unknown fields
60                 ),
61                 (
62                         "lnbc2500u1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpu9qrsgqhtjpauu9ur7fw2thcl4y9vfvh4m9wlfyz2gem29g5ghe2aak2pm3ps8fdhtceqsaagty2vph7utlgj48u0ged6a337aewvraedendscp573dxr".to_owned(),
63                         InvoiceBuilder::new(Currency::Bitcoin)
64                                 .amount_milli_satoshis(250_000_000)
65                                 .duration_since_epoch(Duration::from_secs(1496314658))
66                                 .payment_secret(PaymentSecret([0x11; 32]))
67                                 .payment_hash(sha256::Hash::from_str(
68                                         "0001020304050607080900010203040506070809000102030405060708090102"
69                                 ).unwrap())
70                                 .description("ナンセンス 1杯".to_owned())
71                                 .expiry_time(Duration::from_secs(60))
72                                 .build_raw()
73                                 .unwrap()
74                                 .sign(|_| {
75                                         RecoverableSignature::from_compact(
76                                                 &<Vec<u8>>::from_hex("bae41ef385e0fc972977c7ea42b12cbd76577d2412919da8a8a22f9577b6507710c0e96dd78c821dea16453037f717f44aa7e3d196ebb18fbb97307dcb7336c3").unwrap(),
77                                                 RecoveryId::from_i32(1).unwrap()
78                                         )
79                                 }).unwrap(),
80                         false, // Same features as set in InvoiceBuilder
81                         false, // No unknown fields
82                 ),
83                 (
84                         "lnbc20m1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqs9qrsgq7ea976txfraylvgzuxs8kgcw23ezlrszfnh8r6qtfpr6cxga50aj6txm9rxrydzd06dfeawfk6swupvz4erwnyutnjq7x39ymw6j38gp7ynn44".to_owned(),
85                         InvoiceBuilder::new(Currency::Bitcoin)
86                                 .amount_milli_satoshis(2_000_000_000)
87                                 .duration_since_epoch(Duration::from_secs(1496314658))
88                                 .description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
89                                 .payment_secret(PaymentSecret([0x11; 32]))
90                                 .payment_hash(sha256::Hash::from_str(
91                                         "0001020304050607080900010203040506070809000102030405060708090102"
92                                 ).unwrap())
93                                 .build_raw()
94                                 .unwrap()
95                                 .sign(|_| {
96                                         RecoverableSignature::from_compact(
97                                                 &<Vec<u8>>::from_hex("f67a5f696648fa4fb102e1a07b230e54722f8e024cee71e80b4847ac191da3fb2d2cdb28cc32344d7e9a9cf5c9b6a0ee0582ae46e9938b9c81e344a4dbb5289d").unwrap(),
98                                                 RecoveryId::from_i32(1).unwrap()
99                                         )
100                                 }).unwrap(),
101                         false, // Same features as set in InvoiceBuilder
102                         false, // No unknown fields
103                 ),
104                 (
105                         "lntb20m1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygshp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfpp3x9et2e20v6pu37c5d9vax37wxq72un989qrsgqdj545axuxtnfemtpwkc45hx9d2ft7x04mt8q7y6t0k2dge9e7h8kpy9p34ytyslj3yu569aalz2xdk8xkd7ltxqld94u8h2esmsmacgpghe9k8".to_owned(),
106                         InvoiceBuilder::new(Currency::BitcoinTestnet)
107                                 .amount_milli_satoshis(2_000_000_000)
108                                 .duration_since_epoch(Duration::from_secs(1496314658))
109                                 .description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
110                                 .payment_secret(PaymentSecret([0x11; 32]))
111                                 .payment_hash(sha256::Hash::from_str(
112                                         "0001020304050607080900010203040506070809000102030405060708090102"
113                                 ).unwrap())
114                                 .fallback(Fallback::PubKeyHash(PubkeyHash::from_slice(&[49, 114, 181, 101, 79, 102, 131, 200, 251, 20, 105, 89, 211, 71, 206, 48, 60, 174, 76, 167]).unwrap()))
115                                 .build_raw()
116                                 .unwrap()
117                                 .sign(|_| {
118                                         RecoverableSignature::from_compact(
119                                                 &<Vec<u8>>::from_hex("6ca95a74dc32e69ced6175b15a5cc56a92bf19f5dace0f134b7d94d464b9f5cf6090a18d48b243f289394d17bdf89466d8e6b37df5981f696bc3dd5986e1bee1").unwrap(),
120                                                 RecoveryId::from_i32(1).unwrap()
121                                         )
122                                 }).unwrap(),
123                         false, // Same features as set in InvoiceBuilder
124                         false, // No unknown fields
125                 ),
126                 (
127                         "lnbc20m1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsfpp3qjmp7lwpagxun9pygexvgpjdc4jdj85fr9yq20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqpqqqqq9qqqvpeuqafqxu92d8lr6fvg0r5gv0heeeqgcrqlnm6jhphu9y00rrhy4grqszsvpcgpy9qqqqqqgqqqqq7qqzq9qrsgqdfjcdk6w3ak5pca9hwfwfh63zrrz06wwfya0ydlzpgzxkn5xagsqz7x9j4jwe7yj7vaf2k9lqsdk45kts2fd0fkr28am0u4w95tt2nsq76cqw0".to_owned(),
128                         InvoiceBuilder::new(Currency::Bitcoin)
129                                 .amount_milli_satoshis(2_000_000_000)
130                                 .duration_since_epoch(Duration::from_secs(1496314658))
131                                 .description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
132                                 .payment_secret(PaymentSecret([0x11; 32]))
133                                 .payment_hash(sha256::Hash::from_str(
134                                         "0001020304050607080900010203040506070809000102030405060708090102"
135                                 ).unwrap())
136                                 .fallback(Fallback::PubKeyHash(PubkeyHash::from_slice(&[4, 182, 31, 125, 193, 234, 13, 201, 148, 36, 70, 76, 196, 6, 77, 197, 100, 217, 30, 137]).unwrap()))
137                                 .private_route(RouteHint(vec![RouteHintHop {
138                                         src_node_id: PublicKey::from_slice(&<Vec<u8>>::from_hex(
139                                                         "029e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255"
140                                                 ).unwrap()).unwrap(),
141                                         short_channel_id: (66051 << 40) | (263430 << 16) | 1800,
142                                         fees: RoutingFees { base_msat: 1, proportional_millionths: 20 },
143                                         cltv_expiry_delta: 3,
144                                         htlc_maximum_msat: None, htlc_minimum_msat: None,
145                                 }, RouteHintHop {
146                                         src_node_id: PublicKey::from_slice(&<Vec<u8>>::from_hex(
147                                                         "039e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255"
148                                                 ).unwrap()).unwrap(),
149                                         short_channel_id: (197637 << 40) | (395016 << 16) | 2314,
150                                         fees: RoutingFees { base_msat: 2, proportional_millionths: 30 },
151                                         cltv_expiry_delta: 4,
152                                         htlc_maximum_msat: None, htlc_minimum_msat: None,
153                                 }]))
154                                 .build_raw()
155                                 .unwrap()
156                                 .sign(|_| {
157                                         RecoverableSignature::from_compact(
158                                                 &<Vec<u8>>::from_hex("6a6586db4e8f6d40e3a5bb92e4df5110c627e9ce493af237e20a046b4e86ea200178c59564ecf892f33a9558bf041b6ad2cb8292d7a6c351fbb7f2ae2d16b54e").unwrap(),
159                                                 RecoveryId::from_i32(0).unwrap()
160                                         )
161                                 }).unwrap(),
162                         false, // Same features as set in InvoiceBuilder
163                         false, // No unknown fields
164                 ),
165                 (
166                         "lnbc20m1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygshp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfppj3a24vwu6r8ejrss3axul8rxldph2q7z99qrsgqz6qsgww34xlatfj6e3sngrwfy3ytkt29d2qttr8qz2mnedfqysuqypgqex4haa2h8fx3wnypranf3pdwyluftwe680jjcfp438u82xqphf75ym".to_owned(),
167                         InvoiceBuilder::new(Currency::Bitcoin)
168                                 .amount_milli_satoshis(2_000_000_000)
169                                 .duration_since_epoch(Duration::from_secs(1496314658))
170                                 .description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
171                                 .payment_secret(PaymentSecret([0x11; 32]))
172                                 .payment_hash(sha256::Hash::from_str(
173                                         "0001020304050607080900010203040506070809000102030405060708090102"
174                                 ).unwrap())
175                                 .fallback(Fallback::ScriptHash(ScriptHash::from_slice(&[143, 85, 86, 59, 154, 25, 243, 33, 194, 17, 233, 185, 243, 140, 223, 104, 110, 160, 120, 69]).unwrap()))
176                                 .build_raw()
177                                 .unwrap()
178                                 .sign(|_| {
179                                         RecoverableSignature::from_compact(
180                                                 &<Vec<u8>>::from_hex("16810439d1a9bfd5a65acc61340dc92448bb2d456a80b58ce012b73cb5202438020500c9ab7ef5573a4d174c811f669885ae27f895bb3a3be52c243589f87518").unwrap(),
181                                                 RecoveryId::from_i32(1).unwrap()
182                                         )
183                                 }).unwrap(),
184                         false, // Same features as set in InvoiceBuilder
185                         false, // No unknown fields
186                 ),
187                 (
188                         "lnbc20m1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygshp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfppqw508d6qejxtdg4y5r3zarvary0c5xw7k9qrsgqt29a0wturnys2hhxpner2e3plp6jyj8qx7548zr2z7ptgjjc7hljm98xhjym0dg52sdrvqamxdezkmqg4gdrvwwnf0kv2jdfnl4xatsqmrnsse".to_owned(),
189                         InvoiceBuilder::new(Currency::Bitcoin)
190                                 .amount_milli_satoshis(2_000_000_000)
191                                 .duration_since_epoch(Duration::from_secs(1496314658))
192                                 .description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
193                                 .payment_secret(PaymentSecret([0x11; 32]))
194                                 .payment_hash(sha256::Hash::from_str(
195                                         "0001020304050607080900010203040506070809000102030405060708090102"
196                                 ).unwrap())
197                                 .fallback(Fallback::SegWitProgram { version: WitnessVersion::V0,
198                                         program: vec![117, 30, 118, 232, 25, 145, 150, 212, 84, 148, 28, 69, 209, 179, 163, 35, 241, 67, 59, 214]
199                                 })
200                                 .build_raw()
201                                 .unwrap()
202                                 .sign(|_| {
203                                         RecoverableSignature::from_compact(
204                                                 &<Vec<u8>>::from_hex("5a8bd7b97c1cc9055ee60cf2356621f8752248e037a953886a1782b44a58f5ff2d94e6bc89b7b514541a3603bb33722b6c08aa1a3639d34becc549a99fea6eae").unwrap(),
205                                                 RecoveryId::from_i32(0).unwrap()
206                                         )
207                                 }).unwrap(),
208                         false, // Same features as set in InvoiceBuilder
209                         false, // No unknown fields
210                 ),
211                 (
212                         "lnbc20m1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygshp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfp4qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q9qrsgq9vlvyj8cqvq6ggvpwd53jncp9nwc47xlrsnenq2zp70fq83qlgesn4u3uyf4tesfkkwwfg3qs54qe426hp3tz7z6sweqdjg05axsrjqp9yrrwc".to_owned(),
213                         InvoiceBuilder::new(Currency::Bitcoin)
214                                 .amount_milli_satoshis(2_000_000_000)
215                                 .duration_since_epoch(Duration::from_secs(1496314658))
216                                 .description_hash(sha256::Hash::hash(b"One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon"))
217                                 .payment_secret(PaymentSecret([0x11; 32]))
218                                 .payment_hash(sha256::Hash::from_str(
219                                         "0001020304050607080900010203040506070809000102030405060708090102"
220                                 ).unwrap())
221                                 .fallback(Fallback::SegWitProgram { version: WitnessVersion::V0,
222                                         program: vec![24, 99, 20, 60, 20, 197, 22, 104, 4, 189, 25, 32, 51, 86, 218, 19, 108, 152, 86, 120, 205, 77, 39, 161, 184, 198, 50, 150, 4, 144, 50, 98]
223                                 })
224                                 .build_raw()
225                                 .unwrap()
226                                 .sign(|_| {
227                                         RecoverableSignature::from_compact(
228                                                 &<Vec<u8>>::from_hex("2b3ec248f80301a421817369194f012cdd8af8df1c279981420f9e901e20fa3309d791e11355e609b59ce4a220852a0cd55ab862b1785a83b206c90fa74d01c8").unwrap(),
229                                                 RecoveryId::from_i32(1).unwrap()
230                                         )
231                                 }).unwrap(),
232                         false, // Same features as set in InvoiceBuilder
233                         false, // No unknown fields
234                 ),
235                 (
236                         "lnbc9678785340p1pwmna7lpp5gc3xfm08u9qy06djf8dfflhugl6p7lgza6dsjxq454gxhj9t7a0sd8dgfkx7cmtwd68yetpd5s9xar0wfjn5gpc8qhrsdfq24f5ggrxdaezqsnvda3kkum5wfjkzmfqf3jkgem9wgsyuctwdus9xgrcyqcjcgpzgfskx6eqf9hzqnteypzxz7fzypfhg6trddjhygrcyqezcgpzfysywmm5ypxxjemgw3hxjmn8yptk7untd9hxwg3q2d6xjcmtv4ezq7pqxgsxzmnyyqcjqmt0wfjjq6t5v4khxsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsxqyjw5qcqp2rzjq0gxwkzc8w6323m55m4jyxcjwmy7stt9hwkwe2qxmy8zpsgg7jcuwz87fcqqeuqqqyqqqqlgqqqqn3qq9q9qrsgqrvgkpnmps664wgkp43l22qsgdw4ve24aca4nymnxddlnp8vh9v2sdxlu5ywdxefsfvm0fq3sesf08uf6q9a2ke0hc9j6z6wlxg5z5kqpu2v9wz".to_owned(),
237                         InvoiceBuilder::new(Currency::Bitcoin)
238                                 .amount_milli_satoshis(967878534)
239                                 .duration_since_epoch(Duration::from_secs(1572468703))
240                                 .payment_secret(PaymentSecret([0x11; 32]))
241                                 .payment_hash(sha256::Hash::from_str(
242                                         "462264ede7e14047e9b249da94fefc47f41f7d02ee9b091815a5506bc8abf75f"
243                                 ).unwrap())
244                                 .expiry_time(Duration::from_secs(604800))
245                                 .min_final_cltv_expiry_delta(10)
246                                 .description("Blockstream Store: 88.85 USD for Blockstream Ledger Nano S x 1, \"Back In My Day\" Sticker x 2, \"I Got Lightning Working\" Sticker x 2 and 1 more items".to_owned())
247                                 .private_route(RouteHint(vec![RouteHintHop {
248                                         src_node_id: PublicKey::from_slice(&<Vec<u8>>::from_hex(
249                                                         "03d06758583bb5154774a6eb221b1276c9e82d65bbaceca806d90e20c108f4b1c7"
250                                                 ).unwrap()).unwrap(),
251                                         short_channel_id: (589390 << 40) | (3312 << 16) | 1,
252                                         fees: RoutingFees { base_msat: 1000, proportional_millionths: 2500 },
253                                         cltv_expiry_delta: 40,
254                                         htlc_maximum_msat: None, htlc_minimum_msat: None,
255                                 }]))
256                                 .build_raw()
257                                 .unwrap()
258                                 .sign(|_| {
259                                         RecoverableSignature::from_compact(
260                                                 &<Vec<u8>>::from_hex("1b1160cf6186b55722c1ac7ea502086baaccaabdc76b326e666b7f309d972b15069bfca11cd365304b36f48230cc12f3f13a017aab65f7c165a169df32282a58").unwrap(),
261                                                 RecoveryId::from_i32(1).unwrap()
262                                         )
263                                 }).unwrap(),
264                         false, // Same features as set in InvoiceBuilder
265                         false, // No unknown fields
266                 ),
267                 (
268                         "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q5sqqqqqqqqqqqqqqqqsgq2a25dxl5hrntdtn6zvydt7d66hyzsyhqs4wdynavys42xgl6sgx9c4g7me86a27t07mdtfry458rtjr0v92cnmswpsjscgt2vcse3sgpz3uapa".to_owned(),
269                         InvoiceBuilder::new(Currency::Bitcoin)
270                                 .amount_milli_satoshis(2_500_000_000)
271                                 .duration_since_epoch(Duration::from_secs(1496314658))
272                                 .payment_secret(PaymentSecret([0x11; 32]))
273                                 .payment_hash(sha256::Hash::from_str(
274                                         "0001020304050607080900010203040506070809000102030405060708090102"
275                                 ).unwrap())
276                                 .description("coffee beans".to_owned())
277                                 .build_raw()
278                                 .unwrap()
279                                 .sign(|_| {
280                                         RecoverableSignature::from_compact(
281                                                 &<Vec<u8>>::from_hex("5755469bf4b8e6b6ae7a1308d5f9bad5c82812e0855cd24fac242aa323fa820c5c551ede4faeabcb7fb6d5a464ad0e35c86f615589ee0e0c250c216a662198c1").unwrap(),
282                                                 RecoveryId::from_i32(1).unwrap()
283                                         )
284                                 }).unwrap(),
285                         true, // Different features than set in InvoiceBuilder
286                         false, // No unknown fields
287                 ),
288                 (
289                         "LNBC25M1PVJLUEZPP5QQQSYQCYQ5RQWZQFQQQSYQCYQ5RQWZQFQQQSYQCYQ5RQWZQFQYPQDQ5VDHKVEN9V5SXYETPDEESSP5ZYG3ZYG3ZYG3ZYG3ZYG3ZYG3ZYG3ZYG3ZYG3ZYG3ZYG3ZYG3ZYGS9Q5SQQQQQQQQQQQQQQQQSGQ2A25DXL5HRNTDTN6ZVYDT7D66HYZSYHQS4WDYNAVYS42XGL6SGX9C4G7ME86A27T07MDTFRY458RTJR0V92CNMSWPSJSCGT2VCSE3SGPZ3UAPA".to_owned(),
290                         InvoiceBuilder::new(Currency::Bitcoin)
291                                 .amount_milli_satoshis(2_500_000_000)
292                                 .duration_since_epoch(Duration::from_secs(1496314658))
293                                 .payment_secret(PaymentSecret([0x11; 32]))
294                                 .payment_hash(sha256::Hash::from_str(
295                                         "0001020304050607080900010203040506070809000102030405060708090102"
296                                 ).unwrap())
297                                 .description("coffee beans".to_owned())
298                                 .build_raw()
299                                 .unwrap()
300                                 .sign(|_| {
301                                         RecoverableSignature::from_compact(
302                                                 &<Vec<u8>>::from_hex("5755469bf4b8e6b6ae7a1308d5f9bad5c82812e0855cd24fac242aa323fa820c5c551ede4faeabcb7fb6d5a464ad0e35c86f615589ee0e0c250c216a662198c1").unwrap(),
303                                                 RecoveryId::from_i32(1).unwrap()
304                                         )
305                                 }).unwrap(),
306                         true, // Different features than set in InvoiceBuilder
307                         false, // No unknown fields
308                 ),
309                 (
310                         "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q5sqqqqqqqqqqqqqqqqsgq2qrqqqfppnqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqppnqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqhpnqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqhp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqspnqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqsp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqnp5qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqnpkqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqz599y53s3ujmcfjp5xrdap68qxymkqphwsexhmhr8wdz5usdzkzrse33chw6dlp3jhuhge9ley7j2ayx36kawe7kmgg8sv5ugdyusdcqzn8z9x".to_owned(),
311                         InvoiceBuilder::new(Currency::Bitcoin)
312                                 .amount_milli_satoshis(2_500_000_000)
313                                 .duration_since_epoch(Duration::from_secs(1496314658))
314                                 .payment_secret(PaymentSecret([0x11; 32]))
315                                 .payment_hash(sha256::Hash::from_str(
316                                         "0001020304050607080900010203040506070809000102030405060708090102"
317                                 ).unwrap())
318                                 .description("coffee beans".to_owned())
319                                 .build_raw()
320                                 .unwrap()
321                                 .sign(|_| {
322                                         RecoverableSignature::from_compact(
323                                                 &<Vec<u8>>::from_hex("150a5252308f25bc2641a186de87470189bb003774326beee33b9a2a720d1584386631c5dda6fc3195f97464bfc93d2574868eadd767d6da1078329c4349c837").unwrap(),
324                                                 RecoveryId::from_i32(0).unwrap()
325                                         )
326                                 }).unwrap(),
327                         true, // Different features than set in InvoiceBuilder
328                         true, // Some unknown fields
329                 ),
330                 ( // Older version of the payment metadata test with a payment_pubkey set
331                         "lnbc10m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdp9wpshjmt9de6zqmt9w3skgct5vysxjmnnd9jx2mq8q8a04uqnp4q0n326hr8v9zprg8gsvezcch06gfaqqhde2aj730yg0durunfhv66sp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q2gqqqqqqsgqy9gw6ymamd20jumvdgpfphkhp8fzhhdhycw36egcmla5vlrtrmhs9t7psfy3hkkdqzm9eq64fjg558znccds5nhsfmxveha5xe0dykgpspdha0".to_owned(),
332                         InvoiceBuilder::new(Currency::Bitcoin)
333                                 .amount_milli_satoshis(1_000_000_000)
334                                 .duration_since_epoch(Duration::from_secs(1496314658))
335                                 .payment_hash(sha256::Hash::from_str(
336                                         "0001020304050607080900010203040506070809000102030405060708090102"
337                                 ).unwrap())
338                                 .description("payment metadata inside".to_owned())
339                                 .payment_metadata(<Vec<u8>>::from_hex("01fafaf0").unwrap())
340                                 .require_payment_metadata()
341                                 .payee_pub_key(PublicKey::from_slice(&<Vec<u8>>::from_hex(
342                                                 "03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad"
343                                         ).unwrap()).unwrap())
344                                 .payment_secret(PaymentSecret([0x11; 32]))
345                                 .build_raw()
346                                 .unwrap()
347                                 .sign(|_| {
348                                         RecoverableSignature::from_compact(
349                                                 &<Vec<u8>>::from_hex("2150ed137ddb54f9736c6a0290ded709d22bddb7261d1d6518dffb467c6b1eef02afc182491bdacd00b65c83554c914a1c53c61b0a4ef04eccccdfb4365ed259").unwrap(),
350                                                 RecoveryId::from_i32(1).unwrap()
351                                         )
352                                 }).unwrap(),
353                         false, // Different features than set in InvoiceBuilder
354                         true, // Some unknown fields
355                 ),
356                 (
357                         "lnbc10m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdp9wpshjmt9de6zqmt9w3skgct5vysxjmnnd9jx2mq8q8a04uqsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q2gqqqqqqsgq7hf8he7ecf7n4ffphs6awl9t6676rrclv9ckg3d3ncn7fct63p6s365duk5wrk202cfy3aj5xnnp5gs3vrdvruverwwq7yzhkf5a3xqpd05wjc".to_owned(),
358                         InvoiceBuilder::new(Currency::Bitcoin)
359                                 .amount_milli_satoshis(1_000_000_000)
360                                 .duration_since_epoch(Duration::from_secs(1496314658))
361                                 .payment_hash(sha256::Hash::from_str(
362                                         "0001020304050607080900010203040506070809000102030405060708090102"
363                                 ).unwrap())
364                                 .description("payment metadata inside".to_owned())
365                                 .payment_metadata(<Vec<u8>>::from_hex("01fafaf0").unwrap())
366                                 .require_payment_metadata()
367                                 .payment_secret(PaymentSecret([0x11; 32]))
368                                 .build_raw()
369                                 .unwrap()
370                                 .sign(|_| {
371                                         RecoverableSignature::from_compact(
372                                                 &<Vec<u8>>::from_hex("f5d27be7d9c27d3aa521bc35d77cabd6bda18f1f61716445b19e27e4e17a887508ea8de5a8e1d94f561248f65434e61a221160dac1f1991b9c0f1057b269d898").unwrap(),
373                                                 RecoveryId::from_i32(1).unwrap()
374                                         )
375                                 }).unwrap(),
376                         false, // Different features than set in InvoiceBuilder
377                         true, // Some unknown fields
378                 ),
379
380         ]
381 }
382
383 #[test]
384 fn invoice_deserialize() {
385         for (serialized, deserialized, ignore_feature_diff, ignore_unknown_fields) in get_test_tuples() {
386                 eprintln!("Testing invoice {}...", serialized);
387                 let parsed = serialized.parse::<SignedRawBolt11Invoice>().unwrap();
388
389                 let (parsed_invoice, _, parsed_sig) = parsed.into_parts();
390                 let (deserialized_invoice, _, deserialized_sig) = deserialized.into_parts();
391
392                 assert_eq!(deserialized_sig, parsed_sig);
393                 assert_eq!(deserialized_invoice.hrp, parsed_invoice.hrp);
394                 assert_eq!(deserialized_invoice.data.timestamp, parsed_invoice.data.timestamp);
395
396                 let mut deserialized_hunks: HashSet<_> = deserialized_invoice.data.tagged_fields.iter().collect();
397                 let mut parsed_hunks: HashSet<_> = parsed_invoice.data.tagged_fields.iter().collect();
398                 if ignore_feature_diff {
399                         deserialized_hunks.retain(|h|
400                                 if let RawTaggedField::KnownSemantics(TaggedField::Features(_)) = h { false } else { true });
401                         parsed_hunks.retain(|h|
402                                 if let RawTaggedField::KnownSemantics(TaggedField::Features(_)) = h { false } else { true });
403                 }
404                 if ignore_unknown_fields {
405                         parsed_hunks.retain(|h|
406                                 if let RawTaggedField::UnknownSemantics(_) = h { false } else { true });
407                 }
408                 assert_eq!(deserialized_hunks, parsed_hunks);
409
410                 Bolt11Invoice::from_signed(serialized.parse::<SignedRawBolt11Invoice>().unwrap()).unwrap();
411         }
412 }
413
414 #[test]
415 fn test_bolt_invalid_invoices() {
416         // Tests the BOLT 11 invalid invoice test vectors
417         assert_eq!(Bolt11Invoice::from_str(
418                 "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q4psqqqqqqqqqqqqqqqqsgqtqyx5vggfcsll4wu246hz02kp85x4katwsk9639we5n5yngc3yhqkm35jnjw4len8vrnqnf5ejh0mzj9n3vz2px97evektfm2l6wqccp3y7372"
419                 ), Err(ParseOrSemanticError::SemanticError(Bolt11SemanticError::InvalidFeatures)));
420         assert_eq!(Bolt11Invoice::from_str(
421                 "lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrnt"
422                 ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::Bech32Error(bech32::Error::InvalidChecksum))));
423         assert_eq!(Bolt11Invoice::from_str(
424                 "pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny"
425                 ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::Bech32Error(bech32::Error::MissingSeparator))));
426         assert_eq!(Bolt11Invoice::from_str(
427                 "LNBC2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny"
428                 ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::Bech32Error(bech32::Error::MixedCase))));
429         assert_eq!(Bolt11Invoice::from_str(
430                 "lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgqwgt7mcn5yqw3yx0w94pswkpq6j9uh6xfqqqtsk4tnarugeektd4hg5975x9am52rz4qskukxdmjemg92vvqz8nvmsye63r5ykel43pgz7zq0g2"
431                 ), Err(ParseOrSemanticError::SemanticError(Bolt11SemanticError::InvalidSignature)));
432         assert_eq!(Bolt11Invoice::from_str(
433                 "lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6na6hlh"
434                 ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::TooShortDataPart)));
435         assert_eq!(Bolt11Invoice::from_str(
436                 "lnbc2500x1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgqrrzc4cvfue4zp3hggxp47ag7xnrlr8vgcmkjxk3j5jqethnumgkpqp23z9jclu3v0a7e0aruz366e9wqdykw6dxhdzcjjhldxq0w6wgqcnu43j"
437                 ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::UnknownSiPrefix)));
438         assert_eq!(Bolt11Invoice::from_str(
439                 "lnbc2500000001p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgq0lzc236j96a95uv0m3umg28gclm5lqxtqqwk32uuk4k6673k6n5kfvx3d2h8s295fad45fdhmusm8sjudfhlf6dcsxmfvkeywmjdkxcp99202x"
440                 ), Err(ParseOrSemanticError::SemanticError(Bolt11SemanticError::ImpreciseAmount)));
441 }