mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 15:44:21 +01:00
Added error code parameter to command_fail
Until now, `command_fail()` reported an error code of -1 for all uses. This PR adds an `int code` parameter to `command_fail()`, requiring the caller to explicitly include the error code. This is part of #1464. The majority of the calls are used during parameter validation and their error code is now JSONRPC2_INVALID_PARAMS. The rest of the calls report an error code of LIGHTNINGD, which I defined to -1 in `jsonrpc_errors.h`. The intention here is that as we improve our error reporting, all occurenaces of LIGHTNINGD will go away and we can eventually remove it. I also converted calls to `command_fail_detailed()` that took a `NULL` `data` parameter to use the new `command_fail()`. The only difference from an end user perspecive is that bad input errors that used to be -1 will now be -32602 (JSONRPC2_INVALID_PARAMS).
This commit is contained in:
committed by
Christian Decker
parent
c20e859f05
commit
7f437715d5
@@ -22,7 +22,8 @@ bool wtx_select_utxos(struct wallet_tx * tx, u32 fee_rate_per_kw,
|
|||||||
&tx->amount,
|
&tx->amount,
|
||||||
&fee_estimate);
|
&fee_estimate);
|
||||||
if (!tx->utxos || tx->amount < 546) {
|
if (!tx->utxos || tx->amount < 546) {
|
||||||
command_fail(tx->cmd, "Cannot afford fee %"PRIu64,
|
command_fail(tx->cmd, LIGHTNINGD,
|
||||||
|
"Cannot afford fee %"PRIu64,
|
||||||
fee_estimate);
|
fee_estimate);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -33,8 +34,8 @@ bool wtx_select_utxos(struct wallet_tx * tx, u32 fee_rate_per_kw,
|
|||||||
fee_rate_per_kw, out_len,
|
fee_rate_per_kw, out_len,
|
||||||
&fee_estimate, &tx->change);
|
&fee_estimate, &tx->change);
|
||||||
if (!tx->utxos || tx->amount < 546) {
|
if (!tx->utxos || tx->amount < 546) {
|
||||||
command_fail(tx->cmd,
|
command_fail(tx->cmd, LIGHTNINGD,
|
||||||
"Cannot afford funding transaction");
|
"Cannot afford funding transaction");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (tx->change < 546) {
|
if (tx->change < 546) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "bitcoind.h"
|
#include "bitcoind.h"
|
||||||
#include "chaintopology.h"
|
#include "chaintopology.h"
|
||||||
#include "jsonrpc.h"
|
#include "jsonrpc.h"
|
||||||
|
#include "jsonrpc_errors.h"
|
||||||
#include "lightningd.h"
|
#include "lightningd.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "watch.h"
|
#include "watch.h"
|
||||||
@@ -656,7 +657,8 @@ static void json_dev_setfees(struct command *cmd,
|
|||||||
continue;
|
continue;
|
||||||
if (!json_tok_number(buffer, ratetok[i],
|
if (!json_tok_number(buffer, ratetok[i],
|
||||||
&topo->dev_override_fee_rate[i])) {
|
&topo->dev_override_fee_rate[i])) {
|
||||||
command_fail(cmd, "Invalid feerate %.*s",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Invalid feerate %.*s",
|
||||||
ratetok[i]->end - ratetok[i]->start,
|
ratetok[i]->end - ratetok[i]->start,
|
||||||
buffer + ratetok[i]->start);
|
buffer + ratetok[i]->start);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <lightningd/connect_control.h>
|
#include <lightningd/connect_control.h>
|
||||||
#include <lightningd/json.h>
|
#include <lightningd/json.h>
|
||||||
#include <lightningd/jsonrpc.h>
|
#include <lightningd/jsonrpc.h>
|
||||||
|
#include <lightningd/jsonrpc_errors.h>
|
||||||
#include <lightningd/lightningd.h>
|
#include <lightningd/lightningd.h>
|
||||||
#include <lightningd/log.h>
|
#include <lightningd/log.h>
|
||||||
#include <lightningd/subd.h>
|
#include <lightningd/subd.h>
|
||||||
@@ -70,7 +71,7 @@ void gossip_connect_result(struct lightningd *ld, const u8 *msg)
|
|||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
command_success(c->cmd, response);
|
command_success(c->cmd, response);
|
||||||
} else {
|
} else {
|
||||||
command_fail(c->cmd, "%s", err);
|
command_fail(c->cmd, LIGHTNINGD, "%s", err);
|
||||||
}
|
}
|
||||||
/* They delete themselves from list */
|
/* They delete themselves from list */
|
||||||
}
|
}
|
||||||
@@ -109,14 +110,15 @@ static void json_connect(struct command *cmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!json_tok_pubkey(buffer, idtok, &id)) {
|
if (!json_tok_pubkey(buffer, idtok, &id)) {
|
||||||
command_fail(cmd, "id %.*s not valid",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"id %.*s not valid",
|
||||||
idtok->end - idtok->start,
|
idtok->end - idtok->start,
|
||||||
buffer + idtok->start);
|
buffer + idtok->start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hosttok && ataddr) {
|
if (hosttok && ataddr) {
|
||||||
command_fail(cmd,
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Can't specify host as both xxx@yyy "
|
"Can't specify host as both xxx@yyy "
|
||||||
"and separate argument");
|
"and separate argument");
|
||||||
return;
|
return;
|
||||||
@@ -133,7 +135,8 @@ static void json_connect(struct command *cmd,
|
|||||||
|
|
||||||
/* Port without host name? */
|
/* Port without host name? */
|
||||||
if (porttok && !name) {
|
if (porttok && !name) {
|
||||||
command_fail(cmd, "Can't specify port without host");
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Can't specify port without host");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +146,8 @@ static void json_connect(struct command *cmd,
|
|||||||
/* Is there a port? */
|
/* Is there a port? */
|
||||||
if (porttok) {
|
if (porttok) {
|
||||||
if (!json_tok_number(buffer, porttok, &port) || !port) {
|
if (!json_tok_number(buffer, porttok, &port) || !port) {
|
||||||
command_fail(cmd, "Port %.*s not valid",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Port %.*s not valid",
|
||||||
porttok->end - porttok->start,
|
porttok->end - porttok->start,
|
||||||
buffer + porttok->start);
|
buffer + porttok->start);
|
||||||
return;
|
return;
|
||||||
@@ -156,7 +160,7 @@ static void json_connect(struct command *cmd,
|
|||||||
&& !cmd->ld->pure_tor_setup,
|
&& !cmd->ld->pure_tor_setup,
|
||||||
true,
|
true,
|
||||||
&err_msg)) {
|
&err_msg)) {
|
||||||
command_fail(cmd, "Host %s:%u not valid: %s",
|
command_fail(cmd, LIGHTNINGD, "Host %s:%u not valid: %s",
|
||||||
name, port, err_msg ? err_msg : "port is 0");
|
name, port, err_msg ? err_msg : "port is 0");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <lightningd/htlc_end.h>
|
#include <lightningd/htlc_end.h>
|
||||||
#include <lightningd/json.h>
|
#include <lightningd/json.h>
|
||||||
#include <lightningd/jsonrpc.h>
|
#include <lightningd/jsonrpc.h>
|
||||||
|
#include <lightningd/jsonrpc_errors.h>
|
||||||
#include <lightningd/lightningd.h>
|
#include <lightningd/lightningd.h>
|
||||||
#include <lightningd/log.h>
|
#include <lightningd/log.h>
|
||||||
#include <lightningd/peer_control.h>
|
#include <lightningd/peer_control.h>
|
||||||
@@ -23,9 +24,9 @@ static void ping_reply(struct subd *subd, const u8 *msg, const int *fds UNUSED,
|
|||||||
ok = fromwire_gossip_ping_reply(msg, &sent, &totlen);
|
ok = fromwire_gossip_ping_reply(msg, &sent, &totlen);
|
||||||
|
|
||||||
if (!ok)
|
if (!ok)
|
||||||
command_fail(cmd, "Bad reply message");
|
command_fail(cmd, LIGHTNINGD, "Bad reply message");
|
||||||
else if (!sent)
|
else if (!sent)
|
||||||
command_fail(cmd, "Unknown peer");
|
command_fail(cmd, LIGHTNINGD, "Unknown peer");
|
||||||
else {
|
else {
|
||||||
struct json_result *response = new_json_result(cmd);
|
struct json_result *response = new_json_result(cmd);
|
||||||
|
|
||||||
@@ -57,7 +58,8 @@ static void json_dev_ping(struct command *cmd,
|
|||||||
/* FIXME: These checks are horrible, use a peer flag to say it's
|
/* FIXME: These checks are horrible, use a peer flag to say it's
|
||||||
* ready to forward! */
|
* ready to forward! */
|
||||||
if (!json_tok_number(buffer, lentok, &len)) {
|
if (!json_tok_number(buffer, lentok, &len)) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid number",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid number",
|
||||||
lentok->end - lentok->start,
|
lentok->end - lentok->start,
|
||||||
buffer + lentok->start);
|
buffer + lentok->start);
|
||||||
return;
|
return;
|
||||||
@@ -79,12 +81,14 @@ static void json_dev_ping(struct command *cmd,
|
|||||||
* * [`byteslen`:`ignored`]
|
* * [`byteslen`:`ignored`]
|
||||||
*/
|
*/
|
||||||
if (len > 65535 - 2 - 2 - 2) {
|
if (len > 65535 - 2 - 2 - 2) {
|
||||||
command_fail(cmd, "%u would result in oversize ping", len);
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"%u would result in oversize ping", len);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!json_tok_number(buffer, pongbytestok, &pongbytes)) {
|
if (!json_tok_number(buffer, pongbytestok, &pongbytes)) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid number",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid number",
|
||||||
pongbytestok->end - pongbytestok->start,
|
pongbytestok->end - pongbytestok->start,
|
||||||
buffer + pongbytestok->start);
|
buffer + pongbytestok->start);
|
||||||
return;
|
return;
|
||||||
@@ -92,12 +96,14 @@ static void json_dev_ping(struct command *cmd,
|
|||||||
|
|
||||||
/* Note that > 65531 is valid: it means "no pong reply" */
|
/* Note that > 65531 is valid: it means "no pong reply" */
|
||||||
if (pongbytes > 65535) {
|
if (pongbytes > 65535) {
|
||||||
command_fail(cmd, "pongbytes %u > 65535", pongbytes);
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"pongbytes %u > 65535", pongbytes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!json_tok_pubkey(buffer, idtok, &id)) {
|
if (!json_tok_pubkey(buffer, idtok, &id)) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid pubkey",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid pubkey",
|
||||||
idtok->end - idtok->start,
|
idtok->end - idtok->start,
|
||||||
buffer + idtok->start);
|
buffer + idtok->start);
|
||||||
return;
|
return;
|
||||||
@@ -111,7 +117,7 @@ static void json_dev_ping(struct command *cmd,
|
|||||||
if (!channel
|
if (!channel
|
||||||
|| !channel->owner
|
|| !channel->owner
|
||||||
|| !streq(channel->owner->name, "lightning_channeld")) {
|
|| !streq(channel->owner->name, "lightning_channeld")) {
|
||||||
command_fail(cmd, "Peer in %s",
|
command_fail(cmd, LIGHTNINGD, "Peer in %s",
|
||||||
channel && channel->owner
|
channel && channel->owner
|
||||||
? channel->owner->name
|
? channel->owner->name
|
||||||
: "unattached");
|
: "unattached");
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include <lightningd/hsm_control.h>
|
#include <lightningd/hsm_control.h>
|
||||||
#include <lightningd/json.h>
|
#include <lightningd/json.h>
|
||||||
#include <lightningd/jsonrpc.h>
|
#include <lightningd/jsonrpc.h>
|
||||||
|
#include <lightningd/jsonrpc_errors.h>
|
||||||
#include <lightningd/log.h>
|
#include <lightningd/log.h>
|
||||||
#include <sodium/randombytes.h>
|
#include <sodium/randombytes.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -275,7 +276,7 @@ static void json_getnodes_reply(struct subd *gossip UNUSED, const u8 *reply,
|
|||||||
size_t i, j;
|
size_t i, j;
|
||||||
|
|
||||||
if (!fromwire_gossip_getnodes_reply(reply, reply, &nodes)) {
|
if (!fromwire_gossip_getnodes_reply(reply, reply, &nodes)) {
|
||||||
command_fail(cmd, "Malformed gossip_getnodes response");
|
command_fail(cmd, LIGHTNINGD, "Malformed gossip_getnodes response");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,7 +326,7 @@ static void json_listnodes(struct command *cmd, const char *buffer,
|
|||||||
if (idtok) {
|
if (idtok) {
|
||||||
id = tal_arr(cmd, struct pubkey, 1);
|
id = tal_arr(cmd, struct pubkey, 1);
|
||||||
if (!json_tok_pubkey(buffer, idtok, id)) {
|
if (!json_tok_pubkey(buffer, idtok, id)) {
|
||||||
command_fail(cmd, "Invalid id");
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Invalid id");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -351,7 +352,7 @@ static void json_getroute_reply(struct subd *gossip UNUSED, const u8 *reply, con
|
|||||||
fromwire_gossip_getroute_reply(reply, reply, &hops);
|
fromwire_gossip_getroute_reply(reply, reply, &hops);
|
||||||
|
|
||||||
if (tal_count(hops) == 0) {
|
if (tal_count(hops) == 0) {
|
||||||
command_fail(cmd, "Could not find a route");
|
command_fail(cmd, LIGHTNINGD, "Could not find a route");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,43 +394,46 @@ static void json_getroute(struct command *cmd, const char *buffer, const jsmntok
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!json_tok_pubkey(buffer, idtok, &destination)) {
|
if (!json_tok_pubkey(buffer, idtok, &destination)) {
|
||||||
command_fail(cmd, "Invalid id");
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Invalid id");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cltvtok && !json_tok_number(buffer, cltvtok, &cltv)) {
|
if (cltvtok && !json_tok_number(buffer, cltvtok, &cltv)) {
|
||||||
command_fail(cmd, "Invalid cltv");
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Invalid cltv");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!json_tok_u64(buffer, msatoshitok, &msatoshi)) {
|
if (!json_tok_u64(buffer, msatoshitok, &msatoshi)) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid number",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid number",
|
||||||
msatoshitok->end - msatoshitok->start,
|
msatoshitok->end - msatoshitok->start,
|
||||||
buffer + msatoshitok->start);
|
buffer + msatoshitok->start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!json_tok_double(buffer, riskfactortok, &riskfactor)) {
|
if (!json_tok_double(buffer, riskfactortok, &riskfactor)) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid double",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid double",
|
||||||
riskfactortok->end - riskfactortok->start,
|
riskfactortok->end - riskfactortok->start,
|
||||||
buffer + riskfactortok->start);
|
buffer + riskfactortok->start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromidtok && !json_tok_pubkey(buffer, fromidtok, &source)) {
|
if (fromidtok && !json_tok_pubkey(buffer, fromidtok, &source)) {
|
||||||
command_fail(cmd, "Invalid from id");
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Invalid from id");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fuzztok &&
|
if (fuzztok &&
|
||||||
!json_tok_double(buffer, fuzztok, &fuzz)) {
|
!json_tok_double(buffer, fuzztok, &fuzz)) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid double",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid double",
|
||||||
fuzztok->end - fuzztok->start,
|
fuzztok->end - fuzztok->start,
|
||||||
buffer + fuzztok->start);
|
buffer + fuzztok->start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(0.0 <= fuzz && fuzz <= 100.0)) {
|
if (!(0.0 <= fuzz && fuzz <= 100.0)) {
|
||||||
command_fail(cmd,
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"fuzz must be in range 0.0 <= %f <= 100.0",
|
"fuzz must be in range 0.0 <= %f <= 100.0",
|
||||||
fuzz);
|
fuzz);
|
||||||
return;
|
return;
|
||||||
@@ -439,7 +443,7 @@ static void json_getroute(struct command *cmd, const char *buffer, const jsmntok
|
|||||||
|
|
||||||
if (seedtok) {
|
if (seedtok) {
|
||||||
if (seedtok->end - seedtok->start > sizeof(seed))
|
if (seedtok->end - seedtok->start > sizeof(seed))
|
||||||
command_fail(cmd,
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"seed must be < %zu bytes", sizeof(seed));
|
"seed must be < %zu bytes", sizeof(seed));
|
||||||
|
|
||||||
memset(&seed, 0, sizeof(seed));
|
memset(&seed, 0, sizeof(seed));
|
||||||
@@ -472,7 +476,7 @@ static void json_listchannels_reply(struct subd *gossip UNUSED, const u8 *reply,
|
|||||||
struct json_result *response = new_json_result(cmd);
|
struct json_result *response = new_json_result(cmd);
|
||||||
|
|
||||||
if (!fromwire_gossip_getchannels_reply(reply, reply, &entries)) {
|
if (!fromwire_gossip_getchannels_reply(reply, reply, &entries)) {
|
||||||
command_fail(cmd, "Invalid reply from gossipd");
|
command_fail(cmd, LIGHTNINGD, "Invalid reply from gossipd");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,7 +525,8 @@ static void json_listchannels(struct command *cmd, const char *buffer,
|
|||||||
if (idtok) {
|
if (idtok) {
|
||||||
id = tal_arr(cmd, struct short_channel_id, 1);
|
id = tal_arr(cmd, struct short_channel_id, 1);
|
||||||
if (!json_tok_short_channel_id(buffer, idtok, id)) {
|
if (!json_tok_short_channel_id(buffer, idtok, id)) {
|
||||||
command_fail(cmd, "Invalid short_channel_id");
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Invalid short_channel_id");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "invoice.h"
|
#include "invoice.h"
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
#include "jsonrpc.h"
|
#include "jsonrpc.h"
|
||||||
|
#include "jsonrpc_errors.h"
|
||||||
#include "lightningd.h"
|
#include "lightningd.h"
|
||||||
#include <bitcoin/address.h>
|
#include <bitcoin/address.h>
|
||||||
#include <bitcoin/base58.h>
|
#include <bitcoin/base58.h>
|
||||||
@@ -70,13 +71,15 @@ static void tell_waiter(struct command *cmd, const struct invoice *inv)
|
|||||||
json_add_invoice(response, &details, true);
|
json_add_invoice(response, &details, true);
|
||||||
if (details.state == PAID)
|
if (details.state == PAID)
|
||||||
command_success(cmd, response);
|
command_success(cmd, response);
|
||||||
else
|
else {
|
||||||
|
/* FIXME: -2 should be a constant in jsonrpc_errors.h. */
|
||||||
command_fail_detailed(cmd, -2, response,
|
command_fail_detailed(cmd, -2, response,
|
||||||
"invoice expired during wait");
|
"invoice expired during wait");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
static void tell_waiter_deleted(struct command *cmd)
|
static void tell_waiter_deleted(struct command *cmd)
|
||||||
{
|
{
|
||||||
command_fail(cmd, "Invoice deleted during wait");
|
command_fail(cmd, LIGHTNINGD, "Invoice deleted during wait");
|
||||||
}
|
}
|
||||||
static void wait_on_invoice(const struct invoice *invoice, void *cmd)
|
static void wait_on_invoice(const struct invoice *invoice, void *cmd)
|
||||||
{
|
{
|
||||||
@@ -141,10 +144,11 @@ static bool parse_fallback(struct command *cmd,
|
|||||||
buffer, fallback,
|
buffer, fallback,
|
||||||
fallback_script);
|
fallback_script);
|
||||||
if (fallback_parse == ADDRESS_PARSE_UNRECOGNIZED) {
|
if (fallback_parse == ADDRESS_PARSE_UNRECOGNIZED) {
|
||||||
command_fail(cmd, "Fallback address not valid");
|
command_fail(cmd, LIGHTNINGD, "Fallback address not valid");
|
||||||
return false;
|
return false;
|
||||||
} else if (fallback_parse == ADDRESS_PARSE_WRONG_NETWORK) {
|
} else if (fallback_parse == ADDRESS_PARSE_WRONG_NETWORK) {
|
||||||
command_fail(cmd, "Fallback address does not match our network %s",
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Fallback address does not match our network %s",
|
||||||
get_chainparams(cmd->ld)->network_name);
|
get_chainparams(cmd->ld)->network_name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -189,7 +193,7 @@ static void json_invoice(struct command *cmd,
|
|||||||
msatoshi_val = tal(cmd, u64);
|
msatoshi_val = tal(cmd, u64);
|
||||||
if (!json_tok_u64(buffer, msatoshi, msatoshi_val)
|
if (!json_tok_u64(buffer, msatoshi, msatoshi_val)
|
||||||
|| *msatoshi_val == 0) {
|
|| *msatoshi_val == 0) {
|
||||||
command_fail(cmd,
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"'%.*s' is not a valid positive number",
|
"'%.*s' is not a valid positive number",
|
||||||
msatoshi->end - msatoshi->start,
|
msatoshi->end - msatoshi->start,
|
||||||
buffer + msatoshi->start);
|
buffer + msatoshi->start);
|
||||||
@@ -199,39 +203,42 @@ static void json_invoice(struct command *cmd,
|
|||||||
/* label */
|
/* label */
|
||||||
label_val = json_tok_label(cmd, buffer, label);
|
label_val = json_tok_label(cmd, buffer, label);
|
||||||
if (!label_val) {
|
if (!label_val) {
|
||||||
command_fail(cmd, "label '%.*s' not a string or number",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"label '%.*s' not a string or number",
|
||||||
label->end - label->start, buffer + label->start);
|
label->end - label->start, buffer + label->start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (wallet_invoice_find_by_label(wallet, &invoice, label_val)) {
|
if (wallet_invoice_find_by_label(wallet, &invoice, label_val)) {
|
||||||
command_fail_detailed(cmd, INVOICE_LABEL_ALREADY_EXISTS,
|
command_fail(cmd, INVOICE_LABEL_ALREADY_EXISTS,
|
||||||
NULL,
|
"Duplicate label '%s'", label_val->s);
|
||||||
"Duplicate label '%s'", label_val->s);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (strlen(label_val->s) > INVOICE_MAX_LABEL_LEN) {
|
if (strlen(label_val->s) > INVOICE_MAX_LABEL_LEN) {
|
||||||
command_fail(cmd, "Label '%s' over %u bytes", label_val->s,
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Label '%s' over %u bytes", label_val->s,
|
||||||
INVOICE_MAX_LABEL_LEN);
|
INVOICE_MAX_LABEL_LEN);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
desc = json_tok_escaped_string(cmd, buffer, desctok);
|
desc = json_tok_escaped_string(cmd, buffer, desctok);
|
||||||
if (!desc) {
|
if (!desc) {
|
||||||
command_fail(cmd, "description '%.*s' not a string",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"description '%.*s' not a string",
|
||||||
desctok->end - desctok->start,
|
desctok->end - desctok->start,
|
||||||
buffer + desctok->start);
|
buffer + desctok->start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
desc_val = json_escaped_unescape(cmd, desc);
|
desc_val = json_escaped_unescape(cmd, desc);
|
||||||
if (!desc_val) {
|
if (!desc_val) {
|
||||||
command_fail(cmd, "description '%s' is invalid"
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"description '%s' is invalid"
|
||||||
" (note: we don't allow \\u)",
|
" (note: we don't allow \\u)",
|
||||||
desc->s);
|
desc->s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* description */
|
/* description */
|
||||||
if (strlen(desc_val) >= BOLT11_FIELD_BYTE_LIMIT) {
|
if (strlen(desc_val) >= BOLT11_FIELD_BYTE_LIMIT) {
|
||||||
command_fail(cmd,
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Descriptions greater than %d bytes "
|
"Descriptions greater than %d bytes "
|
||||||
"not yet supported "
|
"not yet supported "
|
||||||
"(description length %zu)",
|
"(description length %zu)",
|
||||||
@@ -241,7 +248,8 @@ static void json_invoice(struct command *cmd,
|
|||||||
}
|
}
|
||||||
/* expiry */
|
/* expiry */
|
||||||
if (exp && !json_tok_u64(buffer, exp, &expiry)) {
|
if (exp && !json_tok_u64(buffer, exp, &expiry)) {
|
||||||
command_fail(cmd, "Expiry '%.*s' invalid seconds",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Expiry '%.*s' invalid seconds",
|
||||||
exp->end - exp->start,
|
exp->end - exp->start,
|
||||||
buffer + exp->start);
|
buffer + exp->start);
|
||||||
return;
|
return;
|
||||||
@@ -255,7 +263,8 @@ static void json_invoice(struct command *cmd,
|
|||||||
&fallback_scripts[0]))
|
&fallback_scripts[0]))
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
command_fail(cmd, "fallback is deprecated: use fallbacks");
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"fallback is deprecated: use fallbacks");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,12 +274,14 @@ static void json_invoice(struct command *cmd,
|
|||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
|
|
||||||
if (fallback) {
|
if (fallback) {
|
||||||
command_fail(cmd, "Cannot use fallback and fallbacks");
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Cannot use fallback and fallbacks");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fallbacks->type != JSMN_ARRAY) {
|
if (fallbacks->type != JSMN_ARRAY) {
|
||||||
command_fail(cmd, "fallback must be an array");
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"fallback must be an array");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fallback_scripts = tal_arr(cmd, const u8 *, n);
|
fallback_scripts = tal_arr(cmd, const u8 *, n);
|
||||||
@@ -291,7 +302,8 @@ static void json_invoice(struct command *cmd,
|
|||||||
if (!hex_decode(buffer + preimagetok->start,
|
if (!hex_decode(buffer + preimagetok->start,
|
||||||
preimagetok->end - preimagetok->start,
|
preimagetok->end - preimagetok->start,
|
||||||
r.r, sizeof(r.r))) {
|
r.r, sizeof(r.r))) {
|
||||||
command_fail(cmd, "preimage must be 64 hex digits");
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"preimage must be 64 hex digits");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@@ -306,8 +318,8 @@ static void json_invoice(struct command *cmd,
|
|||||||
*/
|
*/
|
||||||
if (preimagetok &&
|
if (preimagetok &&
|
||||||
wallet_invoice_find_by_rhash(cmd->ld->wallet, &invoice, &rhash)) {
|
wallet_invoice_find_by_rhash(cmd->ld->wallet, &invoice, &rhash)) {
|
||||||
command_fail_detailed(cmd, INVOICE_PREIMAGE_ALREADY_EXISTS,
|
command_fail(cmd, INVOICE_PREIMAGE_ALREADY_EXISTS,
|
||||||
NULL, "preimage already used");
|
"preimage already used");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,7 +349,8 @@ static void json_invoice(struct command *cmd,
|
|||||||
&rhash);
|
&rhash);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
command_fail(cmd, "Failed to create invoice on database");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Failed to create invoice on database");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,7 +412,8 @@ static void json_listinvoice_internal(struct command *cmd,
|
|||||||
if (labeltok) {
|
if (labeltok) {
|
||||||
label = json_tok_label(cmd, buffer, labeltok);
|
label = json_tok_label(cmd, buffer, labeltok);
|
||||||
if (!label) {
|
if (!label) {
|
||||||
command_fail(cmd, "label '%.*s' is not a string or number",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"label '%.*s' is not a string or number",
|
||||||
labeltok->end - labeltok->start,
|
labeltok->end - labeltok->start,
|
||||||
buffer + labeltok->start);
|
buffer + labeltok->start);
|
||||||
return;
|
return;
|
||||||
@@ -467,13 +481,14 @@ static void json_delinvoice(struct command *cmd,
|
|||||||
|
|
||||||
label = json_tok_label(cmd, buffer, labeltok);
|
label = json_tok_label(cmd, buffer, labeltok);
|
||||||
if (!label) {
|
if (!label) {
|
||||||
command_fail(cmd, "label '%.*s' is not a string or number",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"label '%.*s' is not a string or number",
|
||||||
labeltok->end - labeltok->start,
|
labeltok->end - labeltok->start,
|
||||||
buffer + labeltok->start);
|
buffer + labeltok->start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!wallet_invoice_find_by_label(wallet, &i, label)) {
|
if (!wallet_invoice_find_by_label(wallet, &i, label)) {
|
||||||
command_fail(cmd, "Unknown invoice");
|
command_fail(cmd, LIGHTNINGD, "Unknown invoice");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wallet_invoice_details(cmd, cmd->ld->wallet, i, &details);
|
wallet_invoice_details(cmd, cmd->ld->wallet, i, &details);
|
||||||
@@ -484,7 +499,7 @@ static void json_delinvoice(struct command *cmd,
|
|||||||
* might not make sense if it changed! */
|
* might not make sense if it changed! */
|
||||||
actual_status = invoice_status_str(&details);
|
actual_status = invoice_status_str(&details);
|
||||||
if (!streq(actual_status, status)) {
|
if (!streq(actual_status, status)) {
|
||||||
command_fail(cmd, "Invoice status is %s not %s",
|
command_fail(cmd, LIGHTNINGD, "Invoice status is %s not %s",
|
||||||
actual_status, status);
|
actual_status, status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -497,7 +512,7 @@ static void json_delinvoice(struct command *cmd,
|
|||||||
log_broken(cmd->ld->log,
|
log_broken(cmd->ld->log,
|
||||||
"Error attempting to remove invoice %"PRIu64,
|
"Error attempting to remove invoice %"PRIu64,
|
||||||
i.id);
|
i.id);
|
||||||
command_fail(cmd, "Database error");
|
command_fail(cmd, LIGHTNINGD, "Database error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -526,7 +541,8 @@ static void json_delexpiredinvoice(struct command *cmd, const char *buffer,
|
|||||||
|
|
||||||
if (maxexpirytimetok) {
|
if (maxexpirytimetok) {
|
||||||
if (!json_tok_u64(buffer, maxexpirytimetok, &maxexpirytime)) {
|
if (!json_tok_u64(buffer, maxexpirytimetok, &maxexpirytime)) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid number",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid number",
|
||||||
maxexpirytimetok->end - maxexpirytimetok->start,
|
maxexpirytimetok->end - maxexpirytimetok->start,
|
||||||
buffer + maxexpirytimetok->start);
|
buffer + maxexpirytimetok->start);
|
||||||
return;
|
return;
|
||||||
@@ -566,7 +582,8 @@ static void json_autocleaninvoice(struct command *cmd,
|
|||||||
|
|
||||||
if (cycletok) {
|
if (cycletok) {
|
||||||
if (!json_tok_u64(buffer, cycletok, &cycle)) {
|
if (!json_tok_u64(buffer, cycletok, &cycle)) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid number",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid number",
|
||||||
cycletok->end - cycletok->start,
|
cycletok->end - cycletok->start,
|
||||||
buffer + cycletok->start);
|
buffer + cycletok->start);
|
||||||
return;
|
return;
|
||||||
@@ -574,7 +591,8 @@ static void json_autocleaninvoice(struct command *cmd,
|
|||||||
}
|
}
|
||||||
if (exbytok) {
|
if (exbytok) {
|
||||||
if (!json_tok_u64(buffer, exbytok, &exby)) {
|
if (!json_tok_u64(buffer, exbytok, &exby)) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid number",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid number",
|
||||||
exbytok->end - exbytok->start,
|
exbytok->end - exbytok->start,
|
||||||
buffer + exbytok->start);
|
buffer + exbytok->start);
|
||||||
return;
|
return;
|
||||||
@@ -614,7 +632,8 @@ static void json_waitanyinvoice(struct command *cmd,
|
|||||||
pay_index = 0;
|
pay_index = 0;
|
||||||
} else {
|
} else {
|
||||||
if (!json_tok_u64(buffer, pay_indextok, &pay_index)) {
|
if (!json_tok_u64(buffer, pay_indextok, &pay_index)) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid number",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid number",
|
||||||
pay_indextok->end - pay_indextok->start,
|
pay_indextok->end - pay_indextok->start,
|
||||||
buffer + pay_indextok->start);
|
buffer + pay_indextok->start);
|
||||||
return;
|
return;
|
||||||
@@ -660,14 +679,15 @@ static void json_waitinvoice(struct command *cmd,
|
|||||||
/* Search for invoice */
|
/* Search for invoice */
|
||||||
label = json_tok_label(cmd, buffer, labeltok);
|
label = json_tok_label(cmd, buffer, labeltok);
|
||||||
if (!label) {
|
if (!label) {
|
||||||
command_fail(cmd, "label '%.*s' is not a string or number",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"label '%.*s' is not a string or number",
|
||||||
labeltok->end - labeltok->start,
|
labeltok->end - labeltok->start,
|
||||||
buffer + labeltok->start);
|
buffer + labeltok->start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wallet_invoice_find_by_label(wallet, &i, label)) {
|
if (!wallet_invoice_find_by_label(wallet, &i, label)) {
|
||||||
command_fail(cmd, "Label not found");
|
command_fail(cmd, LIGHTNINGD, "Label not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wallet_invoice_details(cmd, cmd->ld->wallet, i, &details);
|
wallet_invoice_details(cmd, cmd->ld->wallet, i, &details);
|
||||||
@@ -753,7 +773,7 @@ static void json_decodepay(struct command *cmd,
|
|||||||
b11 = bolt11_decode(cmd, str, desc, &fail);
|
b11 = bolt11_decode(cmd, str, desc, &fail);
|
||||||
|
|
||||||
if (!b11) {
|
if (!b11) {
|
||||||
command_fail(cmd, "Invalid bolt11: %s", fail);
|
command_fail(cmd, LIGHTNINGD, "Invalid bolt11: %s", fail);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,8 @@ static void json_rhash(struct command *cmd,
|
|||||||
if (!hex_decode(buffer + secrettok->start,
|
if (!hex_decode(buffer + secrettok->start,
|
||||||
secrettok->end - secrettok->start,
|
secrettok->end - secrettok->start,
|
||||||
&secret, sizeof(secret))) {
|
&secret, sizeof(secret))) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid 32-byte hex value",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid 32-byte hex value",
|
||||||
secrettok->end - secrettok->start,
|
secrettok->end - secrettok->start,
|
||||||
buffer + secrettok->start);
|
buffer + secrettok->start);
|
||||||
return;
|
return;
|
||||||
@@ -225,7 +226,8 @@ static void json_help(struct command *cmd,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
command_fail(cmd, "Unknown command '%.*s'",
|
command_fail(cmd, JSONRPC2_METHOD_NOT_FOUND,
|
||||||
|
"Unknown command '%.*s'",
|
||||||
cmdtok->end - cmdtok->start,
|
cmdtok->end - cmdtok->start,
|
||||||
buffer + cmdtok->start);
|
buffer + cmdtok->start);
|
||||||
return;
|
return;
|
||||||
@@ -380,13 +382,15 @@ static void command_fail_v(struct command *cmd,
|
|||||||
assert(cmd_in_jcon(jcon, cmd));
|
assert(cmd_in_jcon(jcon, cmd));
|
||||||
connection_complete_error(jcon, cmd, cmd->id, error, code, data);
|
connection_complete_error(jcon, cmd, cmd->id, error, code, data);
|
||||||
}
|
}
|
||||||
void command_fail(struct command *cmd, const char *fmt, ...)
|
|
||||||
|
void command_fail(struct command *cmd, int code, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
command_fail_v(cmd, -1, NULL, fmt, ap);
|
command_fail_v(cmd, code, NULL, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_fail_detailed(struct command *cmd,
|
void command_fail_detailed(struct command *cmd,
|
||||||
int code, const struct json_result *data,
|
int code, const struct json_result *data,
|
||||||
const char *fmt, ...)
|
const char *fmt, ...)
|
||||||
@@ -451,34 +455,30 @@ static void parse_request(struct json_connection *jcon, const jsmntok_t tok[])
|
|||||||
tal_add_destructor(c, destroy_cmd);
|
tal_add_destructor(c, destroy_cmd);
|
||||||
|
|
||||||
if (!method || !params) {
|
if (!method || !params) {
|
||||||
command_fail_detailed(c,
|
command_fail(c, JSONRPC2_INVALID_REQUEST,
|
||||||
JSONRPC2_INVALID_REQUEST, NULL,
|
method ? "No params" : "No method");
|
||||||
method ? "No params" : "No method");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method->type != JSMN_STRING) {
|
if (method->type != JSMN_STRING) {
|
||||||
command_fail_detailed(c,
|
command_fail(c, JSONRPC2_INVALID_REQUEST,
|
||||||
JSONRPC2_INVALID_REQUEST, NULL,
|
"Expected string for method");
|
||||||
"Expected string for method");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = find_cmd(jcon->buffer, method);
|
cmd = find_cmd(jcon->buffer, method);
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
command_fail_detailed(c,
|
command_fail(c, JSONRPC2_METHOD_NOT_FOUND,
|
||||||
JSONRPC2_METHOD_NOT_FOUND, NULL,
|
"Unknown command '%.*s'",
|
||||||
"Unknown command '%.*s'",
|
method->end - method->start,
|
||||||
method->end - method->start,
|
jcon->buffer + method->start);
|
||||||
jcon->buffer + method->start);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (cmd->deprecated && !deprecated_apis) {
|
if (cmd->deprecated && !deprecated_apis) {
|
||||||
command_fail_detailed(c,
|
command_fail(c, JSONRPC2_METHOD_NOT_FOUND,
|
||||||
JSONRPC2_METHOD_NOT_FOUND, NULL,
|
"Command '%.*s' is deprecated",
|
||||||
"Command '%.*s' is deprecated",
|
method->end - method->start,
|
||||||
method->end - method->start,
|
jcon->buffer + method->start);
|
||||||
jcon->buffer + method->start);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,8 +507,8 @@ bool json_get_params(struct command *cmd,
|
|||||||
p = param + 1;
|
p = param + 1;
|
||||||
end = json_next(param);
|
end = json_next(param);
|
||||||
} else if (param->type != JSMN_OBJECT) {
|
} else if (param->type != JSMN_OBJECT) {
|
||||||
command_fail_detailed(cmd, JSONRPC2_INVALID_PARAMS, NULL,
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Expected array or object for params");
|
"Expected array or object for params");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,9 +541,9 @@ bool json_get_params(struct command *cmd,
|
|||||||
}
|
}
|
||||||
if (compulsory && !*tokptr) {
|
if (compulsory && !*tokptr) {
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
command_fail_detailed(cmd, JSONRPC2_INVALID_PARAMS, NULL,
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Missing '%s' parameter",
|
"Missing '%s' parameter",
|
||||||
names[num_names]);
|
names[num_names]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
num_names++;
|
num_names++;
|
||||||
@@ -556,10 +556,10 @@ bool json_get_params(struct command *cmd,
|
|||||||
if (param->type == JSMN_ARRAY) {
|
if (param->type == JSMN_ARRAY) {
|
||||||
if (param->size > num_names) {
|
if (param->size > num_names) {
|
||||||
tal_free(names);
|
tal_free(names);
|
||||||
command_fail_detailed(cmd, JSONRPC2_INVALID_PARAMS, NULL,
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Too many parameters:"
|
"Too many parameters:"
|
||||||
" got %u, expected %zu",
|
" got %u, expected %zu",
|
||||||
param->size, num_names);
|
param->size, num_names);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -576,12 +576,10 @@ bool json_get_params(struct command *cmd,
|
|||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
tal_free(names);
|
tal_free(names);
|
||||||
command_fail_detailed(cmd,
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
JSONRPC2_INVALID_PARAMS,
|
"Unknown parameter '%.*s'",
|
||||||
NULL,
|
t->end - t->start,
|
||||||
"Unknown parameter '%.*s'",
|
buffer + t->start);
|
||||||
t->end - t->start,
|
|
||||||
buffer + t->start);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -865,13 +863,15 @@ json_tok_address_scriptpubkey(const tal_t *cxt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool json_tok_wtx(struct wallet_tx * tx, const char * buffer,
|
bool json_tok_wtx(struct wallet_tx * tx, const char * buffer,
|
||||||
const jsmntok_t *sattok)
|
const jsmntok_t *sattok)
|
||||||
{
|
{
|
||||||
if (json_tok_streq(buffer, sattok, "all")) {
|
if (json_tok_streq(buffer, sattok, "all")) {
|
||||||
tx->all_funds = true;
|
tx->all_funds = true;
|
||||||
} else if (!json_tok_u64(buffer, sattok, &tx->amount)) {
|
} else if (!json_tok_u64(buffer, sattok, &tx->amount)) {
|
||||||
command_fail(tx->cmd, "Invalid satoshis");
|
command_fail(tx->cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
return false;
|
"Invalid satoshis");
|
||||||
}
|
return false;
|
||||||
return true;
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,8 @@ bool json_get_params(struct command *cmd,
|
|||||||
|
|
||||||
struct json_result *null_response(const tal_t *ctx);
|
struct json_result *null_response(const tal_t *ctx);
|
||||||
void command_success(struct command *cmd, struct json_result *response);
|
void command_success(struct command *cmd, struct json_result *response);
|
||||||
void PRINTF_FMT(2, 3) command_fail(struct command *cmd, const char *fmt, ...);
|
void PRINTF_FMT(3, 4) command_fail(struct command *cmd, int code,
|
||||||
|
const char *fmt, ...);
|
||||||
void PRINTF_FMT(4, 5) command_fail_detailed(struct command *cmd,
|
void PRINTF_FMT(4, 5) command_fail_detailed(struct command *cmd,
|
||||||
int code,
|
int code,
|
||||||
const struct json_result *data,
|
const struct json_result *data,
|
||||||
|
|||||||
@@ -10,6 +10,12 @@
|
|||||||
#define JSONRPC2_METHOD_NOT_FOUND -32601
|
#define JSONRPC2_METHOD_NOT_FOUND -32601
|
||||||
#define JSONRPC2_INVALID_PARAMS -32602
|
#define JSONRPC2_INVALID_PARAMS -32602
|
||||||
|
|
||||||
|
/* Uncategorized error.
|
||||||
|
* FIXME: This should be replaced in all places
|
||||||
|
* with a specific error code, and then removed.
|
||||||
|
*/
|
||||||
|
#define LIGHTNINGD -1
|
||||||
|
|
||||||
/* Errors from `pay`, `sendpay`, or `waitsendpay` commands */
|
/* Errors from `pay`, `sendpay`, or `waitsendpay` commands */
|
||||||
#define PAY_IN_PROGRESS 200
|
#define PAY_IN_PROGRESS 200
|
||||||
#define PAY_RHASH_ALREADY_USED 201
|
#define PAY_RHASH_ALREADY_USED 201
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <lightningd/jsonrpc.h>
|
#include <lightningd/jsonrpc.h>
|
||||||
|
#include <lightningd/jsonrpc_errors.h>
|
||||||
#include <lightningd/lightningd.h>
|
#include <lightningd/lightningd.h>
|
||||||
#include <lightningd/options.h>
|
#include <lightningd/options.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@@ -664,7 +665,7 @@ static void json_getlog(struct command *cmd,
|
|||||||
if (!level)
|
if (!level)
|
||||||
minlevel = LOG_INFORM;
|
minlevel = LOG_INFORM;
|
||||||
else if (!json_tok_loglevel(buffer, level, &minlevel)) {
|
else if (!json_tok_loglevel(buffer, level, &minlevel)) {
|
||||||
command_fail(cmd, "Invalid level param");
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Invalid level param");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <common/memleak.h>
|
#include <common/memleak.h>
|
||||||
#include <lightningd/chaintopology.h>
|
#include <lightningd/chaintopology.h>
|
||||||
#include <lightningd/jsonrpc.h>
|
#include <lightningd/jsonrpc.h>
|
||||||
|
#include <lightningd/jsonrpc_errors.h>
|
||||||
#include <lightningd/lightningd.h>
|
#include <lightningd/lightningd.h>
|
||||||
#include <lightningd/log.h>
|
#include <lightningd/log.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -148,7 +149,7 @@ static void json_memleak(struct command *cmd,
|
|||||||
struct json_result *response = new_json_result(cmd);
|
struct json_result *response = new_json_result(cmd);
|
||||||
|
|
||||||
if (!getenv("LIGHTNINGD_DEV_MEMLEAK")) {
|
if (!getenv("LIGHTNINGD_DEV_MEMLEAK")) {
|
||||||
command_fail(cmd,
|
command_fail(cmd, LIGHTNINGD,
|
||||||
"Leak detection needs $LIGHTNINGD_DEV_MEMLEAK");
|
"Leak detection needs $LIGHTNINGD_DEV_MEMLEAK");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <lightningd/hsm_control.h>
|
#include <lightningd/hsm_control.h>
|
||||||
#include <lightningd/json.h>
|
#include <lightningd/json.h>
|
||||||
#include <lightningd/jsonrpc.h>
|
#include <lightningd/jsonrpc.h>
|
||||||
|
#include <lightningd/jsonrpc_errors.h>
|
||||||
#include <lightningd/lightningd.h>
|
#include <lightningd/lightningd.h>
|
||||||
#include <lightningd/log.h>
|
#include <lightningd/log.h>
|
||||||
#include <lightningd/opening_control.h>
|
#include <lightningd/opening_control.h>
|
||||||
@@ -113,7 +114,7 @@ static void uncommitted_channel_to_gossipd(struct lightningd *ld,
|
|||||||
|
|
||||||
log_unusual(uc->log, "Opening channel: %s", errstr);
|
log_unusual(uc->log, "Opening channel: %s", errstr);
|
||||||
if (uc->fc)
|
if (uc->fc)
|
||||||
command_fail(uc->fc->cmd, "%s", errstr);
|
command_fail(uc->fc->cmd, LIGHTNINGD, "%s", errstr);
|
||||||
|
|
||||||
/* Hand back to gossipd, (maybe) with an error packet to send. */
|
/* Hand back to gossipd, (maybe) with an error packet to send. */
|
||||||
msg = towire_gossipctl_hand_back_peer(errstr, &uc->peer->id, cs,
|
msg = towire_gossipctl_hand_back_peer(errstr, &uc->peer->id, cs,
|
||||||
@@ -133,7 +134,7 @@ void kill_uncommitted_channel(struct uncommitted_channel *uc,
|
|||||||
uc->openingd = NULL;
|
uc->openingd = NULL;
|
||||||
|
|
||||||
if (uc->fc)
|
if (uc->fc)
|
||||||
command_fail(uc->fc->cmd, "%s", why);
|
command_fail(uc->fc->cmd, LIGHTNINGD, "%s", why);
|
||||||
tal_free(uc);
|
tal_free(uc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,7 +306,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
|
|||||||
log_broken(fc->uc->log,
|
log_broken(fc->uc->log,
|
||||||
"bad OPENING_FUNDER_REPLY %s",
|
"bad OPENING_FUNDER_REPLY %s",
|
||||||
tal_hex(resp, resp));
|
tal_hex(resp, resp));
|
||||||
command_fail(fc->cmd, "bad OPENING_FUNDER_REPLY %s",
|
command_fail(fc->cmd, LIGHTNINGD, "bad OPENING_FUNDER_REPLY %s",
|
||||||
tal_hex(fc->cmd, resp));
|
tal_hex(fc->cmd, resp));
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
@@ -354,7 +355,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
|
|||||||
&local_fundingkey),
|
&local_fundingkey),
|
||||||
type_to_string(fc, struct pubkey,
|
type_to_string(fc, struct pubkey,
|
||||||
&channel_info.remote_fundingkey));
|
&channel_info.remote_fundingkey));
|
||||||
command_fail(fc->cmd,
|
command_fail(fc->cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Funding txid mismatch:"
|
"Funding txid mismatch:"
|
||||||
" satoshi %"PRIu64" change %"PRIu64
|
" satoshi %"PRIu64" change %"PRIu64
|
||||||
" changeidx %u"
|
" changeidx %u"
|
||||||
@@ -380,7 +381,8 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
|
|||||||
&channel_info,
|
&channel_info,
|
||||||
feerate);
|
feerate);
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
command_fail(fc->cmd, "Key generation failure");
|
command_fail(fc->cmd, LIGHTNINGD,
|
||||||
|
"Key generation failure");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,7 +544,7 @@ static void opening_channel_errmsg(struct uncommitted_channel *uc,
|
|||||||
log_info(uc->log, "%s", desc);
|
log_info(uc->log, "%s", desc);
|
||||||
subd_send_msg(uc->peer->ld->gossip, msg);
|
subd_send_msg(uc->peer->ld->gossip, msg);
|
||||||
if (uc->fc)
|
if (uc->fc)
|
||||||
command_fail(uc->fc->cmd, "%s", desc);
|
command_fail(uc->fc->cmd, LIGHTNINGD, "%s", desc);
|
||||||
} else {
|
} else {
|
||||||
/* An error occurred (presumably negotiation fail). */
|
/* An error occurred (presumably negotiation fail). */
|
||||||
const char *errsrc = err_for_them ? "sent" : "received";
|
const char *errsrc = err_for_them ? "sent" : "received";
|
||||||
@@ -761,7 +763,7 @@ static void peer_offer_channel(struct lightningd *ld,
|
|||||||
/* We asked to release this peer, but another raced in? Corner case,
|
/* We asked to release this peer, but another raced in? Corner case,
|
||||||
* close this is easiest. */
|
* close this is easiest. */
|
||||||
if (!fc->uc) {
|
if (!fc->uc) {
|
||||||
command_fail(fc->cmd, "Peer already active");
|
command_fail(fc->cmd, LIGHTNINGD, "Peer already active");
|
||||||
close(peer_fd);
|
close(peer_fd);
|
||||||
close(gossip_fd);
|
close(gossip_fd);
|
||||||
return;
|
return;
|
||||||
@@ -840,12 +842,12 @@ static void gossip_peer_released(struct subd *gossip,
|
|||||||
tal_hex(gossip, resp));
|
tal_hex(gossip, resp));
|
||||||
}
|
}
|
||||||
if (uc)
|
if (uc)
|
||||||
command_fail(fc->cmd, "Peer already OPENING");
|
command_fail(fc->cmd, LIGHTNINGD, "Peer already OPENING");
|
||||||
else if (c)
|
else if (c)
|
||||||
command_fail(fc->cmd, "Peer already %s",
|
command_fail(fc->cmd, LIGHTNINGD, "Peer already %s",
|
||||||
channel_state_name(c));
|
channel_state_name(c));
|
||||||
else
|
else
|
||||||
command_fail(fc->cmd, "Peer not connected");
|
command_fail(fc->cmd, LIGHTNINGD, "Peer not connected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
assert(tal_count(fds) == 2);
|
assert(tal_count(fds) == 2);
|
||||||
@@ -904,7 +906,7 @@ static void json_fund_channel(struct command *cmd,
|
|||||||
if (!pubkey_from_hexstr(buffer + desttok->start,
|
if (!pubkey_from_hexstr(buffer + desttok->start,
|
||||||
desttok->end - desttok->start,
|
desttok->end - desttok->start,
|
||||||
&fc->peerid)) {
|
&fc->peerid)) {
|
||||||
command_fail(cmd, "Could not parse id");
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Could not parse id");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -917,7 +919,8 @@ static void json_fund_channel(struct command *cmd,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (fc->wtx.amount > MAX_FUNDING_SATOSHI) {
|
if (fc->wtx.amount > MAX_FUNDING_SATOSHI) {
|
||||||
command_fail(cmd, "Funding satoshi must be <= %d",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Funding satoshi must be <= %d",
|
||||||
MAX_FUNDING_SATOSHI);
|
MAX_FUNDING_SATOSHI);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <lightningd/bitcoind.h>
|
#include <lightningd/bitcoind.h>
|
||||||
#include <lightningd/chaintopology.h>
|
#include <lightningd/chaintopology.h>
|
||||||
#include <lightningd/jsonrpc.h>
|
#include <lightningd/jsonrpc.h>
|
||||||
|
#include <lightningd/jsonrpc_errors.h>
|
||||||
#include <lightningd/lightningd.h>
|
#include <lightningd/lightningd.h>
|
||||||
#include <lightningd/log.h>
|
#include <lightningd/log.h>
|
||||||
#include <lightningd/options.h>
|
#include <lightningd/options.h>
|
||||||
@@ -1031,7 +1032,8 @@ static void json_listconfigs(struct command *cmd,
|
|||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
|
|
||||||
if (configtok && !found) {
|
if (configtok && !found) {
|
||||||
command_fail(cmd, "Unknown config option '%.*s'",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Unknown config option '%.*s'",
|
||||||
configtok->end - configtok->start,
|
configtok->end - configtok->start,
|
||||||
buffer + configtok->start);
|
buffer + configtok->start);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -932,14 +932,16 @@ static void json_sendpay(struct command *cmd,
|
|||||||
if (!hex_decode(buffer + rhashtok->start,
|
if (!hex_decode(buffer + rhashtok->start,
|
||||||
rhashtok->end - rhashtok->start,
|
rhashtok->end - rhashtok->start,
|
||||||
&rhash, sizeof(rhash))) {
|
&rhash, sizeof(rhash))) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid sha256 hash",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid sha256 hash",
|
||||||
rhashtok->end - rhashtok->start,
|
rhashtok->end - rhashtok->start,
|
||||||
buffer + rhashtok->start);
|
buffer + rhashtok->start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (routetok->type != JSMN_ARRAY) {
|
if (routetok->type != JSMN_ARRAY) {
|
||||||
command_fail(cmd, "'%.*s' is not an array",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not an array",
|
||||||
routetok->end - routetok->start,
|
routetok->end - routetok->start,
|
||||||
buffer + routetok->start);
|
buffer + routetok->start);
|
||||||
return;
|
return;
|
||||||
@@ -953,7 +955,8 @@ static void json_sendpay(struct command *cmd,
|
|||||||
const jsmntok_t *amttok, *idtok, *delaytok, *chantok;
|
const jsmntok_t *amttok, *idtok, *delaytok, *chantok;
|
||||||
|
|
||||||
if (t->type != JSMN_OBJECT) {
|
if (t->type != JSMN_OBJECT) {
|
||||||
command_fail(cmd, "Route %zu '%.*s' is not an object",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Route %zu '%.*s' is not an object",
|
||||||
n_hops,
|
n_hops,
|
||||||
t->end - t->start,
|
t->end - t->start,
|
||||||
buffer + t->start);
|
buffer + t->start);
|
||||||
@@ -964,7 +967,8 @@ static void json_sendpay(struct command *cmd,
|
|||||||
delaytok = json_get_member(buffer, t, "delay");
|
delaytok = json_get_member(buffer, t, "delay");
|
||||||
chantok = json_get_member(buffer, t, "channel");
|
chantok = json_get_member(buffer, t, "channel");
|
||||||
if (!amttok || !idtok || !delaytok || !chantok) {
|
if (!amttok || !idtok || !delaytok || !chantok) {
|
||||||
command_fail(cmd, "Route %zu needs msatoshi/id/channel/delay",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Route %zu needs msatoshi/id/channel/delay",
|
||||||
n_hops);
|
n_hops);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -973,35 +977,40 @@ static void json_sendpay(struct command *cmd,
|
|||||||
|
|
||||||
/* What that hop will forward */
|
/* What that hop will forward */
|
||||||
if (!json_tok_u64(buffer, amttok, &route[n_hops].amount)) {
|
if (!json_tok_u64(buffer, amttok, &route[n_hops].amount)) {
|
||||||
command_fail(cmd, "Route %zu invalid msatoshi",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Route %zu invalid msatoshi",
|
||||||
n_hops);
|
n_hops);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!json_tok_short_channel_id(buffer, chantok,
|
if (!json_tok_short_channel_id(buffer, chantok,
|
||||||
&route[n_hops].channel_id)) {
|
&route[n_hops].channel_id)) {
|
||||||
command_fail(cmd, "Route %zu invalid channel_id", n_hops);
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Route %zu invalid channel_id", n_hops);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!json_tok_pubkey(buffer, idtok, &route[n_hops].nodeid)) {
|
if (!json_tok_pubkey(buffer, idtok, &route[n_hops].nodeid)) {
|
||||||
command_fail(cmd, "Route %zu invalid id", n_hops);
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Route %zu invalid id", n_hops);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!json_tok_number(buffer, delaytok, &route[n_hops].delay)) {
|
if (!json_tok_number(buffer, delaytok, &route[n_hops].delay)) {
|
||||||
command_fail(cmd, "Route %zu invalid delay", n_hops);
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Route %zu invalid delay", n_hops);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
n_hops++;
|
n_hops++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n_hops == 0) {
|
if (n_hops == 0) {
|
||||||
command_fail(cmd, "Empty route");
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Empty route");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msatoshitok) {
|
if (msatoshitok) {
|
||||||
if (!json_tok_u64(buffer, msatoshitok, &msatoshi)) {
|
if (!json_tok_u64(buffer, msatoshitok, &msatoshi)) {
|
||||||
command_fail(cmd, "'%.*s' is not a number",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a number",
|
||||||
msatoshitok->end - msatoshitok->start,
|
msatoshitok->end - msatoshitok->start,
|
||||||
buffer + msatoshitok->start);
|
buffer + msatoshitok->start);
|
||||||
return;
|
return;
|
||||||
@@ -1014,7 +1023,8 @@ static void json_sendpay(struct command *cmd,
|
|||||||
* fail. */
|
* fail. */
|
||||||
if (!(msatoshi <= route[n_hops-1].amount &&
|
if (!(msatoshi <= route[n_hops-1].amount &&
|
||||||
route[n_hops-1].amount <= 2 * msatoshi)) {
|
route[n_hops-1].amount <= 2 * msatoshi)) {
|
||||||
command_fail(cmd, "msatoshi %"PRIu64" out of range",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"msatoshi %"PRIu64" out of range",
|
||||||
msatoshi);
|
msatoshi);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1035,8 +1045,7 @@ AUTODATA(json_command, &sendpay_command);
|
|||||||
|
|
||||||
static void waitsendpay_timeout(struct command *cmd)
|
static void waitsendpay_timeout(struct command *cmd)
|
||||||
{
|
{
|
||||||
command_fail_detailed(cmd, PAY_IN_PROGRESS, NULL,
|
command_fail(cmd, PAY_IN_PROGRESS, "Timed out while waiting");
|
||||||
"Timed out while waiting");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_waitsendpay(struct command *cmd, const char *buffer,
|
static void json_waitsendpay(struct command *cmd, const char *buffer,
|
||||||
@@ -1056,14 +1065,16 @@ static void json_waitsendpay(struct command *cmd, const char *buffer,
|
|||||||
if (!hex_decode(buffer + rhashtok->start,
|
if (!hex_decode(buffer + rhashtok->start,
|
||||||
rhashtok->end - rhashtok->start,
|
rhashtok->end - rhashtok->start,
|
||||||
&rhash, sizeof(rhash))) {
|
&rhash, sizeof(rhash))) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid sha256 hash",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid sha256 hash",
|
||||||
rhashtok->end - rhashtok->start,
|
rhashtok->end - rhashtok->start,
|
||||||
buffer + rhashtok->start);
|
buffer + rhashtok->start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeouttok && !json_tok_number(buffer, timeouttok, &timeout)) {
|
if (timeouttok && !json_tok_number(buffer, timeouttok, &timeout)) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid number",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid number",
|
||||||
timeouttok->end - timeouttok->start,
|
timeouttok->end - timeouttok->start,
|
||||||
buffer + timeouttok->start);
|
buffer + timeouttok->start);
|
||||||
return;
|
return;
|
||||||
@@ -1107,7 +1118,8 @@ static void json_listpayments(struct command *cmd, const char *buffer,
|
|||||||
char *b11str, *fail;
|
char *b11str, *fail;
|
||||||
|
|
||||||
if (rhashtok) {
|
if (rhashtok) {
|
||||||
command_fail(cmd, "Can only specify one of"
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Can only specify one of"
|
||||||
" {bolt11} or {payment_hash}");
|
" {bolt11} or {payment_hash}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1117,7 +1129,8 @@ static void json_listpayments(struct command *cmd, const char *buffer,
|
|||||||
|
|
||||||
b11 = bolt11_decode(cmd, b11str, NULL, &fail);
|
b11 = bolt11_decode(cmd, b11str, NULL, &fail);
|
||||||
if (!b11) {
|
if (!b11) {
|
||||||
command_fail(cmd, "Invalid bolt11: %s", fail);
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Invalid bolt11: %s", fail);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rhash = &b11->payment_hash;
|
rhash = &b11->payment_hash;
|
||||||
@@ -1126,7 +1139,8 @@ static void json_listpayments(struct command *cmd, const char *buffer,
|
|||||||
if (!hex_decode(buffer + rhashtok->start,
|
if (!hex_decode(buffer + rhashtok->start,
|
||||||
rhashtok->end - rhashtok->start,
|
rhashtok->end - rhashtok->start,
|
||||||
rhash, sizeof(*rhash))) {
|
rhash, sizeof(*rhash))) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid sha256 hash",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid sha256 hash",
|
||||||
rhashtok->end - rhashtok->start,
|
rhashtok->end - rhashtok->start,
|
||||||
buffer + rhashtok->start);
|
buffer + rhashtok->start);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -626,7 +626,8 @@ static void json_pay(struct command *cmd,
|
|||||||
|
|
||||||
b11 = bolt11_decode(pay, b11str, desc, &fail);
|
b11 = bolt11_decode(pay, b11str, desc, &fail);
|
||||||
if (!b11) {
|
if (!b11) {
|
||||||
command_fail(cmd, "Invalid bolt11: %s", fail);
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Invalid bolt11: %s", fail);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,7 +639,8 @@ static void json_pay(struct command *cmd,
|
|||||||
pay->min_final_cltv_expiry = b11->min_final_cltv_expiry;
|
pay->min_final_cltv_expiry = b11->min_final_cltv_expiry;
|
||||||
|
|
||||||
if (retryfortok && !json_tok_number(buffer, retryfortok, &retryfor)) {
|
if (retryfortok && !json_tok_number(buffer, retryfortok, &retryfor)) {
|
||||||
command_fail(cmd, "'%.*s' is not an integer",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not an integer",
|
||||||
retryfortok->end - retryfortok->start,
|
retryfortok->end - retryfortok->start,
|
||||||
buffer + retryfortok->start);
|
buffer + retryfortok->start);
|
||||||
return;
|
return;
|
||||||
@@ -647,16 +649,18 @@ static void json_pay(struct command *cmd,
|
|||||||
if (b11->msatoshi) {
|
if (b11->msatoshi) {
|
||||||
msatoshi = *b11->msatoshi;
|
msatoshi = *b11->msatoshi;
|
||||||
if (msatoshitok) {
|
if (msatoshitok) {
|
||||||
command_fail(cmd, "msatoshi parameter unnecessary");
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"msatoshi parameter unnecessary");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!msatoshitok) {
|
if (!msatoshitok) {
|
||||||
command_fail(cmd, "msatoshi parameter required");
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"msatoshi parameter required");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!json_tok_u64(buffer, msatoshitok, &msatoshi)) {
|
if (!json_tok_u64(buffer, msatoshitok, &msatoshi)) {
|
||||||
command_fail(cmd,
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"msatoshi '%.*s' is not a valid number",
|
"msatoshi '%.*s' is not a valid number",
|
||||||
msatoshitok->end-msatoshitok->start,
|
msatoshitok->end-msatoshitok->start,
|
||||||
buffer + msatoshitok->start);
|
buffer + msatoshitok->start);
|
||||||
@@ -667,7 +671,8 @@ static void json_pay(struct command *cmd,
|
|||||||
|
|
||||||
if (riskfactortok
|
if (riskfactortok
|
||||||
&& !json_tok_double(buffer, riskfactortok, &riskfactor)) {
|
&& !json_tok_double(buffer, riskfactortok, &riskfactor)) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid double",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid double",
|
||||||
riskfactortok->end - riskfactortok->start,
|
riskfactortok->end - riskfactortok->start,
|
||||||
buffer + riskfactortok->start);
|
buffer + riskfactortok->start);
|
||||||
return;
|
return;
|
||||||
@@ -676,19 +681,22 @@ static void json_pay(struct command *cmd,
|
|||||||
|
|
||||||
if (maxfeetok
|
if (maxfeetok
|
||||||
&& !json_tok_double(buffer, maxfeetok, &maxfeepercent)) {
|
&& !json_tok_double(buffer, maxfeetok, &maxfeepercent)) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid double",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid double",
|
||||||
maxfeetok->end - maxfeetok->start,
|
maxfeetok->end - maxfeetok->start,
|
||||||
buffer + maxfeetok->start);
|
buffer + maxfeetok->start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Ensure it is in range 0.0 <= maxfeepercent <= 100.0 */
|
/* Ensure it is in range 0.0 <= maxfeepercent <= 100.0 */
|
||||||
if (!(0.0 <= maxfeepercent)) {
|
if (!(0.0 <= maxfeepercent)) {
|
||||||
command_fail(cmd, "%f maxfeepercent must be non-negative",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"%f maxfeepercent must be non-negative",
|
||||||
maxfeepercent);
|
maxfeepercent);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(maxfeepercent <= 100.0)) {
|
if (!(maxfeepercent <= 100.0)) {
|
||||||
command_fail(cmd, "%f maxfeepercent must be <= 100.0",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"%f maxfeepercent must be <= 100.0",
|
||||||
maxfeepercent);
|
maxfeepercent);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -696,13 +704,14 @@ static void json_pay(struct command *cmd,
|
|||||||
|
|
||||||
if (maxdelaytok
|
if (maxdelaytok
|
||||||
&& !json_tok_number(buffer, maxdelaytok, &maxdelay)) {
|
&& !json_tok_number(buffer, maxdelaytok, &maxdelay)) {
|
||||||
command_fail(cmd, "'%.*s' is not a valid double",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'%.*s' is not a valid integer",
|
||||||
maxdelaytok->end - maxdelaytok->start,
|
maxdelaytok->end - maxdelaytok->start,
|
||||||
buffer + maxdelaytok->start);
|
buffer + maxdelaytok->start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (maxdelay < pay->min_final_cltv_expiry) {
|
if (maxdelay < pay->min_final_cltv_expiry) {
|
||||||
command_fail(cmd,
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"maxdelay (%u) must be greater than "
|
"maxdelay (%u) must be greater than "
|
||||||
"min_final_cltv_expiry (%"PRIu32") of "
|
"min_final_cltv_expiry (%"PRIu32") of "
|
||||||
"invoice",
|
"invoice",
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <lightningd/hsm_control.h>
|
#include <lightningd/hsm_control.h>
|
||||||
#include <lightningd/json.h>
|
#include <lightningd/json.h>
|
||||||
#include <lightningd/jsonrpc.h>
|
#include <lightningd/jsonrpc.h>
|
||||||
|
#include <lightningd/jsonrpc_errors.h>
|
||||||
#include <lightningd/log.h>
|
#include <lightningd/log.h>
|
||||||
#include <lightningd/onchain_control.h>
|
#include <lightningd/onchain_control.h>
|
||||||
#include <lightningd/opening_control.h>
|
#include <lightningd/opening_control.h>
|
||||||
@@ -275,7 +276,8 @@ destroy_close_command_on_channel_destroy(struct channel *_ UNUSED,
|
|||||||
* Clear the cc->channel first so that we will not try to
|
* Clear the cc->channel first so that we will not try to
|
||||||
* remove a destructor. */
|
* remove a destructor. */
|
||||||
cc->channel = NULL;
|
cc->channel = NULL;
|
||||||
command_fail(cc->cmd, "Channel forgotten before proper close.");
|
command_fail(cc->cmd, LIGHTNINGD,
|
||||||
|
"Channel forgotten before proper close.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Destroy the close command structure. */
|
/* Destroy the close command structure. */
|
||||||
@@ -307,7 +309,7 @@ close_command_timeout(struct close_command *cc)
|
|||||||
else
|
else
|
||||||
/* Fail the command directly, which will resolve the
|
/* Fail the command directly, which will resolve the
|
||||||
* command and destroy the close_command. */
|
* command and destroy the close_command. */
|
||||||
command_fail(cc->cmd,
|
command_fail(cc->cmd, LIGHTNINGD,
|
||||||
"Channel close negotiation not finished "
|
"Channel close negotiation not finished "
|
||||||
"before timeout");
|
"before timeout");
|
||||||
}
|
}
|
||||||
@@ -727,7 +729,8 @@ static void gossipd_getpeers_complete(struct subd *gossip, const u8 *msg,
|
|||||||
struct peer *p;
|
struct peer *p;
|
||||||
|
|
||||||
if (!fromwire_gossip_getpeers_reply(msg, msg, &ids, &addrs, &nodes)) {
|
if (!fromwire_gossip_getpeers_reply(msg, msg, &ids, &addrs, &nodes)) {
|
||||||
command_fail(gpa->cmd, "Bad response from gossipd");
|
command_fail(gpa->cmd, LIGHTNINGD,
|
||||||
|
"Bad response from gossipd");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -934,7 +937,8 @@ static void json_listpeers(struct command *cmd,
|
|||||||
if (idtok) {
|
if (idtok) {
|
||||||
gpa->specific_id = tal_arr(cmd, struct pubkey, 1);
|
gpa->specific_id = tal_arr(cmd, struct pubkey, 1);
|
||||||
if (!json_tok_pubkey(buffer, idtok, gpa->specific_id)) {
|
if (!json_tok_pubkey(buffer, idtok, gpa->specific_id)) {
|
||||||
command_fail(cmd, "id %.*s not valid",
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"id %.*s not valid",
|
||||||
idtok->end - idtok->start,
|
idtok->end - idtok->start,
|
||||||
buffer + idtok->start);
|
buffer + idtok->start);
|
||||||
return;
|
return;
|
||||||
@@ -943,7 +947,8 @@ static void json_listpeers(struct command *cmd,
|
|||||||
if (leveltok) {
|
if (leveltok) {
|
||||||
gpa->ll = tal(gpa, enum log_level);
|
gpa->ll = tal(gpa, enum log_level);
|
||||||
if (!json_tok_loglevel(buffer, leveltok, gpa->ll)) {
|
if (!json_tok_loglevel(buffer, leveltok, gpa->ll)) {
|
||||||
command_fail(cmd, "Invalid level param");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Invalid level param");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@@ -985,7 +990,7 @@ command_find_channel(struct command *cmd,
|
|||||||
if (structeq(&channel_cid, &cid))
|
if (structeq(&channel_cid, &cid))
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
command_fail(cmd,
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Channel ID not found: '%.*s'",
|
"Channel ID not found: '%.*s'",
|
||||||
tok->end - tok->start,
|
tok->end - tok->start,
|
||||||
buffer + tok->start);
|
buffer + tok->start);
|
||||||
@@ -998,13 +1003,13 @@ command_find_channel(struct command *cmd,
|
|||||||
if (channel->scid && channel->scid->u64 == scid.u64)
|
if (channel->scid && channel->scid->u64 == scid.u64)
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
command_fail(cmd,
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Short channel ID not found: '%.*s'",
|
"Short channel ID not found: '%.*s'",
|
||||||
tok->end - tok->start,
|
tok->end - tok->start,
|
||||||
buffer + tok->start);
|
buffer + tok->start);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
command_fail(cmd,
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Given id is not a channel ID or "
|
"Given id is not a channel ID or "
|
||||||
"short channel ID: '%.*s'",
|
"short channel ID: '%.*s'",
|
||||||
tok->end - tok->start,
|
tok->end - tok->start,
|
||||||
@@ -1033,13 +1038,15 @@ static void json_close(struct command *cmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (forcetok && !json_tok_bool(buffer, forcetok, &force)) {
|
if (forcetok && !json_tok_bool(buffer, forcetok, &force)) {
|
||||||
command_fail(cmd, "Force '%.*s' must be true or false",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Force '%.*s' must be true or false",
|
||||||
forcetok->end - forcetok->start,
|
forcetok->end - forcetok->start,
|
||||||
buffer + forcetok->start);
|
buffer + forcetok->start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (timeouttok && !json_tok_number(buffer, timeouttok, &timeout)) {
|
if (timeouttok && !json_tok_number(buffer, timeouttok, &timeout)) {
|
||||||
command_fail(cmd, "Timeout '%.*s' is not a number",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Timeout '%.*s' is not a number",
|
||||||
timeouttok->end - timeouttok->start,
|
timeouttok->end - timeouttok->start,
|
||||||
buffer + timeouttok->start);
|
buffer + timeouttok->start);
|
||||||
return;
|
return;
|
||||||
@@ -1063,7 +1070,8 @@ static void json_close(struct command *cmd,
|
|||||||
command_success(cmd, null_response(cmd));
|
command_success(cmd, null_response(cmd));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
command_fail(cmd, "Peer has no active channel");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Peer has no active channel");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1076,7 +1084,7 @@ static void json_close(struct command *cmd,
|
|||||||
channel->state != CHANNELD_AWAITING_LOCKIN &&
|
channel->state != CHANNELD_AWAITING_LOCKIN &&
|
||||||
channel->state != CHANNELD_SHUTTING_DOWN &&
|
channel->state != CHANNELD_SHUTTING_DOWN &&
|
||||||
channel->state != CLOSINGD_SIGEXCHANGE)
|
channel->state != CLOSINGD_SIGEXCHANGE)
|
||||||
command_fail(cmd, "Channel is in state %s",
|
command_fail(cmd, LIGHTNINGD, "Channel is in state %s",
|
||||||
channel_state_name(channel));
|
channel_state_name(channel));
|
||||||
|
|
||||||
/* If normal or locking in, transition to shutting down
|
/* If normal or locking in, transition to shutting down
|
||||||
@@ -1153,9 +1161,10 @@ static void gossip_peer_disconnected (struct subd *gossip,
|
|||||||
fatal("Gossip daemon gave invalid reply %s",
|
fatal("Gossip daemon gave invalid reply %s",
|
||||||
tal_hex(gossip, resp));
|
tal_hex(gossip, resp));
|
||||||
if (isconnected)
|
if (isconnected)
|
||||||
command_fail(cmd, "Peer is not in gossip mode");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Peer is not in gossip mode");
|
||||||
else
|
else
|
||||||
command_fail(cmd, "Peer not connected");
|
command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
||||||
} else {
|
} else {
|
||||||
/* Successfully disconnected */
|
/* Successfully disconnected */
|
||||||
command_success(cmd, null_response(cmd));
|
command_success(cmd, null_response(cmd));
|
||||||
@@ -1177,7 +1186,7 @@ static void json_disconnect(struct command *cmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!json_tok_pubkey(buffer, idtok, &id)) {
|
if (!json_tok_pubkey(buffer, idtok, &id)) {
|
||||||
command_fail(cmd, "id %.*s not valid",
|
command_fail(cmd, LIGHTNINGD, "id %.*s not valid",
|
||||||
idtok->end - idtok->start,
|
idtok->end - idtok->start,
|
||||||
buffer + idtok->start);
|
buffer + idtok->start);
|
||||||
return;
|
return;
|
||||||
@@ -1213,12 +1222,14 @@ static void json_sign_last_tx(struct command *cmd,
|
|||||||
|
|
||||||
peer = peer_from_json(cmd->ld, buffer, peertok);
|
peer = peer_from_json(cmd->ld, buffer, peertok);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
command_fail(cmd, "Could not find peer with that id");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Could not find peer with that id");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
channel = peer_active_channel(peer);
|
channel = peer_active_channel(peer);
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
command_fail(cmd, "Could has not active channel");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Could not find active channel");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1256,13 +1267,15 @@ static void json_dev_fail(struct command *cmd,
|
|||||||
|
|
||||||
peer = peer_from_json(cmd->ld, buffer, peertok);
|
peer = peer_from_json(cmd->ld, buffer, peertok);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
command_fail(cmd, "Could not find peer with that id");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Could not find peer with that id");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = peer_active_channel(peer);
|
channel = peer_active_channel(peer);
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
command_fail(cmd, "Could not find active channel with peer");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Could not find active channel with peer");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1301,22 +1314,26 @@ static void json_dev_reenable_commit(struct command *cmd,
|
|||||||
|
|
||||||
peer = peer_from_json(cmd->ld, buffer, peertok);
|
peer = peer_from_json(cmd->ld, buffer, peertok);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
command_fail(cmd, "Could not find peer with that id");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Could not find peer with that id");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = peer_active_channel(peer);
|
channel = peer_active_channel(peer);
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
command_fail(cmd, "Peer has no active channel");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Peer has no active channel");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!channel->owner) {
|
if (!channel->owner) {
|
||||||
command_fail(cmd, "Peer has no owner");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Peer has no owner");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!streq(channel->owner->name, "lightning_channeld")) {
|
if (!streq(channel->owner->name, "lightning_channeld")) {
|
||||||
command_fail(cmd, "Peer owned by %s", channel->owner->name);
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Peer owned by %s", channel->owner->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1347,7 +1364,7 @@ static void process_dev_forget_channel(struct bitcoind *bitcoind UNUSED,
|
|||||||
struct json_result *response;
|
struct json_result *response;
|
||||||
struct dev_forget_channel_cmd *forget = arg;
|
struct dev_forget_channel_cmd *forget = arg;
|
||||||
if (txout != NULL && !forget->force) {
|
if (txout != NULL && !forget->force) {
|
||||||
command_fail(forget->cmd,
|
command_fail(forget->cmd, LIGHTNINGD,
|
||||||
"Cowardly refusing to forget channel with an "
|
"Cowardly refusing to forget channel with an "
|
||||||
"unspent funding output, if you know what "
|
"unspent funding output, if you know what "
|
||||||
"you're doing you can override with "
|
"you're doing you can override with "
|
||||||
@@ -1387,7 +1404,8 @@ static void json_dev_forget_channel(struct command *cmd, const char *buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (scidtok && !json_tok_short_channel_id(buffer, scidtok, &scid)) {
|
if (scidtok && !json_tok_short_channel_id(buffer, scidtok, &scid)) {
|
||||||
command_fail(cmd, "Invalid short_channel_id '%.*s'",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Invalid short_channel_id '%.*s'",
|
||||||
scidtok->end - scidtok->start,
|
scidtok->end - scidtok->start,
|
||||||
buffer + scidtok->start);
|
buffer + scidtok->start);
|
||||||
return;
|
return;
|
||||||
@@ -1399,7 +1417,8 @@ static void json_dev_forget_channel(struct command *cmd, const char *buffer,
|
|||||||
|
|
||||||
peer = peer_from_json(cmd->ld, buffer, nodeidtok);
|
peer = peer_from_json(cmd->ld, buffer, nodeidtok);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
command_fail(cmd, "Could not find channel with that peer");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Could not find channel with that peer");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1412,7 +1431,7 @@ static void json_dev_forget_channel(struct command *cmd, const char *buffer,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (forget->channel) {
|
if (forget->channel) {
|
||||||
command_fail(cmd,
|
command_fail(cmd, LIGHTNINGD,
|
||||||
"Multiple channels:"
|
"Multiple channels:"
|
||||||
" please specify short_channel_id");
|
" please specify short_channel_id");
|
||||||
return;
|
return;
|
||||||
@@ -1420,16 +1439,17 @@ static void json_dev_forget_channel(struct command *cmd, const char *buffer,
|
|||||||
forget->channel = channel;
|
forget->channel = channel;
|
||||||
}
|
}
|
||||||
if (!forget->channel) {
|
if (!forget->channel) {
|
||||||
command_fail(cmd,
|
command_fail(cmd, LIGHTNINGD,
|
||||||
"No channels matching that short_channel_id");
|
"No channels matching that short_channel_id");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel_has_htlc_out(forget->channel) ||
|
if (channel_has_htlc_out(forget->channel) ||
|
||||||
channel_has_htlc_in(forget->channel)) {
|
channel_has_htlc_in(forget->channel)) {
|
||||||
command_fail(cmd, "This channel has HTLCs attached and it is "
|
command_fail(cmd, LIGHTNINGD,
|
||||||
"not safe to forget it. Please use `close` "
|
"This channel has HTLCs attached and it is "
|
||||||
"or `dev-fail` instead.");
|
"not safe to forget it. Please use `close` "
|
||||||
|
"or `dev-fail` instead.");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <lightningd/chaintopology.h>
|
#include <lightningd/chaintopology.h>
|
||||||
#include <lightningd/htlc_end.h>
|
#include <lightningd/htlc_end.h>
|
||||||
#include <lightningd/jsonrpc.h>
|
#include <lightningd/jsonrpc.h>
|
||||||
|
#include <lightningd/jsonrpc_errors.h>
|
||||||
#include <lightningd/lightningd.h>
|
#include <lightningd/lightningd.h>
|
||||||
#include <lightningd/log.h>
|
#include <lightningd/log.h>
|
||||||
#include <lightningd/pay.h>
|
#include <lightningd/pay.h>
|
||||||
@@ -1647,12 +1648,14 @@ static void json_dev_ignore_htlcs(struct command *cmd, const char *buffer,
|
|||||||
|
|
||||||
peer = peer_from_json(cmd->ld, buffer, nodeidtok);
|
peer = peer_from_json(cmd->ld, buffer, nodeidtok);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
command_fail(cmd, "Could not find channel with that peer");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Could not find channel with that peer");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!json_tok_bool(buffer, ignoretok, &peer->ignore_htlcs)) {
|
if (!json_tok_bool(buffer, ignoretok, &peer->ignore_htlcs)) {
|
||||||
command_fail(cmd, "Invalid boolean '%.*s'",
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"Invalid boolean '%.*s'",
|
||||||
ignoretok->end - ignoretok->start,
|
ignoretok->end - ignoretok->start,
|
||||||
buffer + ignoretok->start);
|
buffer + ignoretok->start);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ bool channel_tell_funding_locked(struct lightningd *ld UNNEEDED,
|
|||||||
u32 depth UNNEEDED)
|
u32 depth UNNEEDED)
|
||||||
{ fprintf(stderr, "channel_tell_funding_locked called!\n"); abort(); }
|
{ fprintf(stderr, "channel_tell_funding_locked called!\n"); abort(); }
|
||||||
/* Generated stub for command_fail */
|
/* Generated stub for command_fail */
|
||||||
void command_fail(struct command *cmd UNNEEDED, const char *fmt UNNEEDED, ...)
|
void command_fail(struct command *cmd UNNEEDED, int code UNNEEDED,
|
||||||
|
const char *fmt UNNEEDED, ...)
|
||||||
{ fprintf(stderr, "command_fail called!\n"); abort(); }
|
{ fprintf(stderr, "command_fail called!\n"); abort(); }
|
||||||
/* Generated stub for command_still_pending */
|
/* Generated stub for command_still_pending */
|
||||||
void command_still_pending(struct command *cmd UNNEEDED)
|
void command_still_pending(struct command *cmd UNNEEDED)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <lightningd/hsm_control.h>
|
#include <lightningd/hsm_control.h>
|
||||||
#include <lightningd/json.h>
|
#include <lightningd/json.h>
|
||||||
#include <lightningd/jsonrpc.h>
|
#include <lightningd/jsonrpc.h>
|
||||||
|
#include <lightningd/jsonrpc_errors.h>
|
||||||
#include <lightningd/lightningd.h>
|
#include <lightningd/lightningd.h>
|
||||||
#include <lightningd/log.h>
|
#include <lightningd/log.h>
|
||||||
#include <lightningd/peer_control.h>
|
#include <lightningd/peer_control.h>
|
||||||
@@ -70,7 +71,8 @@ static void wallet_withdrawal_broadcast(struct bitcoind *bitcoind UNUSED,
|
|||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
command_success(cmd, response);
|
command_success(cmd, response);
|
||||||
} else {
|
} else {
|
||||||
command_fail(cmd, "Error broadcasting transaction: %s", output);
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Error broadcasting transaction: %s", output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,13 +111,13 @@ static void json_withdraw(struct command *cmd,
|
|||||||
|
|
||||||
/* Check that destination address could be understood. */
|
/* Check that destination address could be understood. */
|
||||||
if (addr_parse == ADDRESS_PARSE_UNRECOGNIZED) {
|
if (addr_parse == ADDRESS_PARSE_UNRECOGNIZED) {
|
||||||
command_fail(cmd, "Could not parse destination address");
|
command_fail(cmd, LIGHTNINGD, "Could not parse destination address");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check address given is compatible with the chain we are on. */
|
/* Check address given is compatible with the chain we are on. */
|
||||||
if (addr_parse == ADDRESS_PARSE_WRONG_NETWORK) {
|
if (addr_parse == ADDRESS_PARSE_WRONG_NETWORK) {
|
||||||
command_fail(cmd,
|
command_fail(cmd, LIGHTNINGD,
|
||||||
"Destination address is not on network %s",
|
"Destination address is not on network %s",
|
||||||
get_chainparams(cmd->ld)->network_name);
|
get_chainparams(cmd->ld)->network_name);
|
||||||
return;
|
return;
|
||||||
@@ -230,7 +232,7 @@ static void json_newaddr(struct command *cmd, const char *buffer UNUSED,
|
|||||||
else if (json_tok_streq(buffer, addrtype, "bech32"))
|
else if (json_tok_streq(buffer, addrtype, "bech32"))
|
||||||
is_p2wpkh = true;
|
is_p2wpkh = true;
|
||||||
else {
|
else {
|
||||||
command_fail(cmd,
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Invalid address type "
|
"Invalid address type "
|
||||||
"(expected bech32 or p2sh-segwit)");
|
"(expected bech32 or p2sh-segwit)");
|
||||||
return;
|
return;
|
||||||
@@ -238,19 +240,19 @@ static void json_newaddr(struct command *cmd, const char *buffer UNUSED,
|
|||||||
|
|
||||||
keyidx = wallet_get_newindex(cmd->ld);
|
keyidx = wallet_get_newindex(cmd->ld);
|
||||||
if (keyidx < 0) {
|
if (keyidx < 0) {
|
||||||
command_fail(cmd, "Keys exhausted ");
|
command_fail(cmd, LIGHTNINGD, "Keys exhausted ");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bip32_key_from_parent(cmd->ld->wallet->bip32_base, keyidx,
|
if (bip32_key_from_parent(cmd->ld->wallet->bip32_base, keyidx,
|
||||||
BIP32_FLAG_KEY_PUBLIC, &ext) != WALLY_OK) {
|
BIP32_FLAG_KEY_PUBLIC, &ext) != WALLY_OK) {
|
||||||
command_fail(cmd, "Keys generation failure");
|
command_fail(cmd, LIGHTNINGD, "Keys generation failure");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey.pubkey,
|
if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey.pubkey,
|
||||||
ext.pub_key, sizeof(ext.pub_key))) {
|
ext.pub_key, sizeof(ext.pub_key))) {
|
||||||
command_fail(cmd, "Key parsing failure");
|
command_fail(cmd, LIGHTNINGD, "Key parsing failure");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +262,8 @@ static void json_newaddr(struct command *cmd, const char *buffer UNUSED,
|
|||||||
&pubkey, !is_p2wpkh,
|
&pubkey, !is_p2wpkh,
|
||||||
NULL);
|
NULL);
|
||||||
if (!out) {
|
if (!out) {
|
||||||
command_fail(cmd, "p2wpkh address encoding failure.");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"p2wpkh address encoding failure.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,13 +310,14 @@ static void json_listaddrs(struct command *cmd,
|
|||||||
|
|
||||||
if (bip32_key_from_parent(cmd->ld->wallet->bip32_base, keyidx,
|
if (bip32_key_from_parent(cmd->ld->wallet->bip32_base, keyidx,
|
||||||
BIP32_FLAG_KEY_PUBLIC, &ext) != WALLY_OK) {
|
BIP32_FLAG_KEY_PUBLIC, &ext) != WALLY_OK) {
|
||||||
command_fail(cmd, "Keys generation failure");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Keys generation failure");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey.pubkey,
|
if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey.pubkey,
|
||||||
ext.pub_key, sizeof(ext.pub_key))) {
|
ext.pub_key, sizeof(ext.pub_key))) {
|
||||||
command_fail(cmd, "Key parsing failure");
|
command_fail(cmd, LIGHTNINGD, "Key parsing failure");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,7 +335,8 @@ static void json_listaddrs(struct command *cmd,
|
|||||||
false,
|
false,
|
||||||
&redeemscript_p2wpkh);
|
&redeemscript_p2wpkh);
|
||||||
if (!out_p2wpkh) {
|
if (!out_p2wpkh) {
|
||||||
command_fail(cmd, "p2wpkh address encoding failure.");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"p2wpkh address encoding failure.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,7 +392,8 @@ static void json_listfunds(struct command *cmd, const char *buffer UNUSED,
|
|||||||
utxos[i]->is_p2sh,
|
utxos[i]->is_p2sh,
|
||||||
NULL);
|
NULL);
|
||||||
if (!out) {
|
if (!out) {
|
||||||
command_fail(cmd, "p2wpkh address encoding failure.");
|
command_fail(cmd, LIGHTNINGD,
|
||||||
|
"p2wpkh address encoding failure.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
json_add_string(response, "address", out);
|
json_add_string(response, "address", out);
|
||||||
|
|||||||
Reference in New Issue
Block a user