diff --git a/doc/lightning-listpeerchannels.7.md b/doc/lightning-listpeerchannels.7.md index 1d182704a..af7d202a0 100644 --- a/doc/lightning-listpeerchannels.7.md +++ b/doc/lightning-listpeerchannels.7.md @@ -31,6 +31,11 @@ On success, an object containing **channels** is returned. It is an array of ob - **features** (array of strings): - BOLT #9 features which apply to this channel (one of "option\_static\_remotekey", "option\_anchor\_outputs", "option\_zeroconf") - **scratch\_txid** (txid, optional): The txid we would use if we went onchain now +- **channel\_type** (object, optional): channel\_type as negotiated with peer *(added v23.05)*: + - **bits** (array of u32s): Each bit set in this channel\_type: + - Bit number + - **names** (array of strings): Feature name for each bit set in this channel\_type: + - Name of feature bit (one of "static\_remotekey/even", "anchor\_outputs/even", "anchors\_zero\_fee\_htlc\_tx/even", "scid\_alias/even", "zeroconf/even") - **feerate** (object, optional): Feerates for the current tx: - **perkw** (u32): Feerate per 1000 weight (i.e kSipa) - **perkb** (u32): Feerate per 1000 virtual bytes @@ -189,4 +194,4 @@ Main web site: Lightning RFC site (BOLT \#9): -[comment]: # ( SHA256STAMP:f9919b6967137945cb49392d64a42bd159123b9d3bb83833c5df3bc777065d2e) +[comment]: # ( SHA256STAMP:1e589a9e6eace9134d04693dd00caa03da98dd40c2e65d3c675c9bee06daff7f) diff --git a/doc/lightning-sql.7.md b/doc/lightning-sql.7.md index 1fd2808bc..30cc14fde 100644 --- a/doc/lightning-sql.7.md +++ b/doc/lightning-sql.7.md @@ -208,6 +208,14 @@ The following tables are currently supported: - `peer_connected` (type `boolean`, sqltype `INTEGER`) - `state` (type `string`, sqltype `TEXT`) - `scratch_txid` (type `txid`, sqltype `BLOB`) + - related table `peerchannels_channel_type_bits`, from JSON object `channel_type` + - `row` (reference to `peerchannels_channel_type.rowid`, sqltype `INTEGER`) + - `arrindex` (index within array, sqltype `INTEGER`) + - `bits` (type `u32`, sqltype `INTEGER`) + - related table `peerchannels_channel_type_names`, from JSON object `channel_type` + - `row` (reference to `peerchannels_channel_type.rowid`, sqltype `INTEGER`) + - `arrindex` (index within array, sqltype `INTEGER`) + - `names` (type `string`, sqltype `TEXT`) - `feerate_perkw` (type `u32`, sqltype `INTEGER`, from JSON object `feerate`) - `feerate_perkb` (type `u32`, sqltype `INTEGER`, from JSON object `feerate`) - `owner` (type `string`, sqltype `TEXT`) @@ -472,4 +480,4 @@ RESOURCES --------- Main web site: -[comment]: # ( SHA256STAMP:d25af4b0655ebd31db68932c5ea6b532bd134477e42df5d0c7428e4a03fd0335) +[comment]: # ( SHA256STAMP:ccc382f01d39253aff5a6c7ccd74400feb2f900f78f492a4c55b0a80e04fe813) diff --git a/doc/schemas/listpeerchannels.schema.json b/doc/schemas/listpeerchannels.schema.json index 496b564d8..bd3a2e75f 100644 --- a/doc/schemas/listpeerchannels.schema.json +++ b/doc/schemas/listpeerchannels.schema.json @@ -48,6 +48,41 @@ "type": "txid", "description": "The txid we would use if we went onchain now" }, + "channel_type": { + "type": "object", + "description": "channel_type as negotiated with peer", + "added": "v23.05", + "additionalProperties": false, + "required": [ + "bits", + "names" + ], + "properties": { + "bits": { + "type": "array", + "description": "Each bit set in this channel_type", + "items": { + "type": "u32", + "description": "Bit number" + } + }, + "names": { + "type": "array", + "description": "Feature name for each bit set in this channel_type", + "items": { + "type": "string", + "enum": [ + "static_remotekey/even", + "anchor_outputs/even", + "anchors_zero_fee_htlc_tx/even", + "scid_alias/even", + "zeroconf/even" + ], + "description": "Name of feature bit" + } + } + } + }, "feerate": { "type": "object", "description": "Feerates for the current tx", @@ -569,6 +604,7 @@ "peer_id": {}, "peer_connected": {}, "scratch_txid": {}, + "channel_type": {}, "feerate": {}, "owner": {}, "short_channel_id": {}, @@ -658,6 +694,7 @@ "peer_connected": {}, "alias": {}, "scratch_txid": {}, + "channel_type": {}, "feerate": {}, "owner": {}, "short_channel_id": {}, @@ -746,6 +783,7 @@ "peer_connected": {}, "state": {}, "scratch_txid": {}, + "channel_type": {}, "feerate": {}, "owner": {}, "short_channel_id": {}, @@ -835,6 +873,7 @@ "peer_id": {}, "peer_connected": {}, "scratch_txid": {}, + "channel_type": {}, "feerate": {}, "owner": {}, "alias": {}, diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 0306d97a6..3f8ac6852 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -692,6 +692,29 @@ struct amount_msat channel_amount_receivable(const struct channel *channel) return receivable; } +void json_add_channel_type(struct json_stream *response, + const char *fieldname, + const struct channel_type *channel_type) +{ + const char **fnames; + + json_object_start(response, fieldname); + json_array_start(response, "bits"); + for (size_t i = 0; i < tal_bytelen(channel_type->features) * CHAR_BIT; i++) { + if (!feature_is_set(channel_type->features, i)) + continue; + json_add_u64(response, NULL, i); + } + json_array_end(response); + + json_array_start(response, "names"); + fnames = channel_type_name(tmpctx, channel_type); + for (size_t i = 0; i < tal_count(fnames); i++) + json_add_string(response, NULL, fnames[i]); + json_array_end(response); + json_object_end(response); +} + static void json_add_channel(struct lightningd *ld, struct json_stream *response, const char *key, const struct channel *channel, @@ -708,6 +731,7 @@ static void json_add_channel(struct lightningd *ld, if (peer) { json_add_node_id(response, "peer_id", &peer->id); json_add_bool(response, "peer_connected", peer->connected == PEER_CONNECTED); + json_add_channel_type(response, "channel_type", channel->type); } json_add_string(response, "state", channel_state_name(channel)); if (channel->last_tx && !invalid_last_tx(channel->last_tx)) { diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h index a967866bf..5f3044c38 100644 --- a/lightningd/peer_control.h +++ b/lightningd/peer_control.h @@ -11,6 +11,7 @@ #include #include +struct channel_type; struct peer_fd; struct wally_psbt; @@ -140,6 +141,11 @@ command_find_channel(struct command *cmd, const char *buffer, const jsmntok_t *tok, struct channel **channel); +/* Add channel_type object */ +void json_add_channel_type(struct json_stream *response, + const char *fieldname, + const struct channel_type *channel_type); + /* Ancient (0.7.0 and before) releases could create invalid commitment txs! */ bool invalid_last_tx(const struct bitcoin_tx *tx); diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index 0c66bd782..76f5e6e39 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -114,6 +114,9 @@ bool channel_tell_depth(struct lightningd *ld UNNEEDED, /* Generated stub for channel_type_has */ bool channel_type_has(const struct channel_type *type UNNEEDED, int feature UNNEEDED) { fprintf(stderr, "channel_type_has called!\n"); abort(); } +/* Generated stub for channel_type_name */ +const char **channel_type_name(const tal_t *ctx UNNEEDED, const struct channel_type *t UNNEEDED) +{ fprintf(stderr, "channel_type_name called!\n"); abort(); } /* Generated stub for channel_unsaved_close_conn */ void channel_unsaved_close_conn(struct channel *channel UNNEEDED, const char *why UNNEEDED) { fprintf(stderr, "channel_unsaved_close_conn called!\n"); abort(); } diff --git a/tests/test_plugin.py b/tests/test_plugin.py index dd12a6585..397b3a6c3 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -3700,6 +3700,20 @@ def test_sql(node_factory, bitcoind): 'type': 'string'}, {'name': 'message', 'type': 'string'}]}, + 'peerchannels_channel_type_bits': { + 'columns': [{'name': 'row', + 'type': 'u64'}, + {'name': 'arrindex', + 'type': 'u64'}, + {'name': 'bits', + 'type': 'u64'}]}, + 'peerchannels_channel_type_names': { + 'columns': [{'name': 'row', + 'type': 'u64'}, + {'name': 'arrindex', + 'type': 'u64'}, + {'name': 'names', + 'type': 'string'}]}, 'transactions': { 'indices': [['hash']], 'columns': [{'name': 'hash',