From 76cb195ea19f9142fd1d753e8dd70279a5a47392 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 2 May 2016 16:04:56 +0930 Subject: [PATCH] daemon: dev-disconnect command. This lets one end experience a disconnect without the other noticing. Good for testing. Signed-off-by: Rusty Russell --- daemon/jsonrpc.c | 3 ++- daemon/jsonrpc.h | 1 + daemon/peer.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++-- daemon/peer.h | 3 +++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/daemon/jsonrpc.c b/daemon/jsonrpc.c index b4ff96545..387725b0b 100644 --- a/daemon/jsonrpc.c +++ b/daemon/jsonrpc.c @@ -259,7 +259,8 @@ static const struct json_command *cmdlist[] = { &echo_command, &rhash_command, &mocktime_command, - &crash_command + &crash_command, + &disconnect_command, }; static void json_help(struct command *cmd, diff --git a/daemon/jsonrpc.h b/daemon/jsonrpc.h index 84a73d923..b445bfc3c 100644 --- a/daemon/jsonrpc.h +++ b/daemon/jsonrpc.h @@ -65,4 +65,5 @@ extern const struct json_command commit_command; extern const struct json_command mocktime_command; extern const struct json_command close_command; extern const struct json_command newaddr_command; +extern const struct json_command disconnect_command; #endif /* LIGHTNING_DAEMON_JSONRPC_H */ diff --git a/daemon/peer.c b/daemon/peer.c index d8a10f4ab..8dde400b3 100644 --- a/daemon/peer.c +++ b/daemon/peer.c @@ -262,7 +262,7 @@ static struct io_plan *pkt_out(struct io_conn *conn, struct peer *peer) if (n == 0) { /* We close the connection once we've sent everything. */ - if (peer->cond == PEER_CLOSED) + if (!peer->fake_close && peer->cond == PEER_CLOSED) return io_close(conn); return io_out_wait(conn, peer, pkt_out, peer); } @@ -282,7 +282,7 @@ static struct io_plan *pkt_in(struct io_conn *conn, struct peer *peer) idata.pkt = tal_steal(ctx, peer->inpkt); /* We ignore packets if they tell us to. */ - if (peer->cond != PEER_CLOSED) { + if (!peer->fake_close && peer->cond != PEER_CLOSED) { /* These two packets contain acknowledgements. */ if (idata.pkt->pkt_case == PKT__PKT_UPDATE_COMMIT) peer_process_acks(peer, @@ -409,6 +409,7 @@ static struct peer *new_peer(struct lightningd_state *dstate, /* If we free peer, conn should be closed, but can't be freed * immediately so don't make peer a parent. */ peer->conn = conn; + peer->fake_close = false; io_set_finish(conn, peer_disconnect, peer); peer->us.offer_anchor = offer_anchor; @@ -1875,3 +1876,47 @@ const struct json_command close_command = { "Close the channel with peer {peerid}", "Returns an empty result on success" }; + +static void json_disconnect(struct command *cmd, + const char *buffer, const jsmntok_t *params) +{ + struct peer *peer; + jsmntok_t *peeridtok; + const struct bitcoin_tx *broadcast; + + if (!json_get_params(buffer, params, + "peerid", &peeridtok, + NULL)) { + command_fail(cmd, "Need peerid"); + return; + } + + peer = find_peer(cmd->dstate, buffer, peeridtok); + if (!peer) { + command_fail(cmd, "Could not find peer with that peerid"); + return; + } + + if (!peer->conn) { + command_fail(cmd, "Peer is already disconnected"); + return; + } + + /* We don't actually close it, since for testing we want only + * one side to freak out. We just ensure we ignore it. */ + log_debug(peer->log, "Pretending connection is closed"); + peer->fake_close = true; + state(peer, INPUT_CONNECTION_LOST, NULL, &broadcast); + + if (broadcast) + bitcoind_send_tx(peer->dstate, broadcast); + + command_success(cmd, null_response(cmd)); +} + +const struct json_command disconnect_command = { + "dev-disconnect", + json_disconnect, + "Force a disconned with peer {peerid}", + "Returns an empty result on success" +}; diff --git a/daemon/peer.h b/daemon/peer.h index 55a99cb3b..0eb10db25 100644 --- a/daemon/peer.h +++ b/daemon/peer.h @@ -192,6 +192,9 @@ struct peer { /* Private keys for dealing with this peer. */ struct peer_secrets *secrets; + /* For testing. */ + bool fake_close; + /* Stuff we have in common. */ struct peer_visible_state us, them; };