mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 14:42:40 +01:00
libplugin-pay: always use a non-NULL struct command
.
This means we replace p->cmd with an auxillary command after we've finished, so we have a valid command to use. It also means we weave `struct command_result` returns back through all the callers. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
0a909bdea5
commit
ec8293d215
6 changed files with 134 additions and 155 deletions
|
@ -62,7 +62,7 @@ static struct keysend_data *keysend_init(struct payment *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keysend_cb(struct keysend_data *d, struct payment *p) {
|
static struct command_result *keysend_cb(struct keysend_data *d, struct payment *p) {
|
||||||
struct createonion_hop *last_payload;
|
struct createonion_hop *last_payload;
|
||||||
size_t hopcount;
|
size_t hopcount;
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,12 @@ int libplugin_pay_poll(struct pollfd *fds, nfds_t nfds, int timeout)
|
||||||
return daemon_poll(fds, nfds, timeout);
|
return daemon_poll(fds, nfds, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only root has a non-NULL cmd ptr */
|
||||||
|
static struct command *payment_cmd(struct payment *p)
|
||||||
|
{
|
||||||
|
return payment_root(p)->cmd;
|
||||||
|
}
|
||||||
|
|
||||||
struct payment *payment_new(tal_t *ctx, struct command *cmd,
|
struct payment *payment_new(tal_t *ctx, struct command *cmd,
|
||||||
struct payment *parent,
|
struct payment *parent,
|
||||||
struct channel_hint_set *channel_hints,
|
struct channel_hint_set *channel_hints,
|
||||||
|
@ -82,6 +88,7 @@ struct payment *payment_new(tal_t *ctx, struct command *cmd,
|
||||||
p->parent = parent;
|
p->parent = parent;
|
||||||
p->modifiers = mods;
|
p->modifiers = mods;
|
||||||
p->cmd = cmd;
|
p->cmd = cmd;
|
||||||
|
p->finished = false;
|
||||||
p->start_time = time_now();
|
p->start_time = time_now();
|
||||||
p->result = NULL;
|
p->result = NULL;
|
||||||
p->why = NULL;
|
p->why = NULL;
|
||||||
|
@ -230,10 +237,9 @@ static struct command_result *payment_rpc_failure(struct command *cmd,
|
||||||
const jsmntok_t *toks,
|
const jsmntok_t *toks,
|
||||||
struct payment *p)
|
struct payment *p)
|
||||||
{
|
{
|
||||||
payment_fail(p,
|
return payment_fail(p,
|
||||||
"Failing a partial payment due to a failed RPC call: %.*s",
|
"Failing a partial payment due to a failed RPC call: %.*s",
|
||||||
toks->end - toks->start, buffer + toks->start);
|
toks->end - toks->start, buffer + toks->start);
|
||||||
return command_still_pending(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct payment_tree_result payment_collect_result(struct payment *p)
|
struct payment_tree_result payment_collect_result(struct payment *p)
|
||||||
|
@ -306,8 +312,7 @@ static struct command_result *payment_waitblockheight_cb(struct command *cmd,
|
||||||
"(syncheight=%d < headercount=%d)",
|
"(syncheight=%d < headercount=%d)",
|
||||||
p->chainlag, syncheight, p->start_block);
|
p->chainlag, syncheight, p->start_block);
|
||||||
|
|
||||||
payment_continue(p);
|
return payment_continue(p);
|
||||||
return command_still_pending(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct command_result *
|
static struct command_result *
|
||||||
|
@ -330,19 +335,17 @@ payment_getblockheight_success(struct command *cmd,
|
||||||
|
|
||||||
/* Now we just need to ask `lightningd` what height it has
|
/* Now we just need to ask `lightningd` what height it has
|
||||||
* synced up to, and we remember that as chainlag. */
|
* synced up to, and we remember that as chainlag. */
|
||||||
req = jsonrpc_request_start(p->plugin, NULL, "waitblockheight",
|
req = jsonrpc_request_start(p->plugin, cmd, "waitblockheight",
|
||||||
&payment_waitblockheight_cb,
|
&payment_waitblockheight_cb,
|
||||||
&payment_rpc_failure, p);
|
&payment_rpc_failure, p);
|
||||||
json_add_u32(req->js, "blockheight", 0);
|
json_add_u32(req->js, "blockheight", 0);
|
||||||
send_outreq(p->plugin, req);
|
return send_outreq(p->plugin, req);
|
||||||
|
|
||||||
return command_still_pending(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INVALID_BLOCKHEIGHT UINT32_MAX
|
#define INVALID_BLOCKHEIGHT UINT32_MAX
|
||||||
|
|
||||||
static
|
static struct command_result *
|
||||||
void payment_start_at_blockheight(struct payment *p, u32 blockheight)
|
payment_start_at_blockheight(struct payment *p, u32 blockheight)
|
||||||
{
|
{
|
||||||
struct payment *root = payment_root(p);
|
struct payment *root = payment_root(p);
|
||||||
|
|
||||||
|
@ -378,11 +381,11 @@ void payment_start_at_blockheight(struct payment *p, u32 blockheight)
|
||||||
* height, allowing us to send while still syncing.
|
* height, allowing us to send while still syncing.
|
||||||
*/
|
*/
|
||||||
struct out_req *req;
|
struct out_req *req;
|
||||||
req = jsonrpc_request_start(p->plugin, NULL, "getchaininfo",
|
req = jsonrpc_request_start(p->plugin, payment_cmd(p), "getchaininfo",
|
||||||
&payment_getblockheight_success,
|
&payment_getblockheight_success,
|
||||||
&payment_rpc_failure, p);
|
&payment_rpc_failure, p);
|
||||||
json_add_u32(req->js, "last_height", 0);
|
json_add_u32(req->js, "last_height", 0);
|
||||||
send_outreq(p->plugin, req);
|
return send_outreq(p->plugin, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
void payment_start(struct payment *p)
|
void payment_start(struct payment *p)
|
||||||
|
@ -864,22 +867,16 @@ static struct command_result *payment_getroute(struct payment *p)
|
||||||
dst = gossmap_find_node(gossmap, p->getroute->destination);
|
dst = gossmap_find_node(gossmap, p->getroute->destination);
|
||||||
if (!dst) {
|
if (!dst) {
|
||||||
put_gossmap(p);
|
put_gossmap(p);
|
||||||
payment_fail(
|
return payment_fail(
|
||||||
p, "Unknown destination %s",
|
p, "Unknown destination %s",
|
||||||
fmt_node_id(tmpctx, p->getroute->destination));
|
fmt_node_id(tmpctx, p->getroute->destination));
|
||||||
|
|
||||||
/* Let payment_finished_ handle this, so we mark it as pending */
|
|
||||||
return command_still_pending(p->cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we don't exist in gossip, routing can't happen. */
|
/* If we don't exist in gossip, routing can't happen. */
|
||||||
src = gossmap_find_node(gossmap, p->local_id);
|
src = gossmap_find_node(gossmap, p->local_id);
|
||||||
if (!src) {
|
if (!src) {
|
||||||
put_gossmap(p);
|
put_gossmap(p);
|
||||||
payment_fail(p, "We don't have any channels");
|
return payment_fail(p, "We don't have any channels");
|
||||||
|
|
||||||
/* Let payment_finished_ handle this, so we mark it as pending */
|
|
||||||
return command_still_pending(p->cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p->route = route(p, gossmap, src, dst, p->getroute->amount, p->getroute->cltv,
|
p->route = route(p, gossmap, src, dst, p->getroute->amount, p->getroute->cltv,
|
||||||
|
@ -888,9 +885,7 @@ static struct command_result *payment_getroute(struct payment *p)
|
||||||
put_gossmap(p);
|
put_gossmap(p);
|
||||||
|
|
||||||
if (!p->route) {
|
if (!p->route) {
|
||||||
payment_fail(p, "%s", errstr);
|
return payment_fail(p, "%s", errstr);
|
||||||
/* Let payment_finished_ handle this, so we mark it as pending */
|
|
||||||
return command_still_pending(p->cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OK, now we *have* a route */
|
/* OK, now we *have* a route */
|
||||||
|
@ -898,9 +893,8 @@ static struct command_result *payment_getroute(struct payment *p)
|
||||||
|
|
||||||
if (tal_count(p->route) == 0) {
|
if (tal_count(p->route) == 0) {
|
||||||
payment_root(p)->abort = true;
|
payment_root(p)->abort = true;
|
||||||
payment_fail(p, "Empty route returned by getroute, are you "
|
return payment_fail(p, "Empty route returned by getroute, are you "
|
||||||
"trying to pay yourself?");
|
"trying to pay yourself?");
|
||||||
return command_still_pending(p->cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fee = payment_route_fee(p);
|
fee = payment_route_fee(p);
|
||||||
|
@ -908,19 +902,17 @@ static struct command_result *payment_getroute(struct payment *p)
|
||||||
/* Ensure that our fee and CLTV budgets are respected. */
|
/* Ensure that our fee and CLTV budgets are respected. */
|
||||||
if (amount_msat_greater(fee, p->constraints.fee_budget)) {
|
if (amount_msat_greater(fee, p->constraints.fee_budget)) {
|
||||||
p->route = tal_free(p->route);
|
p->route = tal_free(p->route);
|
||||||
payment_fail(
|
return payment_fail(
|
||||||
p, "Fee exceeds our fee budget: %s > %s, discarding route",
|
p, "Fee exceeds our fee budget: %s > %s, discarding route",
|
||||||
fmt_amount_msat(tmpctx, fee),
|
fmt_amount_msat(tmpctx, fee),
|
||||||
fmt_amount_msat(tmpctx, p->constraints.fee_budget));
|
fmt_amount_msat(tmpctx, p->constraints.fee_budget));
|
||||||
return command_still_pending(p->cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->route[0].delay > p->constraints.cltv_budget) {
|
if (p->route[0].delay > p->constraints.cltv_budget) {
|
||||||
u32 delay = p->route[0].delay;
|
u32 delay = p->route[0].delay;
|
||||||
p->route = tal_free(p->route);
|
p->route = tal_free(p->route);
|
||||||
payment_fail(p, "CLTV delay exceeds our CLTV budget: %d > %d",
|
return payment_fail(p, "CLTV delay exceeds our CLTV budget: %d > %d",
|
||||||
delay, p->constraints.cltv_budget);
|
delay, p->constraints.cltv_budget);
|
||||||
return command_still_pending(p->cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now update the constraints in fee_budget and cltv_budget so
|
/* Now update the constraints in fee_budget and cltv_budget so
|
||||||
|
@ -934,8 +926,7 @@ static struct command_result *payment_getroute(struct payment *p)
|
||||||
/* Allow modifiers to modify the route, before
|
/* Allow modifiers to modify the route, before
|
||||||
* payment_compute_onion_payloads uses the route to generate the
|
* payment_compute_onion_payloads uses the route to generate the
|
||||||
* onion_payloads */
|
* onion_payloads */
|
||||||
payment_continue(p);
|
return payment_continue(p);
|
||||||
return command_still_pending(p->cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1018,12 +1009,11 @@ payment_listpeerchannels_success(struct command *cmd, const char *buffer,
|
||||||
"spendable=%s < payment=%s",
|
"spendable=%s < payment=%s",
|
||||||
fmt_amount_msat(tmpctx, spendable),
|
fmt_amount_msat(tmpctx, spendable),
|
||||||
fmt_amount_msat(tmpctx, p->getroute->amount));
|
fmt_amount_msat(tmpctx, p->getroute->amount));
|
||||||
payment_abort(p, PAY_INSUFFICIENT_FUNDS,
|
return payment_abort(p, PAY_INSUFFICIENT_FUNDS,
|
||||||
"Insufficient funds to perform the payment: "
|
"Insufficient funds to perform the payment: "
|
||||||
"spendable=%s < payment=%s",
|
"spendable=%s < payment=%s",
|
||||||
fmt_amount_msat(tmpctx, spendable),
|
fmt_amount_msat(tmpctx, spendable),
|
||||||
fmt_amount_msat(tmpctx, p->getroute->amount));
|
fmt_amount_msat(tmpctx, p->getroute->amount));
|
||||||
return command_still_pending(p->cmd);
|
|
||||||
} else if (amount_msat_greater(maxrequired, spendable)) {
|
} else if (amount_msat_greater(maxrequired, spendable)) {
|
||||||
char *msg = tal_fmt(
|
char *msg = tal_fmt(
|
||||||
tmpctx,
|
tmpctx,
|
||||||
|
@ -1034,7 +1024,7 @@ payment_listpeerchannels_success(struct command *cmd, const char *buffer,
|
||||||
fmt_amount_msat(tmpctx, p->getroute->amount),
|
fmt_amount_msat(tmpctx, p->getroute->amount),
|
||||||
fmt_amount_msat(tmpctx, p->constraints.fee_budget));
|
fmt_amount_msat(tmpctx, p->constraints.fee_budget));
|
||||||
|
|
||||||
plugin_notify_message(p->cmd, LOG_INFORM, "%s", msg);
|
plugin_notify_message(payment_cmd(p), LOG_INFORM, "%s", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return payment_getroute(p);
|
return payment_getroute(p);
|
||||||
|
@ -1048,7 +1038,7 @@ static struct command_result *payment_getlocalmods(struct payment *p)
|
||||||
if (p->mods)
|
if (p->mods)
|
||||||
return payment_getroute(p);
|
return payment_getroute(p);
|
||||||
|
|
||||||
req = jsonrpc_request_start(p->plugin, NULL, "listpeerchannels",
|
req = jsonrpc_request_start(p->plugin, payment_cmd(p), "listpeerchannels",
|
||||||
&payment_listpeerchannels_success,
|
&payment_listpeerchannels_success,
|
||||||
&payment_rpc_failure, p);
|
&payment_rpc_failure, p);
|
||||||
return send_outreq(p->plugin, req);
|
return send_outreq(p->plugin, req);
|
||||||
|
@ -1393,9 +1383,7 @@ error:
|
||||||
payment_root(p)->abort = true;
|
payment_root(p)->abort = true;
|
||||||
|
|
||||||
nonerror:
|
nonerror:
|
||||||
payment_fail(p, "%s", p->result->message);
|
return payment_fail(p, "%s", p->result->message);
|
||||||
return command_still_pending(cmd);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1494,8 +1482,7 @@ strange_error:
|
||||||
failcode, describe_failcode(tmpctx, failcode));
|
failcode, describe_failcode(tmpctx, failcode));
|
||||||
|
|
||||||
error:
|
error:
|
||||||
payment_fail(p, "%s", p->result->message);
|
return payment_fail(p, "%s", p->result->message);
|
||||||
return command_still_pending(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* From the docs:
|
/* From the docs:
|
||||||
|
@ -1609,8 +1596,7 @@ payment_addgossip_success(struct command *cmd, const char *buffer,
|
||||||
json_tok_full(buffer, toks));
|
json_tok_full(buffer, toks));
|
||||||
/* FIXME: Pick a random channel to fail? */
|
/* FIXME: Pick a random channel to fail? */
|
||||||
payment_set_step(p, PAYMENT_STEP_FAILED);
|
payment_set_step(p, PAYMENT_STEP_FAILED);
|
||||||
payment_continue(p);
|
return payment_continue(p);
|
||||||
return command_still_pending(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!errchan)
|
if (!errchan)
|
||||||
|
@ -1650,16 +1636,14 @@ payment_waitsendpay_finished(struct command *cmd, const char *buffer,
|
||||||
json_tok_full_len(toks),
|
json_tok_full_len(toks),
|
||||||
json_tok_full(buffer, toks));
|
json_tok_full(buffer, toks));
|
||||||
payment_set_step(p, PAYMENT_STEP_FAILED);
|
payment_set_step(p, PAYMENT_STEP_FAILED);
|
||||||
payment_continue(p);
|
return payment_continue(p);
|
||||||
return command_still_pending(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
payment_result_infer(p->route, p->result);
|
payment_result_infer(p->route, p->result);
|
||||||
|
|
||||||
if (p->result->state == PAYMENT_COMPLETE) {
|
if (p->result->state == PAYMENT_COMPLETE) {
|
||||||
payment_set_step(p, PAYMENT_STEP_SUCCESS);
|
payment_set_step(p, PAYMENT_STEP_SUCCESS);
|
||||||
payment_continue(p);
|
return payment_continue(p);
|
||||||
return command_still_pending(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
payment_chanhints_unapply_route(p);
|
payment_chanhints_unapply_route(p);
|
||||||
|
@ -1672,12 +1656,11 @@ payment_waitsendpay_finished(struct command *cmd, const char *buffer,
|
||||||
"Extracted channel_update %s from onionreply %s",
|
"Extracted channel_update %s from onionreply %s",
|
||||||
tal_hex(tmpctx, update),
|
tal_hex(tmpctx, update),
|
||||||
tal_hex(tmpctx, p->result->raw_message));
|
tal_hex(tmpctx, p->result->raw_message));
|
||||||
req = jsonrpc_request_start(p->plugin, NULL, "addgossip",
|
req = jsonrpc_request_start(p->plugin, payment_cmd(p), "addgossip",
|
||||||
payment_addgossip_success,
|
payment_addgossip_success,
|
||||||
payment_addgossip_failure, p);
|
payment_addgossip_failure, p);
|
||||||
json_add_hex_talarr(req->js, "message", update);
|
json_add_hex_talarr(req->js, "message", update);
|
||||||
send_outreq(p->plugin, req);
|
return send_outreq(p->plugin, req);
|
||||||
return command_still_pending(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return payment_addgossip_success(cmd, NULL, NULL, p);
|
return payment_addgossip_success(cmd, NULL, NULL, p);
|
||||||
|
@ -1689,15 +1672,13 @@ static struct command_result *payment_sendonion_success(struct command *cmd,
|
||||||
struct payment *p)
|
struct payment *p)
|
||||||
{
|
{
|
||||||
struct out_req *req;
|
struct out_req *req;
|
||||||
req = jsonrpc_request_start(p->plugin, NULL, "waitsendpay",
|
req = jsonrpc_request_start(p->plugin, payment_cmd(p), "waitsendpay",
|
||||||
payment_waitsendpay_finished,
|
payment_waitsendpay_finished,
|
||||||
payment_waitsendpay_finished, p);
|
payment_waitsendpay_finished, p);
|
||||||
json_add_sha256(req->js, "payment_hash", p->payment_hash);
|
json_add_sha256(req->js, "payment_hash", p->payment_hash);
|
||||||
json_add_num(req->js, "partid", p->partid);
|
json_add_num(req->js, "partid", p->partid);
|
||||||
json_add_u64(req->js, "groupid", p->groupid);
|
json_add_u64(req->js, "groupid", p->groupid);
|
||||||
send_outreq(p->plugin, req);
|
return send_outreq(p->plugin, req);
|
||||||
|
|
||||||
return command_still_pending(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct command_result *payment_createonion_success(struct command *cmd,
|
static struct command_result *payment_createonion_success(struct command *cmd,
|
||||||
|
@ -1719,7 +1700,7 @@ static struct command_result *payment_createonion_success(struct command *cmd,
|
||||||
|
|
||||||
p->createonion_response = json_to_createonion_response(p, buffer, toks);
|
p->createonion_response = json_to_createonion_response(p, buffer, toks);
|
||||||
|
|
||||||
req = jsonrpc_request_start(p->plugin, NULL, "sendonion",
|
req = jsonrpc_request_start(p->plugin, payment_cmd(p), "sendonion",
|
||||||
payment_sendonion_success,
|
payment_sendonion_success,
|
||||||
payment_rpc_failure, p);
|
payment_rpc_failure, p);
|
||||||
json_add_hex_talarr(req->js, "onion", p->createonion_response->onion);
|
json_add_hex_talarr(req->js, "onion", p->createonion_response->onion);
|
||||||
|
@ -1762,8 +1743,7 @@ static struct command_result *payment_createonion_success(struct command *cmd,
|
||||||
if (p->local_invreq_id)
|
if (p->local_invreq_id)
|
||||||
json_add_sha256(req->js, "localinvreqid", p->local_invreq_id);
|
json_add_sha256(req->js, "localinvreqid", p->local_invreq_id);
|
||||||
|
|
||||||
send_outreq(p->plugin, req);
|
return send_outreq(p->plugin, req);
|
||||||
return command_still_pending(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Temporary serialization method for the tlv_payload.data until we rework the
|
/* Temporary serialization method for the tlv_payload.data until we rework the
|
||||||
|
@ -1857,7 +1837,7 @@ static void payment_add_blindedpath(const tal_t *ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void payment_compute_onion_payloads(struct payment *p)
|
static struct command_result *payment_compute_onion_payloads(struct payment *p)
|
||||||
{
|
{
|
||||||
struct createonion_request *cr;
|
struct createonion_request *cr;
|
||||||
size_t hopcount;
|
size_t hopcount;
|
||||||
|
@ -1943,14 +1923,14 @@ static void payment_compute_onion_payloads(struct payment *p)
|
||||||
|
|
||||||
/* Now allow all the modifiers to mess with the payloads, before we
|
/* Now allow all the modifiers to mess with the payloads, before we
|
||||||
* serialize via a call to createonion in the next step. */
|
* serialize via a call to createonion in the next step. */
|
||||||
payment_continue(p);
|
return payment_continue(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void payment_sendonion(struct payment *p)
|
static struct command_result *payment_sendonion(struct payment *p)
|
||||||
{
|
{
|
||||||
struct out_req *req;
|
struct out_req *req;
|
||||||
u8 *payload, *tlv;
|
u8 *payload, *tlv;
|
||||||
req = jsonrpc_request_start(p->plugin, NULL, "createonion",
|
req = jsonrpc_request_start(p->plugin, payment_cmd(p), "createonion",
|
||||||
payment_createonion_success,
|
payment_createonion_success,
|
||||||
payment_rpc_failure, p);
|
payment_rpc_failure, p);
|
||||||
|
|
||||||
|
@ -1979,11 +1959,11 @@ static void payment_sendonion(struct payment *p)
|
||||||
json_add_secret(req->js, "sessionkey",
|
json_add_secret(req->js, "sessionkey",
|
||||||
p->createonion_request->session_key);
|
p->createonion_request->session_key);
|
||||||
|
|
||||||
send_outreq(p->plugin, req);
|
return send_outreq(p->plugin, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mutual recursion. */
|
/* Mutual recursion. */
|
||||||
static void payment_finished(struct payment *p);
|
static struct command_result *payment_finished(struct payment *p);
|
||||||
|
|
||||||
/* A payment is finished if a) it is in a final state, of b) it's in a
|
/* A payment is finished if a) it is in a final state, of b) it's in a
|
||||||
* child-spawning state and all of its children are in a final state. */
|
* child-spawning state and all of its children are in a final state. */
|
||||||
|
@ -2033,14 +2013,14 @@ static bool payment_is_success(struct payment *p)
|
||||||
|
|
||||||
/* Function to bubble up completions to the root, which actually holds on to
|
/* Function to bubble up completions to the root, which actually holds on to
|
||||||
* the command that initiated the flow. */
|
* the command that initiated the flow. */
|
||||||
static void payment_child_finished(struct payment *p,
|
static struct command_result *payment_child_finished(struct payment *p,
|
||||||
struct payment *child)
|
struct payment *child)
|
||||||
{
|
{
|
||||||
if (!payment_is_finished(p))
|
if (!payment_is_finished(p))
|
||||||
return;
|
return command_still_pending(payment_cmd(p));
|
||||||
|
|
||||||
/* Should we continue bubbling up? */
|
/* Should we continue bubbling up? */
|
||||||
payment_finished(p);
|
return payment_finished(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void payment_add_attempt(struct json_stream *s, const char *fieldname, struct payment *p, bool recurse)
|
static void payment_add_attempt(struct json_stream *s, const char *fieldname, struct payment *p, bool recurse)
|
||||||
|
@ -2144,7 +2124,7 @@ void json_add_payment_success(struct json_stream *js,
|
||||||
* leafs in the subtree rooted in the payment are all in a final state. It is
|
* leafs in the subtree rooted in the payment are all in a final state. It is
|
||||||
* called only once, and it is guaranteed to be called in post-order
|
* called only once, and it is guaranteed to be called in post-order
|
||||||
* traversal, i.e., all children are finished before the parent is called. */
|
* traversal, i.e., all children are finished before the parent is called. */
|
||||||
static void payment_finished(struct payment *p)
|
static struct command_result *payment_finished(struct payment *p)
|
||||||
{
|
{
|
||||||
struct payment_tree_result result = payment_collect_result(p);
|
struct payment_tree_result result = payment_collect_result(p);
|
||||||
struct json_stream *ret;
|
struct json_stream *ret;
|
||||||
|
@ -2159,14 +2139,14 @@ static void payment_finished(struct payment *p)
|
||||||
if (p->parent != NULL)
|
if (p->parent != NULL)
|
||||||
return payment_child_finished(p->parent, p);
|
return payment_child_finished(p->parent, p);
|
||||||
|
|
||||||
/* We are about to reply, unset the pointer to the cmd so we
|
if (p->finished) {
|
||||||
* don't attempt to return a response twice. */
|
/* cmd is the aux_command: real cmd has been freed. */
|
||||||
p->cmd = NULL;
|
return command_still_pending(p->cmd);
|
||||||
if (cmd == NULL) {
|
}
|
||||||
/* This is the tree root, but we already reported
|
|
||||||
* success or failure, so noop. */
|
/* on_payment_failure / on_payment_success looks at this! */
|
||||||
return;
|
p->finished = true;
|
||||||
} else if (payment_is_success(p)) {
|
if (payment_is_success(p)) {
|
||||||
assert(result.treestates & PAYMENT_STEP_SUCCESS);
|
assert(result.treestates & PAYMENT_STEP_SUCCESS);
|
||||||
assert(result.leafstates & PAYMENT_STEP_SUCCESS);
|
assert(result.leafstates & PAYMENT_STEP_SUCCESS);
|
||||||
assert(result.preimage != NULL);
|
assert(result.preimage != NULL);
|
||||||
|
@ -2266,7 +2246,11 @@ static void payment_finished(struct payment *p)
|
||||||
payment_notify_failure(p, failure->message);
|
payment_notify_failure(p, failure->message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command_finished(cmd, ret)) { /* Ignore result. */}
|
/* We're going to resolve p->cmd. Put an aux_command in place
|
||||||
|
* so we can use that to wrap up any remaining payments */
|
||||||
|
p->cmd = aux_command(cmd);
|
||||||
|
|
||||||
|
return command_finished(cmd, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void payment_set_step(struct payment *p, enum payment_step newstep)
|
void payment_set_step(struct payment *p, enum payment_step newstep)
|
||||||
|
@ -2279,7 +2263,7 @@ void payment_set_step(struct payment *p, enum payment_step newstep)
|
||||||
p->end_time = time_now();
|
p->end_time = time_now();
|
||||||
}
|
}
|
||||||
|
|
||||||
void payment_continue(struct payment *p)
|
struct command_result *payment_continue(struct payment *p)
|
||||||
{
|
{
|
||||||
struct payment_modifier *mod;
|
struct payment_modifier *mod;
|
||||||
void *moddata;
|
void *moddata;
|
||||||
|
@ -2299,27 +2283,23 @@ void payment_continue(struct payment *p)
|
||||||
switch (p->step) {
|
switch (p->step) {
|
||||||
case PAYMENT_STEP_INITIALIZED:
|
case PAYMENT_STEP_INITIALIZED:
|
||||||
case PAYMENT_STEP_RETRY_GETROUTE:
|
case PAYMENT_STEP_RETRY_GETROUTE:
|
||||||
payment_getlocalmods(p);
|
return payment_getlocalmods(p);
|
||||||
return;
|
|
||||||
|
|
||||||
case PAYMENT_STEP_GOT_ROUTE:
|
case PAYMENT_STEP_GOT_ROUTE:
|
||||||
payment_compute_onion_payloads(p);
|
return payment_compute_onion_payloads(p);
|
||||||
return;
|
|
||||||
|
|
||||||
case PAYMENT_STEP_ONION_PAYLOAD:
|
case PAYMENT_STEP_ONION_PAYLOAD:
|
||||||
payment_sendonion(p);
|
return payment_sendonion(p);
|
||||||
return;
|
|
||||||
|
|
||||||
case PAYMENT_STEP_SUCCESS:
|
case PAYMENT_STEP_SUCCESS:
|
||||||
case PAYMENT_STEP_FAILED:
|
case PAYMENT_STEP_FAILED:
|
||||||
payment_finished(p);
|
return payment_finished(p);
|
||||||
return;
|
|
||||||
|
|
||||||
case PAYMENT_STEP_RETRY:
|
case PAYMENT_STEP_RETRY:
|
||||||
case PAYMENT_STEP_SPLIT:
|
case PAYMENT_STEP_SPLIT:
|
||||||
/* Do nothing, we'll get pinged by a child succeeding
|
/* Do nothing, we'll get pinged by a child succeeding
|
||||||
* or failing. */
|
* or failing. */
|
||||||
return;
|
return command_still_pending(payment_cmd(p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* We should never get here, it'd mean one of the state machine called
|
/* We should never get here, it'd mean one of the state machine called
|
||||||
|
@ -2327,7 +2307,7 @@ void payment_continue(struct payment *p)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
void payment_abort(struct payment *p, enum jsonrpc_errcode code, const char *fmt, ...) {
|
struct command_result *payment_abort(struct payment *p, enum jsonrpc_errcode code, const char *fmt, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
struct payment *root = payment_root(p);
|
struct payment *root = payment_root(p);
|
||||||
payment_set_step(p, PAYMENT_STEP_FAILED);
|
payment_set_step(p, PAYMENT_STEP_FAILED);
|
||||||
|
@ -2352,10 +2332,10 @@ void payment_abort(struct payment *p, enum jsonrpc_errcode code, const char *fmt
|
||||||
/* Do not use payment_continue, because that'd continue
|
/* Do not use payment_continue, because that'd continue
|
||||||
* applying the modifiers before calling
|
* applying the modifiers before calling
|
||||||
* payment_finished(). */
|
* payment_finished(). */
|
||||||
payment_finished(p);
|
return payment_finished(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void payment_fail(struct payment *p, const char *fmt, ...)
|
struct command_result *payment_fail(struct payment *p, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
p->end_time = time_now();
|
p->end_time = time_now();
|
||||||
|
@ -2368,7 +2348,7 @@ void payment_fail(struct payment *p, const char *fmt, ...)
|
||||||
|
|
||||||
paymod_log(p, LOG_INFORM, "%s", p->failreason);
|
paymod_log(p, LOG_INFORM, "%s", p->failreason);
|
||||||
|
|
||||||
payment_continue(p);
|
return payment_continue(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *payment_mod_get_data(const struct payment *p,
|
void *payment_mod_get_data(const struct payment *p,
|
||||||
|
@ -2386,8 +2366,8 @@ void *payment_mod_get_data(const struct payment *p,
|
||||||
|
|
||||||
static struct retry_mod_data *retry_data_init(struct payment *p);
|
static struct retry_mod_data *retry_data_init(struct payment *p);
|
||||||
|
|
||||||
static inline void retry_step_cb(struct retry_mod_data *rd,
|
static struct command_result *retry_step_cb(struct retry_mod_data *rd,
|
||||||
struct payment *p);
|
struct payment *p);
|
||||||
|
|
||||||
static struct retry_mod_data *
|
static struct retry_mod_data *
|
||||||
retry_data_init(struct payment *p)
|
retry_data_init(struct payment *p)
|
||||||
|
@ -2460,8 +2440,8 @@ static bool payment_can_retry(struct payment *p)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void retry_step_cb(struct retry_mod_data *rd,
|
static struct command_result *retry_step_cb(struct retry_mod_data *rd,
|
||||||
struct payment *p)
|
struct payment *p)
|
||||||
{
|
{
|
||||||
struct payment *subpayment, *root = payment_root(p);
|
struct payment *subpayment, *root = payment_root(p);
|
||||||
struct retry_mod_data *rdata = payment_mod_retry_get_data(p);
|
struct retry_mod_data *rdata = payment_mod_retry_get_data(p);
|
||||||
|
@ -2511,7 +2491,7 @@ static inline void retry_step_cb(struct retry_mod_data *rd,
|
||||||
rdata->retries - 1);
|
rdata->retries - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
payment_continue(p);
|
return payment_continue(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_PAYMENT_MODIFIER(retry, struct retry_mod_data *, retry_data_init,
|
REGISTER_PAYMENT_MODIFIER(retry, struct retry_mod_data *, retry_data_init,
|
||||||
|
@ -2586,11 +2566,10 @@ local_channel_hints_listpeerchannels(struct command *cmd, const char *buffer,
|
||||||
p->mods = gossmods_from_listpeerchannels(
|
p->mods = gossmods_from_listpeerchannels(
|
||||||
p, p->local_id, buffer, toks, true, gossmod_add_localchan, NULL);
|
p, p->local_id, buffer, toks, true, gossmod_add_localchan, NULL);
|
||||||
|
|
||||||
payment_continue(p);
|
return payment_continue(p);
|
||||||
return command_still_pending(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void local_channel_hints_cb(void *d UNUSED, struct payment *p)
|
static struct command_result *local_channel_hints_cb(void *d UNUSED, struct payment *p)
|
||||||
{
|
{
|
||||||
struct out_req *req;
|
struct out_req *req;
|
||||||
/* If we are not the root we don't look up the channel balances since
|
/* If we are not the root we don't look up the channel balances since
|
||||||
|
@ -2601,10 +2580,10 @@ static void local_channel_hints_cb(void *d UNUSED, struct payment *p)
|
||||||
if (p->parent != NULL || p->step != PAYMENT_STEP_INITIALIZED)
|
if (p->parent != NULL || p->step != PAYMENT_STEP_INITIALIZED)
|
||||||
return payment_continue(p);
|
return payment_continue(p);
|
||||||
|
|
||||||
req = jsonrpc_request_start(p->plugin, NULL, "listpeerchannels",
|
req = jsonrpc_request_start(p->plugin, payment_cmd(p), "listpeerchannels",
|
||||||
local_channel_hints_listpeerchannels,
|
local_channel_hints_listpeerchannels,
|
||||||
local_channel_hints_listpeerchannels, p);
|
local_channel_hints_listpeerchannels, p);
|
||||||
send_outreq(p->plugin, req);
|
return send_outreq(p->plugin, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_PAYMENT_MODIFIER(local_channel_hints, void *, NULL, local_channel_hints_cb);
|
REGISTER_PAYMENT_MODIFIER(local_channel_hints, void *, NULL, local_channel_hints_cb);
|
||||||
|
@ -2908,7 +2887,7 @@ static void routehint_pre_getroute(struct routehints_data *d, struct payment *p)
|
||||||
paymod_log(p, LOG_DBG, "Not using a routehint");
|
paymod_log(p, LOG_DBG, "Not using a routehint");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void routehint_check_reachable(struct payment *p)
|
static struct command_result *routehint_check_reachable(struct payment *p)
|
||||||
{
|
{
|
||||||
const struct gossmap_node *dst, *src;
|
const struct gossmap_node *dst, *src;
|
||||||
struct gossmap *gossmap = get_gossmap(p);
|
struct gossmap *gossmap = get_gossmap(p);
|
||||||
|
@ -2962,14 +2941,13 @@ static void routehint_check_reachable(struct payment *p)
|
||||||
* isn't reachable, then there is no point in
|
* isn't reachable, then there is no point in
|
||||||
* continuing. */
|
* continuing. */
|
||||||
|
|
||||||
payment_abort(
|
put_gossmap(p);
|
||||||
|
return payment_abort(
|
||||||
p,
|
p,
|
||||||
PAY_UNREACHABLE,
|
PAY_UNREACHABLE,
|
||||||
"Destination %s is not reachable directly and "
|
"Destination %s is not reachable directly and "
|
||||||
"all routehints were unusable.",
|
"all routehints were unusable.",
|
||||||
fmt_node_id(tmpctx, p->route_destination));
|
fmt_node_id(tmpctx, p->route_destination));
|
||||||
put_gossmap(p);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
routehint_pre_getroute(d, p);
|
routehint_pre_getroute(d, p);
|
||||||
|
@ -2982,10 +2960,10 @@ static void routehint_check_reachable(struct payment *p)
|
||||||
d->destination_reachable ? "including" : "excluding");
|
d->destination_reachable ? "including" : "excluding");
|
||||||
|
|
||||||
/* Now we can continue on our merry way. */
|
/* Now we can continue on our merry way. */
|
||||||
payment_continue(p);
|
return payment_continue(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void routehint_step_cb(struct routehints_data *d, struct payment *p)
|
static struct command_result *routehint_step_cb(struct routehints_data *d, struct payment *p)
|
||||||
{
|
{
|
||||||
struct route_hop hop;
|
struct route_hop hop;
|
||||||
const struct payment *root = payment_root(p);
|
const struct payment *root = payment_root(p);
|
||||||
|
@ -3075,7 +3053,7 @@ static void routehint_step_cb(struct routehints_data *d, struct payment *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
payment_continue(p);
|
return payment_continue(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct routehints_data *routehint_data_init(struct payment *p)
|
static struct routehints_data *routehint_data_init(struct payment *p)
|
||||||
|
@ -3157,7 +3135,7 @@ static struct exemptfee_data *exemptfee_data_init(struct payment *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exemptfee_cb(struct exemptfee_data *d, struct payment *p)
|
static struct command_result *exemptfee_cb(struct exemptfee_data *d, struct payment *p)
|
||||||
{
|
{
|
||||||
if (p->step != PAYMENT_STEP_INITIALIZED || p->parent != NULL)
|
if (p->step != PAYMENT_STEP_INITIALIZED || p->parent != NULL)
|
||||||
return payment_continue(p);
|
return payment_continue(p);
|
||||||
|
@ -3223,7 +3201,7 @@ static struct command_result *shadow_route_extend(struct shadow_route_data *d,
|
||||||
struct payment *p)
|
struct payment *p)
|
||||||
{
|
{
|
||||||
struct out_req *req;
|
struct out_req *req;
|
||||||
req = jsonrpc_request_start(p->plugin, NULL, "listchannels",
|
req = jsonrpc_request_start(p->plugin, payment_cmd(p), "listchannels",
|
||||||
shadow_route_listchannels,
|
shadow_route_listchannels,
|
||||||
payment_rpc_failure, p);
|
payment_rpc_failure, p);
|
||||||
json_add_node_id(req->js, "source", &d->destination);
|
json_add_node_id(req->js, "source", &d->destination);
|
||||||
|
@ -3364,14 +3342,13 @@ next:
|
||||||
|
|
||||||
/* Now it's time to decide whether we want to extend or continue. */
|
/* Now it's time to decide whether we want to extend or continue. */
|
||||||
if (best == NULL || pseudorand(2) == 0) {
|
if (best == NULL || pseudorand(2) == 0) {
|
||||||
payment_continue(p);
|
return payment_continue(p);
|
||||||
return command_still_pending(cmd);
|
|
||||||
} else {
|
} else {
|
||||||
return shadow_route_extend(d, p);
|
return shadow_route_extend(d, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shadow_route_cb(struct shadow_route_data *d,
|
static struct command_result *shadow_route_cb(struct shadow_route_data *d,
|
||||||
struct payment *p)
|
struct payment *p)
|
||||||
{
|
{
|
||||||
if (!d->use_shadow)
|
if (!d->use_shadow)
|
||||||
|
@ -3390,15 +3367,15 @@ static void shadow_route_cb(struct shadow_route_data *d,
|
||||||
if (pseudorand(2) == 0) {
|
if (pseudorand(2) == 0) {
|
||||||
return payment_continue(p);
|
return payment_continue(p);
|
||||||
} else {
|
} else {
|
||||||
shadow_route_extend(d, p);
|
return shadow_route_extend(d, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_PAYMENT_MODIFIER(shadowroute, struct shadow_route_data *,
|
REGISTER_PAYMENT_MODIFIER(shadowroute, struct shadow_route_data *,
|
||||||
shadow_route_init, shadow_route_cb);
|
shadow_route_init, shadow_route_cb);
|
||||||
|
|
||||||
static void direct_pay_override(struct payment *p) {
|
static struct command_result *direct_pay_override(struct payment *p)
|
||||||
|
{
|
||||||
/* The root has performed the search for a direct channel. */
|
/* The root has performed the search for a direct channel. */
|
||||||
struct payment *root = payment_root(p);
|
struct payment *root = payment_root(p);
|
||||||
struct direct_pay_data *d;
|
struct direct_pay_data *d;
|
||||||
|
@ -3432,8 +3409,7 @@ static void direct_pay_override(struct payment *p) {
|
||||||
payment_set_step(p, PAYMENT_STEP_GOT_ROUTE);
|
payment_set_step(p, PAYMENT_STEP_GOT_ROUTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return payment_continue(p);
|
||||||
payment_continue(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now that we have the listpeerchannels result for the root payment, let's search
|
/* Now that we have the listpeerchannels result for the root payment, let's search
|
||||||
|
@ -3480,12 +3456,11 @@ static struct command_result *direct_pay_listpeerchannels(struct command *cmd,
|
||||||
gossmod_add_localchan,
|
gossmod_add_localchan,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
direct_pay_override(p);
|
return direct_pay_override(p);
|
||||||
return command_still_pending(cmd);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void direct_pay_cb(struct direct_pay_data *d, struct payment *p)
|
static struct command_result *direct_pay_cb(struct direct_pay_data *d, struct payment *p)
|
||||||
{
|
{
|
||||||
struct out_req *req;
|
struct out_req *req;
|
||||||
|
|
||||||
|
@ -3493,14 +3468,12 @@ static void direct_pay_cb(struct direct_pay_data *d, struct payment *p)
|
||||||
if (p->step != PAYMENT_STEP_INITIALIZED)
|
if (p->step != PAYMENT_STEP_INITIALIZED)
|
||||||
return payment_continue(p);
|
return payment_continue(p);
|
||||||
|
|
||||||
|
req = jsonrpc_request_start(p->plugin, payment_cmd(p), "listpeerchannels",
|
||||||
|
|
||||||
req = jsonrpc_request_start(p->plugin, NULL, "listpeerchannels",
|
|
||||||
direct_pay_listpeerchannels,
|
direct_pay_listpeerchannels,
|
||||||
direct_pay_listpeerchannels,
|
direct_pay_listpeerchannels,
|
||||||
p);
|
p);
|
||||||
json_add_node_id(req->js, "id", p->route_destination);
|
json_add_node_id(req->js, "id", p->route_destination);
|
||||||
send_outreq(p->plugin, req);
|
return send_outreq(p->plugin, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct direct_pay_data *direct_pay_init(struct payment *p)
|
static struct direct_pay_data *direct_pay_init(struct payment *p)
|
||||||
|
@ -3596,7 +3569,7 @@ static struct adaptive_split_mod_data *adaptive_splitter_data_init(struct paymen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adaptive_splitter_cb(struct adaptive_split_mod_data *d, struct payment *p)
|
static struct command_result *adaptive_splitter_cb(struct adaptive_split_mod_data *d, struct payment *p)
|
||||||
{
|
{
|
||||||
struct payment *root = payment_root(p);
|
struct payment *root = payment_root(p);
|
||||||
struct adaptive_split_mod_data *root_data =
|
struct adaptive_split_mod_data *root_data =
|
||||||
|
@ -3705,7 +3678,7 @@ static void adaptive_splitter_cb(struct adaptive_split_mod_data *d, struct payme
|
||||||
MPP_ADAPTIVE_LOWER_LIMIT));
|
MPP_ADAPTIVE_LOWER_LIMIT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
payment_continue(p);
|
return payment_continue(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_PAYMENT_MODIFIER(adaptive_splitter, struct adaptive_split_mod_data *,
|
REGISTER_PAYMENT_MODIFIER(adaptive_splitter, struct adaptive_split_mod_data *,
|
||||||
|
@ -3785,11 +3758,10 @@ payee_incoming_limit_count(struct command *cmd,
|
||||||
payment_lower_max_htlcs(p, lim, why);
|
payment_lower_max_htlcs(p, lim, why);
|
||||||
}
|
}
|
||||||
|
|
||||||
payment_continue(p);
|
return payment_continue(p);
|
||||||
return command_still_pending(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void payee_incoming_limit_step_cb(void *d UNUSED, struct payment *p)
|
static struct command_result *payee_incoming_limit_step_cb(void *d UNUSED, struct payment *p)
|
||||||
{
|
{
|
||||||
/* Only operate at the initialization of te root payment.
|
/* Only operate at the initialization of te root payment.
|
||||||
* Also, no point operating if payment does not support MPP anyway.
|
* Also, no point operating if payment does not support MPP anyway.
|
||||||
|
@ -3800,11 +3772,11 @@ static void payee_incoming_limit_step_cb(void *d UNUSED, struct payment *p)
|
||||||
|
|
||||||
/* Get information on the destination. */
|
/* Get information on the destination. */
|
||||||
struct out_req *req;
|
struct out_req *req;
|
||||||
req = jsonrpc_request_start(p->plugin, NULL, "listchannels",
|
req = jsonrpc_request_start(p->plugin, payment_cmd(p), "listchannels",
|
||||||
&payee_incoming_limit_count,
|
&payee_incoming_limit_count,
|
||||||
&payment_rpc_failure, p);
|
&payment_rpc_failure, p);
|
||||||
json_add_node_id(req->js, "source", p->route_destination);
|
json_add_node_id(req->js, "source", p->route_destination);
|
||||||
(void) send_outreq(p->plugin, req);
|
return send_outreq(p->plugin, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_PAYMENT_MODIFIER(payee_incoming_limit, void *, NULL,
|
REGISTER_PAYMENT_MODIFIER(payee_incoming_limit, void *, NULL,
|
||||||
|
@ -3823,7 +3795,7 @@ route_exclusions_data_init(struct payment *p)
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void route_exclusions_step_cb(struct route_exclusions_data *d,
|
static struct command_result *route_exclusions_step_cb(struct route_exclusions_data *d,
|
||||||
struct payment *p)
|
struct payment *p)
|
||||||
{
|
{
|
||||||
if (p->parent)
|
if (p->parent)
|
||||||
|
@ -3841,17 +3813,15 @@ static void route_exclusions_step_cb(struct route_exclusions_data *d,
|
||||||
NULL, total, NULL);
|
NULL, total, NULL);
|
||||||
} else {
|
} else {
|
||||||
if (node_id_eq(&e->u.node_id, p->route_destination)) {
|
if (node_id_eq(&e->u.node_id, p->route_destination)) {
|
||||||
payment_abort(p, PAY_USER_ERROR, "Payee is manually excluded");
|
return payment_abort(p, PAY_USER_ERROR, "Payee is manually excluded");
|
||||||
return;
|
|
||||||
} else if (node_id_eq(&e->u.node_id, p->local_id)) {
|
} else if (node_id_eq(&e->u.node_id, p->local_id)) {
|
||||||
payment_abort(p, PAY_USER_ERROR, "Payer is manually excluded");
|
return payment_abort(p, PAY_USER_ERROR, "Payer is manually excluded");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tal_arr_expand(&p->excluded_nodes, e->u.node_id);
|
tal_arr_expand(&p->excluded_nodes, e->u.node_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
payment_continue(p);
|
return payment_continue(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_PAYMENT_MODIFIER(route_exclusions, struct route_exclusions_data *,
|
REGISTER_PAYMENT_MODIFIER(route_exclusions, struct route_exclusions_data *,
|
||||||
|
|
|
@ -145,8 +145,9 @@ struct payment {
|
||||||
/* Usually in global payments list */
|
/* Usually in global payments list */
|
||||||
struct list_node list;
|
struct list_node list;
|
||||||
/* The command that triggered this payment. Only set for the root
|
/* The command that triggered this payment. Only set for the root
|
||||||
* payment. */
|
* payment. It's an aux command if finished is set. */
|
||||||
struct command *cmd;
|
struct command *cmd;
|
||||||
|
bool finished;
|
||||||
struct plugin *plugin;
|
struct plugin *plugin;
|
||||||
struct node_id *local_id;
|
struct node_id *local_id;
|
||||||
|
|
||||||
|
@ -322,7 +323,7 @@ struct payment {
|
||||||
struct payment_modifier {
|
struct payment_modifier {
|
||||||
const char *name;
|
const char *name;
|
||||||
void *(*data_init)(struct payment *p);
|
void *(*data_init)(struct payment *p);
|
||||||
void (*post_step_cb)(void *data, struct payment *p);
|
struct command_result *(*post_step_cb)(void *data, struct payment *p);
|
||||||
};
|
};
|
||||||
|
|
||||||
void *payment_mod_get_data(const struct payment *payment,
|
void *payment_mod_get_data(const struct payment *payment,
|
||||||
|
@ -333,8 +334,8 @@ void *payment_mod_get_data(const struct payment *payment,
|
||||||
stringify(name), \
|
stringify(name), \
|
||||||
typesafe_cb_cast(void *(*)(struct payment *), \
|
typesafe_cb_cast(void *(*)(struct payment *), \
|
||||||
data_type (*)(struct payment *), data_init_cb), \
|
data_type (*)(struct payment *), data_init_cb), \
|
||||||
typesafe_cb_cast(void (*)(void *, struct payment *), \
|
typesafe_cb_cast(struct command_result *(*)(void *, struct payment *), \
|
||||||
void (*)(data_type, struct payment *), step_cb), \
|
struct command_result *(*)(data_type, struct payment *), step_cb), \
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The UNUSED marker is used to shut some compilers up. */
|
/* The UNUSED marker is used to shut some compilers up. */
|
||||||
|
@ -450,7 +451,7 @@ struct payment *payment_new(tal_t *ctx, struct command *cmd,
|
||||||
struct payment_modifier **mods);
|
struct payment_modifier **mods);
|
||||||
|
|
||||||
void payment_start(struct payment *p);
|
void payment_start(struct payment *p);
|
||||||
void payment_continue(struct payment *p);
|
struct command_result *payment_continue(struct payment *p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the payment to the current step.
|
* Set the payment to the current step.
|
||||||
|
@ -463,14 +464,14 @@ void payment_set_step(struct payment *p, enum payment_step newstep);
|
||||||
|
|
||||||
|
|
||||||
/* Fails a partial payment and continues with the core flow. */
|
/* Fails a partial payment and continues with the core flow. */
|
||||||
void payment_fail(struct payment *p, const char *fmt, ...) PRINTF_FMT(2,3);
|
struct command_result *payment_fail(struct payment *p, const char *fmt, ...) PRINTF_FMT(2,3);
|
||||||
|
|
||||||
/* Fails a payment process by setting the root payment to
|
/* Fails a payment process by setting the root payment to
|
||||||
* aborted. This will cause all subpayments to terminate as soon as
|
* aborted. This will cause all subpayments to terminate as soon as
|
||||||
* they can, and sets the root failreason so we have a sensible error
|
* they can, and sets the root failreason so we have a sensible error
|
||||||
* message. The failreason is overwritten if it is already set, since
|
* message. The failreason is overwritten if it is already set, since
|
||||||
* we probably know better what happened in the modifier.. */
|
* we probably know better what happened in the modifier.. */
|
||||||
void payment_abort(struct payment *p, enum jsonrpc_errcode code, const char *fmt, ...) PRINTF_FMT(3,4);
|
struct command_result *payment_abort(struct payment *p, enum jsonrpc_errcode code, const char *fmt, ...) PRINTF_FMT(3,4);
|
||||||
|
|
||||||
struct payment *payment_root(struct payment *p);
|
struct payment *payment_root(struct payment *p);
|
||||||
struct payment_tree_result payment_collect_result(struct payment *p);
|
struct payment_tree_result payment_collect_result(struct payment *p);
|
||||||
|
|
|
@ -625,11 +625,12 @@ static void on_payment_success(struct payment *payment)
|
||||||
if (!sha256_eq(payment->payment_hash, p->payment_hash) ||
|
if (!sha256_eq(payment->payment_hash, p->payment_hash) ||
|
||||||
payment->groupid != p->groupid)
|
payment->groupid != p->groupid)
|
||||||
continue;
|
continue;
|
||||||
if (p->cmd == NULL)
|
if (p->finished)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cmd = p->cmd;
|
cmd = p->cmd;
|
||||||
p->cmd = NULL;
|
p->cmd = aux_command(cmd);
|
||||||
|
p->finished = true;
|
||||||
|
|
||||||
ret = jsonrpc_stream_success(cmd);
|
ret = jsonrpc_stream_success(cmd);
|
||||||
json_add_node_id(ret, "destination", p->pay_destination);
|
json_add_node_id(ret, "destination", p->pay_destination);
|
||||||
|
@ -713,11 +714,12 @@ static void on_payment_failure(struct payment *payment)
|
||||||
if (!sha256_eq(payment->payment_hash, p->payment_hash) ||
|
if (!sha256_eq(payment->payment_hash, p->payment_hash) ||
|
||||||
payment->groupid != p->groupid)
|
payment->groupid != p->groupid)
|
||||||
continue;
|
continue;
|
||||||
if (p->cmd == NULL)
|
if (p->finished)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cmd = p->cmd;
|
cmd = p->cmd;
|
||||||
p->cmd = NULL;
|
p->cmd = aux_command(cmd);
|
||||||
|
p->finished = true;
|
||||||
if (p->aborterror != NULL) {
|
if (p->aborterror != NULL) {
|
||||||
/* We set an explicit toplevel error message,
|
/* We set an explicit toplevel error message,
|
||||||
* so let's report that. */
|
* so let's report that. */
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
/* AUTOGENERATED MOCKS START */
|
/* AUTOGENERATED MOCKS START */
|
||||||
|
/* Generated stub for aux_command */
|
||||||
|
struct command *aux_command(const struct command *cmd UNNEEDED)
|
||||||
|
{ fprintf(stderr, "aux_command called!\n"); abort(); }
|
||||||
/* Generated stub for blinded_onion_hops */
|
/* Generated stub for blinded_onion_hops */
|
||||||
u8 **blinded_onion_hops(const tal_t *ctx UNNEEDED,
|
u8 **blinded_onion_hops(const tal_t *ctx UNNEEDED,
|
||||||
struct amount_msat final_amount UNNEEDED,
|
struct amount_msat final_amount UNNEEDED,
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
/* AUTOGENERATED MOCKS START */
|
/* AUTOGENERATED MOCKS START */
|
||||||
|
/* Generated stub for aux_command */
|
||||||
|
struct command *aux_command(const struct command *cmd UNNEEDED)
|
||||||
|
{ fprintf(stderr, "aux_command called!\n"); abort(); }
|
||||||
/* Generated stub for blinded_onion_hops */
|
/* Generated stub for blinded_onion_hops */
|
||||||
u8 **blinded_onion_hops(const tal_t *ctx UNNEEDED,
|
u8 **blinded_onion_hops(const tal_t *ctx UNNEEDED,
|
||||||
struct amount_msat final_amount UNNEEDED,
|
struct amount_msat final_amount UNNEEDED,
|
||||||
|
|
Loading…
Add table
Reference in a new issue