diff --git a/common/json_helpers.c b/common/json_helpers.c index 0878be2ff..60ef36c85 100644 --- a/common/json_helpers.c +++ b/common/json_helpers.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -84,6 +85,13 @@ bool json_to_txid(const char *buffer, const jsmntok_t *tok, tok->end - tok->start, txid); } +bool json_to_channel_id(const char *buffer, const jsmntok_t *tok, + struct channel_id *cid) +{ + return hex_decode(buffer + tok->start, tok->end - tok->start, + cid, sizeof(*cid)); +} + bool split_tok(const char *buffer, const jsmntok_t *tok, char split, jsmntok_t *a, diff --git a/common/json_helpers.h b/common/json_helpers.h index 68b29dc31..9e2499045 100644 --- a/common/json_helpers.h +++ b/common/json_helpers.h @@ -4,6 +4,7 @@ #include "config.h" #include #include +#include struct amount_msat; struct amount_sat; @@ -44,6 +45,10 @@ bool json_to_msat(const char *buffer, const jsmntok_t *tok, bool json_to_txid(const char *buffer, const jsmntok_t *tok, struct bitcoin_txid *txid); +/* Extract a channel id from this */ +bool json_to_channel_id(const char *buffer, const jsmntok_t *tok, + struct channel_id *cid); + /* Split a json token into 2 tokens given a splitting character */ bool split_tok(const char *buffer, const jsmntok_t *tok, char split, diff --git a/common/json_tok.c b/common/json_tok.c index e163f23fc..0c9aec460 100644 --- a/common/json_tok.c +++ b/common/json_tok.c @@ -214,3 +214,17 @@ struct command_result *param_node_id(struct command *cmd, const char *name, name, json_tok_full_len(tok), json_tok_full(buffer, tok)); } + +struct command_result *param_channel_id(struct command *cmd, const char *name, + const char *buffer, const jsmntok_t *tok, + struct channel_id **cid) +{ + *cid = tal(cmd, struct channel_id); + if (json_to_channel_id(buffer, tok, *cid)) + return NULL; + + return command_fail(cmd, JSONRPC2_INVALID_PARAMS, + "'%s' should be a channel id, not '%.*s'", + name, json_tok_full_len(tok), + json_tok_full(buffer, tok)); +} diff --git a/common/json_tok.h b/common/json_tok.h index 8ff5322bf..23b53d53f 100644 --- a/common/json_tok.h +++ b/common/json_tok.h @@ -5,6 +5,7 @@ #include #include #include +#include struct amount_msat; struct amount_sat; @@ -89,6 +90,11 @@ struct command_result *param_node_id(struct command *cmd, const jsmntok_t *tok, struct node_id **id); +struct command_result *param_channel_id(struct command *cmd, + const char *name, + const char *buffer, + const jsmntok_t *tok, + struct channel_id **cid); /* * Set the address of @out to @tok. Used as a callback by handlers that * want to unmarshal @tok themselves. @@ -104,4 +110,5 @@ struct command_result *param_tok(struct command *cmd, const char *name, struct command_result *param_ignore(struct command *cmd, const char *name, const char *buffer, const jsmntok_t *tok, const void *unused); + #endif /* LIGHTNING_COMMON_JSON_TOK_H */ diff --git a/common/test/run-param.c b/common/test/run-param.c index 2aa533626..6fe4c65bc 100644 --- a/common/test/run-param.c +++ b/common/test/run-param.c @@ -42,6 +42,10 @@ struct command_result *command_fail(struct command *cmd, /* Generated stub for fromwire_fail */ const void *fromwire_fail(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) { fprintf(stderr, "fromwire_fail called!\n"); abort(); } +/* Generated stub for json_to_channel_id */ +bool json_to_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, + struct channel_id *cid UNNEEDED) +{ fprintf(stderr, "json_to_channel_id called!\n"); abort(); } /* Generated stub for json_to_node_id */ bool json_to_node_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, struct node_id *id UNNEEDED) diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 64745ad07..afc602d5e 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -2106,6 +2106,7 @@ static struct command_result *json_dev_forget_channel(struct command *cmd, struct peer *peer; struct channel *channel; struct short_channel_id *scid; + struct channel_id *find_cid, cid; struct dev_forget_channel_cmd *forget = tal(cmd, struct dev_forget_channel_cmd); forget->cmd = cmd; @@ -2113,6 +2114,7 @@ static struct command_result *json_dev_forget_channel(struct command *cmd, if (!param(cmd, buffer, params, p_req("id", param_node_id, &peerid), p_opt("short_channel_id", param_short_channel_id, &scid), + p_opt("channel_id", param_channel_id, &find_cid), p_opt_def("force", param_bool, &force, false), NULL)) return command_param_failed(); @@ -2126,6 +2128,14 @@ static struct command_result *json_dev_forget_channel(struct command *cmd, forget->channel = NULL; list_for_each(&peer->channels, channel, list) { + /* Check for channel id first */ + if (find_cid) { + derive_channel_id(&cid, &channel->funding_txid, + channel->funding_outnum); + + if (!channel_id_eq(find_cid, &cid)) + continue; + } if (scid) { if (!channel->scid) continue; diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index 2d946a9ef..1cc794a4b 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -319,6 +319,13 @@ struct command_result *param_bool(struct command *cmd UNNEEDED, const char *name const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, bool **b UNNEEDED) { fprintf(stderr, "param_bool called!\n"); abort(); } +/* Generated stub for param_channel_id */ +struct command_result *param_channel_id(struct command *cmd UNNEEDED, + const char *name UNNEEDED, + const char *buffer UNNEEDED, + const jsmntok_t *tok UNNEEDED, + struct channel_id **cid UNNEEDED) +{ fprintf(stderr, "param_channel_id called!\n"); abort(); } /* Generated stub for param_escaped_string */ struct command_result *param_escaped_string(struct command *cmd UNNEEDED, const char *name UNNEEDED, diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index f705848a0..40ee8edec 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -417,6 +417,13 @@ struct command_result *param_bool(struct command *cmd UNNEEDED, const char *name const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, bool **b UNNEEDED) { fprintf(stderr, "param_bool called!\n"); abort(); } +/* Generated stub for param_channel_id */ +struct command_result *param_channel_id(struct command *cmd UNNEEDED, + const char *name UNNEEDED, + const char *buffer UNNEEDED, + const jsmntok_t *tok UNNEEDED, + struct channel_id **cid UNNEEDED) +{ fprintf(stderr, "param_channel_id called!\n"); abort(); } /* Generated stub for param_loglevel */ struct command_result *param_loglevel(struct command *cmd UNNEEDED, const char *name UNNEEDED,