Skip to content

Commit 572d4db

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 5ecb1ef commit 572d4db

7 files changed

Lines changed: 120 additions & 85 deletions

File tree

plugins/fetchinvoice.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@ static struct command_result *establish_path_fail(struct command *cmd,
585585
static struct command_result *try_establish(struct command *cmd,
586586
struct establishing_paths *epaths)
587587
{
588+
const struct offers_data *od = get_offers_data(cmd->plugin);
588589
struct pubkey target;
589590

590591
if (epaths->sent->direct_dest) {
@@ -605,8 +606,8 @@ static struct command_result *try_establish(struct command *cmd,
605606
epaths->sent->issuer_key = &bpath->path[tal_count(bpath->path)-1]->blinded_node_id;
606607
}
607608

608-
return establish_onion_path(cmd, get_gossmap(cmd->plugin), &id, &target,
609-
disable_connect,
609+
return establish_onion_path(cmd, get_gossmap(cmd->plugin), &od->id, &target,
610+
od->disable_connect,
610611
establish_path_done,
611612
establish_path_fail,
612613
epaths);
@@ -815,15 +816,16 @@ static struct command_result *param_dev_reply_path(struct command *cmd, const ch
815816
return NULL;
816817
}
817818

818-
static bool payer_key(const u8 *public_tweak, size_t public_tweak_len,
819+
static bool payer_key(const struct offers_data *od,
820+
const u8 *public_tweak, size_t public_tweak_len,
819821
struct pubkey *key)
820822
{
821823
struct sha256 tweakhash;
822824

823-
bolt12_alias_tweak(&nodealias_base, public_tweak, public_tweak_len,
825+
bolt12_alias_tweak(&od->nodealias_base, public_tweak, public_tweak_len,
824826
&tweakhash);
825827

826-
*key = id;
828+
*key = od->id;
827829
return secp256k1_ec_pubkey_tweak_add(secp256k1_ctx,
828830
&key->pubkey,
829831
tweakhash.u.u8) == 1;
@@ -836,6 +838,7 @@ static bool payer_key(const u8 *public_tweak, size_t public_tweak_len,
836838
* as payer_id must be same for all recurring payments. */
837839
static u8 *recurrence_invreq_metadata(const tal_t *ctx,
838840
const struct tlv_invoice_request *invreq,
841+
const struct secret *nodealias_base,
839842
const char *rec_label)
840843
{
841844
struct sha256 offer_id, tweak;
@@ -850,7 +853,7 @@ static u8 *recurrence_invreq_metadata(const tal_t *ctx,
850853
rec_label,
851854
strlen(rec_label));
852855

853-
bolt12_alias_tweak(&nodealias_base,
856+
bolt12_alias_tweak(nodealias_base,
854857
tweak_input,
855858
tal_bytelen(tweak_input),
856859
&tweak);
@@ -897,6 +900,7 @@ struct command_result *json_fetchinvoice(struct command *cmd,
897900
const char *buffer,
898901
const jsmntok_t *params)
899902
{
903+
const struct offers_data *od = get_offers_data(cmd->plugin);
900904
struct amount_msat *msat;
901905
const char *rec_label, *payer_note;
902906
u8 *payer_metadata;
@@ -1054,7 +1058,9 @@ struct command_result *json_fetchinvoice(struct command *cmd,
10541058
"needs recurrence_label");
10551059

10561060
invreq->invreq_metadata
1057-
= recurrence_invreq_metadata(invreq, invreq, rec_label);
1061+
= recurrence_invreq_metadata(invreq, invreq,
1062+
&od->nodealias_base,
1063+
rec_label);
10581064
} else {
10591065
/* BOLT-recurrence #12:
10601066
* - otherwise:
@@ -1088,7 +1094,7 @@ struct command_result *json_fetchinvoice(struct command *cmd,
10881094

10891095
/* We derive transient payer_id from invreq_metadata */
10901096
invreq->invreq_payer_id = tal(invreq, struct pubkey);
1091-
if (!payer_key(invreq->invreq_metadata,
1097+
if (!payer_key(od, invreq->invreq_metadata,
10921098
tal_bytelen(invreq->invreq_metadata),
10931099
invreq->invreq_payer_id)) {
10941100
/* Doesn't happen! */
@@ -1146,6 +1152,7 @@ struct command_result *json_cancelrecurringinvoice(struct command *cmd,
11461152
const char *buffer,
11471153
const jsmntok_t *params)
11481154
{
1155+
const struct offers_data *od = get_offers_data(cmd->plugin);
11491156
const char *rec_label, *payer_note;
11501157
struct out_req *req;
11511158
struct tlv_invoice_request *invreq;
@@ -1220,11 +1227,13 @@ struct command_result *json_cancelrecurringinvoice(struct command *cmd,
12201227
}
12211228

12221229
invreq->invreq_metadata
1223-
= recurrence_invreq_metadata(invreq, invreq, rec_label);
1230+
= recurrence_invreq_metadata(invreq, invreq,
1231+
&od->nodealias_base,
1232+
rec_label);
12241233

12251234
/* We derive transient payer_id from invreq_metadata */
12261235
invreq->invreq_payer_id = tal(invreq, struct pubkey);
1227-
if (!payer_key(invreq->invreq_metadata,
1236+
if (!payer_key(od, invreq->invreq_metadata,
12281237
tal_bytelen(invreq->invreq_metadata),
12291238
invreq->invreq_payer_id)) {
12301239
/* Doesn't happen! */
@@ -1530,6 +1539,7 @@ struct command_result *json_sendinvoice(struct command *cmd,
15301539
const char *buffer,
15311540
const jsmntok_t *params)
15321541
{
1542+
const struct offers_data *od = get_offers_data(cmd->plugin);
15331543
struct amount_msat *msat;
15341544
u32 *timeout;
15351545
struct sent *sent = tal(cmd, struct sent);
@@ -1602,7 +1612,7 @@ struct command_result *json_sendinvoice(struct command *cmd,
16021612
* - MUST set `invoice_node_id` to the final `blinded_node_id` on the path it received the invoice request
16031613
*/
16041614
sent->inv->invoice_node_id = tal(sent->inv, struct pubkey);
1605-
sent->inv->invoice_node_id->pubkey = id.pubkey;
1615+
sent->inv->invoice_node_id->pubkey = od->id.pubkey;
16061616

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

plugins/offers.c

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -32,36 +32,31 @@
3232
#define HEADER_LEN crypto_secretstream_xchacha20poly1305_HEADERBYTES
3333
#define ABYTES crypto_secretstream_xchacha20poly1305_ABYTES
3434

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

5852
struct gossmap *get_gossmap(struct plugin *plugin)
5953
{
60-
if (!global_gossmap)
61-
init_gossmap(plugin);
54+
struct offers_data *od = get_offers_data(plugin);
55+
if (!od->global_gossmap_)
56+
init_gossmap(plugin, od);
6257
else
63-
gossmap_refresh(global_gossmap);
64-
return global_gossmap;
58+
gossmap_refresh(od->global_gossmap_);
59+
return od->global_gossmap_;
6560
}
6661

6762
/* BOLT #12:
@@ -71,6 +66,7 @@ struct gossmap *get_gossmap(struct plugin *plugin)
7166
*/
7267
bool we_want_blinded_path(struct plugin *plugin, bool for_payment)
7368
{
69+
const struct offers_data *od = get_offers_data(plugin);
7470
struct node_id local_nodeid;
7571
const struct gossmap_node *node;
7672
const u8 *nannounce;
@@ -82,7 +78,7 @@ bool we_want_blinded_path(struct plugin *plugin, bool for_payment)
8278
u8 rgb_color[3], alias[32];
8379
struct tlv_node_ann_tlvs *na_tlvs;
8480

85-
node_id_from_pubkey(&local_nodeid, &id);
81+
node_id_from_pubkey(&local_nodeid, &od->id);
8682

8783
node = gossmap_find_node(gossmap, &local_nodeid);
8884
if (!node)
@@ -237,6 +233,7 @@ send_onion_reply(struct command *cmd,
237233
struct blinded_path *reply_path,
238234
struct tlv_onionmsg_tlv *payload)
239235
{
236+
const struct offers_data *od = get_offers_data(cmd->plugin);
240237
struct onion_reply *onion_reply;
241238

242239
onion_reply = tal(cmd, struct onion_reply);
@@ -253,8 +250,8 @@ send_onion_reply(struct command *cmd,
253250
}
254251

255252
return establish_onion_path(cmd, get_gossmap(cmd->plugin),
256-
&id, &onion_reply->reply_path->first_node_id.pubkey,
257-
disable_connect,
253+
&od->id, &onion_reply->reply_path->first_node_id.pubkey,
254+
od->disable_connect,
258255
send_onion_reply_after_established,
259256
send_onion_reply_not_established,
260257
onion_reply);
@@ -433,8 +430,9 @@ static struct command_result *block_added_notify(struct command *cmd,
433430
const char *buf,
434431
const jsmntok_t *params)
435432
{
433+
struct offers_data *od = get_offers_data(cmd->plugin);
436434
const char *err = json_scan(cmd, buf, params, "{block_added:{height:%}}",
437-
JSON_SCAN(json_to_u32, &blockheight));
435+
JSON_SCAN(json_to_u32, &od->blockheight));
438436
if (err)
439437
plugin_err(cmd->plugin, "Failed to parse block_added (%.*s): %s",
440438
json_tok_full_len(params),
@@ -1620,34 +1618,36 @@ static const char *init(struct command *init_cmd,
16201618
const char *buf UNUSED,
16211619
const jsmntok_t *config UNUSED)
16221620
{
1621+
struct offers_data *od = get_offers_data(init_cmd->plugin);
1622+
16231623
rpc_scan(init_cmd, "getinfo",
16241624
take(json_out_obj(NULL, NULL, NULL)),
1625-
"{id:%}", JSON_SCAN(json_to_pubkey, &id));
1625+
"{id:%}", JSON_SCAN(json_to_pubkey, &od->id));
16261626

16271627
rpc_scan(init_cmd, "getchaininfo",
16281628
take(json_out_obj(NULL, "last_height", NULL)),
1629-
"{headercount:%}", JSON_SCAN(json_to_u32, &blockheight));
1629+
"{headercount:%}", JSON_SCAN(json_to_u32, &od->blockheight));
16301630

16311631
rpc_scan(init_cmd, "listconfigs",
16321632
take(json_out_obj(NULL, NULL, NULL)),
16331633
"{configs:"
16341634
"{cltv-final:{value_int:%}}}",
1635-
JSON_SCAN(json_to_u16, &cltv_final));
1635+
JSON_SCAN(json_to_u16, &od->cltv_final));
16361636

16371637
rpc_scan(init_cmd, "makesecret",
16381638
take(json_out_obj(NULL, "string", BOLT12_ID_BASE_STRING)),
16391639
"{secret:%}",
1640-
JSON_SCAN(json_to_secret, &invoicesecret_base));
1640+
JSON_SCAN(json_to_secret, &od->invoicesecret_base));
16411641

16421642
rpc_scan(init_cmd, "makesecret",
16431643
take(json_out_obj(NULL, "string", "offer-blinded-path")),
16441644
"{secret:%}",
1645-
JSON_SCAN(json_to_secret, &offerblinding_base));
1645+
JSON_SCAN(json_to_secret, &od->offerblinding_base));
16461646

16471647
rpc_scan(init_cmd, "makesecret",
16481648
take(json_out_obj(NULL, "string", NODE_ALIAS_BASE_STRING)),
16491649
"{secret:%}",
1650-
JSON_SCAN(json_to_secret, &nodealias_base));
1650+
JSON_SCAN(json_to_secret, &od->nodealias_base));
16511651

16521652
return NULL;
16531653
}
@@ -1708,22 +1708,28 @@ static bool scid_jsonfmt(struct plugin *plugin, struct json_stream *js, const ch
17081708
int main(int argc, char *argv[])
17091709
{
17101710
setup_locale();
1711+
struct offers_data *od = tal(NULL, struct offers_data);
1712+
1713+
od->disable_connect = false;
1714+
od->dev_invoice_bpath_scid = false;
1715+
od->dev_invoice_internal_scid = NULL;
1716+
od->global_gossmap_ = NULL;
17111717

17121718
/* We deal in UTC; mktime() uses local time */
17131719
setenv("TZ", "", 1);
1714-
plugin_main(argv, init, NULL, PLUGIN_RESTARTABLE, true, NULL,
1720+
plugin_main(argv, init, take(od), PLUGIN_RESTARTABLE, true, NULL,
17151721
commands, ARRAY_SIZE(commands),
17161722
notifications, ARRAY_SIZE(notifications),
17171723
hooks, ARRAY_SIZE(hooks),
17181724
NULL, 0,
17191725
plugin_option("fetchinvoice-noconnect", "flag",
17201726
"Don't try to connect directly to fetch/pay an invoice.",
1721-
flag_option, flag_jsonfmt, &disable_connect),
1727+
flag_option, flag_jsonfmt, &od->disable_connect),
17221728
plugin_option_dev("dev-invoice-bpath-scid", "flag",
17231729
"Use short_channel_id instead of pubkey when creating a blinded payment path",
1724-
flag_option, flag_jsonfmt, &dev_invoice_bpath_scid),
1730+
flag_option, flag_jsonfmt, &od->dev_invoice_bpath_scid),
17251731
plugin_option_dev("dev-invoice-internal-scid", "string",
17261732
"Use short_channel_id instead of pubkey when creating a blinded payment path",
1727-
scid_option, scid_jsonfmt, &dev_invoice_internal_scid),
1733+
scid_option, scid_jsonfmt, &od->dev_invoice_internal_scid),
17281734
NULL);
17291735
}

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
@@ -218,6 +218,7 @@ struct command_result *handle_invoice(struct command *cmd,
218218
struct blinded_path *reply_path STEALS,
219219
const struct secret *secret)
220220
{
221+
const struct offers_data *od = get_offers_data(cmd->plugin);
221222
size_t len = tal_count(invbin);
222223
struct inv *inv = tal(cmd, struct inv);
223224
struct out_req *req;
@@ -243,7 +244,7 @@ struct command_result *handle_invoice(struct command *cmd,
243244
invoice_invreq_id(inv->inv, &invreq_id_nopath);
244245
inv->inv->invreq_paths = invreq_paths;
245246

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

0 commit comments

Comments
 (0)