mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
close: add notification for slow closes.
For compatibility, we only do this if `allow-deprecated-apis` is false for now. Otherwise scripts parsing should use `grep -v '^# '` or start using `-N none`. Changelog-Added: JSON-RPC: `close` now sends notifications for slow closes (if `allow-deprecated-apis`=false) Changelog-Deprecated: cli: scripts should filter out '^# ' or use `-N none`, as commands will start returning notifications soon Fixes: #3925 Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
f395404a10
commit
1e5789d421
8
doc/lightning-close.7
generated
8
doc/lightning-close.7
generated
@ -66,6 +66,12 @@ Prior to 0\.7\.2, \fBclose\fR took two parameters: \fIforce\fR and \fItimeout\fR
|
|||||||
an RPC error (default)\. Even after the timeout, the channel would be
|
an RPC error (default)\. Even after the timeout, the channel would be
|
||||||
closed if the peer reconnected\.
|
closed if the peer reconnected\.
|
||||||
|
|
||||||
|
.SH NOTIFICATIONS
|
||||||
|
|
||||||
|
If \fBallow-deprecated-apis\fR is false, notifications may be returned
|
||||||
|
indicating what is going on, especially if the peer is offline and we
|
||||||
|
are waiting\. This will be enabled by default in future!
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
|
|
||||||
On success, an object with fields \fItx\fR and \fItxid\fR containing the closing
|
On success, an object with fields \fItx\fR and \fItxid\fR containing the closing
|
||||||
@ -95,4 +101,4 @@ ZmnSCPxj \fI<ZmnSCPxj@protonmail.com\fR> is mainly responsible\.
|
|||||||
|
|
||||||
Main web site: \fIhttps://github.com/ElementsProject/lightning\fR
|
Main web site: \fIhttps://github.com/ElementsProject/lightning\fR
|
||||||
|
|
||||||
\" SHA256STAMP:3763db99c82aebedf40e1ef39407f2970d0408601f9250ec9c52995956da621b
|
\" SHA256STAMP:d16e185f9a781f23987dfb65aaa1eae8dab19796975433c69e16f1f6b18751c5
|
||||||
|
@ -57,6 +57,12 @@ Prior to 0.7.2, **close** took two parameters: *force* and *timeout*.
|
|||||||
an RPC error (default). Even after the timeout, the channel would be
|
an RPC error (default). Even after the timeout, the channel would be
|
||||||
closed if the peer reconnected.
|
closed if the peer reconnected.
|
||||||
|
|
||||||
|
NOTIFICATIONS
|
||||||
|
-------------
|
||||||
|
If `allow-deprecated-apis` is false, notifications may be returned
|
||||||
|
indicating what is going on, especially if the peer is offline and we
|
||||||
|
are waiting. This will be enabled by default in future!
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
@ -284,6 +284,9 @@ close_command_timeout(struct close_command *cc)
|
|||||||
/* This will trigger drop_to_chain, which will trigger
|
/* This will trigger drop_to_chain, which will trigger
|
||||||
* resolution of the command and destruction of the
|
* resolution of the command and destruction of the
|
||||||
* close_command. */
|
* close_command. */
|
||||||
|
if (!deprecated_apis)
|
||||||
|
json_notify_fmt(cc->cmd, LOG_INFORM,
|
||||||
|
"Timed out, forcing close.");
|
||||||
channel_fail_permanent(cc->channel,
|
channel_fail_permanent(cc->channel,
|
||||||
"Forcibly closed by 'close' command timeout");
|
"Forcibly closed by 'close' command timeout");
|
||||||
}
|
}
|
||||||
@ -306,6 +309,14 @@ register_close_command(struct lightningd *ld,
|
|||||||
tal_add_destructor2(channel,
|
tal_add_destructor2(channel,
|
||||||
&destroy_close_command_on_channel_destroy,
|
&destroy_close_command_on_channel_destroy,
|
||||||
cc);
|
cc);
|
||||||
|
|
||||||
|
if (!deprecated_apis && !channel->owner) {
|
||||||
|
char *msg = tal_strdup(tmpctx, "peer is offline, will negotiate once they reconnect");
|
||||||
|
if (timeout)
|
||||||
|
tal_append_fmt(&msg, " (%u seconds before unilateral close)",
|
||||||
|
timeout);
|
||||||
|
json_notify_fmt(cmd, LOG_INFORM, "%s.", msg);
|
||||||
|
}
|
||||||
log_debug(ld->log, "close_command: timeout = %u", timeout);
|
log_debug(ld->log, "close_command: timeout = %u", timeout);
|
||||||
if (timeout)
|
if (timeout)
|
||||||
new_reltimer(ld->timers, cc, time_from_sec(timeout),
|
new_reltimer(ld->timers, cc, time_from_sec(timeout),
|
||||||
|
@ -277,6 +277,12 @@ void json_array_start(struct json_stream *js UNNEEDED, const char *fieldname UNN
|
|||||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||||
|
/* Generated stub for json_notify_fmt */
|
||||||
|
void json_notify_fmt(struct command *cmd UNNEEDED,
|
||||||
|
enum log_level level UNNEEDED,
|
||||||
|
const char *fmt UNNEEDED, ...)
|
||||||
|
|
||||||
|
{ fprintf(stderr, "json_notify_fmt called!\n"); abort(); }
|
||||||
/* Generated stub for json_object_end */
|
/* Generated stub for json_object_end */
|
||||||
void json_object_end(struct json_stream *js UNNEEDED)
|
void json_object_end(struct json_stream *js UNNEEDED)
|
||||||
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
|
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
|
||||||
|
@ -4,13 +4,14 @@ from pyln.client import RpcError
|
|||||||
from shutil import copyfile
|
from shutil import copyfile
|
||||||
from utils import (
|
from utils import (
|
||||||
only_one, sync_blockheight, wait_for, DEVELOPER, TIMEOUT,
|
only_one, sync_blockheight, wait_for, DEVELOPER, TIMEOUT,
|
||||||
account_balance, first_channel_id, basic_fee
|
account_balance, first_channel_id, basic_fee, TEST_NETWORK,
|
||||||
)
|
)
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import queue
|
import queue
|
||||||
import pytest
|
import pytest
|
||||||
import re
|
import re
|
||||||
|
import subprocess
|
||||||
import threading
|
import threading
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
@ -126,6 +127,25 @@ def test_closing_while_disconnected(node_factory, bitcoind, executor):
|
|||||||
wait_for(lambda: len(l2.rpc.listchannels()['channels']) == 0)
|
wait_for(lambda: len(l2.rpc.listchannels()['channels']) == 0)
|
||||||
|
|
||||||
|
|
||||||
|
def test_closing_disconnected_notify(node_factory, bitcoind, executor):
|
||||||
|
l1, l2 = node_factory.line_graph(2)
|
||||||
|
|
||||||
|
l1.pay(l2, 200000000)
|
||||||
|
l2.stop()
|
||||||
|
wait_for(lambda: not only_one(l1.rpc.listpeers(l2.info['id'])['peers'])['connected'])
|
||||||
|
|
||||||
|
out = subprocess.check_output(['cli/lightning-cli',
|
||||||
|
'--network={}'.format(TEST_NETWORK),
|
||||||
|
'--lightning-dir={}'
|
||||||
|
.format(l1.daemon.lightning_dir),
|
||||||
|
'close',
|
||||||
|
l2.info['id'],
|
||||||
|
'5']).decode('utf-8').splitlines()
|
||||||
|
assert out[0] == '# peer is offline, will negotiate once they reconnect (5 seconds before unilateral close).'
|
||||||
|
assert out[1] == '# Timed out, forcing close.'
|
||||||
|
assert not any([line.startswith('#') for line in out[2:]])
|
||||||
|
|
||||||
|
|
||||||
def test_closing_id(node_factory):
|
def test_closing_id(node_factory):
|
||||||
"""Test closing using peer ID and full channel ID
|
"""Test closing using peer ID and full channel ID
|
||||||
"""
|
"""
|
||||||
|
2
wallet/db_postgres_sqlgen.c
generated
2
wallet/db_postgres_sqlgen.c
generated
@ -1660,4 +1660,4 @@ struct db_query db_postgres_queries[] = {
|
|||||||
|
|
||||||
#endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */
|
#endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */
|
||||||
|
|
||||||
// SHA256STAMP:17fb4d8f180303fb57e28b5b5ac5a9a326826297933461030e9c4f85e02723f9
|
// SHA256STAMP:8a260050ced7606fcad6e15df51a42a442f3119ad82d8e86fa2d348a2a45ee1a
|
||||||
|
2
wallet/db_sqlite3_sqlgen.c
generated
2
wallet/db_sqlite3_sqlgen.c
generated
@ -1660,4 +1660,4 @@ struct db_query db_sqlite3_queries[] = {
|
|||||||
|
|
||||||
#endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */
|
#endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */
|
||||||
|
|
||||||
// SHA256STAMP:17fb4d8f180303fb57e28b5b5ac5a9a326826297933461030e9c4f85e02723f9
|
// SHA256STAMP:8a260050ced7606fcad6e15df51a42a442f3119ad82d8e86fa2d348a2a45ee1a
|
||||||
|
4
wallet/statements_gettextgen.po
generated
4
wallet/statements_gettextgen.po
generated
@ -1090,7 +1090,7 @@ msgstr ""
|
|||||||
msgid "not a valid SQL statement"
|
msgid "not a valid SQL statement"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: wallet/test/run-wallet.c:1359
|
#: wallet/test/run-wallet.c:1365
|
||||||
msgid "INSERT INTO channels (id) VALUES (1);"
|
msgid "INSERT INTO channels (id) VALUES (1);"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
# SHA256STAMP:13b6fd428b7832d7122e64b76c7833788472fdaacf521ef9cb2d0890f65b8db8
|
# SHA256STAMP:9d0158f039940ef277ed6fc3a27b3695dec7f9869ea11e0f9eea8313a5849f08
|
||||||
|
@ -347,6 +347,12 @@ void json_array_start(struct json_stream *js UNNEEDED, const char *fieldname UNN
|
|||||||
const jsmntok_t *json_get_member(const char *buffer UNNEEDED, const jsmntok_t tok[] UNNEEDED,
|
const jsmntok_t *json_get_member(const char *buffer UNNEEDED, const jsmntok_t tok[] UNNEEDED,
|
||||||
const char *label UNNEEDED)
|
const char *label UNNEEDED)
|
||||||
{ fprintf(stderr, "json_get_member called!\n"); abort(); }
|
{ fprintf(stderr, "json_get_member called!\n"); abort(); }
|
||||||
|
/* Generated stub for json_notify_fmt */
|
||||||
|
void json_notify_fmt(struct command *cmd UNNEEDED,
|
||||||
|
enum log_level level UNNEEDED,
|
||||||
|
const char *fmt UNNEEDED, ...)
|
||||||
|
|
||||||
|
{ fprintf(stderr, "json_notify_fmt called!\n"); abort(); }
|
||||||
/* Generated stub for json_object_end */
|
/* Generated stub for json_object_end */
|
||||||
void json_object_end(struct json_stream *js UNNEEDED)
|
void json_object_end(struct json_stream *js UNNEEDED)
|
||||||
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
|
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
|
||||||
|
Loading…
Reference in New Issue
Block a user