mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-01 09:40:19 +01:00
openingd: tell lightningd if we get a reestablish.
It simply uses connectd to send an error if it doesn't know anything about the channel. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
9929d6383a
commit
44829d1361
8 changed files with 147 additions and 18 deletions
|
@ -1,8 +1,10 @@
|
|||
#include <ccan/ccan/tal/str/str.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/jsonrpc_errors.h>
|
||||
#include <common/wire_error.h>
|
||||
#include <connectd/connectd_wiregen.h>
|
||||
#include <lightningd/channel.h>
|
||||
#include <lightningd/channel_control.h>
|
||||
#include <lightningd/log.h>
|
||||
#include <lightningd/notification.h>
|
||||
#include <lightningd/opening_common.h>
|
||||
|
@ -151,6 +153,46 @@ void channel_config(struct lightningd *ld,
|
|||
ours->channel_reserve = AMOUNT_SAT(UINT64_MAX);
|
||||
}
|
||||
|
||||
void handle_reestablish(struct lightningd *ld,
|
||||
const struct node_id *peer_id,
|
||||
const struct channel_id *channel_id,
|
||||
const u8 *reestablish,
|
||||
struct per_peer_state *pps)
|
||||
{
|
||||
struct peer *peer;
|
||||
struct channel *c;
|
||||
|
||||
/* We very carefully re-xmit the last reestablish, so they can get
|
||||
* their secrets back. We don't otherwise touch them. */
|
||||
peer = peer_by_id(ld, peer_id);
|
||||
if (peer)
|
||||
c = find_channel_by_id(peer, channel_id);
|
||||
else
|
||||
c = NULL;
|
||||
|
||||
if (c && channel_closed(c)) {
|
||||
log_debug(c->log, "Reestablish on %s channel: using channeld to reply",
|
||||
channel_state_name(c));
|
||||
peer_start_channeld(c, pps, NULL, true, reestablish);
|
||||
} else {
|
||||
const u8 *err = towire_errorfmt(tmpctx, channel_id,
|
||||
"Unknown channel for reestablish");
|
||||
log_debug(ld->log, "Reestablish on UNKNOWN channel %s",
|
||||
type_to_string(tmpctx, struct channel_id, channel_id));
|
||||
subd_send_msg(ld->connectd,
|
||||
take(towire_connectd_peer_final_msg(NULL, peer_id,
|
||||
pps, err)));
|
||||
subd_send_fd(ld->connectd, pps->peer_fd);
|
||||
subd_send_fd(ld->connectd, pps->gossip_fd);
|
||||
subd_send_fd(ld->connectd, pps->gossip_store_fd);
|
||||
/* Don't close those fds! */
|
||||
pps->peer_fd
|
||||
= pps->gossip_fd
|
||||
= pps->gossip_store_fd
|
||||
= -1;
|
||||
}
|
||||
}
|
||||
|
||||
#if DEVELOPER
|
||||
/* Indented to avoid include ordering check */
|
||||
#include <lightningd/memdump.h>
|
||||
|
|
|
@ -118,6 +118,12 @@ void channel_config(struct lightningd *ld,
|
|||
u32 *max_to_self_delay,
|
||||
struct amount_msat *min_effective_htlc_capacity);
|
||||
|
||||
void handle_reestablish(struct lightningd *ld,
|
||||
const struct node_id *peer_id,
|
||||
const struct channel_id *channel_id,
|
||||
const u8 *reestablish,
|
||||
struct per_peer_state *pps);
|
||||
|
||||
#if DEVELOPER
|
||||
struct command;
|
||||
/* Calls report_leak_info() async. */
|
||||
|
|
|
@ -801,6 +801,31 @@ static void opening_got_offer(struct subd *openingd,
|
|||
plugin_hook_call_openchannel(openingd->ld, payload);
|
||||
}
|
||||
|
||||
static void opening_got_reestablish(struct subd *openingd, const u8 *msg,
|
||||
const int fds[3],
|
||||
struct uncommitted_channel *uc)
|
||||
{
|
||||
struct lightningd *ld = openingd->ld;
|
||||
struct node_id peer_id = uc->peer->id;
|
||||
struct channel_id channel_id;
|
||||
u8 *reestablish;
|
||||
struct per_peer_state *pps;
|
||||
|
||||
if (!fromwire_openingd_got_reestablish(tmpctx, msg, &channel_id,
|
||||
&reestablish, &pps)) {
|
||||
log_broken(openingd->log, "Malformed opening_got_reestablish %s",
|
||||
tal_hex(tmpctx, msg));
|
||||
tal_free(openingd);
|
||||
return;
|
||||
}
|
||||
per_peer_state_set_fds_arr(pps, fds);
|
||||
|
||||
/* This could free peer */
|
||||
tal_free(uc);
|
||||
|
||||
handle_reestablish(ld, &peer_id, &channel_id, reestablish, pps);
|
||||
}
|
||||
|
||||
static unsigned int openingd_msg(struct subd *openingd,
|
||||
const u8 *msg, const int *fds)
|
||||
{
|
||||
|
@ -848,6 +873,12 @@ static unsigned int openingd_msg(struct subd *openingd,
|
|||
opening_got_offer(openingd, msg, uc);
|
||||
return 0;
|
||||
|
||||
case WIRE_OPENINGD_GOT_REESTABLISH:
|
||||
if (tal_count(fds) != 3)
|
||||
return 3;
|
||||
opening_got_reestablish(openingd, msg, fds, uc);
|
||||
return 0;
|
||||
|
||||
/* We send these! */
|
||||
case WIRE_OPENINGD_INIT:
|
||||
case WIRE_OPENINGD_FUNDER_START:
|
||||
|
|
|
@ -1149,6 +1149,7 @@ static u8 *handle_peer_in(struct state *state)
|
|||
u8 *msg = sync_crypto_read(tmpctx, state->pps);
|
||||
enum peer_wire t = fromwire_peektype(msg);
|
||||
struct channel_id channel_id;
|
||||
bool extracted;
|
||||
|
||||
if (t == WIRE_OPEN_CHANNEL)
|
||||
return fundee_channel(state, msg);
|
||||
|
@ -1170,21 +1171,20 @@ static u8 *handle_peer_in(struct state *state)
|
|||
&state->channel_id, false, msg))
|
||||
return NULL;
|
||||
|
||||
if (extract_channel_id(msg, &channel_id)) {
|
||||
sync_crypto_write(state->pps,
|
||||
take(towire_errorfmt(NULL,
|
||||
&channel_id,
|
||||
"Unexpected message %s: %s",
|
||||
peer_wire_name(t),
|
||||
tal_hex(tmpctx, msg))));
|
||||
} else {
|
||||
extracted = extract_channel_id(msg, &channel_id);
|
||||
|
||||
/* Reestablish on some now-closed channel? Be nice. */
|
||||
if (extracted && fromwire_peektype(msg) == WIRE_CHANNEL_REESTABLISH) {
|
||||
return towire_openingd_got_reestablish(NULL,
|
||||
&channel_id, msg,
|
||||
state->pps);
|
||||
}
|
||||
sync_crypto_write(state->pps,
|
||||
take(towire_warningfmt(NULL,
|
||||
NULL,
|
||||
extracted ? &channel_id : NULL,
|
||||
"Unexpected message %s: %s",
|
||||
peer_wire_name(t),
|
||||
tal_hex(tmpctx, msg))));
|
||||
}
|
||||
|
||||
/* FIXME: We don't actually want master to try to send an
|
||||
* error, since peer is transient. This is a hack.
|
||||
|
@ -1296,6 +1296,7 @@ static u8 *handle_master_in(struct state *state)
|
|||
case WIRE_OPENINGD_FUNDER_FAILED:
|
||||
case WIRE_OPENINGD_GOT_OFFER:
|
||||
case WIRE_OPENINGD_GOT_OFFER_REPLY:
|
||||
case WIRE_OPENINGD_GOT_REESTABLISH:
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,13 @@ msgdata,openingd_init,option_anchor_outputs,bool,
|
|||
msgdata,openingd_init,dev_temporary_channel_id,?byte,32
|
||||
msgdata,openingd_init,dev_fast_gossip,bool,
|
||||
|
||||
# Openingd->master: they tried to reestablish a channel.
|
||||
msgtype,openingd_got_reestablish,6001
|
||||
msgdata,openingd_got_reestablish,channel_id,channel_id,
|
||||
msgdata,openingd_got_reestablish,len,u16,
|
||||
msgdata,openingd_got_reestablish,msg,u8,len
|
||||
msgdata,openingd_got_reestablish,pps,per_peer_state,
|
||||
|
||||
# Openingd->master: they offered channel, should we continue?
|
||||
msgtype,openingd_got_offer,6005
|
||||
msgdata,openingd_got_offer,funding_satoshis,amount_sat,
|
||||
|
|
|
37
openingd/openingd_wiregen.c
generated
37
openingd/openingd_wiregen.c
generated
|
@ -21,6 +21,7 @@ const char *openingd_wire_name(int e)
|
|||
|
||||
switch ((enum openingd_wire)e) {
|
||||
case WIRE_OPENINGD_INIT: return "WIRE_OPENINGD_INIT";
|
||||
case WIRE_OPENINGD_GOT_REESTABLISH: return "WIRE_OPENINGD_GOT_REESTABLISH";
|
||||
case WIRE_OPENINGD_GOT_OFFER: return "WIRE_OPENINGD_GOT_OFFER";
|
||||
case WIRE_OPENINGD_GOT_OFFER_REPLY: return "WIRE_OPENINGD_GOT_OFFER_REPLY";
|
||||
case WIRE_OPENINGD_FUNDER_REPLY: return "WIRE_OPENINGD_FUNDER_REPLY";
|
||||
|
@ -42,6 +43,7 @@ bool openingd_wire_is_defined(u16 type)
|
|||
{
|
||||
switch ((enum openingd_wire)type) {
|
||||
case WIRE_OPENINGD_INIT:;
|
||||
case WIRE_OPENINGD_GOT_REESTABLISH:;
|
||||
case WIRE_OPENINGD_GOT_OFFER:;
|
||||
case WIRE_OPENINGD_GOT_OFFER_REPLY:;
|
||||
case WIRE_OPENINGD_FUNDER_REPLY:;
|
||||
|
@ -138,6 +140,39 @@ bool fromwire_openingd_init(const tal_t *ctx, const void *p, const struct chainp
|
|||
return cursor != NULL;
|
||||
}
|
||||
|
||||
/* WIRE: OPENINGD_GOT_REESTABLISH */
|
||||
/* Openingd->master: they tried to reestablish a channel. */
|
||||
u8 *towire_openingd_got_reestablish(const tal_t *ctx, const struct channel_id *channel_id, const u8 *msg, const struct per_peer_state *pps)
|
||||
{
|
||||
u16 len = tal_count(msg);
|
||||
u8 *p = tal_arr(ctx, u8, 0);
|
||||
|
||||
towire_u16(&p, WIRE_OPENINGD_GOT_REESTABLISH);
|
||||
towire_channel_id(&p, channel_id);
|
||||
towire_u16(&p, len);
|
||||
towire_u8_array(&p, msg, len);
|
||||
towire_per_peer_state(&p, pps);
|
||||
|
||||
return memcheck(p, tal_count(p));
|
||||
}
|
||||
bool fromwire_openingd_got_reestablish(const tal_t *ctx, const void *p, struct channel_id *channel_id, u8 **msg, struct per_peer_state **pps)
|
||||
{
|
||||
u16 len;
|
||||
|
||||
const u8 *cursor = p;
|
||||
size_t plen = tal_count(p);
|
||||
|
||||
if (fromwire_u16(&cursor, &plen) != WIRE_OPENINGD_GOT_REESTABLISH)
|
||||
return false;
|
||||
fromwire_channel_id(&cursor, &plen, channel_id);
|
||||
len = fromwire_u16(&cursor, &plen);
|
||||
// 2nd case msg
|
||||
*msg = len ? tal_arr(ctx, u8, len) : NULL;
|
||||
fromwire_u8_array(&cursor, &plen, *msg, len);
|
||||
*pps = fromwire_per_peer_state(ctx, &cursor, &plen);
|
||||
return cursor != NULL;
|
||||
}
|
||||
|
||||
/* WIRE: OPENINGD_GOT_OFFER */
|
||||
/* Openingd->master: they offered channel */
|
||||
u8 *towire_openingd_got_offer(const tal_t *ctx, struct amount_sat funding_satoshis, struct amount_msat push_msat, struct amount_sat dust_limit_satoshis, struct amount_msat max_htlc_value_in_flight_msat, struct amount_sat channel_reserve_satoshis, struct amount_msat htlc_minimum_msat, u32 feerate_per_kw, u16 to_self_delay, u16 max_accepted_htlcs, u8 channel_flags, const u8 *shutdown_scriptpubkey)
|
||||
|
@ -569,4 +604,4 @@ bool fromwire_openingd_dev_memleak_reply(const void *p, bool *leak)
|
|||
*leak = fromwire_bool(&cursor, &plen);
|
||||
return cursor != NULL;
|
||||
}
|
||||
// SHA256STAMP:d2fcabdf157b098608e47dcdc37db0f46fe8d466d74159969544d7c4bb77f061
|
||||
// SHA256STAMP:005577de0219577522210df32b3ed325f028b24fc25d3b77a1dc770077381b6b
|
||||
|
|
9
openingd/openingd_wiregen.h
generated
9
openingd/openingd_wiregen.h
generated
|
@ -18,6 +18,8 @@
|
|||
|
||||
enum openingd_wire {
|
||||
WIRE_OPENINGD_INIT = 6000,
|
||||
/* Openingd->master: they tried to reestablish a channel. */
|
||||
WIRE_OPENINGD_GOT_REESTABLISH = 6001,
|
||||
/* Openingd->master: they offered channel */
|
||||
WIRE_OPENINGD_GOT_OFFER = 6005,
|
||||
/* master->openingd: optional rejection message */
|
||||
|
@ -61,6 +63,11 @@ bool openingd_wire_is_defined(u16 type);
|
|||
u8 *towire_openingd_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_features, const struct channel_config *our_config, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, u32 minimum_depth, u32 min_feerate, u32 max_feerate, const u8 *lfeatures, bool option_static_remotekey, bool option_anchor_outputs, const struct channel_id *dev_temporary_channel_id, bool dev_fast_gossip);
|
||||
bool fromwire_openingd_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_features, struct channel_config *our_config, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, u32 *minimum_depth, u32 *min_feerate, u32 *max_feerate, u8 **lfeatures, bool *option_static_remotekey, bool *option_anchor_outputs, struct channel_id **dev_temporary_channel_id, bool *dev_fast_gossip);
|
||||
|
||||
/* WIRE: OPENINGD_GOT_REESTABLISH */
|
||||
/* Openingd->master: they tried to reestablish a channel. */
|
||||
u8 *towire_openingd_got_reestablish(const tal_t *ctx, const struct channel_id *channel_id, const u8 *msg, const struct per_peer_state *pps);
|
||||
bool fromwire_openingd_got_reestablish(const tal_t *ctx, const void *p, struct channel_id *channel_id, u8 **msg, struct per_peer_state **pps);
|
||||
|
||||
/* WIRE: OPENINGD_GOT_OFFER */
|
||||
/* Openingd->master: they offered channel */
|
||||
u8 *towire_openingd_got_offer(const tal_t *ctx, struct amount_sat funding_satoshis, struct amount_msat push_msat, struct amount_sat dust_limit_satoshis, struct amount_msat max_htlc_value_in_flight_msat, struct amount_sat channel_reserve_satoshis, struct amount_msat htlc_minimum_msat, u32 feerate_per_kw, u16 to_self_delay, u16 max_accepted_htlcs, u8 channel_flags, const u8 *shutdown_scriptpubkey);
|
||||
|
@ -121,4 +128,4 @@ bool fromwire_openingd_dev_memleak_reply(const void *p, bool *leak);
|
|||
|
||||
|
||||
#endif /* LIGHTNING_OPENINGD_OPENINGD_WIREGEN_H */
|
||||
// SHA256STAMP:d2fcabdf157b098608e47dcdc37db0f46fe8d466d74159969544d7c4bb77f061
|
||||
// SHA256STAMP:005577de0219577522210df32b3ed325f028b24fc25d3b77a1dc770077381b6b
|
||||
|
|
|
@ -1149,7 +1149,7 @@ def test_funding_by_utxos(node_factory, bitcoind):
|
|||
@pytest.mark.developer("needs dev_forget_channel")
|
||||
@pytest.mark.openchannel('v1')
|
||||
def test_funding_external_wallet_corners(node_factory, bitcoind):
|
||||
l1 = node_factory.get_node(may_reconnect=True, allow_broken_log=True)
|
||||
l1 = node_factory.get_node(may_reconnect=True)
|
||||
l2 = node_factory.get_node(may_reconnect=True)
|
||||
|
||||
amount = 2**24
|
||||
|
@ -1242,7 +1242,7 @@ def test_funding_external_wallet_corners(node_factory, bitcoind):
|
|||
|
||||
# on reconnect, channel should get destroyed
|
||||
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
||||
l1.daemon.wait_for_log('Unexpected message WIRE_CHANNEL_REESTABLISH')
|
||||
l1.daemon.wait_for_log('Reestablish on UNKNOWN channel')
|
||||
wait_for(lambda: len(l1.rpc.listpeers()['peers']) == 0)
|
||||
wait_for(lambda: len(l2.rpc.listpeers()['peers']) == 0)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue