Skip to content

Commit 84dc943

Browse files
committed
common/bolt11_json: extract bolt11->json code.
Our new "decode" command will also handle bolt11. We make a few cleanups: 1. Avoid type_to_string() in JSON, instead use format functions directly. 2. Don't need to escape description now that JSON core does that for us. Signed-off-by: Rusty Russell <[email protected]>
1 parent 1aa7e8e commit 84dc943

11 files changed

+151
-136
lines changed

bitcoin/signature.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,7 @@ bool signature_from_der(const u8 *der, size_t len, struct bitcoin_signature *sig
310310
return true;
311311
}
312312

313-
static char *signature_to_hexstr(const tal_t *ctx,
314-
const secp256k1_ecdsa_signature *sig)
313+
char *fmt_signature(const tal_t *ctx, const secp256k1_ecdsa_signature *sig)
315314
{
316315
u8 der[72];
317316
size_t len = 72;
@@ -321,7 +320,7 @@ static char *signature_to_hexstr(const tal_t *ctx,
321320

322321
return tal_hexstr(ctx, der, len);
323322
}
324-
REGISTER_TYPE_TO_STRING(secp256k1_ecdsa_signature, signature_to_hexstr);
323+
REGISTER_TYPE_TO_STRING(secp256k1_ecdsa_signature, fmt_signature);
325324

326325
static char *bitcoin_signature_to_hexstr(const tal_t *ctx,
327326
const struct bitcoin_signature *sig)

bitcoin/signature.h

+1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ void fromwire_bip340sig(const u8 **cursor, size_t *max,
142142
struct bip340sig *bip340sig);
143143

144144
/* Get a hex string sig */
145+
char *fmt_signature(const tal_t *ctx, const secp256k1_ecdsa_signature *sig);
145146
char *fmt_bip340sig(const tal_t *ctx, const struct bip340sig *bip340sig);
146147

147148
/* For caller convenience, we hand in tag in parts (any can be "") */

common/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ COMMON_SRC_NOGEN := \
99
common/bip32.c \
1010
common/blinding.c \
1111
common/bolt11.c \
12+
common/bolt11_json.c \
1213
common/bolt12.c \
1314
common/channel_config.c \
1415
common/channel_id.c \

common/bolt11.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,7 @@ static char *decode_n(struct bolt11 *b11,
297297
data_length * 5, false);
298298
if (!node_id_valid(&b11->receiver_id))
299299
return tal_fmt(b11, "n: invalid pubkey %s",
300-
type_to_string(tmpctx, struct node_id,
301-
&b11->receiver_id));
300+
node_id_to_hexstr(tmpctx, &b11->receiver_id));
302301

303302
*have_n = true;
304303
return NULL;

common/bolt11_json.c

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#include <bitcoin/address.h>
2+
#include <bitcoin/base58.h>
3+
#include <bitcoin/chainparams.h>
4+
#include <bitcoin/script.h>
5+
#include <common/bech32.h>
6+
#include <common/bolt11.h>
7+
#include <common/bolt11_json.h>
8+
#include <common/json.h>
9+
#include <common/json_helpers.h>
10+
#include <common/json_stream.h>
11+
12+
static void json_add_fallback(struct json_stream *response,
13+
const char *fieldname,
14+
const u8 *fallback,
15+
const struct chainparams *chain)
16+
{
17+
struct bitcoin_address pkh;
18+
struct ripemd160 sh;
19+
struct sha256 wsh;
20+
21+
json_object_start(response, fieldname);
22+
if (is_p2pkh(fallback, &pkh)) {
23+
json_add_string(response, "type", "P2PKH");
24+
json_add_string(response, "addr",
25+
bitcoin_to_base58(tmpctx, chain, &pkh));
26+
} else if (is_p2sh(fallback, &sh)) {
27+
json_add_string(response, "type", "P2SH");
28+
json_add_string(response, "addr",
29+
p2sh_to_base58(tmpctx, chain, &sh));
30+
} else if (is_p2wpkh(fallback, &pkh)) {
31+
char out[73 + strlen(chain->bip173_name)];
32+
json_add_string(response, "type", "P2WPKH");
33+
if (segwit_addr_encode(out, chain->bip173_name, 0,
34+
(const u8 *)&pkh, sizeof(pkh)))
35+
json_add_string(response, "addr", out);
36+
} else if (is_p2wsh(fallback, &wsh)) {
37+
char out[73 + strlen(chain->bip173_name)];
38+
json_add_string(response, "type", "P2WSH");
39+
if (segwit_addr_encode(out, chain->bip173_name, 0,
40+
(const u8 *)&wsh, sizeof(wsh)))
41+
json_add_string(response, "addr", out);
42+
}
43+
json_add_hex_talarr(response, "hex", fallback);
44+
json_object_end(response);
45+
}
46+
47+
void json_add_bolt11(struct json_stream *response,
48+
const struct bolt11 *b11)
49+
{
50+
json_add_string(response, "currency", b11->chain->bip173_name);
51+
json_add_u64(response, "created_at", b11->timestamp);
52+
json_add_u64(response, "expiry", b11->expiry);
53+
json_add_node_id(response, "payee", &b11->receiver_id);
54+
if (b11->msat)
55+
json_add_amount_msat_compat(response, *b11->msat,
56+
"msatoshi", "amount_msat");
57+
if (b11->description)
58+
json_add_string(response, "description", b11->description);
59+
if (b11->description_hash)
60+
json_add_sha256(response, "description_hash",
61+
b11->description_hash);
62+
json_add_num(response, "min_final_cltv_expiry",
63+
b11->min_final_cltv_expiry);
64+
if (b11->payment_secret)
65+
json_add_secret(response, "payment_secret",
66+
b11->payment_secret);
67+
if (b11->features)
68+
json_add_hex_talarr(response, "features", b11->features);
69+
if (tal_count(b11->fallbacks)) {
70+
json_array_start(response, "fallbacks");
71+
for (size_t i = 0; i < tal_count(b11->fallbacks); i++)
72+
json_add_fallback(response, NULL,
73+
b11->fallbacks[i], b11->chain);
74+
json_array_end(response);
75+
}
76+
77+
if (tal_count(b11->routes)) {
78+
size_t i, n;
79+
80+
json_array_start(response, "routes");
81+
for (i = 0; i < tal_count(b11->routes); i++) {
82+
json_array_start(response, NULL);
83+
for (n = 0; n < tal_count(b11->routes[i]); n++) {
84+
json_object_start(response, NULL);
85+
json_add_node_id(response, "pubkey",
86+
&b11->routes[i][n].pubkey);
87+
json_add_short_channel_id(response,
88+
"short_channel_id",
89+
&b11->routes[i][n]
90+
.short_channel_id);
91+
json_add_u64(response, "fee_base_msat",
92+
b11->routes[i][n].fee_base_msat);
93+
json_add_u64(response, "fee_proportional_millionths",
94+
b11->routes[i][n].fee_proportional_millionths);
95+
json_add_num(response, "cltv_expiry_delta",
96+
b11->routes[i][n]
97+
.cltv_expiry_delta);
98+
json_object_end(response);
99+
}
100+
json_array_end(response);
101+
}
102+
json_array_end(response);
103+
}
104+
105+
if (!list_empty(&b11->extra_fields)) {
106+
struct bolt11_field *extra;
107+
108+
json_array_start(response, "extra");
109+
list_for_each(&b11->extra_fields, extra, list) {
110+
char *data = tal_arr(NULL, char, tal_count(extra->data)+1);
111+
size_t i;
112+
113+
for (i = 0; i < tal_count(extra->data); i++)
114+
data[i] = bech32_charset[extra->data[i]];
115+
data[i] = '\0';
116+
json_object_start(response, NULL);
117+
json_add_string(response, "tag",
118+
tal_fmt(data, "%c", extra->tag));
119+
json_add_string(response, "data", data);
120+
tal_free(data);
121+
json_object_end(response);
122+
}
123+
json_array_end(response);
124+
}
125+
126+
json_add_sha256(response, "payment_hash", &b11->payment_hash);
127+
128+
json_add_string(response, "signature", fmt_signature(tmpctx, &b11->sig));
129+
}

common/bolt11_json.h

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef LIGHTNING_COMMON_BOLT11_JSON_H
2+
#define LIGHTNING_COMMON_BOLT11_JSON_H
3+
#include "config.h"
4+
5+
struct bolt11;
6+
struct json_stream;
7+
8+
void json_add_bolt11(struct json_stream *response,
9+
const struct bolt11 *b11);
10+
#endif /* LIGHTNING_COMMON_BOLT11_JSON_H */

common/test/run-bolt11.c

-4
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@
1616
#include <wally_core.h>
1717

1818
/* AUTOGENERATED MOCKS START */
19-
/* Generated stub for type_to_string_ */
20-
const char *type_to_string_(const tal_t *ctx UNNEEDED, const char *typename UNNEEDED,
21-
union printable_types u UNNEEDED)
22-
{ fprintf(stderr, "type_to_string_ called!\n"); abort(); }
2319
/* AUTOGENERATED MOCKS END */
2420

2521
static struct privkey privkey;

lightningd/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ LIGHTNINGD_COMMON_OBJS := \
7676
common/bip32.o \
7777
common/blinding.o \
7878
common/bolt11.o \
79+
common/bolt11_json.o \
7980
common/channel_id.o \
8081
common/channel_config.o \
8182
common/coin_mvt.o \

lightningd/invoice.c

+2-121
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
#include "invoice.h"
2-
#include <bitcoin/address.h>
3-
#include <bitcoin/base58.h>
4-
#include <bitcoin/script.h>
52
#include <ccan/array_size/array_size.h>
63
#include <ccan/asort/asort.h>
74
#include <ccan/json_escape/json_escape.h>
@@ -10,6 +7,7 @@
107
#include <common/amount.h>
118
#include <common/bech32.h>
129
#include <common/bolt11.h>
10+
#include <common/bolt11_json.h>
1311
#if EXPERIMENTAL_FEATURES
1412
#include <common/bolt12.h>
1513
#include <common/bolt12_merkle.h>
@@ -1391,41 +1389,6 @@ static const struct json_command waitinvoice_command = {
13911389
};
13921390
AUTODATA(json_command, &waitinvoice_command);
13931391

1394-
static void json_add_fallback(struct json_stream *response,
1395-
const char *fieldname,
1396-
const u8 *fallback,
1397-
const struct chainparams *chain)
1398-
{
1399-
struct bitcoin_address pkh;
1400-
struct ripemd160 sh;
1401-
struct sha256 wsh;
1402-
1403-
json_object_start(response, fieldname);
1404-
if (is_p2pkh(fallback, &pkh)) {
1405-
json_add_string(response, "type", "P2PKH");
1406-
json_add_string(response, "addr",
1407-
bitcoin_to_base58(tmpctx, chain, &pkh));
1408-
} else if (is_p2sh(fallback, &sh)) {
1409-
json_add_string(response, "type", "P2SH");
1410-
json_add_string(response, "addr",
1411-
p2sh_to_base58(tmpctx, chain, &sh));
1412-
} else if (is_p2wpkh(fallback, &pkh)) {
1413-
char out[73 + strlen(chain->bip173_name)];
1414-
json_add_string(response, "type", "P2WPKH");
1415-
if (segwit_addr_encode(out, chain->bip173_name, 0,
1416-
(const u8 *)&pkh, sizeof(pkh)))
1417-
json_add_string(response, "addr", out);
1418-
} else if (is_p2wsh(fallback, &wsh)) {
1419-
char out[73 + strlen(chain->bip173_name)];
1420-
json_add_string(response, "type", "P2WSH");
1421-
if (segwit_addr_encode(out, chain->bip173_name, 0,
1422-
(const u8 *)&wsh, sizeof(wsh)))
1423-
json_add_string(response, "addr", out);
1424-
}
1425-
json_add_hex_talarr(response, "hex", fallback);
1426-
json_object_end(response);
1427-
}
1428-
14291392
static struct command_result *json_decodepay(struct command *cmd,
14301393
const char *buffer,
14311394
const jsmntok_t *obj UNNEEDED,
@@ -1450,89 +1413,7 @@ static struct command_result *json_decodepay(struct command *cmd,
14501413
}
14511414

14521415
response = json_stream_success(cmd);
1453-
json_add_string(response, "currency", b11->chain->bip173_name);
1454-
json_add_u64(response, "created_at", b11->timestamp);
1455-
json_add_u64(response, "expiry", b11->expiry);
1456-
json_add_node_id(response, "payee", &b11->receiver_id);
1457-
if (b11->msat)
1458-
json_add_amount_msat_compat(response, *b11->msat,
1459-
"msatoshi", "amount_msat");
1460-
if (b11->description) {
1461-
struct json_escape *esc = json_escape(NULL, b11->description);
1462-
json_add_escaped_string(response, "description", take(esc));
1463-
}
1464-
if (b11->description_hash)
1465-
json_add_sha256(response, "description_hash",
1466-
b11->description_hash);
1467-
json_add_num(response, "min_final_cltv_expiry",
1468-
b11->min_final_cltv_expiry);
1469-
if (b11->payment_secret)
1470-
json_add_secret(response, "payment_secret",
1471-
b11->payment_secret);
1472-
if (b11->features)
1473-
json_add_hex_talarr(response, "features", b11->features);
1474-
if (tal_count(b11->fallbacks)) {
1475-
json_array_start(response, "fallbacks");
1476-
for (size_t i = 0; i < tal_count(b11->fallbacks); i++)
1477-
json_add_fallback(response, NULL,
1478-
b11->fallbacks[i], b11->chain);
1479-
json_array_end(response);
1480-
}
1481-
1482-
if (tal_count(b11->routes)) {
1483-
size_t i, n;
1484-
1485-
json_array_start(response, "routes");
1486-
for (i = 0; i < tal_count(b11->routes); i++) {
1487-
json_array_start(response, NULL);
1488-
for (n = 0; n < tal_count(b11->routes[i]); n++) {
1489-
json_object_start(response, NULL);
1490-
json_add_node_id(response, "pubkey",
1491-
&b11->routes[i][n].pubkey);
1492-
json_add_short_channel_id(response,
1493-
"short_channel_id",
1494-
&b11->routes[i][n]
1495-
.short_channel_id);
1496-
json_add_u64(response, "fee_base_msat",
1497-
b11->routes[i][n].fee_base_msat);
1498-
json_add_u64(response, "fee_proportional_millionths",
1499-
b11->routes[i][n].fee_proportional_millionths);
1500-
json_add_num(response, "cltv_expiry_delta",
1501-
b11->routes[i][n]
1502-
.cltv_expiry_delta);
1503-
json_object_end(response);
1504-
}
1505-
json_array_end(response);
1506-
}
1507-
json_array_end(response);
1508-
}
1509-
1510-
if (!list_empty(&b11->extra_fields)) {
1511-
struct bolt11_field *extra;
1512-
1513-
json_array_start(response, "extra");
1514-
list_for_each(&b11->extra_fields, extra, list) {
1515-
char *data = tal_arr(cmd, char, tal_count(extra->data)+1);
1516-
size_t i;
1517-
1518-
for (i = 0; i < tal_count(extra->data); i++)
1519-
data[i] = bech32_charset[extra->data[i]];
1520-
data[i] = '\0';
1521-
json_object_start(response, NULL);
1522-
json_add_string(response, "tag",
1523-
tal_fmt(data, "%c", extra->tag));
1524-
json_add_string(response, "data", data);
1525-
tal_free(data);
1526-
json_object_end(response);
1527-
}
1528-
json_array_end(response);
1529-
}
1530-
1531-
json_add_sha256(response, "payment_hash", &b11->payment_hash);
1532-
1533-
json_add_string(response, "signature",
1534-
type_to_string(cmd, secp256k1_ecdsa_signature,
1535-
&b11->sig));
1416+
json_add_bolt11(response, b11);
15361417
return command_success(cmd, response);
15371418
}
15381419

lightningd/peer_control.c

-1
Original file line numberDiff line numberDiff line change
@@ -1377,7 +1377,6 @@ static struct command_result *json_listpeers(struct command *cmd,
13771377
return command_success(cmd, response);
13781378
}
13791379

1380-
/* Magic marker: remove at your own peril! */
13811380
static const struct json_command listpeers_command = {
13821381
"listpeers",
13831382
"network",

lightningd/test/run-invoice-select-inchan.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,10 @@ void json_add_amount_sat_compat(struct json_stream *result UNNEEDED,
250250
const char *msatfieldname)
251251

252252
{ fprintf(stderr, "json_add_amount_sat_compat called!\n"); abort(); }
253+
/* Generated stub for json_add_bolt11 */
254+
void json_add_bolt11(struct json_stream *response UNNEEDED,
255+
const struct bolt11 *b11 UNNEEDED)
256+
{ fprintf(stderr, "json_add_bolt11 called!\n"); abort(); }
253257
/* Generated stub for json_add_log */
254258
void json_add_log(struct json_stream *result UNNEEDED,
255259
const struct log_book *lr UNNEEDED,
@@ -271,11 +275,6 @@ void json_add_node_id(struct json_stream *response UNNEEDED,
271275
void json_add_preimage(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
272276
const struct preimage *preimage UNNEEDED)
273277
{ fprintf(stderr, "json_add_preimage called!\n"); abort(); }
274-
/* Generated stub for json_add_secret */
275-
void json_add_secret(struct json_stream *response UNNEEDED,
276-
const char *fieldname UNNEEDED,
277-
const struct secret *secret UNNEEDED)
278-
{ fprintf(stderr, "json_add_secret called!\n"); abort(); }
279278
/* Generated stub for json_add_sha256 */
280279
void json_add_sha256(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
281280
const struct sha256 *hash UNNEEDED)

0 commit comments

Comments
 (0)