mirror of
https://github.com/aljazceru/lightning.git
synced 2026-01-07 16:14:26 +01:00
peer_control: Have close accept channel IDs also.
This commit is contained in:
committed by
Christian Decker
parent
7767b68ee9
commit
e588737511
@@ -2,12 +2,12 @@
|
||||
.\" Title: lightning-close
|
||||
.\" Author: [see the "AUTHOR" section]
|
||||
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
|
||||
.\" Date: 04/15/2018
|
||||
.\" Date: 04/30/2018
|
||||
.\" Manual: \ \&
|
||||
.\" Source: \ \&
|
||||
.\" Language: English
|
||||
.\"
|
||||
.TH "LIGHTNING\-CLOSE" "7" "04/15/2018" "\ \&" "\ \&"
|
||||
.TH "LIGHTNING\-CLOSE" "7" "04/30/2018" "\ \&" "\ \&"
|
||||
.\" -----------------------------------------------------------------
|
||||
.\" * Define some portability stuff
|
||||
.\" -----------------------------------------------------------------
|
||||
@@ -34,7 +34,7 @@ lightning-close \- Command for closing channels with direct peers
|
||||
\fBclose\fR \fIid\fR [\fIforce\fR] [\fItimeout\fR]
|
||||
.SH "DESCRIPTION"
|
||||
.sp
|
||||
The \fBclose\fR RPC command attempts to close the channel cooperatively with the peer\&. It applies to the active channel of the direct peer corresponding to the given peer \fIid\fR\&.
|
||||
The \fBclose\fR RPC command attempts to close the channel cooperatively with the peer\&. If the given \fIid\fR is a peer ID (66 hex digits as a string), then it applies to the active channel of the direct peer corresponding to the given peer ID\&. If the given \fIid\fR is a channel ID (64 hex digits as a string, or the short channel ID \fIblockheight:txindex:outindex\fR form), then it applies to that channel\&.
|
||||
.sp
|
||||
The \fBclose\fR command will time out and return with an error when the number of seconds specified in \fItimeout\fR is reached\&. If unspecified, it times out in 30 seconds\&.
|
||||
.sp
|
||||
|
||||
@@ -15,8 +15,12 @@ DESCRIPTION
|
||||
|
||||
The *close* RPC command attempts to close the channel cooperatively
|
||||
with the peer.
|
||||
It applies to the active channel of the direct peer corresponding to
|
||||
the given peer 'id'.
|
||||
If the given 'id' is a peer ID (66 hex digits as a string), then
|
||||
it applies to the active channel of the direct peer corresponding to
|
||||
the given peer ID.
|
||||
If the given 'id' is a channel ID (64 hex digits as a string, or
|
||||
the short channel ID 'blockheight:txindex:outindex' form), then it
|
||||
applies to that channel.
|
||||
|
||||
The *close* command will time out and return with an error when the
|
||||
number of seconds specified in 'timeout' is reached.
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <lightningd/options.h>
|
||||
#include <sys/socket.h>
|
||||
#include <wallet/wallet.h>
|
||||
#include <wire/wire.h>
|
||||
|
||||
/* Output a route hop */
|
||||
static void
|
||||
@@ -110,6 +111,14 @@ bool json_tok_short_channel_id(const char *buffer, const jsmntok_t *tok,
|
||||
scid);
|
||||
}
|
||||
|
||||
bool
|
||||
json_tok_channel_id(const char *buffer, const jsmntok_t *tok,
|
||||
struct channel_id *cid)
|
||||
{
|
||||
return hex_decode(buffer + tok->start, tok->end - tok->start,
|
||||
cid, sizeof(*cid));
|
||||
}
|
||||
|
||||
void json_add_address(struct json_result *response, const char *fieldname,
|
||||
const struct wireaddr *addr)
|
||||
{
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
# include <external/jsmn/jsmn.h>
|
||||
|
||||
struct bitcoin_txid;
|
||||
struct channel_id;
|
||||
struct json_result;
|
||||
struct pubkey;
|
||||
struct route_hop;
|
||||
@@ -50,6 +51,9 @@ void json_add_short_channel_id(struct json_result *response,
|
||||
const char *fieldname,
|
||||
const struct short_channel_id *id);
|
||||
|
||||
bool json_tok_channel_id(const char *buffer, const jsmntok_t *tok,
|
||||
struct channel_id *cid);
|
||||
|
||||
/* JSON serialize a network address for a node */
|
||||
void json_add_address(struct json_result *response, const char *fieldname,
|
||||
const struct wireaddr *addr);
|
||||
|
||||
@@ -985,10 +985,60 @@ static const struct json_command listpeers_command = {
|
||||
};
|
||||
AUTODATA(json_command, &listpeers_command);
|
||||
|
||||
static struct channel *
|
||||
command_find_channel(struct command *cmd,
|
||||
const char *buffer, const jsmntok_t *tok)
|
||||
{
|
||||
struct lightningd *ld = cmd->ld;
|
||||
struct channel_id cid;
|
||||
struct channel_id channel_cid;
|
||||
struct short_channel_id scid;
|
||||
struct peer *peer;
|
||||
struct channel *channel;
|
||||
|
||||
if (json_tok_channel_id(buffer, tok, &cid)) {
|
||||
list_for_each(&ld->peers, peer, list) {
|
||||
channel = peer_active_channel(peer);
|
||||
if (!channel)
|
||||
continue;
|
||||
derive_channel_id(&channel_cid,
|
||||
&channel->funding_txid,
|
||||
channel->funding_outnum);
|
||||
if (structeq(&channel_cid, &cid))
|
||||
return channel;
|
||||
}
|
||||
command_fail(cmd,
|
||||
"Channel ID not found: '%.*s'",
|
||||
tok->end - tok->start,
|
||||
buffer + tok->start);
|
||||
return NULL;
|
||||
} else if (json_tok_short_channel_id(buffer, tok, &scid)) {
|
||||
list_for_each(&ld->peers, peer, list) {
|
||||
channel = peer_active_channel(peer);
|
||||
if (!channel)
|
||||
continue;
|
||||
if (channel->scid && channel->scid->u64 == scid.u64)
|
||||
return channel;
|
||||
}
|
||||
command_fail(cmd,
|
||||
"Short channel ID not found: '%.*s'",
|
||||
tok->end - tok->start,
|
||||
buffer + tok->start);
|
||||
return NULL;
|
||||
} else {
|
||||
command_fail(cmd,
|
||||
"Given id is not a channel ID or "
|
||||
"short channel ID: '%.*s'",
|
||||
tok->end - tok->start,
|
||||
buffer + tok->start);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void json_close(struct command *cmd,
|
||||
const char *buffer, const jsmntok_t *params)
|
||||
{
|
||||
jsmntok_t *peertok;
|
||||
jsmntok_t *idtok;
|
||||
jsmntok_t *timeouttok;
|
||||
jsmntok_t *forcetok;
|
||||
struct peer *peer;
|
||||
@@ -997,18 +1047,13 @@ static void json_close(struct command *cmd,
|
||||
bool force = false;
|
||||
|
||||
if (!json_get_params(cmd, buffer, params,
|
||||
"id", &peertok,
|
||||
"id", &idtok,
|
||||
"?force", &forcetok,
|
||||
"?timeout", &timeouttok,
|
||||
NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
peer = peer_from_json(cmd->ld, buffer, peertok);
|
||||
if (!peer) {
|
||||
command_fail(cmd, "Could not find peer with that id");
|
||||
return;
|
||||
}
|
||||
if (forcetok && !json_tok_bool(buffer, forcetok, &force)) {
|
||||
command_fail(cmd, "Force '%.*s' must be true or false",
|
||||
forcetok->end - forcetok->start,
|
||||
@@ -1022,8 +1067,16 @@ static void json_close(struct command *cmd,
|
||||
return;
|
||||
}
|
||||
|
||||
channel = peer_active_channel(peer);
|
||||
if (!channel) {
|
||||
peer = peer_from_json(cmd->ld, buffer, idtok);
|
||||
if (peer)
|
||||
channel = peer_active_channel(peer);
|
||||
else {
|
||||
channel = command_find_channel(cmd, buffer, idtok);
|
||||
if (!channel)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!channel && peer) {
|
||||
struct uncommitted_channel *uc = peer->uncommitted_channel;
|
||||
if (uc) {
|
||||
/* Easy case: peer can simply be forgotten. */
|
||||
@@ -1045,7 +1098,7 @@ static void json_close(struct command *cmd,
|
||||
channel->state != CHANNELD_AWAITING_LOCKIN &&
|
||||
channel->state != CHANNELD_SHUTTING_DOWN &&
|
||||
channel->state != CLOSINGD_SIGEXCHANGE)
|
||||
command_fail(cmd, "Peer is in state %s",
|
||||
command_fail(cmd, "Channel is in state %s",
|
||||
channel_state_name(channel));
|
||||
|
||||
/* If normal or locking in, transition to shutting down
|
||||
@@ -1071,7 +1124,12 @@ static void json_close(struct command *cmd,
|
||||
static const struct json_command close_command = {
|
||||
"close",
|
||||
json_close,
|
||||
"Close the channel with peer {id}"
|
||||
"Close the channel with {id} "
|
||||
"(either peer ID, channel ID, or short channel ID). "
|
||||
"If {force} (default false) is true, force a unilateral close "
|
||||
"after {timeout} seconds (default 30), "
|
||||
"otherwise just schedule a mutual close later and fail after "
|
||||
"timing out."
|
||||
};
|
||||
AUTODATA(json_command, &close_command);
|
||||
|
||||
|
||||
@@ -257,6 +257,10 @@ void json_object_start(struct json_result *ptr UNNEEDED, const char *fieldname U
|
||||
/* Generated stub for json_tok_bool */
|
||||
bool json_tok_bool(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, bool *b UNNEEDED)
|
||||
{ fprintf(stderr, "json_tok_bool called!\n"); abort(); }
|
||||
/* Generated stub for json_tok_channel_id */
|
||||
bool json_tok_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct channel_id *cid UNNEEDED)
|
||||
{ fprintf(stderr, "json_tok_channel_id called!\n"); abort(); }
|
||||
/* Generated stub for json_tok_loglevel */
|
||||
bool json_tok_loglevel(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
enum log_level *level UNNEEDED)
|
||||
|
||||
Reference in New Issue
Block a user