From b99293fbb62cfb5c826a401f83d4799306bac65e Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 8 Feb 2019 09:53:25 +1030 Subject: [PATCH] short_channel_id: don't accept :-separated in JSON if --allow-deprecated-apis=false We need to still accept it when parsing the database, but this flag should allow upgrade testing for devs building on top Signed-off-by: Rusty Russell --- CHANGELOG.md | 2 ++ bitcoin/short_channel_id.c | 11 +++++++---- bitcoin/short_channel_id.h | 7 +++++-- common/json_helpers.c | 6 ++++-- common/json_helpers.h | 3 ++- gossipd/test/run-find_route-specific.c | 3 ++- lightningd/gossip_control.c | 6 ++++-- lightningd/invoice.c | 3 ++- lightningd/json.c | 3 ++- lightningd/peer_control.c | 3 ++- lightningd/test/run-invoice-select-inchan.c | 3 ++- lightningd/test/run-jsonrpc.c | 3 ++- plugins/pay.c | 2 +- wallet/db.c | 2 +- wallet/test/run-wallet.c | 3 ++- 15 files changed, 40 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 624853ab0..7611c3285 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. Note: You should always set `allow-deprecated-apis=false` to test for changes. +- JSON API: `short_channel_id` fields in JSON commands with `:` separators (use `x` instead). + ### Removed - JSON API: the `waitsendpay` command error return no longer includes `channel_update` diff --git a/bitcoin/short_channel_id.c b/bitcoin/short_channel_id.c index 90432afa1..7dd219794 100644 --- a/bitcoin/short_channel_id.c +++ b/bitcoin/short_channel_id.c @@ -36,7 +36,8 @@ bool mk_short_channel_id(struct short_channel_id *scid, } bool short_channel_id_from_str(const char *str, size_t strlen, - struct short_channel_id *dst) + struct short_channel_id *dst, + bool may_be_deprecated_form) { u32 blocknum, txnum; u16 outnum; @@ -48,7 +49,7 @@ bool short_channel_id_from_str(const char *str, size_t strlen, #ifdef COMPAT_V062 /* Pre-adelaide format vs. post-adelaide format */ - if (strchr(buf, ':')) + if (may_be_deprecated_form && strchr(buf, ':')) matches = sscanf(buf, "%u:%u:%hu", &blocknum, &txnum, &outnum); else matches = sscanf(buf, "%ux%ux%hu", &blocknum, &txnum, &outnum); @@ -68,12 +69,14 @@ char *short_channel_id_to_str(const tal_t *ctx, const struct short_channel_id *s } bool short_channel_id_dir_from_str(const char *str, size_t strlen, - struct short_channel_id_dir *scidd) + struct short_channel_id_dir *scidd, + bool may_be_deprecated_form) { const char *slash = memchr(str, '/', strlen); if (!slash || slash + 2 != str + strlen) return false; - if (!short_channel_id_from_str(str, slash - str, &scidd->scid)) + if (!short_channel_id_from_str(str, slash - str, &scidd->scid, + may_be_deprecated_form)) return false; if (slash[1] == '0') scidd->dir = 0; diff --git a/bitcoin/short_channel_id.h b/bitcoin/short_channel_id.h index bcf2ef38d..4e0a25441 100644 --- a/bitcoin/short_channel_id.h +++ b/bitcoin/short_channel_id.h @@ -51,13 +51,16 @@ static inline u16 short_channel_id_outnum(const struct short_channel_id *scid) bool WARN_UNUSED_RESULT mk_short_channel_id(struct short_channel_id *scid, u64 blocknum, u64 txnum, u64 outnum); +/* may_be_deprecated_form allows : separators if COMPAT defined */ bool WARN_UNUSED_RESULT short_channel_id_from_str(const char *str, size_t strlen, - struct short_channel_id *dst); + struct short_channel_id *dst, + bool may_be_deprecated_form); char *short_channel_id_to_str(const tal_t *ctx, const struct short_channel_id *scid); bool WARN_UNUSED_RESULT short_channel_id_dir_from_str(const char *str, size_t strlen, - struct short_channel_id_dir *scidd); + struct short_channel_id_dir *scidd, + bool may_be_deprecated_form); char *short_channel_id_dir_to_str(const tal_t *ctx, const struct short_channel_id_dir *scidd); diff --git a/common/json_helpers.c b/common/json_helpers.c index 42ace5b15..df4f5cd09 100644 --- a/common/json_helpers.c +++ b/common/json_helpers.c @@ -39,8 +39,10 @@ bool json_to_pubkey(const char *buffer, const jsmntok_t *tok, } bool json_to_short_channel_id(const char *buffer, const jsmntok_t *tok, - struct short_channel_id *scid) + struct short_channel_id *scid, + bool may_be_deprecated_form) { return (short_channel_id_from_str(buffer + tok->start, - tok->end - tok->start, scid)); + tok->end - tok->start, scid, + may_be_deprecated_form)); } diff --git a/common/json_helpers.h b/common/json_helpers.h index 3a54ce387..5659fe856 100644 --- a/common/json_helpers.h +++ b/common/json_helpers.h @@ -17,6 +17,7 @@ bool json_to_bitcoin_amount(const char *buffer, const jsmntok_t *tok, /* Extract a short_channel_id from this */ bool json_to_short_channel_id(const char *buffer, const jsmntok_t *tok, - struct short_channel_id *scid); + struct short_channel_id *scid, + bool may_be_deprecated_form); #endif /* LIGHTNING_COMMON_JSON_HELPERS_H */ diff --git a/gossipd/test/run-find_route-specific.c b/gossipd/test/run-find_route-specific.c index 53bf1a105..c27cc769e 100644 --- a/gossipd/test/run-find_route-specific.c +++ b/gossipd/test/run-find_route-specific.c @@ -126,7 +126,8 @@ get_or_make_connection(struct routing_state *rstate, struct chan *chan; const int idx = pubkey_idx(from_id, to_id); - if (!short_channel_id_from_str(shortid, strlen(shortid), &scid)) + if (!short_channel_id_from_str(shortid, strlen(shortid), &scid, + false)) abort(); chan = get_channel(rstate, &scid); if (!chan) diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 1b2a9b30f..9fc6e7be3 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -339,7 +339,8 @@ static struct command_result *json_getroute(struct command *cmd, json_for_each_arr(i, t, excludetok) { if (!short_channel_id_dir_from_str(buffer + t->start, t->end - t->start, - &excluded[i])) { + &excluded[i], + deprecated_apis)) { return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "%.*s is not a valid" " short_channel_id/direction", @@ -497,7 +498,8 @@ static struct command_result *json_dev_query_scids(struct command *cmd, scids = tal_arr(cmd, struct short_channel_id, scidstok->size); json_for_each_arr(i, t, scidstok) { - if (!json_to_short_channel_id(buffer, t, &scids[i])) { + if (!json_to_short_channel_id(buffer, t, &scids[i], + deprecated_apis)) { return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "scid %zu '%.*s' is not an scid", i, json_tok_full_len(t), diff --git a/lightningd/invoice.c b/lightningd/invoice.c index e7f296791..76c315d72 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -325,7 +325,8 @@ static struct route_info *unpack_route(const tal_t *ctx, if (!json_to_pubkey(buffer, pubkey, &r->pubkey) || !json_to_short_channel_id(buffer, scid, - &r->short_channel_id) + &r->short_channel_id, + deprecated_apis) || !json_to_number(buffer, fee_base, &r->fee_base_msat) || !json_to_number(buffer, fee_prop, &r->fee_proportional_millionths) diff --git a/lightningd/json.c b/lightningd/json.c index fa9a8edef..e43635482 100644 --- a/lightningd/json.c +++ b/lightningd/json.c @@ -97,7 +97,8 @@ struct command_result *param_short_channel_id(struct command *cmd, struct short_channel_id **scid) { *scid = tal(cmd, struct short_channel_id); - if (json_to_short_channel_id(buffer, tok, *scid)) + if (json_to_short_channel_id(buffer, tok, *scid, + deprecated_apis)) return NULL; return command_fail(cmd, JSONRPC2_INVALID_PARAMS, diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 18970e06b..e21e5d90d 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -897,7 +897,8 @@ command_find_channel(struct command *cmd, "Channel ID not found: '%.*s'", tok->end - tok->start, buffer + tok->start); - } else if (json_to_short_channel_id(buffer, tok, &scid)) { + } else if (json_to_short_channel_id(buffer, tok, &scid, + deprecated_apis)) { list_for_each(&ld->peers, peer, list) { *channel = peer_active_channel(peer); if (!*channel) diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index 385d9f791..f5af4c008 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -207,7 +207,8 @@ bool json_to_pubkey(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, { fprintf(stderr, "json_to_pubkey called!\n"); abort(); } /* Generated stub for json_to_short_channel_id */ bool json_to_short_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, - struct short_channel_id *scid UNNEEDED) + struct short_channel_id *scid UNNEEDED, + bool may_be_deprecated_form UNNEEDED) { fprintf(stderr, "json_to_short_channel_id called!\n"); abort(); } /* Generated stub for kill_uncommitted_channel */ void kill_uncommitted_channel(struct uncommitted_channel *uc UNNEEDED, diff --git a/lightningd/test/run-jsonrpc.c b/lightningd/test/run-jsonrpc.c index 876774c3b..28a7141d9 100644 --- a/lightningd/test/run-jsonrpc.c +++ b/lightningd/test/run-jsonrpc.c @@ -27,7 +27,8 @@ bool json_to_pubkey(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, { fprintf(stderr, "json_to_pubkey called!\n"); abort(); } /* Generated stub for json_to_short_channel_id */ bool json_to_short_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, - struct short_channel_id *scid UNNEEDED) + struct short_channel_id *scid UNNEEDED, + bool may_be_deprecated_form UNNEEDED) { fprintf(stderr, "json_to_short_channel_id called!\n"); abort(); } /* Generated stub for log_ */ void log_(struct log *log UNNEEDED, enum log_level level UNNEEDED, const char *fmt UNNEEDED, ...) diff --git a/plugins/pay.c b/plugins/pay.c index 352c25f7c..bd5d4a7ab 100644 --- a/plugins/pay.c +++ b/plugins/pay.c @@ -148,7 +148,7 @@ static bool channel_in_routehint(const struct route_info *routehint, { struct short_channel_id scid; - if (!json_to_short_channel_id(buf, scidtok, &scid)) + if (!json_to_short_channel_id(buf, scidtok, &scid, false)) plugin_err("bad erring_channel '%.*s'", scidtok->end - scidtok->start, buf + scidtok->start); diff --git a/wallet/db.c b/wallet/db.c index a57f4df41..5082d593f 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -742,7 +742,7 @@ bool sqlite3_column_short_channel_id(sqlite3_stmt *stmt, int col, { const char *source = sqlite3_column_blob(stmt, col); size_t sourcelen = sqlite3_column_bytes(stmt, col); - return short_channel_id_from_str(source, sourcelen, dest); + return short_channel_id_from_str(source, sourcelen, dest, true); } bool sqlite3_bind_short_channel_id_array(sqlite3_stmt *stmt, int col, const struct short_channel_id *id) diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index b00f65f12..9dc4e392f 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -279,7 +279,8 @@ bool json_to_pubkey(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, { fprintf(stderr, "json_to_pubkey called!\n"); abort(); } /* Generated stub for json_to_short_channel_id */ bool json_to_short_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, - struct short_channel_id *scid UNNEEDED) + struct short_channel_id *scid UNNEEDED, + bool may_be_deprecated_form UNNEEDED) { fprintf(stderr, "json_to_short_channel_id called!\n"); abort(); } /* Generated stub for kill_uncommitted_channel */ void kill_uncommitted_channel(struct uncommitted_channel *uc UNNEEDED,