close: change to a unilateraltimeout argument.

`close` takes two optional arguments: `force` and `timeout`.
`timeout` doesn't timeout the close (there's no way to do that), just
the JSON call.  `force` (default `false`) if set, means we unilaterally
close at the timeout, instead of just failing.

Timing out JSON calls is generally deprecated: that's the job of the
client.  And the semantics of this are confusing, even to me!  A
better API is a timeout which, if non-zero, is the time at which we
give up and unilaterally close.

The transition code is awkward, but we'll manage for the three
releases until we can remove it.

The new defaults are to unilaterally close after 48 hours.

Fixes: #2791
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2019-08-08 16:16:05 +09:30
parent b35dc4689b
commit 83e654a106
6 changed files with 157 additions and 48 deletions

View File

@@ -3,6 +3,7 @@ import json
import logging
from math import floor, log10
import socket
import warnings
__version__ = "0.0.7.3"
@@ -309,12 +310,10 @@ class LightningRpc(UnixDomainSocketRpc):
payload.update({k: v for k, v in kwargs.items()})
return self.call("check", payload)
def close(self, peer_id, force=None, timeout=None):
"""
Close the channel with peer {id}, forcing a unilateral
close if {force} is True, and timing out with {timeout}
seconds.
"""
def _deprecated_close(self, peer_id, force=None, timeout=None):
warnings.warn("close now takes unilateraltimeout arg: expect removal"
" in early 2020",
DeprecationWarning)
payload = {
"id": peer_id,
"force": force,
@@ -322,6 +321,35 @@ class LightningRpc(UnixDomainSocketRpc):
}
return self.call("close", payload)
def close(self, peer_id, *args, **kwargs):
"""
Close the channel with peer {id}, forcing a unilateral
close after {unilateraltimeout} seconds if non-zero.
Deprecated usage has {force} and {timeout} args.
"""
unilateraltimeout = None
if 'force' in kwargs or 'timeout' in kwargs:
return self._deprecated_close(peer_id, *args, **kwargs)
# Single arg is ambigious.
if len(args) == 1:
if isinstance(args[0], bool):
return self._deprecated_close(peer_id, *args, **kwargs)
unilateraltimeout = args[0]
elif len(args) > 1:
return self._deprecated_close(peer_id, *args, **kwargs)
if 'unilateraltimeout' in kwargs:
unilateraltimeout = kwargs['unilateraltimeout']
payload = {
"id": peer_id,
"unilateraltimeout": unilateraltimeout
}
return self.call("close", payload)
def connect(self, peer_id, host=None, port=None):
"""
Connect to {peer_id} at {host} and {port}