diff --git a/lightningd/pay.c b/lightningd/pay.c index 757099a86..7620bd42a 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -27,29 +27,6 @@ struct routing_failure { int channel_dir; }; -/* Result of send_payment */ -struct sendpay_result { - /* Did the payment succeed? */ - bool succeeded; - /* Preimage. Only loaded if payment succeeded. */ - struct preimage preimage; - /* Error code, one of the PAY_* macro in jsonrpc_errors.h. - * Only loaded if payment failed. */ - int errorcode; - /* Pointer to the payment. Only loaded if payment - * succeeded or if error is PAY_IN_PROGRESS */ - const struct wallet_payment *payment; - /* Unparseable onion reply. Only loaded if payment failed, - * and errorcode == PAY_UNPARSEABLE_ONION. */ - const u8* onionreply; - /* Routing failure object. Only loaded if payment failed, - * and errorcode == PAY_DESTINATION_PERM_FAIL or - * errorcode == PAY_TRY_OTHER_ROUTE */ - struct routing_failure* routing_failure; - /* Error message. Only loaded if payment failed. */ - const char *details; -}; - /* sendpay command */ struct sendpay_command { struct list_node list; @@ -63,7 +40,7 @@ static void destroy_sendpay_command(struct sendpay_command *pc) list_del(&pc->list); } -/* Owned by cmd, if cmd is deleted, then json_sendpay_on_resolve will +/* Owned by cmd, if cmd is deleted, then sendpay_success/sendpay_fail will * no longer be called. */ static void add_sendpay_waiter(struct lightningd *ld, @@ -78,7 +55,7 @@ add_sendpay_waiter(struct lightningd *ld, tal_add_destructor(pc, destroy_sendpay_command); } -/* Owned by cmd, if cmd is deleted, then json_waitsendpay_on_resolve will +/* Owned by cmd, if cmd is deleted, then sendpay_success/sendpay_fail will * no longer be called. */ static void add_waitsendpay_waiter(struct lightningd *ld, @@ -124,210 +101,136 @@ json_add_payment_fields(struct json_stream *response, json_add_string(response, "description", t->description); } -static void -json_sendpay_success(struct command *cmd, - const struct sendpay_result *r) +static struct command_result *sendpay_success(struct command *cmd, + const struct wallet_payment *payment) { struct json_stream *response; - assert(r->payment->status == PAYMENT_COMPLETE); + assert(payment->status == PAYMENT_COMPLETE); response = json_stream_success(cmd); json_object_start(response, NULL); - json_add_payment_fields(response, r->payment); + json_add_payment_fields(response, payment); json_object_end(response); - was_pending(command_success(cmd, response)); + return command_success(cmd, response); } -static void json_waitsendpay_on_resolve(struct command *cmd, - const struct sendpay_result *r) +static void +json_add_routefail_info(struct json_stream *js, + unsigned int erring_index, + enum onion_type failcode, + const struct pubkey *erring_node, + const struct short_channel_id *erring_channel, + int channel_dir) { - const char *msg = NULL; - struct routing_failure *fail; + const char *failcodename = onion_type_name(failcode); - if (r->succeeded) - json_sendpay_success(cmd, r); - else { - struct json_stream *data; - switch (r->errorcode) { - /* We will never handle this case */ - case PAY_IN_PROGRESS: - abort(); + json_object_start(js, NULL); + json_add_num(js, "erring_index", erring_index); + json_add_num(js, "failcode", failcode); + /* FIXME: Better way to detect this? */ + if (!strstarts(failcodename, "INVALID ")) + json_add_string(js, "failcodename", failcodename); + json_add_pubkey(js, "erring_node", erring_node); + json_add_short_channel_id(js, "erring_channel", erring_channel); + json_add_num(js, "erring_direction", channel_dir); + json_object_end(js); +} - case PAY_RHASH_ALREADY_USED: - case PAY_UNSPECIFIED_ERROR: - case PAY_NO_SUCH_PAYMENT: - was_pending(command_fail(cmd, r->errorcode, "%s", - r->details)); - return; +/* onionreply used if pay_errcode == PAY_UNPARSEABLE_ONION */ +static struct command_result * +sendpay_fail(struct command *cmd, + int pay_errcode, + const u8 *onionreply, + const struct routing_failure *fail, + const char *details) +{ + struct json_stream *data; - case PAY_UNPARSEABLE_ONION: - msg = tal_fmt(tmpctx, - "failed: WIRE_PERMANENT_NODE_FAILURE " - "(%s)", - r->details); - - data = json_stream_fail(cmd, r->errorcode, msg); - json_object_start(data, NULL); - json_add_hex_talarr(data, "onionreply", r->onionreply); - json_object_end(data); - was_pending(command_failed(cmd, data)); - return; - - case PAY_DESTINATION_PERM_FAIL: - case PAY_TRY_OTHER_ROUTE: - fail = r->routing_failure; - msg = tal_fmt(cmd, - "failed: %s (%s)", - onion_type_name(fail->failcode), - r->details); - data = json_stream_fail(cmd, r->errorcode, msg); - - json_object_start(data, NULL); - json_add_num(data, "erring_index", - fail->erring_index); - json_add_num(data, "failcode", - (unsigned) fail->failcode); - json_add_pubkey(data, "erring_node", &fail->erring_node); - json_add_short_channel_id(data, "erring_channel", - &fail->erring_channel); - json_add_num(data, "erring_direction", - fail->channel_dir); - json_object_end(data); - was_pending(command_failed(cmd, data)); - return; - } - abort(); + if (pay_errcode == PAY_UNPARSEABLE_ONION) { + data = json_stream_fail(cmd, PAY_UNPARSEABLE_ONION, + "Malformed error reply"); + json_object_start(data, NULL); + json_add_hex_talarr(data, "onionreply", onionreply); + json_object_end(data); + return command_failed(cmd, data); } + + assert(fail); + data = json_stream_fail(cmd, pay_errcode, + tal_fmt(tmpctx, "failed: %s (%s)", + onion_type_name(fail->failcode), + details)); + json_add_routefail_info(data, + fail->erring_index, + fail->failcode, + &fail->erring_node, + &fail->erring_channel, + fail->channel_dir); + return command_failed(cmd, data); } -static void json_sendpay_on_resolve(struct command *cmd, - const struct sendpay_result* r) +/* We defer sendpay "success" until we know it's pending; consumes cmd */ +static struct command_result * +json_sendpay_in_progress(struct command *cmd, + const struct wallet_payment *payment) { - if (!r->succeeded && r->errorcode == PAY_IN_PROGRESS) { - /* This is normal for sendpay. Succeed. */ - struct json_stream *response = json_stream_success(cmd); - json_object_start(response, NULL); - json_add_string(response, "message", - "Monitor status with listpayments or waitsendpay"); - json_add_payment_fields(response, r->payment); - json_object_end(response); - was_pending(command_success(cmd, response)); - } else - json_waitsendpay_on_resolve(cmd, r); + struct json_stream *response = json_stream_success(cmd); + json_object_start(response, NULL); + json_add_string(response, "message", + "Monitor status with listpayments or waitsendpay"); + json_add_payment_fields(response, payment); + json_object_end(response); + return command_success(cmd, response); } -static void waitsendpay_resolve(struct lightningd *ld, +static void tell_waiters_failed(struct lightningd *ld, const struct sha256 *payment_hash, - const struct sendpay_result *result) + int pay_errcode, + const u8 *onionreply, + const struct routing_failure *fail, + const char *details) { struct sendpay_command *pc; struct sendpay_command *next; + /* Careful: sendpay_fail deletes cmd */ list_for_each_safe(&ld->waitsendpay_commands, pc, next, list) { if (!sha256_eq(payment_hash, &pc->payment_hash)) continue; - /* Delete later if callback does not delete. */ - tal_steal(tmpctx, pc); - json_waitsendpay_on_resolve(pc->cmd, result); + sendpay_fail(pc->cmd, pay_errcode, onionreply, fail, details); } } -static struct sendpay_result* -sendpay_result_success(const tal_t *ctx, - const struct preimage *payment_preimage, - const struct wallet_payment *payment) +static void tell_waiters_success(struct lightningd *ld, + const struct sha256 *payment_hash, + struct wallet_payment *payment) { - struct sendpay_result *result = tal(ctx, struct sendpay_result); - result->succeeded = true; - result->preimage = *payment_preimage; - result->payment = payment; - return result; -} + struct sendpay_command *pc; + struct sendpay_command *next; -static void payment_trigger_success(struct lightningd *ld, - const struct sha256 *payment_hash) -{ - struct sendpay_result *result; - struct wallet_payment *payment; + /* Careful: sendpay_success deletes cmd */ + list_for_each_safe(&ld->waitsendpay_commands, pc, next, list) { + if (!sha256_eq(payment_hash, &pc->payment_hash)) + continue; - payment = wallet_payment_by_hash(tmpctx, ld->wallet, payment_hash); - assert(payment); - - result = sendpay_result_success(tmpctx, payment->payment_preimage, payment); - - waitsendpay_resolve(ld, payment_hash, result); -} - -static struct sendpay_result* -sendpay_result_route_failure(const tal_t *ctx, - bool retry_plausible, - struct routing_failure *fail, - const u8 *onionreply, - const char *details) -{ - struct sendpay_result *result = tal(ctx, struct sendpay_result); - result->succeeded = false; - result->errorcode = - (!fail) ? PAY_UNPARSEABLE_ONION : - (!retry_plausible) ? PAY_DESTINATION_PERM_FAIL : - /*otherwise*/ PAY_TRY_OTHER_ROUTE ; - result->onionreply = onionreply; - result->routing_failure = fail; - result->details = details; - return result; -} - -static void payment_route_failure(struct lightningd *ld, - const struct sha256 *payment_hash, - bool retry_plausible, - struct routing_failure *fail, - const u8 *onionreply, - const char *details) -{ - struct sendpay_result *result; - - result = sendpay_result_route_failure(tmpctx, - retry_plausible, - fail, - onionreply, - details); - - waitsendpay_resolve(ld, payment_hash, result); -} - -static struct sendpay_result * -sendpay_result_simple_fail(const tal_t *ctx, - int errorcode, - char const *details) -{ - struct sendpay_result *result = tal(ctx, struct sendpay_result); - result->succeeded = false; - result->errorcode = errorcode; - result->details = details; - return result; -} - -static struct sendpay_result * -sendpay_result_in_progress(const tal_t *ctx, - const struct wallet_payment* payment, - char const *details) -{ - struct sendpay_result *result = tal(ctx, struct sendpay_result); - result->succeeded = false; - result->errorcode = PAY_IN_PROGRESS; - result->payment = payment; - result->details = details; - return result; + sendpay_success(pc->cmd, payment); + } } void payment_succeeded(struct lightningd *ld, struct htlc_out *hout, const struct preimage *rval) { + struct wallet_payment *payment; + wallet_payment_set_status(ld->wallet, &hout->payment_hash, PAYMENT_COMPLETE, rval); - payment_trigger_success(ld, &hout->payment_hash); + payment = wallet_payment_by_hash(tmpctx, ld->wallet, + &hout->payment_hash); + assert(payment); + + tell_waiters_success(ld, &hout->payment_hash, payment); } /* Return a struct routing_failure for an immediate failure @@ -349,11 +252,7 @@ immediate_routing_failure(const tal_t *ctx, routing_failure->failcode = failcode; routing_failure->erring_node = ld->id; routing_failure->erring_channel = *channel0; - if (dstid) - routing_failure->channel_dir = pubkey_idx(&ld->id, dstid); - /* FIXME: Don't set at all unless we know. */ - else - routing_failure->channel_dir = 0; + routing_failure->channel_dir = pubkey_idx(&ld->id, dstid); return routing_failure; } @@ -383,17 +282,14 @@ local_routing_failure(const tal_t *ctx, return routing_failure; } -/* Return false if permanent failure at the destination, true if - * retrying is plausible. Fill *routing_failure with NULL if - * we cannot report the remote failure, or with the routing - * failure to report (allocated from ctx) otherwise. */ +/* Fills in *pay_errcode with PAY_TRY_OTHER_ROUTE or PAY_DESTINATION_PERM_FAIL */ static struct routing_failure* remote_routing_failure(const tal_t *ctx, struct lightningd *ld, - bool *p_retry_plausible, const struct wallet_payment *payment, const struct onionreply *failure, - struct log *log) + struct log *log, + int *pay_errcode) { enum onion_type failcode = fromwire_peektype(failure->msg); struct routing_failure *routing_failure; @@ -403,14 +299,12 @@ remote_routing_failure(const tal_t *ctx, const struct short_channel_id *erring_channel; static const struct short_channel_id dummy_channel = { 0 }; int origin_index; - bool retry_plausible; int dir; routing_failure = tal(ctx, struct routing_failure); route_nodes = payment->route_nodes; route_channels = payment->route_channels; origin_index = failure->origin_index; - retry_plausible = true; assert(origin_index < tal_count(route_nodes)); @@ -427,13 +321,15 @@ remote_routing_failure(const tal_t *ctx, * - SHOULD fail the payment. * */ if (failcode & PERM) - retry_plausible = false; + *pay_errcode = PAY_DESTINATION_PERM_FAIL; else - retry_plausible = true; + *pay_errcode = PAY_TRY_OTHER_ROUTE; erring_node = &route_nodes[origin_index]; } else { u8 *gossip_msg; + *pay_errcode = PAY_TRY_OTHER_ROUTE; + /* Report the *next* channel as failing. */ erring_channel = &route_channels[origin_index + 1]; @@ -466,35 +362,26 @@ remote_routing_failure(const tal_t *ctx, routing_failure->erring_channel = *erring_channel; routing_failure->channel_dir = dir; - *p_retry_plausible = retry_plausible; - return routing_failure; } -void payment_store(struct lightningd *ld, - const struct sha256 *payment_hash) +void payment_store(struct lightningd *ld, const struct sha256 *payment_hash) { struct sendpay_command *pc; struct sendpay_command *next; - struct sendpay_result *result; const struct wallet_payment *payment; wallet_payment_store(ld->wallet, payment_hash); payment = wallet_payment_by_hash(tmpctx, ld->wallet, payment_hash); assert(payment); - /* Invent a sendpay result with PAY_IN_PROGRESS. */ - result = sendpay_result_in_progress(tmpctx, payment, - "Payment is still in progress"); - /* Trigger any sendpay commands waiting for the store to occur. */ list_for_each_safe(&ld->sendpay_commands, pc, next, list) { if (!sha256_eq(payment_hash, &pc->payment_hash)) continue; - /* Delete later if callback does not delete. */ - tal_steal(tmpctx, pc); - json_sendpay_on_resolve(pc->cmd, result); + /* Deletes from list, frees pc */ + json_sendpay_in_progress(pc->cmd, payment); } } @@ -504,7 +391,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout, struct wallet_payment *payment; struct routing_failure* fail = NULL; const char *failmsg; - bool retry_plausible; + int pay_errcode; payment = wallet_payment_by_hash(tmpctx, ld->wallet, &hout->payment_hash); @@ -543,7 +430,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout, if (localfail) { fail = local_routing_failure(tmpctx, ld, hout, payment); failmsg = localfail; - retry_plausible = true; + pay_errcode = PAY_TRY_OTHER_ROUTE; } else { /* Must be remote fail. */ assert(!hout->failcode); @@ -562,7 +449,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout, tal_hex(tmpctx, hout->failuremsg)); /* Cannot record failure. */ fail = NULL; - retry_plausible = true; + pay_errcode = PAY_UNPARSEABLE_ONION; } else { enum onion_type failcode = fromwire_peektype(reply->msg); log_info(hout->key.channel->log, @@ -573,9 +460,9 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout, reply->origin_index, failcode, onion_type_name(failcode)); fail = remote_routing_failure(tmpctx, ld, - &retry_plausible, payment, reply, - hout->key.channel->log); + hout->key.channel->log, + &pay_errcode); } } @@ -586,7 +473,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout, wallet_payment_set_failinfo(ld->wallet, &hout->payment_hash, fail ? NULL : hout->failuremsg, - (fail && !retry_plausible), + pay_errcode == PAY_DESTINATION_PERM_FAIL, fail ? fail->erring_index : -1, fail ? fail->failcode : 0, fail ? &fail->erring_node : NULL, @@ -595,24 +482,18 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout, failmsg, fail ? fail->channel_dir : 0); - /* Report to client. */ - payment_route_failure(ld, &hout->payment_hash, - retry_plausible, fail, hout->failuremsg, - failmsg); + tell_waiters_failed(ld, &hout->payment_hash, pay_errcode, + hout->failuremsg, fail, failmsg); } /* Wait for a payment. If cmd is deleted, then json_waitsendpay_on_resolve * no longer be called. - * Return false if we called callback already, true if - * callback is scheduled for later. */ -static bool wait_payment(struct lightningd *ld, - struct command *cmd, - const struct sha256 *payment_hash) + * Return callback if we called already, otherwise NULL. */ +static struct command_result *wait_payment(struct lightningd *ld, + struct command *cmd, + const struct sha256 *payment_hash) { struct wallet_payment *payment; - struct sendpay_result *result; - char const *details; - bool cb_not_called; u8 *failonionreply; bool faildestperm; int failindex; @@ -626,31 +507,19 @@ static bool wait_payment(struct lightningd *ld, payment = wallet_payment_by_hash(tmpctx, ld->wallet, payment_hash); if (!payment) { - details = tal_fmt(tmpctx, - "Never attempted payment for '%s'", - type_to_string(tmpctx, struct sha256, - payment_hash)); - result = sendpay_result_simple_fail(tmpctx, - PAY_NO_SUCH_PAYMENT, - details); - json_waitsendpay_on_resolve(cmd, result); - cb_not_called = false; - goto end; + return command_fail(cmd, PAY_NO_SUCH_PAYMENT, + "Never attempted payment for '%s'", + type_to_string(tmpctx, struct sha256, + payment_hash)); } switch (payment->status) { case PAYMENT_PENDING: add_waitsendpay_waiter(ld, cmd, payment_hash); - cb_not_called = true; - goto end; + return NULL; case PAYMENT_COMPLETE: - result = sendpay_result_success(tmpctx, - payment->payment_preimage, - payment); - json_waitsendpay_on_resolve(cmd, result); - cb_not_called = false; - goto end; + return sendpay_success(cmd, payment); case PAYMENT_FAILED: /* Get error from DB */ @@ -665,13 +534,14 @@ static bool wait_payment(struct lightningd *ld, &faildetail, &faildirection); /* Old DB might not save failure information */ - if (!failonionreply && !failnode) - result = sendpay_result_simple_fail(tmpctx, - PAY_UNSPECIFIED_ERROR, - "Payment failure reason unknown"); - else if (failonionreply) { + if (!failonionreply && !failnode) { + return command_fail(cmd, PAY_UNSPECIFIED_ERROR, + "Payment failure reason unknown"); + } else if (failonionreply) { /* failed to parse returned onion error */ - result = sendpay_result_route_failure(tmpctx, true, NULL, failonionreply, faildetail); + return sendpay_fail(cmd, PAY_UNPARSEABLE_ONION, + failonionreply, + NULL, faildetail); } else { /* Parsed onion error, get its details */ assert(failnode); @@ -682,23 +552,21 @@ static bool wait_payment(struct lightningd *ld, fail->erring_node = *failnode; fail->erring_channel = *failchannel; fail->channel_dir = faildirection; - result = sendpay_result_route_failure(tmpctx, !faildestperm, fail, NULL, faildetail); + return sendpay_fail(cmd, + faildestperm + ? PAY_DESTINATION_PERM_FAIL + : PAY_TRY_OTHER_ROUTE, + NULL, + fail, faildetail); } - - json_waitsendpay_on_resolve(cmd, result); - cb_not_called = false; - goto end; } /* Impossible. */ abort(); - -end: - return cb_not_called; } -/* Returns false if json_sendpay_on_resolve was called, true if not yet called. */ -static bool +/* Returns command_result if cmd was resolved, NULL if not yet called. */ +static struct command_result * send_payment(struct lightningd *ld, struct command *cmd, const struct sha256 *rhash, @@ -720,7 +588,6 @@ send_payment(struct lightningd *ld, struct short_channel_id *channels; struct routing_failure *fail; struct channel *channel; - struct sendpay_result *result; /* Expiry for HTLCs is absolute. And add one to give some margin. */ base_expiry = get_block_height(ld->topology) + 1; @@ -751,61 +618,40 @@ send_payment(struct lightningd *ld, log_debug(ld->log, "send_payment: found previous"); if (payment->status == PAYMENT_PENDING) { log_add(ld->log, "Payment is still in progress"); - result = sendpay_result_in_progress(tmpctx, - payment, - "Payment is still in progress"); - json_sendpay_on_resolve(cmd, result); - return false; + return json_sendpay_in_progress(cmd, payment); } if (payment->status == PAYMENT_COMPLETE) { log_add(ld->log, "... succeeded"); /* Must match successful payment parameters. */ if (payment->msatoshi != msatoshi) { - char *msg = tal_fmt(tmpctx, + return command_fail(cmd, PAY_RHASH_ALREADY_USED, "Already succeeded " "with amount %"PRIu64, payment->msatoshi); - result = sendpay_result_simple_fail(tmpctx, - PAY_RHASH_ALREADY_USED, - msg); - json_sendpay_on_resolve(cmd, result); - return false; } if (!pubkey_eq(&payment->destination, &ids[n_hops-1])) { - char *msg = tal_fmt(tmpctx, + return command_fail(cmd, PAY_RHASH_ALREADY_USED, "Already succeeded to %s", type_to_string(tmpctx, struct pubkey, &payment->destination)); - result = sendpay_result_simple_fail(tmpctx, - PAY_RHASH_ALREADY_USED, - msg); - json_sendpay_on_resolve(cmd, result); - return false; } - result = sendpay_result_success(tmpctx, - payment->payment_preimage, - payment); - json_sendpay_on_resolve(cmd, result); - return false; + return sendpay_success(cmd, payment); } log_add(ld->log, "... retrying"); } channel = active_channel_by_id(ld, &ids[0], NULL); if (!channel) { - /* Report routing failure to gossipd */ - fail = immediate_routing_failure(cmd, ld, - WIRE_UNKNOWN_NEXT_PEER, - &route[0].channel_id, - 0); + struct json_stream *data + = json_stream_fail(cmd, PAY_TRY_OTHER_ROUTE, + "No connection to first " + "peer found"); - /* Report routing failure to caller */ - result = sendpay_result_route_failure(tmpctx, true, fail, NULL, - "No connection to first " - "peer found"); - json_sendpay_on_resolve(cmd, result); - return false; + json_add_routefail_info(data, 0, WIRE_UNKNOWN_NEXT_PEER, + &ld->id, &route[0].channel_id, + pubkey_idx(&ld->id, &route[0].nodeid)); + return command_failed(cmd, data); } randombytes_buf(&sessionkey, sizeof(sessionkey)); @@ -822,17 +668,13 @@ send_payment(struct lightningd *ld, base_expiry + route[0].delay, rhash, onion, NULL, &hout); if (failcode) { - /* Report routing failure to gossipd */ fail = immediate_routing_failure(cmd, ld, failcode, &route[0].channel_id, &channel->peer->id); - /* Report routing failure to caller */ - result = sendpay_result_route_failure(tmpctx, true, fail, NULL, - "First peer not ready"); - json_sendpay_on_resolve(cmd, result); - return false; + return sendpay_fail(cmd, PAY_TRY_OTHER_ROUTE, NULL, + fail, "First peer not ready"); } /* Copy channels used along the route. */ @@ -872,8 +714,7 @@ send_payment(struct lightningd *ld, wallet_payment_setup(ld->wallet, payment); add_sendpay_waiter(ld, cmd, rhash); - - return true; + return NULL; } /*----------------------------------------------------------------------------- @@ -892,6 +733,7 @@ static struct command_result *json_sendpay(struct command *cmd, struct route_hop *route; u64 *msatoshi; const char *description; + struct command_result *res; if (!param(cmd, buffer, params, p_req("route", param_array, &routetok), @@ -942,12 +784,12 @@ static struct command_result *json_sendpay(struct command *cmd, } } - if (send_payment(cmd->ld, cmd, rhash, route, - msatoshi ? *msatoshi : route[routetok->size-1].amount, - description)) - return command_still_pending(cmd); - return command_its_complicated("send_payment is called in multiple paths," - " patching return value through is hard"); + res = send_payment(cmd->ld, cmd, rhash, route, + msatoshi ? *msatoshi : route[routetok->size-1].amount, + description); + if (res) + return res; + return command_still_pending(cmd); } static const struct json_command sendpay_command = { @@ -970,6 +812,7 @@ static struct command_result *json_waitsendpay(struct command *cmd, { struct sha256 *rhash; unsigned int *timeout; + struct command_result *res; if (!param(cmd, buffer, params, p_req("payment_hash", param_sha256, &rhash), @@ -977,10 +820,9 @@ static struct command_result *json_waitsendpay(struct command *cmd, NULL)) return command_param_failed(); - if (!wait_payment(cmd->ld, cmd, rhash)) - return command_its_complicated("wait_payment called in multiple" - " paths, patching return value" - " through is hard"); + res = wait_payment(cmd->ld, cmd, rhash); + if (res) + return res; if (timeout) new_reltimer(&cmd->ld->timers, cmd, time_from_sec(*timeout),