From 85cd7522420077753414da1fe13e88d608bca6f7 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Fri, 8 May 2020 16:46:56 +0200 Subject: [PATCH] paymod: Generate type-safe accessor functions for modifier data This should make it easy for JSON-RPC functions and modifiers to get the associated data for a given modifier name. Useful if a modifier needs to access its parent's modifier data, or in other functions that need to access modifier data, e.g., when passing destination pointers into the `param()` call. --- plugins/libplugin-pay.c | 13 +++++++++++++ plugins/libplugin-pay.h | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c index 2c7174616..630f7d3b2 100644 --- a/plugins/libplugin-pay.c +++ b/plugins/libplugin-pay.c @@ -146,6 +146,19 @@ void payment_continue(struct payment *p) abort(); } +void *payment_mod_get_data(const struct payment *p, + const struct payment_modifier *mod) +{ + for (size_t i = 0; p->modifiers[i] != NULL; i++) + if (p->modifiers[i] == mod) + return p->modifier_data[i]; + + /* If we ever get here it means that we asked for the data for a + * non-existent modifier. This is a compile-time/wiring issue, so we + * better check that modifiers match the data we ask for. */ + abort(); +} + static inline struct dummy_data * dummy_data_init(struct payment *p) { diff --git a/plugins/libplugin-pay.h b/plugins/libplugin-pay.h index 4b74ed6f4..783e088fa 100644 --- a/plugins/libplugin-pay.h +++ b/plugins/libplugin-pay.h @@ -120,6 +120,9 @@ struct payment_modifier { void (*post_step_cb)(void *data, struct payment *p); }; +void *payment_mod_get_data(const struct payment *payment, + const struct payment_modifier *mod); + #define REGISTER_PAYMENT_MODIFIER(name, data_type, data_init_cb, step_cb) \ struct payment_modifier name##_pay_mod = { \ stringify(name), \ @@ -129,12 +132,22 @@ struct payment_modifier { void (*)(data_type, struct payment *), step_cb), \ }; +/* The UNUSED marker is used to shut some compilers up. */ +#define REGISTER_PAYMENT_MODIFIER_HEADER(name, data_type) \ + extern struct payment_modifier name##_pay_mod; \ + UNUSED static inline data_type *payment_mod_##name##_get_data( \ + const struct payment *p) \ + { \ + return payment_mod_get_data(p, &name##_pay_mod); \ + } + struct dummy_data { unsigned int *dummy_param; }; /* List of globally available payment modifiers. */ extern struct payment_modifier dummy_pay_mod; +REGISTER_PAYMENT_MODIFIER_HEADER(retry, struct retry_mod_data); struct payment *payment_new(tal_t *ctx, struct command *cmd, struct payment *parent,