Skip to content

Commit 31105a0

Browse files
committed
offers: encapsulate globals in plugin_get_data()
This is how modern plugins do it, and it has the benefit of not requiring extra code for memleak tracking. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent 24d4d21 commit 31105a0

File tree

6 files changed

+116
-85
lines changed

6 files changed

+116
-85
lines changed

plugins/fetchinvoice.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,7 @@ static struct command_result *establish_path_fail(struct command *cmd,
594594
static struct command_result *try_establish(struct command *cmd,
595595
struct establishing_paths *epaths)
596596
{
597+
const struct offers_data *od = get_offers_data(cmd->plugin);
597598
struct pubkey target;
598599

599600
if (epaths->sent->direct_dest) {
@@ -614,8 +615,8 @@ static struct command_result *try_establish(struct command *cmd,
614615
epaths->sent->issuer_key = &bpath->path[tal_count(bpath->path)-1]->blinded_node_id;
615616
}
616617

617-
return establish_onion_path(cmd, get_gossmap(cmd->plugin), &id, &target,
618-
disable_connect,
618+
return establish_onion_path(cmd, get_gossmap(cmd->plugin), &od->id, &target,
619+
od->disable_connect,
619620
establish_path_done,
620621
establish_path_fail,
621622
epaths);
@@ -824,15 +825,16 @@ static struct command_result *param_dev_reply_path(struct command *cmd, const ch
824825
return NULL;
825826
}
826827

827-
static bool payer_key(const u8 *public_tweak, size_t public_tweak_len,
828+
static bool payer_key(const struct offers_data *od,
829+
const u8 *public_tweak, size_t public_tweak_len,
828830
struct pubkey *key)
829831
{
830832
struct sha256 tweakhash;
831833

832-
bolt12_alias_tweak(&nodealias_base, public_tweak, public_tweak_len,
834+
bolt12_alias_tweak(&od->nodealias_base, public_tweak, public_tweak_len,
833835
&tweakhash);
834836

835-
*key = id;
837+
*key = od->id;
836838
return secp256k1_ec_pubkey_tweak_add(secp256k1_ctx,
837839
&key->pubkey,
838840
tweakhash.u.u8) == 1;
@@ -845,6 +847,7 @@ static bool payer_key(const u8 *public_tweak, size_t public_tweak_len,
845847
* as payer_id must be same for all recurring payments. */
846848
static u8 *recurrence_invreq_metadata(const tal_t *ctx,
847849
const struct tlv_invoice_request *invreq,
850+
const struct secret *nodealias_base,
848851
const char *rec_label)
849852
{
850853
struct sha256 offer_id, tweak;
@@ -859,7 +862,7 @@ static u8 *recurrence_invreq_metadata(const tal_t *ctx,
859862
rec_label,
860863
strlen(rec_label));
861864

862-
bolt12_alias_tweak(&nodealias_base,
865+
bolt12_alias_tweak(nodealias_base,
863866
tweak_input,
864867
tal_bytelen(tweak_input),
865868
&tweak);
@@ -906,6 +909,7 @@ struct command_result *json_fetchinvoice(struct command *cmd,
906909
const char *buffer,
907910
const jsmntok_t *params)
908911
{
912+
const struct offers_data *od = get_offers_data(cmd->plugin);
909913
struct amount_msat *msat;
910914
const char *rec_label, *payer_note;
911915
u8 *payer_metadata;
@@ -1063,7 +1067,9 @@ struct command_result *json_fetchinvoice(struct command *cmd,
10631067
"needs recurrence_label");
10641068

10651069
invreq->invreq_metadata
1066-
= recurrence_invreq_metadata(invreq, invreq, rec_label);
1070+
= recurrence_invreq_metadata(invreq, invreq,
1071+
&od->nodealias_base,
1072+
rec_label);
10671073
} else {
10681074
/* BOLT-recurrence #12:
10691075
* - otherwise:
@@ -1097,7 +1103,7 @@ struct command_result *json_fetchinvoice(struct command *cmd,
10971103

10981104
/* We derive transient payer_id from invreq_metadata */
10991105
invreq->invreq_payer_id = tal(invreq, struct pubkey);
1100-
if (!payer_key(invreq->invreq_metadata,
1106+
if (!payer_key(od, invreq->invreq_metadata,
11011107
tal_bytelen(invreq->invreq_metadata),
11021108
invreq->invreq_payer_id)) {
11031109
/* Doesn't happen! */
@@ -1155,6 +1161,7 @@ struct command_result *json_cancelrecurringinvoice(struct command *cmd,
11551161
const char *buffer,
11561162
const jsmntok_t *params)
11571163
{
1164+
const struct offers_data *od = get_offers_data(cmd->plugin);
11581165
const char *rec_label, *payer_note;
11591166
struct out_req *req;
11601167
struct tlv_invoice_request *invreq;
@@ -1229,11 +1236,13 @@ struct command_result *json_cancelrecurringinvoice(struct command *cmd,
12291236
}
12301237

12311238
invreq->invreq_metadata
1232-
= recurrence_invreq_metadata(invreq, invreq, rec_label);
1239+
= recurrence_invreq_metadata(invreq, invreq,
1240+
&od->nodealias_base,
1241+
rec_label);
12331242

12341243
/* We derive transient payer_id from invreq_metadata */
12351244
invreq->invreq_payer_id = tal(invreq, struct pubkey);
1236-
if (!payer_key(invreq->invreq_metadata,
1245+
if (!payer_key(od, invreq->invreq_metadata,
12371246
tal_bytelen(invreq->invreq_metadata),
12381247
invreq->invreq_payer_id)) {
12391248
/* Doesn't happen! */
@@ -1539,6 +1548,7 @@ struct command_result *json_sendinvoice(struct command *cmd,
15391548
const char *buffer,
15401549
const jsmntok_t *params)
15411550
{
1551+
const struct offers_data *od = get_offers_data(cmd->plugin);
15421552
struct amount_msat *msat;
15431553
u32 *timeout;
15441554
struct sent *sent = tal(cmd, struct sent);
@@ -1611,7 +1621,7 @@ struct command_result *json_sendinvoice(struct command *cmd,
16111621
* - MUST set `invoice_node_id` to the final `blinded_node_id` on the path it received the invoice request
16121622
*/
16131623
sent->inv->invoice_node_id = tal(sent->inv, struct pubkey);
1614-
sent->inv->invoice_node_id->pubkey = id.pubkey;
1624+
sent->inv->invoice_node_id->pubkey = od->id.pubkey;
16151625

16161626
/* BOLT #12:
16171627
* - if the expiry for accepting payment is not 7200 seconds

plugins/offers.c

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -30,36 +30,31 @@
3030
#define HEADER_LEN crypto_secretstream_xchacha20poly1305_HEADERBYTES
3131
#define ABYTES crypto_secretstream_xchacha20poly1305_ABYTES
3232

33-
struct pubkey id;
34-
u32 blockheight;
35-
u16 cltv_final;
36-
bool disable_connect;
37-
bool dev_invoice_bpath_scid;
38-
struct short_channel_id *dev_invoice_internal_scid;
39-
struct secret invoicesecret_base;
40-
struct secret offerblinding_base;
41-
struct secret nodealias_base;
42-
static struct gossmap *global_gossmap;
43-
44-
static void init_gossmap(struct plugin *plugin)
33+
struct offers_data *get_offers_data(struct plugin *plugin)
4534
{
46-
global_gossmap
47-
= notleak_with_children(gossmap_load(plugin,
48-
GOSSIP_STORE_FILENAME,
49-
plugin_gossmap_logcb,
50-
plugin));
51-
if (!global_gossmap)
35+
return plugin_get_data(plugin, struct offers_data);
36+
}
37+
38+
static void init_gossmap(struct plugin *plugin,
39+
struct offers_data *od)
40+
{
41+
od->global_gossmap_ = gossmap_load(plugin,
42+
GOSSIP_STORE_FILENAME,
43+
plugin_gossmap_logcb,
44+
plugin);
45+
if (!od->global_gossmap_)
5246
plugin_err(plugin, "Could not load gossmap %s: %s",
5347
GOSSIP_STORE_FILENAME, strerror(errno));
5448
}
5549

5650
struct gossmap *get_gossmap(struct plugin *plugin)
5751
{
58-
if (!global_gossmap)
59-
init_gossmap(plugin);
52+
struct offers_data *od = get_offers_data(plugin);
53+
if (!od->global_gossmap_)
54+
init_gossmap(plugin, od);
6055
else
61-
gossmap_refresh(global_gossmap);
62-
return global_gossmap;
56+
gossmap_refresh(od->global_gossmap_);
57+
return od->global_gossmap_;
6358
}
6459

6560
/* BOLT #12:
@@ -69,6 +64,7 @@ struct gossmap *get_gossmap(struct plugin *plugin)
6964
*/
7065
bool we_want_blinded_path(struct plugin *plugin, bool for_payment)
7166
{
67+
const struct offers_data *od = get_offers_data(plugin);
7268
struct node_id local_nodeid;
7369
const struct gossmap_node *node;
7470
const u8 *nannounce;
@@ -80,7 +76,7 @@ bool we_want_blinded_path(struct plugin *plugin, bool for_payment)
8076
u8 rgb_color[3], alias[32];
8177
struct tlv_node_ann_tlvs *na_tlvs;
8278

83-
node_id_from_pubkey(&local_nodeid, &id);
79+
node_id_from_pubkey(&local_nodeid, &od->id);
8480

8581
node = gossmap_find_node(gossmap, &local_nodeid);
8682
if (!node)
@@ -235,6 +231,7 @@ send_onion_reply(struct command *cmd,
235231
struct blinded_path *reply_path,
236232
struct tlv_onionmsg_tlv *payload)
237233
{
234+
const struct offers_data *od = get_offers_data(cmd->plugin);
238235
struct onion_reply *onion_reply;
239236

240237
onion_reply = tal(cmd, struct onion_reply);
@@ -251,8 +248,8 @@ send_onion_reply(struct command *cmd,
251248
}
252249

253250
return establish_onion_path(cmd, get_gossmap(cmd->plugin),
254-
&id, &onion_reply->reply_path->first_node_id.pubkey,
255-
disable_connect,
251+
&od->id, &onion_reply->reply_path->first_node_id.pubkey,
252+
od->disable_connect,
256253
send_onion_reply_after_established,
257254
send_onion_reply_not_established,
258255
onion_reply);
@@ -421,8 +418,9 @@ static struct command_result *block_added_notify(struct command *cmd,
421418
const char *buf,
422419
const jsmntok_t *params)
423420
{
421+
struct offers_data *od = get_offers_data(cmd->plugin);
424422
const char *err = json_scan(cmd, buf, params, "{block_added:{height:%}}",
425-
JSON_SCAN(json_to_u32, &blockheight));
423+
JSON_SCAN(json_to_u32, &od->blockheight));
426424
if (err)
427425
plugin_err(cmd->plugin, "Failed to parse block_added (%.*s): %s",
428426
json_tok_full_len(params),
@@ -1517,34 +1515,36 @@ static const char *init(struct command *init_cmd,
15171515
const char *buf UNUSED,
15181516
const jsmntok_t *config UNUSED)
15191517
{
1518+
struct offers_data *od = get_offers_data(init_cmd->plugin);
1519+
15201520
rpc_scan(init_cmd, "getinfo",
15211521
take(json_out_obj(NULL, NULL, NULL)),
1522-
"{id:%}", JSON_SCAN(json_to_pubkey, &id));
1522+
"{id:%}", JSON_SCAN(json_to_pubkey, &od->id));
15231523

15241524
rpc_scan(init_cmd, "getchaininfo",
15251525
take(json_out_obj(NULL, "last_height", NULL)),
1526-
"{headercount:%}", JSON_SCAN(json_to_u32, &blockheight));
1526+
"{headercount:%}", JSON_SCAN(json_to_u32, &od->blockheight));
15271527

15281528
rpc_scan(init_cmd, "listconfigs",
15291529
take(json_out_obj(NULL, NULL, NULL)),
15301530
"{configs:"
15311531
"{cltv-final:{value_int:%}}}",
1532-
JSON_SCAN(json_to_u16, &cltv_final));
1532+
JSON_SCAN(json_to_u16, &od->cltv_final));
15331533

15341534
rpc_scan(init_cmd, "makesecret",
15351535
take(json_out_obj(NULL, "string", BOLT12_ID_BASE_STRING)),
15361536
"{secret:%}",
1537-
JSON_SCAN(json_to_secret, &invoicesecret_base));
1537+
JSON_SCAN(json_to_secret, &od->invoicesecret_base));
15381538

15391539
rpc_scan(init_cmd, "makesecret",
15401540
take(json_out_obj(NULL, "string", "offer-blinded-path")),
15411541
"{secret:%}",
1542-
JSON_SCAN(json_to_secret, &offerblinding_base));
1542+
JSON_SCAN(json_to_secret, &od->offerblinding_base));
15431543

15441544
rpc_scan(init_cmd, "makesecret",
15451545
take(json_out_obj(NULL, "string", NODE_ALIAS_BASE_STRING)),
15461546
"{secret:%}",
1547-
JSON_SCAN(json_to_secret, &nodealias_base));
1547+
JSON_SCAN(json_to_secret, &od->nodealias_base));
15481548

15491549
return NULL;
15501550
}
@@ -1605,22 +1605,27 @@ static bool scid_jsonfmt(struct plugin *plugin, struct json_stream *js, const ch
16051605
int main(int argc, char *argv[])
16061606
{
16071607
setup_locale();
1608+
struct offers_data *od = tal(NULL, struct offers_data);
1609+
1610+
od->disable_connect = false;
1611+
od->dev_invoice_bpath_scid = false;
1612+
od->dev_invoice_internal_scid = NULL;
16081613

16091614
/* We deal in UTC; mktime() uses local time */
16101615
setenv("TZ", "", 1);
1611-
plugin_main(argv, init, NULL, PLUGIN_RESTARTABLE, true, NULL,
1616+
plugin_main(argv, init, take(od), PLUGIN_RESTARTABLE, true, NULL,
16121617
commands, ARRAY_SIZE(commands),
16131618
notifications, ARRAY_SIZE(notifications),
16141619
hooks, ARRAY_SIZE(hooks),
16151620
NULL, 0,
16161621
plugin_option("fetchinvoice-noconnect", "flag",
16171622
"Don't try to connect directly to fetch/pay an invoice.",
1618-
flag_option, flag_jsonfmt, &disable_connect),
1623+
flag_option, flag_jsonfmt, &od->disable_connect),
16191624
plugin_option_dev("dev-invoice-bpath-scid", "flag",
16201625
"Use short_channel_id instead of pubkey when creating a blinded payment path",
1621-
flag_option, flag_jsonfmt, &dev_invoice_bpath_scid),
1626+
flag_option, flag_jsonfmt, &od->dev_invoice_bpath_scid),
16221627
plugin_option_dev("dev-invoice-internal-scid", "string",
16231628
"Use short_channel_id instead of pubkey when creating a blinded payment path",
1624-
scid_option, scid_jsonfmt, &dev_invoice_internal_scid),
1629+
scid_option, scid_jsonfmt, &od->dev_invoice_internal_scid),
16251630
NULL);
16261631
}

plugins/offers.h

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,31 @@ struct command;
77
struct onion_message;
88
struct plugin;
99

10-
/* This is me. */
11-
extern struct pubkey id;
12-
/* --fetchinvoice-noconnect */
13-
extern bool disable_connect;
14-
/* --cltv-final */
15-
extern u16 cltv_final;
16-
/* Current header_count */
17-
extern u32 blockheight;
18-
/* Basis for invoice path_secrets */
19-
extern struct secret invoicesecret_base;
20-
/* Base for offers path_secrets */
21-
extern struct secret offerblinding_base;
22-
/* Base for node aliases for invoice requests */
23-
extern struct secret nodealias_base;
24-
/* --dev-invoice-bpath-scid */
25-
extern bool dev_invoice_bpath_scid;
26-
/* --dev-invoice-internal-scid */
27-
extern struct short_channel_id *dev_invoice_internal_scid;
28-
/* This is me. */
29-
extern struct pubkey id;
10+
/* plugin_data for this plugin */
11+
struct offers_data {
12+
/* This is me. */
13+
struct pubkey id;
14+
/* --fetchinvoice-noconnect */
15+
bool disable_connect;
16+
/* --cltv-final */
17+
u16 cltv_final;
18+
/* Current header_count */
19+
u32 blockheight;
20+
/* Basis for invoice path_secrets */
21+
struct secret invoicesecret_base;
22+
/* Base for offers path_secrets */
23+
struct secret offerblinding_base;
24+
/* Base for node aliases for invoice requests */
25+
struct secret nodealias_base;
26+
/* --dev-invoice-bpath-scid */
27+
bool dev_invoice_bpath_scid;
28+
/* --dev-invoice-internal-scid */
29+
struct short_channel_id *dev_invoice_internal_scid;
30+
/* Use get_gossmap() to access this! */
31+
struct gossmap *global_gossmap_;
32+
};
33+
34+
struct offers_data *get_offers_data(struct plugin *plugin);
3035

3136
/* Helper to send a reply (connecting if required), and discard result */
3237
struct command_result *WARN_UNUSED_RESULT

plugins/offers_inv_hook.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ struct command_result *handle_invoice(struct command *cmd,
217217
struct blinded_path *reply_path STEALS,
218218
const struct secret *secret)
219219
{
220+
const struct offers_data *od = get_offers_data(cmd->plugin);
220221
size_t len = tal_count(invbin);
221222
struct inv *inv = tal(cmd, struct inv);
222223
struct out_req *req;
@@ -242,7 +243,7 @@ struct command_result *handle_invoice(struct command *cmd,
242243
invoice_invreq_id(inv->inv, &invreq_id_nopath);
243244
inv->inv->invreq_paths = invreq_paths;
244245

245-
path_secret = bolt12_path_id(tmpctx, &offerblinding_base, &invreq_id_nopath);
246+
path_secret = bolt12_path_id(tmpctx, &od->offerblinding_base, &invreq_id_nopath);
246247
if (!memeq(path_secret, tal_count(path_secret),
247248
secret, sizeof(*secret))) {
248249
if (command_dev_apis(cmd))

0 commit comments

Comments
 (0)