mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
lightningd: add dev-fail command to inject permenant failure.
A couple of double-free bugs founnd doing this, too. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
524e56cf56
commit
8e0c19c76a
@ -59,6 +59,8 @@ static void reconnect_failed(struct lightningd_state *dstate,
|
||||
struct lightningd *ld = ld_from_dstate(dstate);
|
||||
struct peer *peer = peer_by_id(ld, connection_known_id(c));
|
||||
|
||||
log_debug(peer->log, "reconnect_failed");
|
||||
|
||||
tal_free(c);
|
||||
peer_reconnect(peer);
|
||||
}
|
||||
@ -68,6 +70,8 @@ static void try_reconnect(struct peer *peer)
|
||||
struct connection *c;
|
||||
struct netaddr *addrs;
|
||||
|
||||
log_debug(peer->log, "try_reconnect: trying to reconnect");
|
||||
|
||||
/* We may already be reconnected (another incoming connection) */
|
||||
if (peer->owner) {
|
||||
log_debug(peer->log, "try_reconnect: already reconnected (%s)",
|
||||
@ -109,7 +113,7 @@ void peer_fail_permanent(struct peer *peer, const u8 *msg)
|
||||
peer_state_name(peer->state),
|
||||
(int)tal_len(msg), (char *)msg);
|
||||
peer->error = towire_error(peer, &all_channels, msg);
|
||||
peer->owner = NULL;
|
||||
peer->owner = tal_free(peer->owner);
|
||||
if (taken(msg))
|
||||
tal_free(msg);
|
||||
|
||||
@ -202,6 +206,7 @@ static void peer_start_closingd(struct peer *peer,
|
||||
static struct io_plan *send_error(struct io_conn *conn,
|
||||
struct peer_crypto_state *pcs)
|
||||
{
|
||||
log_debug(pcs->peer->log, "Sending canned error");
|
||||
return peer_write_message(conn, pcs, pcs->peer->error, (void *)io_close_cb);
|
||||
}
|
||||
|
||||
@ -720,6 +725,38 @@ static const struct json_command connect_command = {
|
||||
};
|
||||
AUTODATA(json_command, &connect_command);
|
||||
|
||||
static void json_dev_fail(struct command *cmd,
|
||||
const char *buffer, const jsmntok_t *params)
|
||||
{
|
||||
struct lightningd *ld = ld_from_dstate(cmd->dstate);
|
||||
jsmntok_t *peertok;
|
||||
struct peer *peer;
|
||||
|
||||
if (!json_get_params(buffer, params,
|
||||
"id", &peertok,
|
||||
NULL)) {
|
||||
command_fail(cmd, "Need id");
|
||||
return;
|
||||
}
|
||||
|
||||
peer = peer_from_json(ld, buffer, peertok);
|
||||
if (!peer) {
|
||||
command_fail(cmd, "Could not find peer with that id");
|
||||
return;
|
||||
}
|
||||
|
||||
peer_internal_error(peer, "Failing due to dev-fail command");
|
||||
command_success(cmd, null_response(cmd));
|
||||
}
|
||||
|
||||
static const struct json_command dev_fail_command = {
|
||||
"dev-fail",
|
||||
json_dev_fail,
|
||||
"Fail with peer {id}",
|
||||
"Returns {} on success"
|
||||
};
|
||||
AUTODATA(json_command, &dev_fail_command);
|
||||
|
||||
struct log_info {
|
||||
enum log_level level;
|
||||
struct json_result *response;
|
||||
|
@ -371,6 +371,11 @@ static void destroy_subd(struct subd *sd)
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* In case we're freed manually, such as peer_fail_permanent */
|
||||
if (sd->conn)
|
||||
sd->conn = tal_free(sd->conn);
|
||||
|
||||
log_debug(sd->log, "finishing: %p", sd->finished);
|
||||
if (sd->finished)
|
||||
sd->finished(sd, status);
|
||||
|
@ -336,6 +336,20 @@ class LightningDTests(BaseLightningDTests):
|
||||
l2.daemon.wait_for_log('sendrawtx exit 0')
|
||||
assert l1.bitcoin.rpc.getmempoolinfo()['size'] == 1
|
||||
|
||||
def test_permfail(self):
|
||||
l1,l2 = self.connect()
|
||||
|
||||
self.fund_channel(l1, l2, 10**6)
|
||||
self.pay(l1,l2,200000000)
|
||||
|
||||
# We fail l2, so l1 will reconnect to it.
|
||||
l2.rpc.dev_fail(l1.info['id']);
|
||||
l2.daemon.wait_for_log('Failing due to dev-fail command')
|
||||
l2.daemon.wait_for_log('sendrawtx exit 0')
|
||||
|
||||
# "Internal error" in hex
|
||||
l1.daemon.wait_for_log('WIRE_ERROR.*496e7465726e616c206572726f72')
|
||||
|
||||
def test_gossip_jsonrpc(self):
|
||||
l1,l2 = self.connect()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user