Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cln-grpc/proto/node.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cln-grpc/src/convert.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion cln-rpc/src/notifications.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ impl ToString for ChannelStateChangedCause {

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ChannelStateChangedNotification {
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub old_state: Option<ChannelState>,
#[serde(skip_serializing_if = "Option::is_none")]
Expand All @@ -201,7 +203,6 @@ pub struct ChannelStateChangedNotification {
// Path `channel_state_changed.new_state`
pub new_state: ChannelState,
pub channel_id: Sha256,
pub message: String,
pub peer_id: PublicKey,
pub timestamp: String,
}
Expand Down
5 changes: 0 additions & 5 deletions common/json_stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,11 +323,6 @@ void json_add_bool(struct json_stream *result, const char *fieldname, bool value
json_add_primitive(result, fieldname, value ? "true" : "false");
}

void json_add_null(struct json_stream *stream, const char *fieldname)
{
json_add_primitive(stream, fieldname, "null");
}

void json_add_hex(struct json_stream *js, const char *fieldname,
const void *data, size_t len)
{
Expand Down
3 changes: 1 addition & 2 deletions common/json_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,7 @@ void json_add_s32(struct json_stream *result, const char *fieldname,
void json_add_bool(struct json_stream *result, const char *fieldname,
bool value);

/* '"fieldname" : null' or 'null' if fieldname is NULL */
void json_add_null(struct json_stream *stream, const char *fieldname);
/* Looking for json_add_null? Don't do that: we omit fields, don't 'null' them! */

/* '"fieldname" : "0189abcdef..."' or "0189abcdef..." if fieldname is NULL */
void json_add_hex(struct json_stream *result, const char *fieldname,
Expand Down
9 changes: 5 additions & 4 deletions contrib/msggen/msggen/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -36355,8 +36355,7 @@
"channel_id",
"timestamp",
"new_state",
"cause",
"message"
"cause"
],
"properties": {
"peer_id": {
Expand Down Expand Up @@ -36427,10 +36426,12 @@
"DUALOPEND_AWAITING_LOCKIN",
"CHANNELD_AWAITING_SPLICE",
"DUALOPEND_OPEN_COMMITTED",
"DUALOPEND_OPEN_COMMIT_READY"
"DUALOPEND_OPEN_COMMIT_READY",
"CLOSED"
],
"description": [
"The channel state, in particular \"CHANNELD_NORMAL\" and \"CHANNELD_AWAITING_SPLICE\" mean the channel can be used normally"
"The channel state, in particular \"CHANNELD_NORMAL\" and \"CHANNELD_AWAITING_SPLICE\" mean the channel can be used normally",
"Note: *CLOSED* state was only added in v25.12."
],
"added": "pre-v0.10.1"
},
Expand Down
12 changes: 6 additions & 6 deletions contrib/pyln-grpc-proto/pyln/grpc/node_pb2.py

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions doc/developers-guide/deprecated-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ hidden: false
| channel_state_changed.null_scid | Notification Field | v25.09 | v26.09 | In channel_state_changed notification, `short_channel_id` will be missing instead of `null` |
| notification.payload | Notification Field | v25.09 | v26.09 | Notifications from plugins used to have fields in `payload` sub-object, now they are not (just like normal notifications) |
| pay_notifications.raw_fields | Field | v25.09 | v26.09 | `channel_hint_update`, `pay_failure` and `pay_success` notifications now wrap members in an object of the same name |
| channel_state_changed.null_message | Notification Field | v25.12 | v26.12 | In channel_state_changed notification, `message` will be missing instead of `null` |

Inevitably there are features which need to change: either to be generalized, or removed when they can no longer be supported.

Expand Down
9 changes: 5 additions & 4 deletions doc/schemas/notification/channel_state_changed.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
"channel_id",
"timestamp",
"new_state",
"cause",
"message"
"cause"
],
"properties": {
"peer_id": {
Expand Down Expand Up @@ -87,10 +86,12 @@
"DUALOPEND_AWAITING_LOCKIN",
"CHANNELD_AWAITING_SPLICE",
"DUALOPEND_OPEN_COMMITTED",
"DUALOPEND_OPEN_COMMIT_READY"
"DUALOPEND_OPEN_COMMIT_READY",
"CLOSED"
],
"description": [
"The channel state, in particular \"CHANNELD_NORMAL\" and \"CHANNELD_AWAITING_SPLICE\" mean the channel can be used normally"
"The channel state, in particular \"CHANNELD_NORMAL\" and \"CHANNELD_AWAITING_SPLICE\" mean the channel can be used normally",
"Note: *CLOSED* state was only added in v25.12."
],
"added": "pre-v0.10.1"
},
Expand Down
13 changes: 12 additions & 1 deletion lightningd/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ static void destroy_channel(struct channel *channel)
list_del_from(&channel->peer->channels, &channel->list);
}

void delete_channel(struct channel *channel STEALS, bool completely_eliminate)
void delete_channel(struct channel *channel STEALS,
bool completely_eliminate)
{
const u8 *msg;
struct peer *peer = channel->peer;
Expand All @@ -111,6 +112,16 @@ void delete_channel(struct channel *channel STEALS, bool completely_eliminate)
fatal("HSM gave bad hsm_forget_channel_reply %s", tal_hex(msg, msg));
}

notify_channel_state_changed(channel->peer->ld,
&channel->peer->id,
&channel->cid,
channel->scid,
time_now(),
channel->state,
CLOSED,
REASON_UNKNOWN,
NULL);

tal_free(channel);

maybe_delete_peer(peer);
Expand Down
3 changes: 2 additions & 1 deletion lightningd/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,8 @@ channel_current_inflight(const struct channel *channel);
u32 channel_last_funding_feerate(const struct channel *channel);

/* Only set completely_eliminate for never-existed channels */
void delete_channel(struct channel *channel STEALS, bool completely_eliminate);
void delete_channel(struct channel *channel STEALS,
bool completely_eliminate);

/* Add a historic (public) short_channel_id to this channel */
void channel_add_old_scid(struct channel *channel,
Expand Down
12 changes: 11 additions & 1 deletion lightningd/notification.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,12 @@ void notify_channel_opened(struct lightningd *ld,
notify_send(ld, n);
}

/* Don't use this: omit fields instead! */
static void json_add_null(struct json_stream *stream, const char *fieldname)
{
json_add_primitive(stream, fieldname, "null");
}

static void channel_state_changed_notification_serialize(struct json_stream *stream,
struct lightningd *ld,
const struct node_id *peer_id,
Expand Down Expand Up @@ -304,8 +310,12 @@ static void channel_state_changed_notification_serialize(struct json_stream *str
json_add_string(stream, "cause", channel_change_state_reason_str(cause));
if (message != NULL)
json_add_string(stream, "message", message);
else
else if (lightningd_deprecated_out_ok(ld, ld->deprecated_ok,
"channel_state_changed",
"null_message",
"v25.12", "v26.12")) {
json_add_null(stream, "message");
}
}

REGISTER_NOTIFICATION(channel_state_changed)
Expand Down
6 changes: 6 additions & 0 deletions plugins/bcli.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,12 @@ static struct command_result *command_err_bcli_badjson(struct bitcoin_cli *bcli,
return command_done_err(bcli->cmd, BCLI_ERROR, err, NULL);
}

/* Don't use this in general: it's better to omit fields. */
static void json_add_null(struct json_stream *stream, const char *fieldname)
{
json_add_primitive(stream, fieldname, "null");
}

static struct command_result *process_getutxout(struct bitcoin_cli *bcli)
{
const jsmntok_t *tokens;
Expand Down
31 changes: 28 additions & 3 deletions tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,7 @@ def wait_for_event(node):
assert(event2['cause'] == "remote")
assert(event2['message'] == "Closing complete")

bitcoind.generate_block(100, wait_for_mempool=1) # so it gets settled
bitcoind.generate_block(99, wait_for_mempool=1) # so it gets settled

event1 = wait_for_event(l1)
assert(event1['old_state'] == "CLOSINGD_COMPLETE")
Expand All @@ -962,6 +962,18 @@ def wait_for_event(node):
assert(event2['cause'] == "remote")
assert(event2['message'] == "Onchain init reply")

bitcoind.generate_block(1)
event1 = wait_for_event(l1)
assert(event1['old_state'] == "ONCHAIN")
assert(event1['new_state'] == "CLOSED")
assert(event1['cause'] == "unknown")
assert('message' not in event1)
event2 = wait_for_event(l2)
assert(event2['old_state'] == "ONCHAIN")
assert(event2['new_state'] == "CLOSED")
assert(event2['cause'] == "unknown")
assert('message' not in event2)


@pytest.mark.openchannel('v1')
@pytest.mark.openchannel('v2')
Expand Down Expand Up @@ -1056,8 +1068,8 @@ def wait_for_event(node):
assert(event1['cause'] == "protocol")
assert(event1['message'] == "channeld: received ERROR channel {}: Forcibly closed by `close` command timeout".format(cid))

# settle the channel closure
bitcoind.generate_block(100)
# Almost settle the channel closure
bitcoind.generate_block(99, wait_for_mempool=1)

event2 = wait_for_event(l2)
assert(event2['old_state'] == "AWAITING_UNILATERAL")
Expand Down Expand Up @@ -1085,6 +1097,19 @@ def wait_for_event(node):
assert(event1['cause'] == "onchain")
assert(event1['message'] == "Onchain init reply")

bitcoind.generate_block(1)
event1 = wait_for_event(l1)
assert(event1['old_state'] == "ONCHAIN")
assert(event1['new_state'] == "CLOSED")
assert(event1['cause'] == "unknown")
assert('message' not in event1)

event2 = wait_for_event(l2)
assert(event2['old_state'] == "ONCHAIN")
assert(event2['new_state'] == "CLOSED")
assert(event2['cause'] == "unknown")
assert('message' not in event2)


@pytest.mark.openchannel('v1')
@pytest.mark.openchannel('v2')
Expand Down
22 changes: 11 additions & 11 deletions wallet/test/run-wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -758,17 +758,6 @@ void notify_channel_mvt(struct lightningd *ld UNNEEDED,
void notify_channel_open_failed(struct lightningd *ld UNNEEDED,
const struct channel_id *cid UNNEEDED)
{ fprintf(stderr, "notify_channel_open_failed called!\n"); abort(); }
/* Generated stub for notify_channel_state_changed */
void notify_channel_state_changed(struct lightningd *ld UNNEEDED,
const struct node_id *peer_id UNNEEDED,
const struct channel_id *cid UNNEEDED,
const struct short_channel_id *scid UNNEEDED,
struct timeabs timestamp UNNEEDED,
enum channel_state old_state UNNEEDED,
enum channel_state new_state UNNEEDED,
enum state_change cause UNNEEDED,
const char *message UNNEEDED)
{ fprintf(stderr, "notify_channel_state_changed called!\n"); abort(); }
/* Generated stub for notify_connect */
void notify_connect(struct lightningd *ld UNNEEDED,
const struct node_id *nodeid UNNEEDED,
Expand Down Expand Up @@ -1313,6 +1302,17 @@ u8 *wire_sync_read(const tal_t *ctx UNNEEDED, int fd UNNEEDED)
void plugin_hook_db_sync(struct db *db UNNEEDED)
{
}
void notify_channel_state_changed(struct lightningd *ld UNNEEDED,
const struct node_id *peer_id UNNEEDED,
const struct channel_id *cid UNNEEDED,
const struct short_channel_id *scid UNNEEDED,
struct timeabs timestamp UNNEEDED,
enum channel_state old_state UNNEEDED,
enum channel_state new_state UNNEEDED,
enum state_change cause UNNEEDED,
const char *message UNNEEDED)
{
}
bool fromwire_hsmd_get_channel_basepoints_reply(const void *p UNNEEDED,
struct basepoints *basepoints,
struct pubkey *funding_pubkey)
Expand Down
Loading