Browse Source

peer_control: Have `close` accept channel IDs also.

ppa-0.6.1
ZmnSCPxj 7 years ago
committed by Christian Decker
parent
commit
e588737511
  1. 6
      doc/lightning-close.7
  2. 8
      doc/lightning-close.7.txt
  3. 9
      lightningd/json.c
  4. 4
      lightningd/json.h
  5. 80
      lightningd/peer_control.c
  6. 4
      wallet/test/run-wallet.c

6
doc/lightning-close.7

@ -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

8
doc/lightning-close.7.txt

@ -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.

9
lightningd/json.c

@ -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)
{

4
lightningd/json.h

@ -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);

80
lightningd/peer_control.c

@ -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);

4
wallet/test/run-wallet.c

@ -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)

Loading…
Cancel
Save