@@ -11,7 +11,8 @@ use std::error;
11
11
use bech32:: primitives:: decode:: { CheckedHrpstring , CheckedHrpstringError } ;
12
12
use bech32:: { Fe32 , Fe32IterExt } ;
13
13
14
- use crate :: { prelude:: * , Bolt11Bech32 } ;
14
+ use crate :: prelude:: * ;
15
+ use crate :: Bolt11Bech32 ;
15
16
use bitcoin:: hashes:: sha256;
16
17
use bitcoin:: hashes:: Hash ;
17
18
use bitcoin:: { PubkeyHash , ScriptHash , WitnessVersion } ;
@@ -1176,8 +1177,10 @@ mod test {
1176
1177
)
1177
1178
}
1178
1179
1180
+ // Test some long invoice test vectors successfully roundtrip. Generated
1181
+ // from Lexe proptest: <https://github.com/lexe-app/lexe-public/blob/4bc7018307e5221e1e1ee8b17ce366338fb11a16/common/src/ln/invoice.rs#L183>.
1179
1182
#[ test]
1180
- fn test_deser_long ( ) {
1183
+ fn test_deser_long_test_vectors ( ) {
1181
1184
use crate :: Bolt11Invoice ;
1182
1185
1183
1186
#[ track_caller]
@@ -1187,27 +1190,227 @@ mod test {
1187
1190
if invoice_str != invoice_str2 {
1188
1191
panic ! (
1189
1192
"Invoice does not roundtrip: invoice_str != invoice_str2\n \
1190
- invoice_str: {invoice_str}\n \
1193
+ invoice_str: {invoice_str}\n \
1191
1194
invoice_str2: {invoice_str2}\n \
1192
1195
\n \
1193
1196
{invoice:?}"
1194
1197
) ;
1195
1198
}
1196
1199
}
1197
1200
1198
- parse_ok ( "lnbc10000000000000000010p1qqqqqqqdtuxpqkzq8sjzqgps4pvyczqq8sjzqgpuysszq0pyyqsrp2zs0sjzqgps4pxrcfpqyqc2slpyyqsqsv9gwz59s5zqpqyps5rc9qsrs2pqxz5ysyzcfqgysyzs0sjzqgqq8sjzqgps4pxqqzps4pqpssqgzpxps5ruysszqrps4pg8p2zgpsc2snpuysszqzqsgqvys0pyyqsrcfpqyqvycv9gfqqrcfpqyq7zggpq8q5zqyruysszqwpgyqxpsjqsgq7zggpqps7zggpq8sjzqgqgqq7zggpqpq7zggpq8q5zqqpuysszq0pyyqsqs0pyyqspsnqgzpqpqlpyyqsqszpuysszqyzvzpvysrqq8sjzqgqvrp7zggpqpqxpsspp5mf45hs3cgphh0074r5qmr74y82r26ac4pzdg4nd9mdmsvz6ffqpssp5vr4yra4pcv74h9hk3d0233nqu4gktpuykjamrafrdpuedqugzh3q9q2sqqqqqysgqcqrpqqxq8pqqqqqqnp4qgvcxpme2q5lng36j9gruwlrtk2f86s3c5xmk87yhvyuwdeh025q5r9yqwnqegv9hj9nzkhyxaeyq92wcrnqp36pyrc2qzrvswj5g96ey2dn6qqqqqqqqqqqqqqqqqqqqqqqqqqqqqp9a5vs0t4z56p64xyma8s84yvdx7uhqj0gvrr424fea2wpztq2fwqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqmy9qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpcnsxc32du9n7amlypuhclzqrt6lkegq0v3r7nczjv9tv30z7phq80r3dm7pvgykl7gwuenmem93h5xwdwac6ngsmzqc34khrg3qjgsq6qk6lc" ) ;
1199
- parse_ok ( "lnbc8735500635020489010p1av5kfs8deupvyk4u5ynj03hmalhhhml0fxc2jlrv9z4lg6s4hnhkz69malhhet3x9yqpsxru4a3kwar2qtu2q2ughx367q600s5x7c7tln4k0fu78skxqevaqm8sayhuur377zgf3uf94n57xzhdw99u42hwc089djn5xj723w7zageflsnzdmyte89tecf2ac7xhg4y3u9f4xpuv2hwxjlsarp0e24fu8tme6rgv0tqj08z9f4u30rw59k8emhtvs7wye0xfw6x5q5tju2p208rvtkunzwtwghtp22tlnh62gxwhfkxp4cnz7ts3rxvlzszhv9y00h77lpdvcjyhjtmalh5dn5e8n5w8cqle0vunzduu4nza9y0734qhxday9hzywl0aa0vhzy0qmphc64d4hduj08dv2krpgqtc2v83gptk34reelxyc7wsgnze890c6nrv6p0cmepatc269eayzjjkqk30n52rfl5dg7wztl96f7wc2tzx34q909xuajnyt4u4lnk87lwal7z0etdz5tmece0v3u796jfp68nccn05ty54ncfelts3v8g0sn6v6hsu87zat4r03368ersu87252dd0nswymxzc2pyxl8yy844hspuyj47w0px4u4leefq568sk0rr9th4ql9f9ykawrczkz5hp22nstg3lrlsa6u2q2ull3kzce2sh0h77sjv0zszhzy4hfh6u0pwux5l3gpthsn72mfu47sw9zw3hzk7srznp27z0etdp0725me00sn72mgkf0fteehruk0lg6swh34z52puaekzmjlmalhhe6m8ug7z3c8g8zhjjspp5zj0sm85g5ufng9w7s6p4ucdk80tyvz64sg54v0cy4vgnr37f78sqsp5l6azu2hv6we30er90jrslqpvdtrnrphhesca2wg5q83k52rsu2cq9q2sqqqqqysgqcqr8h2np4qw0ha2k282hm8jh5rcfq0hsp2zhddtlc5vs23uphyv0lv3k8sqsfgfp4qyrk86tx5xg2aa7et4cdzhnvl5s4nd33ugytt7gamk9tugn9yransr9yq08gpwsn8t2tq4ducjfhrcz707av0ss20urjh8vldrpmehqxa0stkesvuq82txyqzfhej7qccswy7k5wvcppk63c6zpjytfdaccadacjtn52lpe6s85rjfqlxzp6frq33xshaz2nr9xjkhd3jj8qg39nmfzvpgmayakqmy9rseakwgcudug7hs45wh430ywh7qhj3khczh8gle4cn93ymgfwa7rrvcw9lywyyz58k4p40a3nu9svthaf0qeg8f2ay4tw9p48p70qmayu3ejl2q8pj9e2l22h7775tl44hs6ke4sdfgcr6aj8wra4r2v9sj6xa5chd5ctpfg8chtrer3kkp0e6af88lkrfxcklf2hyslv2hr0xl5lwrm5y5uttxn4ndfz8789znf78nspa3xy68" ) ;
1200
- parse_ok ( "lnbcrt17124979001314909880p1y6lkcwgd76tfnxksfk2atyy4tzw4nyg6jrx3282s2ygvcxyj64gevhxsjk2ymhzv3e0p5h5u3kfey92jt9ge44gsfnwycxynm2g3unw3ntt9qh25texe98jcfhxvcxuezxw9tngwrndpy9s4p4x9eyze2tfe9rxm68tp5yj5jfduen2nny8prhsm6edegn2stww4n4gwp4vfjkvdthd43524n9fa8h262vweskg66nw3vnyafn29zhsvfeg9mxummtfp35uumzfqmhy3jwgdh55mt5xpvhgmjn25uku5e5g939wmmnvdfygnrdgdh56uzcx4a92vfhgdcky3z9gfnrsvp4f4f55j68vak9yufhvdm8x5zrgc6955jvf429zumv89nh2a35wae5yntgv985jumpxehyv7t92pjrwufs89yh23f5ddy5s568wgchve3cg9ek5nzewgcrzjz0dftxg3nvf4hngje52ac4zmesxpvk6sfef4hkuetvd4vk6n29wftrw5rvg4yy2vjjwyexc5mnvfd8xknndpqkkenx0q642j35298hwve3dyc525jrd3295sm9v9jrqup3wpykg7zd239ns7jgtqu95jz0deaxksjh2fu56n6n2f5x6mm8wa89qjfef385sam2x9mxcs20gfpnq460d3axzknnf3e4sw2kvf25wjjxddpyg52dw4vx7nn2w9cyu5t8vfnyxjtpg33kssjp24ch536pd938snmtx345x6r4x93kvv2tff855um3tfekxjted4kxys2kve5hvu6g89z4ynmjgfhnw7tv892rymejgvey77rcfqe9xjr92d85636fvajxyajndfa92k2nxycx5jtjx4zxsm2y2dyn2up50f5ku3nrfdk4g5npxehkzjjv8y69gveev4z56denddaxy7tfwe8xx42zgf6kzmnxxpk826ze2s6xk6jrwearw6ejvd8rsvj2fpg525jtd5pp5j2tlt28m4kakjr84w6ce4fd8e7awy6ncyswcyut760rdnem30ptssp5p5u3xgxxtr6aev8y2w9m30wcw3kyn7fgm8wmf8qw8wzrqt34zcvq9q2sqqqqqysgqcqypmw9xq8lllllllnp4qt36twam2ca08m3s7vnhre3c0j89589wyw4vdk7fln0lryxzkdcrur28qwqq3hnyt84vsasuldd2786eysdf4dyuggwsmvw2atftf7spkmpa9dd3efq5tenpqm2v7vcz2a4s0s7jnqpjn0srysnstnw5y5z9taxn0ue37aqgufxcdsj6f8a2m4pm9udppdzc4shsdqzzx0u0rm4xljs0dqz3c5zqyvglda7nsqvqfztmlyup7vyuadzav4zyuqwx90ev6nmk53nkhkt0sev9e745wxqtdvrqzgqkakazen7e2qmsdauk665g3llg5qtl79t3xulrhjnducehdn72gpmkjvtth7kh6ejpl9dv0qcsxv2jvzzvg0hzdmk3yjsmydqksdk3h78kc63qnr265h8vyeslqexszppfm7y287t3gxvhw0ulg2wp0rsw3tevz03z50kpy77zdz9snxmkkwxd76xvj4qvj2f89rrnuvdvzw947ay0kydc077pkec2jet9qwp2tud98s24u65uz07eaxk5jk3e4nggn2caaek2p5pkrc6mm6mxjm2ezpdu8p5jstg6tgvnttgac3ygt5ys04t4udujzlshpl7e4f3ff03xe6v24cp6aq4wa" ) ;
1201
- parse_ok ( "lntb5826417333454665580p1c5rwh5edlhf33hvkj5vav5z3t02a5hxvj3vfv5kuny2f3yzj6zwf9hx3nn2fk9gepc2a3ywvj6dax5v3jy2d5nxmp3gaxhycjkv38hx4z4d4vyznrp2p24xa6t2pg4w4rrxfens6tcxdhxvvfhxa8xvvpkgat8xnpe2p44juz9g43hyur00989gvfhwd2kj72wfum4g4mgx5m5cs2rg9d9vnn6xe89ydnnvfpyy52s2dxx2er4x4xxwstdd5cxwdrjw3nkxnnv2uexxnrxw4t56sjswfn52s2xv4t8xmjtwpn8xm6sfeh4q526dyu8x3r9gceyw6fhd934qjttvdk57az5w368zdrhwfjxxu35xcmrsmmpd4g8wwtev4tkzutdd32k56mxveuy6c6v2emyv7zkfp39zjpjgd8hx7n4xph5kceswf6xxmnyfcuxca20fp24z7ncvfhyu5jf2exhw36nwf68s7rh2a6yzjf4dgukcenfxpchqsjn2pt5x334tf98wsm6dvcrvvfcwapxvk2cdvmk2npcfe68zue3w4f9xc6s2fvrw6nrg3fkskte2ftxyc20ffckcd692964sdzjwdp4yvrfdfm9q72pxp3kwat5f4j9xee5da8rss60w92857tgwych55f5w3n8zmzexpy4jwredejrqm6txf3nxm64ffh8x460dp9yjazhw4yx6dm5xerysnn5wa455k3h2d89ss2fd9axwjp3f4r9qdmfd4fx6stx2eg9sezrv369w7nvvfvhj4nnwaz5z3ny8qcxcdnvwd64jc2nx9uy2e2gxdrnx6r3w9ykxatxxg6kk6rv2ekr2emwx5ehy362d3x82dzvddfxs5rcg4vn27npf564qdtg2anycc6523jnwe3e0p65unrpvccrs5m2fuexgmnj23ay5e34v4xk5jnrwpg4xemfwqe5vjjjw9qk76zsd9yrzu6xdpv5v5ntdejxg6jtv3kx65t6gdhrgvj3fe34sj2vv3h5kegpp57hjf5kv6clw97y2e063yuz0psrz9a6l49v836dflum00rh8qtn8qsp5gd29qycuze08xls8l32zjaaf2uqv78v97lg9ss0c699huw980h2q9q2sqqqqqysgqcqr8ulnp4q26hcfwr7qxz7lwwlr2kjcrws7m2u5j36mm0kxa45uxy6zvsqt2zzfppjdkrm2rlgadt9dq3d6jkv4r2cugmf2kamr28qwuleyzzyyly8a6tu70eldahx7hzxx5x9gms7vjjr577ps8n4qyds5nern39j0v7czkch2letnt46895jupxgehf208xgxz8d6j8gu3h2qqtsk9nr9nuquhkqjxw40h2ucpldrawmktxzxdgtkt9a3p95g98nywved8s8laj2a0c98rq5zzdnzddz6ndw0lvr6u0av9m7859844cgz9vpeq05gw79zqae2s7jzeq66wydyueqtp56qc67g7krv6lj5aahxtmq4y208q5qyz38cnwl9ma6m5f4nhzqaj0tjxpfrk4nr5arv9d20lvxvddvffhzygmyuvwd959uhdcgcgjejchqt2qncuwpqqk5vws7dflw8x6esrfwhz7h3jwmhevf445k76nme926sr8drsdveqg7l7t7lnjvhaludqnwk4l2pmevkjf9pla924p77v76r7x8jzyy7h59hmk0lgzfsk6c8dpj37hssj7jt4q7jzvy8hq25l3pag37axxanjqnq56c47gpgy6frsyc0str9w2aahz4h6t7axaka4cwvhwg49r6qgj8kwz2mt6vcje25l9ekvmgq5spqtn" ) ;
1202
- // TODO(phlip9): generate an invoice that's MAX_LENGTH long
1201
+ // 1024 B shrunk invoice just above previous limit of 1023 B from Lexe proptest
1202
+ parse_ok (
1203
+ "lnbc10000000000000000010p1qqqqqqqdtuxpqkzq8sjzqgps4pvyczqq8sjzqgpuysszq0pyyqsrp2zs0sjz\
1204
+ qgps4pxrcfpqyqc2slpyyqsqsv9gwz59s5zqpqyps5rc9qsrs2pqxz5ysyzcfqgysyzs0sjzqgqq8sjzqgps4p\
1205
+ xqqzps4pqpssqgzpxps5ruysszqrps4pg8p2zgpsc2snpuysszqzqsgqvys0pyyqsrcfpqyqvycv9gfqqrcfpq\
1206
+ yq7zggpq8q5zqyruysszqwpgyqxpsjqsgq7zggpqps7zggpq8sjzqgqgqq7zggpqpq7zggpq8q5zqqpuysszq0\
1207
+ pyyqsqs0pyyqspsnqgzpqpqlpyyqsqszpuysszqyzvzpvysrqq8sjzqgqvrp7zggpqpqxpsspp5mf45hs3cgph\
1208
+ h0074r5qmr74y82r26ac4pzdg4nd9mdmsvz6ffqpssp5vr4yra4pcv74h9hk3d0233nqu4gktpuykjamrafrdp\
1209
+ uedqugzh3q9q2sqqqqqysgqcqrpqqxq8pqqqqqqnp4qgvcxpme2q5lng36j9gruwlrtk2f86s3c5xmk87yhvyu\
1210
+ wdeh025q5r9yqwnqegv9hj9nzkhyxaeyq92wcrnqp36pyrc2qzrvswj5g96ey2dn6qqqqqqqqqqqqqqqqqqqqq\
1211
+ qqqqqqqqp9a5vs0t4z56p64xyma8s84yvdx7uhqj0gvrr424fea2wpztq2fwqqqqqqqqqqqqqqqqqqqqqqqqqq\
1212
+ qqqqmy9qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\
1213
+ qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpcnsxc32du9n7amlypuhclzqrt6lkegq\
1214
+ 0v3r7nczjv9tv30z7phq80r3dm7pvgykl7gwuenmem93h5xwdwac6ngsmzqc34khrg3qjgsq6qk6lc"
1215
+ ) ;
1216
+ // 1517 B mainnet invoice from Lexe proptest
1217
+ parse_ok (
1218
+ "lnbc8735500635020489010p1av5kfs8deupvyk4u5ynj03hmalhhhml0fxc2jlrv9z4lg6s4hnhkz69malhhe\
1219
+ t3x9yqpsxru4a3kwar2qtu2q2ughx367q600s5x7c7tln4k0fu78skxqevaqm8sayhuur377zgf3uf94n57xzh\
1220
+ dw99u42hwc089djn5xj723w7zageflsnzdmyte89tecf2ac7xhg4y3u9f4xpuv2hwxjlsarp0e24fu8tme6rgv\
1221
+ 0tqj08z9f4u30rw59k8emhtvs7wye0xfw6x5q5tju2p208rvtkunzwtwghtp22tlnh62gxwhfkxp4cnz7ts3rx\
1222
+ vlzszhv9y00h77lpdvcjyhjtmalh5dn5e8n5w8cqle0vunzduu4nza9y0734qhxday9hzywl0aa0vhzy0qmphc\
1223
+ 64d4hduj08dv2krpgqtc2v83gptk34reelxyc7wsgnze890c6nrv6p0cmepatc269eayzjjkqk30n52rfl5dg7\
1224
+ wztl96f7wc2tzx34q909xuajnyt4u4lnk87lwal7z0etdz5tmece0v3u796jfp68nccn05ty54ncfelts3v8g0\
1225
+ sn6v6hsu87zat4r03368ersu87252dd0nswymxzc2pyxl8yy844hspuyj47w0px4u4leefq568sk0rr9th4ql9\
1226
+ f9ykawrczkz5hp22nstg3lrlsa6u2q2ull3kzce2sh0h77sjv0zszhzy4hfh6u0pwux5l3gpthsn72mfu47sw9\
1227
+ zw3hzk7srznp27z0etdp0725me00sn72mgkf0fteehruk0lg6swh34z52puaekzmjlmalhhe6m8ug7z3c8g8zh\
1228
+ jjspp5zj0sm85g5ufng9w7s6p4ucdk80tyvz64sg54v0cy4vgnr37f78sqsp5l6azu2hv6we30er90jrslqpvd\
1229
+ trnrphhesca2wg5q83k52rsu2cq9q2sqqqqqysgqcqr8h2np4qw0ha2k282hm8jh5rcfq0hsp2zhddtlc5vs23\
1230
+ uphyv0lv3k8sqsfgfp4qyrk86tx5xg2aa7et4cdzhnvl5s4nd33ugytt7gamk9tugn9yransr9yq08gpwsn8t2\
1231
+ tq4ducjfhrcz707av0ss20urjh8vldrpmehqxa0stkesvuq82txyqzfhej7qccswy7k5wvcppk63c6zpjytfda\
1232
+ ccadacjtn52lpe6s85rjfqlxzp6frq33xshaz2nr9xjkhd3jj8qg39nmfzvpgmayakqmy9rseakwgcudug7hs4\
1233
+ 5wh430ywh7qhj3khczh8gle4cn93ymgfwa7rrvcw9lywyyz58k4p40a3nu9svthaf0qeg8f2ay4tw9p48p70qm\
1234
+ ayu3ejl2q8pj9e2l22h7775tl44hs6ke4sdfgcr6aj8wra4r2v9sj6xa5chd5ctpfg8chtrer3kkp0e6af88lk\
1235
+ rfxcklf2hyslv2hr0xl5lwrm5y5uttxn4ndfz8789znf78nspa3xy68"
1236
+ ) ;
1237
+ // 1804 B regtest invoice from Lexe proptest
1238
+ parse_ok (
1239
+ "lnbcrt17124979001314909880p1y6lkcwgd76tfnxksfk2atyy4tzw4nyg6jrx3282s2ygvcxyj64gevhxsjk\
1240
+ 2ymhzv3e0p5h5u3kfey92jt9ge44gsfnwycxynm2g3unw3ntt9qh25texe98jcfhxvcxuezxw9tngwrndpy9s4\
1241
+ p4x9eyze2tfe9rxm68tp5yj5jfduen2nny8prhsm6edegn2stww4n4gwp4vfjkvdthd43524n9fa8h262vwesk\
1242
+ g66nw3vnyafn29zhsvfeg9mxummtfp35uumzfqmhy3jwgdh55mt5xpvhgmjn25uku5e5g939wmmnvdfygnrdgd\
1243
+ h56uzcx4a92vfhgdcky3z9gfnrsvp4f4f55j68vak9yufhvdm8x5zrgc6955jvf429zumv89nh2a35wae5yntg\
1244
+ v985jumpxehyv7t92pjrwufs89yh23f5ddy5s568wgchve3cg9ek5nzewgcrzjz0dftxg3nvf4hngje52ac4zm\
1245
+ esxpvk6sfef4hkuetvd4vk6n29wftrw5rvg4yy2vjjwyexc5mnvfd8xknndpqkkenx0q642j35298hwve3dyc5\
1246
+ 25jrd3295sm9v9jrqup3wpykg7zd239ns7jgtqu95jz0deaxksjh2fu56n6n2f5x6mm8wa89qjfef385sam2x9\
1247
+ mxcs20gfpnq460d3axzknnf3e4sw2kvf25wjjxddpyg52dw4vx7nn2w9cyu5t8vfnyxjtpg33kssjp24ch536p\
1248
+ d938snmtx345x6r4x93kvv2tff855um3tfekxjted4kxys2kve5hvu6g89z4ynmjgfhnw7tv892rymejgvey77\
1249
+ rcfqe9xjr92d85636fvajxyajndfa92k2nxycx5jtjx4zxsm2y2dyn2up50f5ku3nrfdk4g5npxehkzjjv8y69\
1250
+ gveev4z56denddaxy7tfwe8xx42zgf6kzmnxxpk826ze2s6xk6jrwearw6ejvd8rsvj2fpg525jtd5pp5j2tlt\
1251
+ 28m4kakjr84w6ce4fd8e7awy6ncyswcyut760rdnem30ptssp5p5u3xgxxtr6aev8y2w9m30wcw3kyn7fgm8wm\
1252
+ f8qw8wzrqt34zcvq9q2sqqqqqysgqcqypmw9xq8lllllllnp4qt36twam2ca08m3s7vnhre3c0j89589wyw4vd\
1253
+ k7fln0lryxzkdcrur28qwqq3hnyt84vsasuldd2786eysdf4dyuggwsmvw2atftf7spkmpa9dd3efq5tenpqm2\
1254
+ v7vcz2a4s0s7jnqpjn0srysnstnw5y5z9taxn0ue37aqgufxcdsj6f8a2m4pm9udppdzc4shsdqzzx0u0rm4xl\
1255
+ js0dqz3c5zqyvglda7nsqvqfztmlyup7vyuadzav4zyuqwx90ev6nmk53nkhkt0sev9e745wxqtdvrqzgqkaka\
1256
+ zen7e2qmsdauk665g3llg5qtl79t3xulrhjnducehdn72gpmkjvtth7kh6ejpl9dv0qcsxv2jvzzvg0hzdmk3y\
1257
+ jsmydqksdk3h78kc63qnr265h8vyeslqexszppfm7y287t3gxvhw0ulg2wp0rsw3tevz03z50kpy77zdz9snxm\
1258
+ kkwxd76xvj4qvj2f89rrnuvdvzw947ay0kydc077pkec2jet9qwp2tud98s24u65uz07eaxk5jk3e4nggn2caa\
1259
+ ek2p5pkrc6mm6mxjm2ezpdu8p5jstg6tgvnttgac3ygt5ys04t4udujzlshpl7e4f3ff03xe6v24cp6aq4wa"
1260
+ ) ;
1261
+ // 1870 B testnet invoice from Lexe proptest
1262
+ parse_ok (
1263
+ "lntb5826417333454665580p1c5rwh5edlhf33hvkj5vav5z3t02a5hxvj3vfv5kuny2f3yzj6zwf9hx3nn2fk\
1264
+ 9gepc2a3ywvj6dax5v3jy2d5nxmp3gaxhycjkv38hx4z4d4vyznrp2p24xa6t2pg4w4rrxfens6tcxdhxvvfhx\
1265
+ a8xvvpkgat8xnpe2p44juz9g43hyur00989gvfhwd2kj72wfum4g4mgx5m5cs2rg9d9vnn6xe89ydnnvfpyy52\
1266
+ s2dxx2er4x4xxwstdd5cxwdrjw3nkxnnv2uexxnrxw4t56sjswfn52s2xv4t8xmjtwpn8xm6sfeh4q526dyu8x\
1267
+ 3r9gceyw6fhd934qjttvdk57az5w368zdrhwfjxxu35xcmrsmmpd4g8wwtev4tkzutdd32k56mxveuy6c6v2em\
1268
+ yv7zkfp39zjpjgd8hx7n4xph5kceswf6xxmnyfcuxca20fp24z7ncvfhyu5jf2exhw36nwf68s7rh2a6yzjf4d\
1269
+ gukcenfxpchqsjn2pt5x334tf98wsm6dvcrvvfcwapxvk2cdvmk2npcfe68zue3w4f9xc6s2fvrw6nrg3fkskt\
1270
+ e2ftxyc20ffckcd692964sdzjwdp4yvrfdfm9q72pxp3kwat5f4j9xee5da8rss60w92857tgwych55f5w3n8z\
1271
+ mzexpy4jwredejrqm6txf3nxm64ffh8x460dp9yjazhw4yx6dm5xerysnn5wa455k3h2d89ss2fd9axwjp3f4r\
1272
+ 9qdmfd4fx6stx2eg9sezrv369w7nvvfvhj4nnwaz5z3ny8qcxcdnvwd64jc2nx9uy2e2gxdrnx6r3w9ykxatxx\
1273
+ g6kk6rv2ekr2emwx5ehy362d3x82dzvddfxs5rcg4vn27npf564qdtg2anycc6523jnwe3e0p65unrpvccrs5m\
1274
+ 2fuexgmnj23ay5e34v4xk5jnrwpg4xemfwqe5vjjjw9qk76zsd9yrzu6xdpv5v5ntdejxg6jtv3kx65t6gdhrg\
1275
+ vj3fe34sj2vv3h5kegpp57hjf5kv6clw97y2e063yuz0psrz9a6l49v836dflum00rh8qtn8qsp5gd29qycuze\
1276
+ 08xls8l32zjaaf2uqv78v97lg9ss0c699huw980h2q9q2sqqqqqysgqcqr8ulnp4q26hcfwr7qxz7lwwlr2kjc\
1277
+ rws7m2u5j36mm0kxa45uxy6zvsqt2zzfppjdkrm2rlgadt9dq3d6jkv4r2cugmf2kamr28qwuleyzzyyly8a6t\
1278
+ u70eldahx7hzxx5x9gms7vjjr577ps8n4qyds5nern39j0v7czkch2letnt46895jupxgehf208xgxz8d6j8gu\
1279
+ 3h2qqtsk9nr9nuquhkqjxw40h2ucpldrawmktxzxdgtkt9a3p95g98nywved8s8laj2a0c98rq5zzdnzddz6nd\
1280
+ w0lvr6u0av9m7859844cgz9vpeq05gw79zqae2s7jzeq66wydyueqtp56qc67g7krv6lj5aahxtmq4y208q5qy\
1281
+ z38cnwl9ma6m5f4nhzqaj0tjxpfrk4nr5arv9d20lvxvddvffhzygmyuvwd959uhdcgcgjejchqt2qncuwpqqk\
1282
+ 5vws7dflw8x6esrfwhz7h3jwmhevf445k76nme926sr8drsdveqg7l7t7lnjvhaludqnwk4l2pmevkjf9pla92\
1283
+ 4p77v76r7x8jzyy7h59hmk0lgzfsk6c8dpj37hssj7jt4q7jzvy8hq25l3pag37axxanjqnq56c47gpgy6frsy\
1284
+ c0str9w2aahz4h6t7axaka4cwvhwg49r6qgj8kwz2mt6vcje25l9ekvmgq5spqtn"
1285
+ ) ;
1203
1286
}
1204
1287
1288
+ // Generate a valid invoice of `MAX_LENGTH` bytes and ensure that it roundtrips.
1289
+ #[ test]
1290
+ fn test_serde_long_invoice ( ) {
1291
+ use crate :: TaggedField :: * ;
1292
+ use crate :: {
1293
+ Bolt11Invoice , Bolt11InvoiceFeatures , Bolt11InvoiceSignature , Currency ,
1294
+ PositiveTimestamp , RawBolt11Invoice , RawDataPart , RawHrp , RawTaggedField , Sha256 ,
1295
+ SignedRawBolt11Invoice ,
1296
+ } ;
1297
+ use bitcoin:: secp256k1:: ecdsa:: { RecoverableSignature , RecoveryId } ;
1298
+ use bitcoin:: secp256k1:: PublicKey ;
1299
+ use lightning_types:: routing:: { RouteHint , RouteHintHop , RoutingFees } ;
1300
+
1301
+ // Generate an `UnknownSemantics` field with a given length.
1302
+ fn unknown_semantics_field ( len : usize ) -> Vec < Fe32 > {
1303
+ assert ! ( len <= 1023 ) ;
1304
+ let mut field = Vec :: with_capacity ( len + 3 ) ;
1305
+ // Big-endian encoded length prefix
1306
+ field. push ( Fe32 :: Q ) ;
1307
+ field. push ( Fe32 :: try_from ( ( len >> 5 ) as u8 ) . unwrap ( ) ) ;
1308
+ field. push ( Fe32 :: try_from ( ( len & 0x1f ) as u8 ) . unwrap ( ) ) ;
1309
+ // Data
1310
+ field. extend ( std:: iter:: repeat ( Fe32 :: P ) . take ( len) ) ;
1311
+ field
1312
+ }
1313
+
1314
+ let payee_pk = PublicKey :: from_slice ( & [
1315
+ 0x03 , 0x24 , 0x65 , 0x3e , 0xac , 0x43 , 0x44 , 0x88 , 0x00 , 0x2c , 0xc0 , 0x6b , 0xbf , 0xb7 ,
1316
+ 0xf1 , 0x0f , 0xe1 , 0x89 , 0x91 , 0xe3 , 0x5f , 0x9f , 0xe4 , 0x30 , 0x2d , 0xbe , 0xa6 , 0xd2 ,
1317
+ 0x35 , 0x3d , 0xc0 , 0xab , 0x1c ,
1318
+ ] )
1319
+ . unwrap ( ) ;
1320
+
1321
+ let raw_invoice = RawBolt11Invoice {
1322
+ hrp : RawHrp {
1323
+ currency : Currency :: Bitcoin ,
1324
+ raw_amount : Some ( 10000000000000000010 ) ,
1325
+ si_prefix : Some ( crate :: SiPrefix :: Pico ) ,
1326
+ } ,
1327
+ data : RawDataPart {
1328
+ timestamp : PositiveTimestamp :: from_unix_timestamp ( 1496314658 ) . unwrap ( ) ,
1329
+ tagged_fields : vec ! [
1330
+ PaymentHash ( Sha256 (
1331
+ sha256:: Hash :: from_str(
1332
+ "0001020304050607080900010203040506070809000102030405060708090102" ,
1333
+ )
1334
+ . unwrap( ) ,
1335
+ ) )
1336
+ . into( ) ,
1337
+ Description (
1338
+ crate :: Description :: new(
1339
+ std:: iter:: repeat( "A" ) . take( 639 ) . collect:: <String >( ) ,
1340
+ )
1341
+ . unwrap( ) ,
1342
+ )
1343
+ . into( ) ,
1344
+ PayeePubKey ( crate :: PayeePubKey ( payee_pk) ) . into( ) ,
1345
+ ExpiryTime ( crate :: ExpiryTime ( std:: time:: Duration :: from_secs( u64 :: MAX ) ) ) . into( ) ,
1346
+ MinFinalCltvExpiryDelta ( crate :: MinFinalCltvExpiryDelta ( u64 :: MAX ) ) . into( ) ,
1347
+ Fallback ( crate :: Fallback :: SegWitProgram {
1348
+ version: bitcoin:: WitnessVersion :: V0 ,
1349
+ program: vec![ 0 ; 32 ] ,
1350
+ } )
1351
+ . into( ) ,
1352
+ PrivateRoute ( crate :: PrivateRoute ( RouteHint (
1353
+ std:: iter:: repeat( RouteHintHop {
1354
+ src_node_id: payee_pk,
1355
+ short_channel_id: 0x0102030405060708 ,
1356
+ fees: RoutingFees { base_msat: 1 , proportional_millionths: 20 } ,
1357
+ cltv_expiry_delta: 3 ,
1358
+ htlc_minimum_msat: None ,
1359
+ htlc_maximum_msat: None ,
1360
+ } )
1361
+ . take( 12 )
1362
+ . collect:: <Vec <_>>( ) ,
1363
+ ) ) )
1364
+ . into( ) ,
1365
+ PaymentSecret ( crate :: PaymentSecret ( [ 17 ; 32 ] ) ) . into( ) ,
1366
+ PaymentMetadata ( vec![ 0x69 ; 639 ] ) . into( ) ,
1367
+ Features ( Bolt11InvoiceFeatures :: from_le_bytes( vec![ 0xaa ; 639 ] ) ) . into( ) ,
1368
+ // This invoice is 4458 B w/o unknown semantics fields.
1369
+ // Need to add some non-standard fields to reach 7089 B limit.
1370
+ RawTaggedField :: UnknownSemantics ( unknown_semantics_field( 1023 ) ) ,
1371
+ RawTaggedField :: UnknownSemantics ( unknown_semantics_field( 1023 ) ) ,
1372
+ RawTaggedField :: UnknownSemantics ( unknown_semantics_field( 576 ) ) ,
1373
+ ] ,
1374
+ } ,
1375
+ } ;
1376
+
1377
+ let signed_invoice = SignedRawBolt11Invoice {
1378
+ raw_invoice,
1379
+ hash : [
1380
+ 0x75 , 0x99 , 0xe1 , 0x51 , 0x7f , 0xa1 , 0x0e , 0xb5 , 0xc0 , 0x79 , 0xb4 , 0x6e , 0x8e , 0x62 ,
1381
+ 0x0c , 0x4f , 0xb0 , 0x72 , 0x71 , 0xd2 , 0x81 , 0xa1 , 0x92 , 0x65 , 0x9c , 0x90 , 0x89 , 0x69 ,
1382
+ 0xe1 , 0xf3 , 0xd6 , 0x59 ,
1383
+ ] ,
1384
+ signature : Bolt11InvoiceSignature (
1385
+ RecoverableSignature :: from_compact (
1386
+ & [
1387
+ 0x6c , 0xbe , 0xbe , 0xfe , 0xd3 , 0xfb , 0x07 , 0x68 , 0xb5 , 0x79 , 0x98 , 0x82 ,
1388
+ 0x29 , 0xab , 0x0e , 0xcc , 0x8d , 0x3a , 0x81 , 0xee , 0xee , 0x07 , 0xb3 , 0x5d ,
1389
+ 0x64 , 0xca , 0xb4 , 0x12 , 0x33 , 0x99 , 0x33 , 0x2a , 0x31 , 0xc2 , 0x2c , 0x2b ,
1390
+ 0x62 , 0x96 , 0x4e , 0x37 , 0xd7 , 0x96 , 0x50 , 0x5e , 0xdb , 0xe9 , 0xa9 , 0x5b ,
1391
+ 0x0b , 0x3b , 0x87 , 0x22 , 0x89 , 0xed , 0x95 , 0xf1 , 0xf1 , 0xdf , 0x2d , 0xb6 ,
1392
+ 0xbd , 0xf5 , 0x0a , 0x20 ,
1393
+ ] ,
1394
+ RecoveryId :: from_i32 ( 1 ) . unwrap ( ) ,
1395
+ )
1396
+ . unwrap ( ) ,
1397
+ ) ,
1398
+ } ;
1399
+
1400
+ // Ensure serialized invoice roundtrips
1401
+ let invoice = Bolt11Invoice :: from_signed ( signed_invoice) . unwrap ( ) ;
1402
+ let invoice_str = invoice. to_string ( ) ;
1403
+ assert_eq ! ( invoice_str. len( ) , crate :: MAX_LENGTH ) ;
1404
+ assert_eq ! ( invoice, Bolt11Invoice :: from_str( & invoice_str) . unwrap( ) ) ;
1405
+ }
1406
+
1407
+ // Test that invoices above the maximum length fail to parse with the expected error.
1205
1408
#[ test]
1206
1409
fn test_deser_too_long_fails ( ) {
1207
1410
use crate :: { Bolt11Invoice , ParseOrSemanticError , MAX_LENGTH } ;
1208
1411
use bech32:: primitives:: decode:: { CheckedHrpstringError , ChecksumError } ;
1209
1412
1210
- fn parses_too_long ( s : & str ) -> bool {
1413
+ fn parse_is_code_length_err ( s : & str ) -> bool {
1211
1414
// Need matches! b/c ChecksumError::CodeLength(_) is marked non-exhaustive
1212
1415
matches ! (
1213
1416
Bolt11Invoice :: from_str( s) ,
@@ -1221,7 +1424,7 @@ mod test {
1221
1424
too_long. push_str (
1222
1425
String :: from_utf8 ( vec ! [ b'x' ; ( MAX_LENGTH + 1 ) - too_long. len( ) ] ) . unwrap ( ) . as_str ( ) ,
1223
1426
) ;
1224
- assert ! ( parses_too_long ( & too_long) ) ;
1225
- assert ! ( !parses_too_long ( & too_long[ ..too_long. len( ) - 1 ] ) ) ;
1427
+ assert ! ( parse_is_code_length_err ( & too_long) ) ;
1428
+ assert ! ( !parse_is_code_length_err ( & too_long[ ..too_long. len( ) - 1 ] ) ) ;
1226
1429
}
1227
1430
}
0 commit comments