Skip to content

Commit 483f0d3

Browse files
committed
lightningd: immediately close without broadcast whenever we close a withheld channel.
There's no funding tx to spend. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent bb84dc5 commit 483f0d3

File tree

5 files changed

+42
-8
lines changed

5 files changed

+42
-8
lines changed

lightningd/channel.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,21 +1104,31 @@ static void channel_fail_perm(struct channel *channel,
11041104

11051105
channel_set_owner(channel, NULL);
11061106

1107-
if (channel_state_wants_onchain_fail(channel->state))
1107+
if (channel->withheld) {
1108+
channel_set_state(channel,
1109+
channel->state,
1110+
CLOSED,
1111+
reason,
1112+
why);
1113+
} else if (channel_state_wants_onchain_fail(channel->state)) {
11081114
channel_set_state(channel,
11091115
channel->state,
11101116
AWAITING_UNILATERAL,
11111117
reason,
11121118
why);
1119+
}
1120+
1121+
if (channel_state_open_uncommitted(channel->state)) {
1122+
delete_channel(channel, false);
1123+
return;
1124+
}
11131125

11141126
/* Drop non-cooperatively (unilateral) to chain. If we detect
11151127
* the close from the blockchain, then we can observe
11161128
* passively, and not broadcast our own unilateral close, as
11171129
* it doesn't stand a chance anyway. */
11181130
drop_to_chain(ld, channel, false, spent_by);
11191131

1120-
if (channel_state_open_uncommitted(channel->state))
1121-
delete_channel(channel, false);
11221132
}
11231133

11241134
void channel_fail_permanent(struct channel *channel,

lightningd/closing_control.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,18 @@ static void
5454
resolve_one_close_command(struct close_command *cc, bool cooperative,
5555
const struct bitcoin_tx **close_txs)
5656
{
57-
assert(tal_count(close_txs));
5857
struct json_stream *result = json_stream_success(cc->cmd);
59-
const struct bitcoin_tx *close_tx = close_txs[tal_count(close_txs) - 1];
58+
const struct bitcoin_tx *close_tx;
6059

61-
if (command_deprecated_out_ok(cc->cmd, "tx", "v24.11", "v25.12"))
60+
/* Withheld funding channels can have no close_txs! */
61+
if (tal_count(close_txs) != 0)
62+
close_tx = close_txs[tal_count(close_txs) - 1];
63+
else
64+
close_tx = NULL;
65+
66+
if (close_tx && command_deprecated_out_ok(cc->cmd, "tx", "v24.11", "v25.12"))
6267
json_add_tx(result, "tx", close_tx);
63-
if (!invalid_last_tx(close_tx)) {
68+
if (close_tx && !invalid_last_tx(close_tx)) {
6469
struct bitcoin_txid txid;
6570
bitcoin_txid(close_tx, &txid);
6671
if (command_deprecated_out_ok(cc->cmd, "txid", "v24.11", "v25.12"))

lightningd/peer_control.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,17 @@ void drop_to_chain(struct lightningd *ld, struct channel *channel,
377377
struct channel_inflight *inflight;
378378
const char *cmd_id;
379379

380+
/* If we withheld the funding tx, we simply close */
381+
if (channel->withheld) {
382+
log_info(channel->log,
383+
"Withheld channel: not sending a close transaction");
384+
resolve_close_command(ld, channel, cooperative,
385+
tal_arr(tmpctx, const struct bitcoin_tx *, 0));
386+
free_htlcs(ld, channel);
387+
delete_channel(channel, false);
388+
return;
389+
}
390+
380391
/* If we're not already (e.g. close before channel fully open),
381392
* make sure we're watching for the funding spend */
382393
if (!channel->funding_spend_watch) {

lightningd/test/run-invoice-select-inchan.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,9 @@ void force_peer_disconnect(struct lightningd *ld UNNEEDED,
315315
const struct peer *peer UNNEEDED,
316316
const char *why UNNEEDED)
317317
{ fprintf(stderr, "force_peer_disconnect called!\n"); abort(); }
318+
/* Generated stub for free_htlcs */
319+
void free_htlcs(struct lightningd *ld UNNEEDED, const struct channel *channel UNNEEDED)
320+
{ fprintf(stderr, "free_htlcs called!\n"); abort(); }
318321
/* Generated stub for fromwire_bigsize */
319322
bigsize_t fromwire_bigsize(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
320323
{ fprintf(stderr, "fromwire_bigsize called!\n"); abort(); }

plugins/spender/openchannel.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1095,17 +1095,22 @@ static void list_awaiting_channels(struct command *init_cmd)
10951095
struct channel_id cid;
10961096
struct command *aux_cmd;
10971097
struct wally_psbt *psbt;
1098+
bool withheld;
10981099

1099-
if (json_scan(tmpctx, buf, t, "{state:%,channel_id:%,funding:{psbt:%}}",
1100+
if (json_scan(tmpctx, buf, t, "{state:%,channel_id:%,funding:{withheld:%,psbt:%}}",
11001101
JSON_SCAN_TAL(tmpctx, json_strdup, &state),
11011102
JSON_SCAN(json_tok_channel_id, &cid),
1103+
JSON_SCAN(json_to_bool, &withheld),
11021104
JSON_SCAN_TAL(tmpctx, json_to_psbt, &psbt)) != NULL)
11031105
continue;
11041106

11051107
if (!streq(state, "CHANNELD_AWAITING_LOCKIN")
11061108
&& !streq(state, "DUALOPEND_AWAITING_LOCKIN"))
11071109
continue;
11081110

1111+
if (withheld)
1112+
continue;
1113+
11091114
/* Don't do this sync, as it can reasonably fail! */
11101115
aux_cmd = aux_command(init_cmd);
11111116
req = jsonrpc_request_start(aux_cmd, "signpsbt",

0 commit comments

Comments
 (0)