mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 14:42:40 +01:00
pay: move preapproveinvoice command out so it can be called bu check
.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Added: JSON-RPC: `check` `keysend` now checks with HSM that it will approve it.
This commit is contained in:
parent
e1034eec43
commit
68c4b83ab1
3 changed files with 39 additions and 97 deletions
|
@ -3809,87 +3809,6 @@ static void payee_incoming_limit_step_cb(void *d UNUSED, struct payment *p)
|
|||
REGISTER_PAYMENT_MODIFIER(payee_incoming_limit, void *, NULL,
|
||||
payee_incoming_limit_step_cb);
|
||||
|
||||
/*****************************************************************************
|
||||
* check_preapproveinvoice
|
||||
*
|
||||
* @desc submit the invoice to the HSM for approval, fail the payment if not approved.
|
||||
*
|
||||
* This paymod checks the invoice for approval with the HSM, which might:
|
||||
* - check with the user for specific approval
|
||||
* - enforce velocity controls
|
||||
* - automatically approve the invoice (default)
|
||||
*/
|
||||
|
||||
static struct command_result *
|
||||
check_preapproveinvoice_allow(struct command *cmd,
|
||||
const char *buf,
|
||||
const jsmntok_t *result,
|
||||
struct payment *p)
|
||||
{
|
||||
/* On success, an empty object is returned. */
|
||||
// struct preapproveinvoice_data *d
|
||||
|
||||
struct preapproveinvoice_data *d = payment_mod_check_preapproveinvoice_get_data(payment_root(p));
|
||||
d->approved = true;
|
||||
paymod_log(p, LOG_DBG, "Result from preapproveinvoice: allow");
|
||||
payment_continue(p);
|
||||
return command_still_pending(cmd);
|
||||
}
|
||||
|
||||
static struct command_result *preapproveinvoice_rpc_failure(struct command *cmd,
|
||||
const char *buffer,
|
||||
const jsmntok_t *toks,
|
||||
struct payment *p)
|
||||
{
|
||||
payment_abort(p,
|
||||
"Failing payment due to a failed RPC call: %.*s",
|
||||
toks->end - toks->start, buffer + toks->start);
|
||||
return command_still_pending(cmd);
|
||||
}
|
||||
|
||||
static void check_preapproveinvoice_start(struct preapproveinvoice_data *d UNUSED, struct payment *p)
|
||||
{
|
||||
struct payment *root = payment_root(p);
|
||||
|
||||
struct preapproveinvoice_data *data =
|
||||
payment_mod_check_preapproveinvoice_get_data(root);
|
||||
/* If the root payment was used to send the
|
||||
* `preapproveinvoice` message to the signer, we don't need to
|
||||
* do that again. */
|
||||
if (data->approved) {
|
||||
return payment_continue(p);
|
||||
}
|
||||
|
||||
paymod_log(p, LOG_DBG, "Calling preapproveinvoice on signer for payment=%"PRIu64, root->id);
|
||||
/* Ask the HSM if the invoice is OK to pay */
|
||||
struct out_req *req;
|
||||
req = jsonrpc_request_start(p->plugin, NULL, "preapproveinvoice",
|
||||
&check_preapproveinvoice_allow,
|
||||
&preapproveinvoice_rpc_failure, p);
|
||||
/* FIXME: rename parameter to invstring */
|
||||
json_add_string(req->js, "bolt11", p->invstring);
|
||||
(void) send_outreq(p->plugin, req);
|
||||
}
|
||||
|
||||
static struct preapproveinvoice_data* preapproveinvoice_data_init(struct payment *p)
|
||||
{
|
||||
struct preapproveinvoice_data *d;
|
||||
/* Only keep state on the root. We will use the root's flag
|
||||
* for all payments. */
|
||||
if (p == payment_root(p)) {
|
||||
d = tal(p, struct preapproveinvoice_data);
|
||||
d->approved = false;
|
||||
return d;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_PAYMENT_MODIFIER(check_preapproveinvoice,
|
||||
struct preapproveinvoice_data *,
|
||||
preapproveinvoice_data_init,
|
||||
check_preapproveinvoice_start);
|
||||
|
||||
static struct route_exclusions_data *
|
||||
route_exclusions_data_init(struct payment *p)
|
||||
{
|
||||
|
|
|
@ -435,10 +435,6 @@ struct route_exclusions_data {
|
|||
struct route_exclusion **exclusions;
|
||||
};
|
||||
|
||||
struct preapproveinvoice_data {
|
||||
bool approved;
|
||||
};
|
||||
|
||||
/* List of globally available payment modifiers. */
|
||||
REGISTER_PAYMENT_MODIFIER_HEADER(retry, struct retry_mod_data);
|
||||
REGISTER_PAYMENT_MODIFIER_HEADER(routehints, struct routehints_data);
|
||||
|
@ -460,7 +456,6 @@ REGISTER_PAYMENT_MODIFIER_HEADER(local_channel_hints, void);
|
|||
* each of those channels can bear. */
|
||||
REGISTER_PAYMENT_MODIFIER_HEADER(payee_incoming_limit, void);
|
||||
REGISTER_PAYMENT_MODIFIER_HEADER(route_exclusions, struct route_exclusions_data);
|
||||
REGISTER_PAYMENT_MODIFIER_HEADER(check_preapproveinvoice, struct preapproveinvoice_data);
|
||||
|
||||
|
||||
struct payment *payment_new(tal_t *ctx, struct command *cmd,
|
||||
|
|
|
@ -970,7 +970,6 @@ payment_listsendpays_previous(struct command *cmd, const char *buf,
|
|||
}
|
||||
|
||||
struct payment_modifier *paymod_mods[] = {
|
||||
&check_preapproveinvoice_pay_mod,
|
||||
/* NOTE: The order in which these four paymods are executed is
|
||||
* significant!
|
||||
* local_channel_hints *must* execute first before route_exclusions
|
||||
|
@ -1010,6 +1009,32 @@ static void destroy_payment(struct payment *p)
|
|||
list_del(&p->list);
|
||||
}
|
||||
|
||||
static struct command_result *
|
||||
preapproveinvoice_succeed(struct command *cmd,
|
||||
const char *buf,
|
||||
const jsmntok_t *result,
|
||||
struct payment *p)
|
||||
{
|
||||
struct out_req *req;
|
||||
|
||||
/* Now we can conclude `check` command */
|
||||
if (command_check_only(cmd)) {
|
||||
return command_check_done(cmd);
|
||||
}
|
||||
|
||||
list_add_tail(&payments, &p->list);
|
||||
tal_add_destructor(p, destroy_payment);
|
||||
/* We're keeping this around now */
|
||||
tal_steal(cmd->plugin, p);
|
||||
|
||||
req = jsonrpc_request_start(cmd->plugin, cmd, "listsendpays",
|
||||
payment_listsendpays_previous,
|
||||
payment_listsendpays_previous, p);
|
||||
|
||||
json_add_sha256(req->js, "payment_hash", p->payment_hash);
|
||||
return send_outreq(cmd->plugin, req);
|
||||
}
|
||||
|
||||
static struct command_result *json_pay(struct command *cmd,
|
||||
const char *buf,
|
||||
const jsmntok_t *params)
|
||||
|
@ -1036,7 +1061,7 @@ static struct command_result *json_pay(struct command *cmd,
|
|||
/* If any of the modifiers need to add params to the JSON-RPC call we
|
||||
* would add them to the `param()` call below, and have them be
|
||||
* initialized directly that way. */
|
||||
if (!param(cmd, buf, params,
|
||||
if (!param_check(cmd, buf, params,
|
||||
/* FIXME: parameter should be invstring now */
|
||||
p_req("bolt11", param_invstring, &b11str),
|
||||
p_opt("amount_msat", param_msat, &msat),
|
||||
|
@ -1279,16 +1304,19 @@ static struct command_result *json_pay(struct command *cmd,
|
|||
tal_free(dev_use_shadow);
|
||||
|
||||
p->label = tal_steal(p, label);
|
||||
list_add_tail(&payments, &p->list);
|
||||
tal_add_destructor(p, destroy_payment);
|
||||
/* We're keeping this around now */
|
||||
tal_steal(cmd->plugin, p);
|
||||
|
||||
req = jsonrpc_request_start(cmd->plugin, cmd, "listsendpays",
|
||||
payment_listsendpays_previous,
|
||||
payment_listsendpays_previous, p);
|
||||
|
||||
json_add_sha256(req->js, "payment_hash", p->payment_hash);
|
||||
/* Now preapprove, then start payment. */
|
||||
if (command_check_only(cmd)) {
|
||||
req = jsonrpc_request_start(p->plugin, cmd, "check",
|
||||
&preapproveinvoice_succeed,
|
||||
&forward_error, p);
|
||||
json_add_string(req->js, "command_to_check", "preapproveinvoice");
|
||||
} else {
|
||||
req = jsonrpc_request_start(p->plugin, cmd, "preapproveinvoice",
|
||||
&preapproveinvoice_succeed,
|
||||
&forward_error, p);
|
||||
}
|
||||
json_add_string(req->js, "bolt11", p->invstring);
|
||||
return send_outreq(cmd->plugin, req);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue