openingd: take peer before we're opening, wait for explicit funding msg.

Prior to this, lightningd would hand uninteresting peers back to connectd,
which would then return it to lightningd if it sent a non-gossip msg,
or if lightningd asked it to release the peer.

Now connectd hands the peer to lightningd once we've done the init
handshake, which hands it off to openingd.

This is a deep structural change, so we do the minimum here and cleanup
in the following patches.

Lightningd:
1. Remove peer_nongossip handling from connect_control and peer_control.
2. Remove list of outstanding fundchannel command; it was only needed to
   find the race between us asking connectd to release the peer and it
   reconnecting.
3. We can no longer tell if the remote end has started trying to fund a
   channel (until it has succeeded): it's very transitory anyway so not
   worth fixing.
4. We now always have a struct peer, and allocate an uncommitted_channel
   for it, though it may never be used if neither end funds a channel.
5. We start funding on messages for openingd: we can get a funder_reply
   or a fundee, or an error in response to our request to fund a channel.
   so we handle all of them.
6. A new peer_start_openingd() is called after connectd hands us a peer.
7. json_fund_channel just looks through local peers; there are none
   hidden in connectd any more.
8. We sometimes start a new openingd just to send an error message.

Openingd:
1. We always have information we need to accept them funding a channel (in
   the init message).
2. We have to listen for three fds: peer, gossip and master, so we opencode
   the poll.
3. We have an explicit message to start trying to fund a channel.
4. We can be told to send a message in our init message.

Testing:
1. We don't handle some things gracefully yet, so two tests are disabled.
2. 'hand_back_peer .*: now local again' from connectd is no longer a message,
   openingd says 'Handed peer, entering loop' once its managing it.
3. peer['state'] used to be set to 'GOSSIPING' (otherwise this field doesn't
   exist; 'state' is now per-channel.  It doesn't exist at all now.
4. Some tests now need to turn on IO logging in openingd, not connectd.
5. There's a gap between connecting on one node and having connectd on
   the peer hand over the connection to openingd.  Our tests sometimes
   checked getpeers() on the peer, and didn't see anything, so line_graph
   needed updating.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2018-08-08 23:40:58 +09:30 committed by Christian Decker
parent 5cd72c9620
commit 50f5eb34b4
14 changed files with 472 additions and 672 deletions

View File

@ -216,38 +216,6 @@ static void peer_please_disconnect(struct lightningd *ld, const u8 *msg)
channel_fail_transient(c, "Reconnected");
}
static void peer_nongossip(struct subd *connectd, const u8 *msg,
int peer_fd, int gossip_fd)
{
struct pubkey id;
struct crypto_state cs;
struct wireaddr_internal addr;
u8 *gfeatures, *lfeatures, *in_pkt;
if (!fromwire_connect_peer_nongossip(msg, msg,
&id, &addr, &cs,
&gfeatures,
&lfeatures,
&in_pkt))
fatal("Connectd gave bad CONNECT_PEER_NONGOSSIP message %s",
tal_hex(msg, msg));
/* We already checked the features when it first connected. */
if (!features_supported(gfeatures, lfeatures)) {
log_unusual(connectd->log,
"Connectd gave unsupported features %s/%s",
tal_hex(msg, gfeatures),
tal_hex(msg, lfeatures));
close(peer_fd);
close(gossip_fd);
return;
}
peer_sent_nongossip(connectd->ld, &id, &addr, &cs,
gfeatures, lfeatures,
peer_fd, gossip_fd, in_pkt);
}
static unsigned connectd_msg(struct subd *connectd, const u8 *msg, const int *fds)
{
enum connect_wire_type t = fromwire_peektype(msg);
@ -272,6 +240,7 @@ static unsigned connectd_msg(struct subd *connectd, const u8 *msg, const int *fd
case WIRE_CONNECTCTL_RELEASE_PEER_REPLYFAIL:
case WIRE_CONNECTCTL_PEER_DISCONNECT_REPLY:
case WIRE_CONNECTCTL_PEER_DISCONNECT_REPLYFAIL:
case WIRE_CONNECT_PEER_NONGOSSIP:
break;
case WIRE_CONNECT_RECONNECTED:
@ -283,11 +252,7 @@ static unsigned connectd_msg(struct subd *connectd, const u8 *msg, const int *fd
return 2;
peer_connected(connectd->ld, msg, fds[0], fds[1]);
break;
case WIRE_CONNECT_PEER_NONGOSSIP:
if (tal_count(fds) != 2)
return 2;
peer_nongossip(connectd, msg, fds[0], fds[1]);
break;
case WIRE_CONNECTCTL_CONNECT_TO_PEER_RESULT:
connectd_connect_result(connectd->ld, msg);
break;

View File

@ -68,7 +68,6 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
ld->alias = NULL;
ld->rgb = NULL;
list_head_init(&ld->connects);
list_head_init(&ld->fundchannels);
list_head_init(&ld->waitsendpay_commands);
list_head_init(&ld->sendpay_commands);
list_head_init(&ld->close_commands);

View File

@ -145,9 +145,6 @@ struct lightningd {
/* Outstanding connect commands. */
struct list_head connects;
/* Outstanding fundchannel commands. */
struct list_head fundchannels;
/* Our chain topology. */
struct chain_topology *topology;

View File

@ -63,9 +63,6 @@ struct uncommitted_channel {
struct funding_channel {
/* In lightningd->fundchannels while waiting for connectd reply. */
struct list_node list;
struct command *cmd; /* Which also owns us. */
struct wallet_tx wtx;
u64 push_msat;
@ -78,52 +75,6 @@ struct funding_channel {
struct uncommitted_channel *uc;
};
static struct funding_channel *find_funding_channel(struct lightningd *ld,
const struct pubkey *id)
{
struct funding_channel *i;
list_for_each(&ld->fundchannels, i, list) {
if (pubkey_eq(&i->peerid, id))
return i;
}
return NULL;
}
static void remove_funding_channel_from_list(struct funding_channel *fc)
{
list_del_from(&fc->cmd->ld->fundchannels, &fc->list);
}
/* Opening failed: hand back to connectd (sending errpkt if not NULL) */
static void uncommitted_channel_to_connectd(struct lightningd *ld,
struct uncommitted_channel *uc,
const struct crypto_state *cs,
int peer_fd, int gossip_fd,
const u8 *errorpkt,
const char *fmt,
...)
{
va_list ap;
char *errstr;
u8 *msg;
va_start(ap, fmt);
errstr = tal_vfmt(uc, fmt, ap);
va_end(ap);
log_unusual(uc->log, "Opening channel: %s", errstr);
if (uc->fc)
command_fail(uc->fc->cmd, LIGHTNINGD, "%s", errstr);
/* Hand back to connectd, (maybe) with an error packet to send. */
msg = towire_connectctl_hand_back_peer(errstr, &uc->peer->id, cs,
errorpkt);
subd_send_msg(ld->connectd, take(msg));
subd_send_fd(ld->connectd, peer_fd);
subd_send_fd(ld->connectd, gossip_fd);
}
static void uncommitted_channel_disconnect(struct uncommitted_channel *uc,
const char *desc)
{
@ -150,27 +101,28 @@ void kill_uncommitted_channel(struct uncommitted_channel *uc,
void json_add_uncommitted_channel(struct json_result *response,
const struct uncommitted_channel *uc)
{
u64 msatoshi_total, our_msatoshi;
if (!uc)
return;
/* If we're chatting but no channel, that's shown by connected: True */
if (!uc->fc)
return;
json_object_start(response, NULL);
json_add_string(response, "state", "OPENINGD");
json_add_string(response, "owner", "lightning_openingd");
json_add_string(response, "funder",
uc->fc ? "LOCAL" : "REMOTE");
json_add_string(response, "funding", "LOCAL");
if (uc->transient_billboard) {
json_array_start(response, "status");
json_add_string(response, NULL, uc->transient_billboard);
json_array_end(response);
}
if (uc->fc) {
u64 msatoshi_total, our_msatoshi;
msatoshi_total = uc->fc->wtx.amount * 1000;
our_msatoshi = msatoshi_total - uc->fc->push_msat;
json_add_u64(response, "msatoshi_to_us", our_msatoshi);
json_add_u64(response, "msatoshi_total", msatoshi_total);
}
msatoshi_total = uc->fc->wtx.amount * 1000;
our_msatoshi = msatoshi_total - uc->fc->push_msat;
json_add_u64(response, "msatoshi_to_us", our_msatoshi);
json_add_u64(response, "msatoshi_total", msatoshi_total);
json_object_end(response);
}
@ -486,7 +438,7 @@ static void opening_fundee_finished(struct subd *openingd,
/* This is a new channel_info.their_config, set its ID to 0 */
channel_info.their_config.id = 0;
if (!fromwire_opening_fundee_reply(tmpctx, reply,
if (!fromwire_opening_fundee(tmpctx, reply,
&channel_info.their_config,
&remote_commit,
&remote_commit_sig,
@ -511,6 +463,29 @@ static void opening_fundee_finished(struct subd *openingd,
return;
}
/* If we resumed chatting with them to send an error, this could
* happen: refuse to let them open another active channel.
*
* FIXME: Perhaps we should not consider channels with errors to be
* active, however we don't store errors in the db so we could end
* up with multiple on restart. */
if (peer_active_channel(uc->peer)) {
u8 *errmsg;
struct peer *peer = uc->peer;
struct channel_id channel_id;
derive_channel_id(&channel_id, &funding_txid, funding_outnum);
errmsg = towire_errorfmt(tmpctx, &channel_id,
"Already have active channel");
/* Won't free peer, since has active channel */
tal_free(uc);
/* Hand back to openingd. */
peer_start_openingd(peer, &cs, fds[0], fds[1], errmsg);
return;
}
/* Consumes uc */
channel = wallet_commit_channel(ld, uc,
remote_commit,
@ -551,18 +526,11 @@ static void opening_channel_errmsg(struct uncommitted_channel *uc,
const char *desc,
const u8 *err_for_them)
{
if (peer_fd == -1) {
uncommitted_channel_disconnect(uc, desc);
} else {
/* An error occurred (presumably negotiation fail). */
const char *errsrc = err_for_them ? "sent" : "received";
uncommitted_channel_to_connectd(uc->peer->ld, uc,
cs,
peer_fd, gossip_fd,
err_for_them,
"%s ERROR %s", errsrc, desc);
if (peer_fd != -1) {
close(peer_fd);
close(gossip_fd);
}
uncommitted_channel_disconnect(uc, desc);
tal_free(uc);
}
@ -593,27 +561,15 @@ static void destroy_uncommitted_channel(struct uncommitted_channel *uc)
maybe_delete_peer(uc->peer);
}
/* Returns NULL if there's already an opening or active channel for this peer */
static struct uncommitted_channel *
new_uncommitted_channel(struct lightningd *ld,
struct funding_channel *fc,
const struct pubkey *peer_id,
const struct wireaddr_internal *addr,
const u8 *gfeatures, const u8 *lfeatures)
new_uncommitted_channel(struct peer *peer)
{
struct lightningd *ld = peer->ld;
struct uncommitted_channel *uc = tal(ld, struct uncommitted_channel);
char *idname;
/* We make a new peer if necessary. */
uc->peer = peer_by_id(ld, peer_id);
if (!uc->peer)
uc->peer = new_peer(ld, 0, peer_id, addr, gfeatures, lfeatures);
if (uc->peer->uncommitted_channel)
return tal_free(uc);
if (peer_active_channel(uc->peer))
return tal_free(uc);
uc->peer = peer;
assert(!peer->uncommitted_channel);
uc->transient_billboard = NULL;
uc->dbid = wallet_get_channel_dbid(ld->wallet);
@ -623,7 +579,7 @@ new_uncommitted_channel(struct lightningd *ld,
idname, uc->dbid);
tal_free(idname);
uc->fc = fc;
uc->fc = NULL;
uc->our_config.id = 0;
get_channel_basepoints(ld, &uc->peer->id, uc->dbid,
@ -679,238 +635,100 @@ static void channel_config(struct lightningd *ld,
ours->channel_reserve_satoshis = -1;
}
/* Peer has spontaneously exited from connectd due to open msg. Return
* NULL if we took over, otherwise hand back to connectd with this
* error.
*/
u8 *peer_accept_channel(const tal_t *ctx,
struct lightningd *ld,
const struct pubkey *peer_id,
const struct wireaddr_internal *addr,
const struct crypto_state *cs,
const u8 *gfeatures, const u8 *lfeatures,
int peer_fd, int gossip_fd,
const struct channel_id *channel_id,
const u8 *open_msg)
static unsigned int openingd_msg(struct subd *openingd,
const u8 *msg, const int *fds)
{
enum opening_wire_type t = fromwire_peektype(msg);
struct uncommitted_channel *uc = openingd->channel;
switch (t) {
case WIRE_OPENING_FUNDER_REPLY:
if (!uc->fc) {
log_broken(openingd->log, "Unexpected FUNDER_REPLY %s",
tal_hex(tmpctx, msg));
tal_free(openingd);
return 0;
}
if (tal_count(fds) != 2)
return 2;
opening_funder_finished(openingd, msg, fds, uc->fc);
return 0;
case WIRE_OPENING_FUNDEE:
if (tal_count(fds) != 2)
return 2;
opening_fundee_finished(openingd, msg, fds, uc);
return 0;
/* We send these! */
case WIRE_OPENING_INIT:
case WIRE_OPENING_FUNDER:
break;
}
log_broken(openingd->log, "Unexpected msg %s: %s",
opening_wire_type_name(t), tal_hex(tmpctx, msg));
tal_free(openingd);
return 0;
}
void peer_start_openingd(struct peer *peer,
const struct crypto_state *cs,
int peer_fd, int gossip_fd,
const u8 *send_msg)
{
int hsmfd;
u32 max_to_self_delay;
u64 min_effective_htlc_capacity_msat;
u8 *msg;
struct uncommitted_channel *uc;
int hsmfd;
const u8 *msg;
assert(fromwire_peektype(open_msg) == WIRE_OPEN_CHANNEL);
assert(!peer->uncommitted_channel);
/* Fails if there's already one */
uc = new_uncommitted_channel(ld, NULL, peer_id, addr,
gfeatures, lfeatures);
if (!uc)
return towire_errorfmt(ctx, channel_id,
"Multiple channels unsupported");
uc = peer->uncommitted_channel = new_uncommitted_channel(peer);
hsmfd = hsm_get_client_fd(ld, &uc->peer->id, uc->dbid,
hsmfd = hsm_get_client_fd(peer->ld, &uc->peer->id, uc->dbid,
HSM_CAP_COMMITMENT_POINT
| HSM_CAP_SIGN_REMOTE_TX);
uc->openingd = new_channel_subd(ld, "lightning_openingd", uc, uc->log,
true, opening_wire_type_name, NULL,
uc->openingd = new_channel_subd(peer->ld,
"lightning_openingd",
uc, uc->log,
true, opening_wire_type_name,
openingd_msg,
opening_channel_errmsg,
opening_channel_set_billboard,
take(&peer_fd), take(&gossip_fd),
take(&hsmfd), NULL);
if (!uc->openingd) {
u8 *errpkt;
char *errmsg;
errmsg = tal_fmt(uc, "INTERNAL ERROR:"
" Failed to subdaemon opening: %s",
strerror(errno));
errpkt = towire_errorfmt(uc, channel_id, "%s", errmsg);
uncommitted_channel_to_connectd(ld, uc,
cs,
peer_fd, gossip_fd,
errpkt, "%s", errmsg);
tal_free(uc);
return NULL;
uncommitted_channel_disconnect(uc,
tal_fmt(tmpctx,
"Running lightning_openingd: %s",
strerror(errno)));
return;
}
channel_config(peer->ld, &uc->our_config,
&max_to_self_delay,
&min_effective_htlc_capacity_msat);
/* BOLT #2:
*
* The sender:
* - SHOULD set `minimum_depth` to a number of blocks it considers
* reasonable to avoid double-spending of the funding transaction.
*/
uc->minimum_depth = ld->config.anchor_confirms;
uc->minimum_depth = peer->ld->config.anchor_confirms;
channel_config(ld, &uc->our_config,
&max_to_self_delay,
&min_effective_htlc_capacity_msat);
msg = towire_opening_init(uc, get_chainparams(ld)->index,
msg = towire_opening_init(NULL, get_chainparams(peer->ld)->index,
&uc->our_config,
max_to_self_delay,
min_effective_htlc_capacity_msat,
cs, &uc->local_basepoints,
&uc->local_funding_pubkey);
&uc->local_funding_pubkey,
uc->minimum_depth,
feerate_min(peer->ld), feerate_max(peer->ld),
send_msg);
subd_send_msg(uc->openingd, take(msg));
msg = towire_opening_fundee(uc, uc->minimum_depth,
feerate_min(ld), feerate_max(ld),
open_msg);
subd_req(uc, uc->openingd, take(msg), -1, 2,
opening_fundee_finished, uc);
return NULL;
}
static void peer_offer_channel(struct lightningd *ld,
struct funding_channel *fc,
const struct wireaddr_internal *addr,
const struct crypto_state *cs,
const u8 *gfeatures, const u8 *lfeatures,
int peer_fd, int gossip_fd)
{
u8 *msg;
u32 max_to_self_delay;
u64 min_effective_htlc_capacity_msat;
int hsmfd;
/* Remove from list, it's not pending any more. */
list_del_from(&ld->fundchannels, &fc->list);
tal_del_destructor(fc, remove_funding_channel_from_list);
fc->uc = new_uncommitted_channel(ld, fc, &fc->peerid, addr,
gfeatures, lfeatures);
/* We asked to release this peer, but another raced in? Corner case,
* close this is easiest. */
if (!fc->uc) {
command_fail(fc->cmd, LIGHTNINGD, "Peer already active");
close(peer_fd);
close(gossip_fd);
return;
}
/* Channel now owns fc; if it dies, we free fc. */
tal_steal(fc->uc, fc);
hsmfd = hsm_get_client_fd(ld, &fc->uc->peer->id, fc->uc->dbid,
HSM_CAP_COMMITMENT_POINT
| HSM_CAP_SIGN_REMOTE_TX);
fc->uc->openingd = new_channel_subd(ld,
"lightning_openingd",
fc->uc, fc->uc->log,
true, opening_wire_type_name, NULL,
opening_channel_errmsg,
opening_channel_set_billboard,
take(&peer_fd), take(&gossip_fd),
take(&hsmfd),
NULL);
if (!fc->uc->openingd) {
/* We don't send them an error packet: for them, nothing
* happened! */
uncommitted_channel_to_connectd(ld, fc->uc, NULL,
peer_fd, gossip_fd,
NULL,
"Failed to launch openingd: %s",
strerror(errno));
tal_free(fc->uc);
return;
}
channel_config(ld, &fc->uc->our_config,
&max_to_self_delay,
&min_effective_htlc_capacity_msat);
msg = towire_opening_init(fc,
get_chainparams(ld)->index,
&fc->uc->our_config,
max_to_self_delay,
min_effective_htlc_capacity_msat,
cs, &fc->uc->local_basepoints,
&fc->uc->local_funding_pubkey);
subd_send_msg(fc->uc->openingd, take(msg));
msg = towire_opening_funder(fc, fc->wtx.amount,
fc->push_msat,
get_feerate(ld->topology, FEERATE_NORMAL),
fc->wtx.change, fc->wtx.change_key_index,
fc->channel_flags,
fc->wtx.utxos,
ld->wallet->bip32_base);
subd_req(fc, fc->uc->openingd,
take(msg), -1, 2, opening_funder_finished, fc);
}
/* Peer has been released from connectd. Start opening. */
static void connectd_peer_released(struct subd *connectd,
const u8 *resp,
const int *fds,
struct funding_channel *fc)
{
struct lightningd *ld = connectd->ld;
struct crypto_state cs;
u8 *gfeatures, *lfeatures;
struct wireaddr_internal addr;
struct channel *c;
struct uncommitted_channel *uc;
/* handle_opening_channel might have already taken care of this. */
if (fc->uc)
return;
c = active_channel_by_id(ld, &fc->peerid, &uc);
if (!fromwire_connectctl_release_peer_reply(fc, resp, &addr, &cs,
&gfeatures, &lfeatures)) {
if (!fromwire_connectctl_release_peer_replyfail(resp)) {
fatal("Connect daemon gave invalid reply %s",
tal_hex(connectd, resp));
}
if (uc)
command_fail(fc->cmd, LIGHTNINGD, "Peer already OPENING");
else if (c)
command_fail(fc->cmd, LIGHTNINGD, "Peer already %s",
channel_state_name(c));
else
command_fail(fc->cmd, LIGHTNINGD, "Peer not connected");
return;
}
assert(tal_count(fds) == 2);
/* Connectd should guarantee peer is unique: we would have killed any
* old connection when it was told us peer reconnected. */
assert(!c);
assert(!uc);
/* OK, offer peer a channel. */
peer_offer_channel(ld, fc, &addr, &cs,
gfeatures, lfeatures,
fds[0], fds[1]);
}
/* We can race: we're trying to get connectd to release peer just as it
* reconnects. If that's happened, treat it as if it were
* released. */
bool handle_opening_channel(struct lightningd *ld,
const struct pubkey *id,
const struct wireaddr_internal *addr,
const struct crypto_state *cs,
const u8 *gfeatures, const u8 *lfeatures,
int peer_fd, int gossip_fd)
{
struct funding_channel *fc = find_funding_channel(ld, id);
if (!fc)
return false;
peer_offer_channel(ld, fc, addr, cs, gfeatures, lfeatures,
peer_fd, gossip_fd);
return true;
}
/**
@ -919,8 +737,11 @@ bool handle_opening_channel(struct lightningd *ld,
static void json_fund_channel(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
const jsmntok_t *desttok, *sattok;
const jsmntok_t *sattok;
struct funding_channel * fc = tal(cmd, struct funding_channel);
struct pubkey id;
struct peer *peer;
struct channel *channel;
u32 feerate_per_kw = get_feerate(cmd->ld->topology, FEERATE_NORMAL);
u8 *msg;
@ -928,17 +749,34 @@ static void json_fund_channel(struct command *cmd,
fc->uc = NULL;
wtx_init(cmd, &fc->wtx);
if (!param(fc->cmd, buffer, params,
p_req("id", json_tok_tok, &desttok),
p_req("id", json_tok_pubkey, &id),
p_req("satoshi", json_tok_tok, &sattok),
NULL))
return;
if (!json_tok_wtx(&fc->wtx, buffer, sattok, MAX_FUNDING_SATOSHI))
return;
if (!pubkey_from_hexstr(buffer + desttok->start,
desttok->end - desttok->start,
&fc->peerid)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Could not parse id");
peer = peer_by_id(cmd->ld, &id);
if (!peer) {
command_fail(cmd, LIGHTNINGD, "Unknown peer");
return;
}
channel = peer_active_channel(peer);
if (channel) {
command_fail(cmd, LIGHTNINGD, "Peer already %s",
channel_state_name(channel));
return;
}
if (!peer->uncommitted_channel) {
command_fail(cmd, LIGHTNINGD, "Peer not connected");
return;
}
if (peer->uncommitted_channel->fc) {
command_fail(cmd, LIGHTNINGD, "Already funding channel");
return;
}
@ -952,11 +790,23 @@ static void json_fund_channel(struct command *cmd,
assert(fc->wtx.amount <= MAX_FUNDING_SATOSHI);
list_add(&cmd->ld->fundchannels, &fc->list);
tal_add_destructor(fc, remove_funding_channel_from_list);
peer->uncommitted_channel->fc = tal_steal(peer->uncommitted_channel, fc);
fc->uc = peer->uncommitted_channel;
msg = towire_connectctl_release_peer(cmd, &fc->peerid);
subd_req(fc, cmd->ld->connectd, msg, -1, 2, connectd_peer_released, fc);
msg = towire_opening_funder(NULL,
fc->wtx.amount,
fc->push_msat,
get_feerate(cmd->ld->topology,
FEERATE_NORMAL),
fc->wtx.change,
fc->wtx.change_key_index,
fc->channel_flags,
fc->wtx.utxos,
cmd->ld->wallet->bip32_base);
/* Openingd will either succeed, or fail, or tell us the other side
* funded first. */
subd_send_msg(peer->uncommitted_channel->openingd, take(msg));
command_still_pending(cmd);
}

View File

@ -7,35 +7,15 @@ struct channel_id;
struct crypto_state;
struct json_result;
struct lightningd;
struct pubkey;
struct uncommitted_channel;
struct wireaddr_internal;
void json_add_uncommitted_channel(struct json_result *response,
const struct uncommitted_channel *uc);
/* Peer has spontaneously exited from gossip due to open msg. Return
* NULL if we took over, otherwise hand back to gossipd with this
* error (allocated off @ctx).
*/
u8 *peer_accept_channel(const tal_t *ctx,
struct lightningd *ld,
const struct pubkey *peer_id,
const struct wireaddr_internal *addr,
const struct crypto_state *cs,
const u8 *gfeatures, const u8 *lfeatures,
int peer_fd, int gossip_fd,
const struct channel_id *channel_id,
const u8 *open_msg);
/* Gossipd spat out peer: were we currently asking gossipd to release it
* so we could open a channel? Returns true if it took over. */
bool handle_opening_channel(struct lightningd *ld,
const struct pubkey *id,
const struct wireaddr_internal *addr,
const struct crypto_state *cs,
const u8 *gfeatures, const u8 *lfeatures,
int peer_fd, int gossip_fd);
void peer_start_openingd(struct peer *peer,
const struct crypto_state *cs,
int peer_fd, int gossip_fd,
const u8 *msg);
void kill_uncommitted_channel(struct uncommitted_channel *uc,
const char *why);

View File

@ -447,26 +447,23 @@ void peer_connected(struct lightningd *ld, const u8 *msg,
u8 *error;
struct channel *channel;
struct wireaddr_internal addr;
struct uncommitted_channel *uc;
struct peer *peer;
if (!fromwire_connect_peer_connected(msg, msg,
&id, &addr, &cs,
&gfeatures, &lfeatures))
&id, &addr, &cs,
&gfeatures, &lfeatures))
fatal("Connectd gave bad CONNECT_PEER_CONNECTED message %s",
tal_hex(msg, msg));
/* Were we trying to open a channel, and we've raced? */
if (handle_opening_channel(ld, &id, &addr, &cs,
gfeatures, lfeatures, peer_fd, gossip_fd))
return;
/* If we're already dealing with this peer, hand off to correct
* subdaemon. Otherwise, we'll respond iff they ask about an inactive
* channel. */
channel = active_channel_by_id(ld, &id, &uc);
* subdaemon. Otherwise, we'll hand to openingd to wait there. */
peer = peer_by_id(ld, &id);
if (!peer)
peer = new_peer(ld, 0, &id, &addr, gfeatures, lfeatures);
/* Can't be opening now, since we wouldn't have sent peer_died. */
assert(!uc);
/* Can't be opening, since we wouldn't have sent peer_disconnected. */
assert(!peer->uncommitted_channel);
channel = peer_active_channel(peer);
if (channel) {
log_debug(channel->log, "Peer has reconnected, state %s",
@ -480,17 +477,18 @@ void peer_connected(struct lightningd *ld, const u8 *msg,
#if DEVELOPER
if (dev_disconnect_permanent(ld)) {
channel_internal_error(channel, "dev_disconnect permfail");
channel_internal_error(channel,
"dev_disconnect permfail");
error = channel->error;
goto send_error;
}
}
#endif
switch (channel->state) {
case ONCHAIN:
case FUNDING_SPEND_SEEN:
case CLOSINGD_COMPLETE:
/* Channel is active! */
/* Channel is supposed to be active! */
abort();
case CHANNELD_AWAITING_LOCKIN:
@ -520,96 +518,7 @@ void peer_connected(struct lightningd *ld, const u8 *msg,
error = NULL;
send_error:
/* Hand back to channeld, with an error packet. */
msg = towire_connectctl_hand_back_peer(msg, &id, &cs, error);
subd_send_msg(ld->connectd, take(msg));
subd_send_fd(ld->connectd, peer_fd);
subd_send_fd(ld->connectd, gossip_fd);
}
static struct channel *channel_by_channel_id(struct peer *peer,
const struct channel_id *channel_id)
{
struct channel *channel;
list_for_each(&peer->channels, channel, list) {
struct channel_id cid;
derive_channel_id(&cid,
&channel->funding_txid,
channel->funding_outnum);
if (channel_id_eq(&cid, channel_id))
return channel;
}
return NULL;
}
/* We only get here IF we weren't trying to connect to it. */
void peer_sent_nongossip(struct lightningd *ld,
const struct pubkey *id,
const struct wireaddr_internal *addr,
const struct crypto_state *cs,
const u8 *gfeatures,
const u8 *lfeatures,
int peer_fd, int gossip_fd,
const u8 *in_msg)
{
struct channel_id *channel_id, extracted_channel_id;
struct peer *peer;
u8 *error, *msg;
if (!extract_channel_id(in_msg, &extracted_channel_id))
channel_id = NULL;
else
channel_id = &extracted_channel_id;
peer = peer_by_id(ld, id);
/* Open request? */
if (fromwire_peektype(in_msg) == WIRE_OPEN_CHANNEL) {
error = peer_accept_channel(tmpctx,
ld, id, addr, cs,
gfeatures, lfeatures,
peer_fd, gossip_fd, channel_id,
in_msg);
if (error)
goto send_error;
return;
}
/* If they are talking about a specific channel id, we may have an
* error for them. */
if (peer && channel_id) {
struct channel *channel;
channel = channel_by_channel_id(peer, channel_id);
if (channel && channel->error) {
error = channel->error;
goto send_error;
}
/* Reestablish for a now-closed channel? They might have
* missed final update, so do the closing negotiation dance
* again. */
if (fromwire_peektype(in_msg) == WIRE_CHANNEL_REESTABLISH
&& channel
&& channel->state == CLOSINGD_COMPLETE) {
peer_start_closingd(channel, cs,
peer_fd, gossip_fd, true, in_msg);
return;
}
}
/* Weird request. */
error = towire_errorfmt(tmpctx, channel_id,
"Unexpected message %i for peer",
fromwire_peektype(in_msg));
send_error:
/* Hand back to channeld, with an error packet. */
msg = towire_connectctl_hand_back_peer(ld, id, cs, error);
subd_send_msg(ld->connectd, take(msg));
subd_send_fd(ld->connectd, peer_fd);
subd_send_fd(ld->connectd, gossip_fd);
peer_start_openingd(peer, &cs, peer_fd, gossip_fd, error);
}
static enum watch_result funding_lockin_cb(struct channel *channel,

View File

@ -68,25 +68,9 @@ struct peer *peer_from_json(struct lightningd *ld,
const char *buffer,
const jsmntok_t *peeridtok);
/* The three ways peers enter from the network:
*
* peer_connected - when it first connects to gossipd (after init exchange).
* peer_sent_nongossip - when it tries to fund a channel.
* gossip_peer_released - when we tell gossipd to release it so we can fund
* a channel.
*/
void peer_connected(struct lightningd *ld, const u8 *msg,
int peer_fd, int gossip_fd);
void peer_sent_nongossip(struct lightningd *ld,
const struct pubkey *id,
const struct wireaddr_internal *addr,
const struct crypto_state *cs,
const u8 *gfeatures,
const u8 *lfeatures,
int peer_fd, int gossip_fd,
const u8 *in_msg);
/* Could be configurable. */
#define OUR_CHANNEL_FLAGS CHANNEL_FLAGS_ANNOUNCE_CHANNEL

View File

@ -2,6 +2,7 @@
#include <bitcoin/chainparams.h>
#include <bitcoin/privkey.h>
#include <bitcoin/script.h>
#include <ccan/array_size/array_size.h>
#include <ccan/breakpoint/breakpoint.h>
#include <ccan/cast/cast.h>
#include <ccan/fdpass/fdpass.h>
@ -25,6 +26,7 @@
#include <hsmd/gen_hsm_client_wire.h>
#include <inttypes.h>
#include <openingd/gen_opening_wire.h>
#include <poll.h>
#include <secp256k1.h>
#include <stdio.h>
#include <wally_bip32.h>
@ -43,6 +45,13 @@ struct state {
struct crypto_state cs;
struct pubkey next_per_commit[NUM_SIDES];
/* Constriants on a channel they open. */
u32 minimum_depth;
u32 min_feerate, max_feerate;
struct basepoints our_points;
struct pubkey our_funding_pubkey;
/* Initially temporary, then final channel id. */
struct channel_id channel_id;
@ -63,6 +72,8 @@ struct state {
const struct chainparams *chainparams;
};
/* FIXME: Don't close connection in this case, but inform master and
* continue! */
/* For negotiation failures: we tell them it's their fault. Same
* as peer_failed, with slightly different local and remote wording. */
static void negotiation_failed(struct state *state, const char *fmt, ...)
@ -246,8 +257,6 @@ static u8 *opening_read_peer_msg(const tal_t *ctx, struct state *state)
}
static u8 *funder_channel(struct state *state,
const struct pubkey *our_funding_pubkey,
const struct basepoints *ours,
u64 change_satoshis, u32 change_keyindex,
u8 channel_flags,
struct utxo **utxos,
@ -296,11 +305,11 @@ static u8 *funder_channel(struct state *state,
state->feerate_per_kw,
state->localconf.to_self_delay,
state->localconf.max_accepted_htlcs,
our_funding_pubkey,
&ours->revocation,
&ours->payment,
&ours->delayed_payment,
&ours->htlc,
&state->our_funding_pubkey,
&state->our_points.revocation,
&state->our_points.payment,
&state->our_points.delayed_payment,
&state->our_points.htlc,
&state->next_per_commit[LOCAL],
channel_flags);
sync_crypto_write(&state->cs, PEER_FD, msg);
@ -404,7 +413,7 @@ static u8 *funder_channel(struct state *state,
funding = funding_tx(state, &state->funding_txout,
cast_const2(const struct utxo **, utxos),
state->funding_satoshis,
our_funding_pubkey,
&state->our_funding_pubkey,
&their_funding_pubkey,
change_satoshis, changekey,
bip32_base);
@ -419,8 +428,8 @@ static u8 *funder_channel(struct state *state,
state->feerate_per_kw,
&state->localconf,
state->remoteconf,
ours, &theirs,
our_funding_pubkey,
&state->our_points, &theirs,
&state->our_funding_pubkey,
&their_funding_pubkey,
LOCAL);
if (!state->channel)
@ -457,7 +466,8 @@ static u8 *funder_channel(struct state *state,
status_trace("signature %s on tx %s using key %s",
type_to_string(tmpctx, secp256k1_ecdsa_signature, &sig),
type_to_string(tmpctx, struct bitcoin_tx, tx),
type_to_string(tmpctx, struct pubkey, our_funding_pubkey));
type_to_string(tmpctx, struct pubkey,
&state->our_funding_pubkey));
msg = towire_funding_created(state, &state->channel_id,
&state->funding_txid,
@ -548,13 +558,7 @@ static u8 *funder_channel(struct state *state,
state->localconf.channel_reserve_satoshis);
}
/* This is handed the message the peer sent which caused gossip to stop:
* it should be an open_channel */
static u8 *fundee_channel(struct state *state,
const struct pubkey *our_funding_pubkey,
const struct basepoints *ours,
u32 minimum_depth,
u32 min_feerate, u32 max_feerate, const u8 *peer_msg)
static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
{
struct channel_id id_in;
struct basepoints theirs;
@ -576,7 +580,7 @@ static u8 *fundee_channel(struct state *state,
* `payment_basepoint`, or `delayed_payment_basepoint` are not valid
* DER-encoded compressed secp256k1 pubkeys.
*/
if (!fromwire_open_channel(peer_msg, &chain_hash,
if (!fromwire_open_channel(open_channel_msg, &chain_hash,
&state->channel_id,
&state->funding_satoshis, &state->push_msat,
&state->remoteconf->dust_limit_satoshis,
@ -595,7 +599,7 @@ static u8 *fundee_channel(struct state *state,
&channel_flags))
peer_failed(&state->cs, NULL,
"Bad open_channel %s",
tal_hex(peer_msg, peer_msg));
tal_hex(open_channel_msg, open_channel_msg));
/* BOLT #2:
*
@ -608,7 +612,7 @@ static u8 *fundee_channel(struct state *state,
&state->chainparams->genesis_blockhash)) {
negotiation_failed(state,
"Unknown chain-hash %s",
type_to_string(peer_msg,
type_to_string(tmpctx,
struct bitcoin_blkid,
&chain_hash));
}
@ -641,15 +645,15 @@ static u8 *fundee_channel(struct state *state,
* - it considers `feerate_per_kw` too small for timely processing or
* unreasonably large.
*/
if (state->feerate_per_kw < min_feerate)
if (state->feerate_per_kw < state->min_feerate)
negotiation_failed(state,
"feerate_per_kw %u below minimum %u",
state->feerate_per_kw, min_feerate);
state->feerate_per_kw, state->min_feerate);
if (state->feerate_per_kw > max_feerate)
if (state->feerate_per_kw > state->max_feerate)
negotiation_failed(state,
"feerate_per_kw %u above maximum %u",
state->feerate_per_kw, max_feerate);
state->feerate_per_kw, state->max_feerate);
set_reserve(state);
@ -685,14 +689,14 @@ static u8 *fundee_channel(struct state *state,
.max_htlc_value_in_flight_msat,
state->localconf.channel_reserve_satoshis,
state->localconf.htlc_minimum_msat,
minimum_depth,
state->minimum_depth,
state->localconf.to_self_delay,
state->localconf.max_accepted_htlcs,
our_funding_pubkey,
&ours->revocation,
&ours->payment,
&ours->delayed_payment,
&ours->htlc,
&state->our_funding_pubkey,
&state->our_points.revocation,
&state->our_points.payment,
&state->our_points.delayed_payment,
&state->our_points.htlc,
&state->next_per_commit[LOCAL]);
sync_crypto_write(&state->cs, PEER_FD, take(msg));
@ -730,8 +734,8 @@ static u8 *fundee_channel(struct state *state,
state->feerate_per_kw,
&state->localconf,
state->remoteconf,
ours, &theirs,
our_funding_pubkey,
&state->our_points, &theirs,
&state->our_funding_pubkey,
&their_funding_pubkey,
REMOTE);
if (!state->channel)
@ -788,6 +792,8 @@ static u8 *fundee_channel(struct state *state,
negotiation_failed(state,
"Could not meet their fees and reserve");
/* FIXME: Perhaps we should have channeld generate this, so we
* can't possibly send before channel committed? */
msg = towire_hsm_sign_remote_commitment_tx(NULL,
remote_commit,
&state->channel->funding_pubkey[REMOTE],
@ -803,43 +809,165 @@ static u8 *fundee_channel(struct state *state,
* to save state to disk before doing so. */
msg = towire_funding_signed(state, &state->channel_id, &sig);
return towire_opening_fundee_reply(state,
state->remoteconf,
local_commit,
&theirsig,
&state->cs,
&theirs.revocation,
&theirs.payment,
&theirs.htlc,
&theirs.delayed_payment,
&state->next_per_commit[REMOTE],
&their_funding_pubkey,
&state->funding_txid,
state->funding_txout,
state->funding_satoshis,
state->push_msat,
channel_flags,
state->feerate_per_kw,
msg,
state->localconf.channel_reserve_satoshis);
return towire_opening_fundee(state,
state->remoteconf,
local_commit,
&theirsig,
&state->cs,
&theirs.revocation,
&theirs.payment,
&theirs.htlc,
&theirs.delayed_payment,
&state->next_per_commit[REMOTE],
&their_funding_pubkey,
&state->funding_txid,
state->funding_txout,
state->funding_satoshis,
state->push_msat,
channel_flags,
state->feerate_per_kw,
msg,
state->localconf.channel_reserve_satoshis);
}
#ifndef TESTING
int main(int argc, char *argv[])
static u8 *handle_peer_in(struct state *state)
{
setup_locale();
u8 *msg = sync_crypto_read(NULL, &state->cs, PEER_FD);
enum wire_type t = fromwire_peektype(msg);
struct channel_id channel_id;
u8 *msg, *peer_msg;
struct state *state = tal(NULL, struct state);
struct basepoints our_points;
struct pubkey our_funding_pubkey;
u32 minimum_depth;
u32 min_feerate, max_feerate;
switch (t) {
case WIRE_OPEN_CHANNEL:
return fundee_channel(state, msg);
/* These are handled by handle_peer_gossip_or_error. */
case WIRE_PING:
case WIRE_PONG:
case WIRE_CHANNEL_ANNOUNCEMENT:
case WIRE_NODE_ANNOUNCEMENT:
case WIRE_CHANNEL_UPDATE:
case WIRE_QUERY_SHORT_CHANNEL_IDS:
case WIRE_REPLY_SHORT_CHANNEL_IDS_END:
case WIRE_QUERY_CHANNEL_RANGE:
case WIRE_REPLY_CHANNEL_RANGE:
case WIRE_GOSSIP_TIMESTAMP_FILTER:
case WIRE_ERROR:
case WIRE_CHANNEL_REESTABLISH:
/* These are all protocol violations at this stage. */
case WIRE_INIT:
case WIRE_ACCEPT_CHANNEL:
case WIRE_FUNDING_CREATED:
case WIRE_FUNDING_SIGNED:
case WIRE_FUNDING_LOCKED:
case WIRE_SHUTDOWN:
case WIRE_CLOSING_SIGNED:
case WIRE_UPDATE_ADD_HTLC:
case WIRE_UPDATE_FULFILL_HTLC:
case WIRE_UPDATE_FAIL_HTLC:
case WIRE_UPDATE_FAIL_MALFORMED_HTLC:
case WIRE_COMMITMENT_SIGNED:
case WIRE_REVOKE_AND_ACK:
case WIRE_UPDATE_FEE:
case WIRE_ANNOUNCEMENT_SIGNATURES:
/* Standard cases */
if (handle_peer_gossip_or_error(PEER_FD, GOSSIP_FD, &state->cs,
&state->channel_id, msg))
return NULL;
break;
}
sync_crypto_write(&state->cs, PEER_FD,
take(towire_errorfmt(NULL,
extract_channel_id(msg, &channel_id) ? &channel_id : NULL,
"Unexpected message %s: %s",
wire_type_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.
*/
status_broken("Unexpected message %s", wire_type_name(t));
peer_failed_connection_lost();
}
static void handle_gossip_in(struct state *state)
{
u8 *msg = wire_sync_read(NULL, GOSSIP_FD);
if (!msg)
status_failed(STATUS_FAIL_GOSSIP_IO,
"Reading gossip: %s", strerror(errno));
handle_gossip_msg(PEER_FD, &state->cs, take(msg));
}
static bool is_all_channel_error(const u8 *msg)
{
struct channel_id channel_id;
u8 *data;
if (!fromwire_error(msg, msg, &channel_id, &data))
return false;
tal_free(data);
return channel_id_is_all(&channel_id);
}
static void fail_if_all_error(const u8 *inner)
{
if (!is_all_channel_error(inner))
return;
status_info("Master said send err: %s",
sanitize_error(tmpctx, inner, NULL));
exit(0);
}
static u8 *handle_master_in(struct state *state)
{
u8 *msg = wire_sync_read(state, REQ_FD);
enum opening_wire_type t = fromwire_peektype(msg);
u64 change_satoshis;
u32 change_keyindex;
u8 channel_flags;
struct utxo **utxos;
struct ext_key bip32_base;
switch (t) {
case WIRE_OPENING_FUNDER:
if (!fromwire_opening_funder(state, msg,
&state->funding_satoshis,
&state->push_msat,
&state->feerate_per_kw,
&change_satoshis, &change_keyindex,
&channel_flags, &utxos,
&bip32_base))
master_badmsg(WIRE_OPENING_FUNDER, msg);
msg = funder_channel(state,
change_satoshis,
change_keyindex, channel_flags,
utxos, &bip32_base);
peer_billboard(false,
"Funding channel: opening negotiation succeeded");
return msg;
case WIRE_OPENING_INIT:
case WIRE_OPENING_FUNDER_REPLY:
case WIRE_OPENING_FUNDEE:
break;
}
status_failed(STATUS_FAIL_MASTER_IO,
"Unknown msg %s", tal_hex(tmpctx, msg));
}
int main(int argc, char *argv[])
{
setup_locale();
u8 *msg, *inner;
struct pollfd pollfd[3];
struct state *state = tal(NULL, struct state);
u32 network_index;
struct secret *none;
@ -847,20 +975,32 @@ int main(int argc, char *argv[])
status_setup_sync(REQ_FD);
msg = wire_sync_read(state, REQ_FD);
if (!fromwire_opening_init(msg,
msg = wire_sync_read(tmpctx, REQ_FD);
if (!fromwire_opening_init(tmpctx, msg,
&network_index,
&state->localconf,
&state->max_to_self_delay,
&state->min_effective_htlc_capacity_msat,
&state->cs,
&our_points,
&our_funding_pubkey))
&state->our_points,
&state->our_funding_pubkey,
&state->minimum_depth,
&state->min_feerate, &state->max_feerate,
&inner))
master_badmsg(WIRE_OPENING_INIT, msg);
tal_free(msg);
/* If they wanted to send an msg, do so before we waste time
* doing work. If it's a global error, we'll close
* immediately. */
if (inner != NULL) {
sync_crypto_write(&state->cs, PEER_FD, inner);
fail_if_all_error(inner);
}
state->chainparams = chainparams_by_index(network_index);
/* Initially we're not associated with a channel, but
* handle_peer_gossip_or_error wants this. */
memset(&state->channel_id, 0, sizeof(state->channel_id));
wire_sync_write(HSM_FD,
take(towire_hsm_get_per_commitment_point(NULL, 0)));
@ -872,33 +1012,28 @@ int main(int argc, char *argv[])
"Bad get_per_commitment_point_reply %s",
tal_hex(tmpctx, msg));
assert(none == NULL);
status_trace("First per_commit_point = %s",
type_to_string(tmpctx, struct pubkey,
&state->next_per_commit[LOCAL]));
msg = wire_sync_read(state, REQ_FD);
if (fromwire_opening_funder(state, msg,
&state->funding_satoshis,
&state->push_msat,
&state->feerate_per_kw,
&change_satoshis, &change_keyindex,
&channel_flags, &utxos, &bip32_base)) {
msg = funder_channel(state, &our_funding_pubkey, &our_points,
change_satoshis,
change_keyindex, channel_flags,
utxos, &bip32_base);
peer_billboard(false,
"Funding channel: opening negotiation succeeded");
} else if (fromwire_opening_fundee(state, msg, &minimum_depth,
&min_feerate, &max_feerate, &peer_msg)) {
msg = fundee_channel(state, &our_funding_pubkey, &our_points,
minimum_depth, min_feerate, max_feerate,
peer_msg);
peer_billboard(false,
"Incoming channel: opening negotiation succeeded");
} else
status_failed(STATUS_FAIL_MASTER_IO,
"neither funder nor fundee: %s",
tal_hex(msg, msg));
status_trace("Handed peer, entering loop");
pollfd[0].fd = REQ_FD;
pollfd[0].events = POLLIN;
pollfd[1].fd = GOSSIP_FD;
pollfd[1].events = POLLIN;
pollfd[2].fd = PEER_FD;
pollfd[2].events = POLLIN;
msg = NULL;
while (!msg) {
poll(pollfd, ARRAY_SIZE(pollfd), -1);
/* Subtle: handle_master_in can do its own poll loop, so
* don't try to service more than one fd per loop. */
if (pollfd[0].revents & POLLIN)
msg = handle_master_in(state);
else if (pollfd[1].revents & POLLIN)
handle_gossip_in(state);
else if (pollfd[2].revents & POLLIN)
msg = handle_peer_in(state);
clean_tmpctx();
}
/* Write message and hand back the fd. */
wire_sync_write(REQ_FD, msg);
@ -910,4 +1045,3 @@ int main(int argc, char *argv[])
daemon_shutdown();
return 0;
}
#endif /* TESTING */

View File

@ -13,10 +13,17 @@ opening_init,,min_effective_htlc_capacity_msat,u64
opening_init,,crypto_state,struct crypto_state
opening_init,,our_basepoints,struct basepoints
opening_init,,our_funding_pubkey,struct pubkey
# Constraints in case the other end tries to open a channel.
opening_init,,minimum_depth,u32
opening_init,,min_feerate,u32
opening_init,,max_feerate,u32
# Optional msg to send.
opening_init,,len,u16
opening_init,,msg,len*u8
#include <common/bip32.h>
#include <common/htlc_wire.h>
# This means we offer the open.
# Master->openingd: please fund a channel.
opening_funder,6001
opening_funder,,funding_satoshis,u64
opening_funder,,push_msat,u64
@ -29,6 +36,7 @@ opening_funder,,num_inputs,u16
opening_funder,,inputs,num_inputs*struct utxo
opening_funder,,bip32,struct ext_key
# Openingd->master: we've successfully offered channel.
# This gives their sig, means we can broadcast tx: we're done.
opening_funder_reply,6101
opening_funder_reply,,their_config,struct channel_config
@ -46,33 +54,26 @@ opening_funder_reply,,funding_txid,struct bitcoin_txid
opening_funder_reply,,feerate_per_kw,u32
opening_funder_reply,,our_channel_reserve_satoshis,u64
# This means they offer the open (contains their offer packet)
opening_fundee,6003
opening_fundee,,minimum_depth,u32
opening_fundee,,min_feerate,u32
opening_fundee,,max_feerate,u32
opening_fundee,,len,u16
opening_fundee,,msg,len*u8
# Openingd->master: they offered channel.
# This gives their txid and info, means we can send funding_signed: we're done.
opening_fundee_reply,6103
opening_fundee_reply,,their_config,struct channel_config
opening_fundee_reply,,first_commit,struct bitcoin_tx
opening_fundee_reply,,first_commit_sig,secp256k1_ecdsa_signature
opening_fundee_reply,,crypto_state,struct crypto_state
opening_fundee_reply,,revocation_basepoint,struct pubkey
opening_fundee_reply,,payment_basepoint,struct pubkey
opening_fundee_reply,,htlc_basepoint,struct pubkey
opening_fundee_reply,,delayed_payment_basepoint,struct pubkey
opening_fundee_reply,,their_per_commit_point,struct pubkey
opening_fundee_reply,,remote_fundingkey,struct pubkey
opening_fundee_reply,,funding_txid,struct bitcoin_txid
opening_fundee_reply,,funding_txout,u16
opening_fundee_reply,,funding_satoshis,u64
opening_fundee_reply,,push_msat,u64
opening_fundee_reply,,channel_flags,u8
opening_fundee_reply,,feerate_per_kw,u32
# The (encrypted) funding signed message: send this and we're committed.
opening_fundee_reply,,msglen,u16
opening_fundee_reply,,funding_signed_msg,msglen*u8
opening_fundee_reply,,our_channel_reserve_satoshis,u64
opening_fundee,6003
opening_fundee,,their_config,struct channel_config
opening_fundee,,first_commit,struct bitcoin_tx
opening_fundee,,first_commit_sig,secp256k1_ecdsa_signature
opening_fundee,,crypto_state,struct crypto_state
opening_fundee,,revocation_basepoint,struct pubkey
opening_fundee,,payment_basepoint,struct pubkey
opening_fundee,,htlc_basepoint,struct pubkey
opening_fundee,,delayed_payment_basepoint,struct pubkey
opening_fundee,,their_per_commit_point,struct pubkey
opening_fundee,,remote_fundingkey,struct pubkey
opening_fundee,,funding_txid,struct bitcoin_txid
opening_fundee,,funding_txout,u16
opening_fundee,,funding_satoshis,u64
opening_fundee,,push_msat,u64
opening_fundee,,channel_flags,u8
opening_fundee,,feerate_per_kw,u32
# The funding signed message: send this and we're committed.
opening_fundee,,msglen,u16
opening_fundee,,funding_signed_msg,msglen*u8
opening_fundee,,our_channel_reserve_satoshis,u64

1 #include <common/cryptomsg.h>
13 opening_init,,our_basepoints,struct basepoints
14 opening_init,,our_funding_pubkey,struct pubkey
15 #include <common/bip32.h> # Constraints in case the other end tries to open a channel.
16 opening_init,,minimum_depth,u32
17 opening_init,,min_feerate,u32
18 opening_init,,max_feerate,u32
19 # Optional msg to send.
20 opening_init,,len,u16
21 opening_init,,msg,len*u8
22 #include <common/bip32.h>
23 #include <common/htlc_wire.h>
24 # This means we offer the open. # Master->openingd: please fund a channel.
25 opening_funder,6001
26 opening_funder,,funding_satoshis,u64
27 opening_funder,,push_msat,u64
28 opening_funder,,feerate_per_kw,u32
29 opening_funder,,change_satoshis,u64
36 # This gives their sig, means we can broadcast tx: we're done. # Openingd->master: we've successfully offered channel.
37 opening_funder_reply,6101 # This gives their sig, means we can broadcast tx: we're done.
38 opening_funder_reply,,their_config,struct channel_config opening_funder_reply,6101
39 opening_funder_reply,,their_config,struct channel_config
40 opening_funder_reply,,first_commit,struct bitcoin_tx
41 opening_funder_reply,,first_commit_sig,secp256k1_ecdsa_signature
42 opening_funder_reply,,crypto_state,struct crypto_state
54 opening_fundee,6003 # This gives their txid and info, means we can send funding_signed: we're done.
55 opening_fundee,,minimum_depth,u32 opening_fundee,6003
56 opening_fundee,,min_feerate,u32 opening_fundee,,their_config,struct channel_config
57 opening_fundee,,max_feerate,u32 opening_fundee,,first_commit,struct bitcoin_tx
opening_fundee,,len,u16
opening_fundee,,msg,len*u8
# This gives their txid and info, means we can send funding_signed: we're done.
opening_fundee_reply,6103
opening_fundee_reply,,their_config,struct channel_config
opening_fundee_reply,,first_commit,struct bitcoin_tx
opening_fundee_reply,,first_commit_sig,secp256k1_ecdsa_signature
58 opening_fundee_reply,,crypto_state,struct crypto_state opening_fundee,,first_commit_sig,secp256k1_ecdsa_signature
59 opening_fundee_reply,,revocation_basepoint,struct pubkey opening_fundee,,crypto_state,struct crypto_state
60 opening_fundee_reply,,payment_basepoint,struct pubkey opening_fundee,,revocation_basepoint,struct pubkey
61 opening_fundee_reply,,htlc_basepoint,struct pubkey opening_fundee,,payment_basepoint,struct pubkey
62 opening_fundee_reply,,delayed_payment_basepoint,struct pubkey opening_fundee,,htlc_basepoint,struct pubkey
63 opening_fundee_reply,,their_per_commit_point,struct pubkey opening_fundee,,delayed_payment_basepoint,struct pubkey
64 opening_fundee_reply,,remote_fundingkey,struct pubkey opening_fundee,,their_per_commit_point,struct pubkey
65 opening_fundee_reply,,funding_txid,struct bitcoin_txid opening_fundee,,remote_fundingkey,struct pubkey
66 opening_fundee_reply,,funding_txout,u16 opening_fundee,,funding_txid,struct bitcoin_txid
67 opening_fundee_reply,,funding_satoshis,u64 opening_fundee,,funding_txout,u16
68 opening_fundee_reply,,push_msat,u64 opening_fundee,,funding_satoshis,u64
69 opening_fundee_reply,,channel_flags,u8 opening_fundee,,push_msat,u64
70 opening_fundee_reply,,feerate_per_kw,u32 opening_fundee,,channel_flags,u8
71 # The (encrypted) funding signed message: send this and we're committed. opening_fundee,,feerate_per_kw,u32
72 opening_fundee_reply,,msglen,u16 # The funding signed message: send this and we're committed.
73 opening_fundee_reply,,funding_signed_msg,msglen*u8 opening_fundee,,msglen,u16
74 opening_fundee_reply,,our_channel_reserve_satoshis,u64 opening_fundee,,funding_signed_msg,msglen*u8
75 opening_fundee,,our_channel_reserve_satoshis,u64
76
77
78
79

View File

@ -130,7 +130,7 @@ def test_closing_id(node_factory):
# Close by peer ID.
l2.rpc.connect(l1.info['id'], 'localhost', l1.port)
l1.daemon.wait_for_log("hand_back_peer .*: now local again")
l1.daemon.wait_for_log("Handed peer, entering loop")
l2.fund_channel(l1, 10**6)
pid = l1.info['id']
l2.rpc.close(pid)

View File

@ -11,13 +11,11 @@ import unittest
def test_connect(node_factory):
l1, l2 = node_factory.line_graph(2, fundchannel=False)
# These should be in gossipd.
assert l1.rpc.getpeer(l2.info['id'])['state'] == 'GOSSIPING'
assert l2.rpc.getpeer(l1.info['id'])['state'] == 'GOSSIPING'
# Both gossipds will have them as new peers once handed back.
l1.daemon.wait_for_log('hand_back_peer {}: now local again'.format(l2.info['id']))
l2.daemon.wait_for_log('hand_back_peer {}: now local again'.format(l1.info['id']))
# These should be in openingd.
assert l1.rpc.getpeer(l2.info['id'])['connected']
assert l2.rpc.getpeer(l1.info['id'])['connected']
assert len(l1.rpc.getpeer(l2.info['id'])['channels']) == 0
assert len(l2.rpc.getpeer(l1.info['id'])['channels']) == 0
# Reconnect should be a noop
ret = l1.rpc.connect(l2.info['id'], 'localhost', port=l2.port)
@ -116,8 +114,8 @@ def test_bad_opening(node_factory):
assert ret['id'] == l2.info['id']
l1.daemon.wait_for_log('Handing back peer .* to master')
l2.daemon.wait_for_log('Handing back peer .* to master')
l1.daemon.wait_for_log('openingd-.*: Handed peer, entering loop')
l2.daemon.wait_for_log('openingd-.*: Handed peer, entering loop')
l1.fundwallet(10**6 + 1000000)
with pytest.raises(RpcError):
@ -291,7 +289,7 @@ def test_reconnect_openingd(node_factory):
l1.daemon.wait_for_log('sendrawtx exit 0')
# Just to be sure, second openingd hand over to channeld.
l2.daemon.wait_for_log('lightning_openingd.*REPLY WIRE_OPENING_FUNDEE_REPLY with 2 fds')
l2.daemon.wait_for_log('lightning_openingd.*UPDATE WIRE_OPENING_FUNDEE')
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1")
@ -545,6 +543,7 @@ def test_funding_all_too_much(node_factory):
assert only_one(l1.rpc.listfunds()['channels'])['channel_total_sat'] == 2**24 - 1
@unittest.skip("FIXME: Disabled during transition: openingd closes on negotiation fail")
def test_funding_fail(node_factory, bitcoind):
"""Add some funds, fund a channel without enough funds"""
# Previous runs with same bitcoind can leave funds!
@ -902,8 +901,8 @@ def test_multiple_channels(node_factory):
ret = l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
assert ret['id'] == l2.info['id']
l1.daemon.wait_for_log('Handing back peer .* to master')
l2.daemon.wait_for_log('Handing back peer .* to master')
l1.daemon.wait_for_log('openingd-.*: Handed peer, entering loop')
l2.daemon.wait_for_log('openingd-.*: Handed peer, entering loop')
chan = l1.fund_channel(l2, 10**6)
l1.rpc.close(chan)
@ -944,7 +943,8 @@ def test_forget_channel(node_factory):
def test_peerinfo(node_factory, bitcoind):
l1, l2 = node_factory.line_graph(2, fundchannel=False)
# Gossiping but no node announcement yet
assert l1.rpc.getpeer(l2.info['id'])['state'] == "GOSSIPING"
assert l1.rpc.getpeer(l2.info['id'])['connected']
assert len(l1.rpc.getpeer(l2.info['id'])['channels']) == 0
assert l1.rpc.getpeer(l2.info['id'])['local_features'] == '88'
assert l1.rpc.getpeer(l2.info['id'])['global_features'] == ''
@ -977,14 +977,17 @@ def test_peerinfo(node_factory, bitcoind):
assert l2.rpc.listnodes()['nodes'] == []
@unittest.skip("FIXME: Disabled during transition: disconnect not updated")
def test_disconnectpeer(node_factory, bitcoind):
l1, l2, l3 = node_factory.get_nodes(3, opts={'may_reconnect': False})
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.rpc.connect(l3.info['id'], 'localhost', l3.port)
# Gossiping
assert l1.rpc.getpeer(l2.info['id'])['state'] == "GOSSIPING"
assert l1.rpc.getpeer(l3.info['id'])['state'] == "GOSSIPING"
assert l1.rpc.getpeer(l2.info['id'])['connected']
assert len(l1.rpc.getpeer(l2.info['id'])['channels']) == 0
assert l1.rpc.getpeer(l3.info['id'])['connected']
assert len(l1.rpc.getpeer(l3.info['id'])['channels']) == 0
# Disconnect l2 from l1
l1.rpc.disconnect(l2.info['id'])

View File

@ -471,14 +471,16 @@ def test_gossip_no_empty_announcements(node_factory, bitcoind):
may_reconnect=True)
l4 = node_factory.get_node(may_reconnect=True)
# Turn on IO logging for connectd
subprocess.run(['kill', '-USR1', l1.subd_pid('connectd')])
subprocess.run(['kill', '-USR1', l2.subd_pid('connectd')])
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
l3.rpc.connect(l4.info['id'], 'localhost', l4.port)
# Turn on IO logging for openingd (make sure it's ready!)
l1.daemon.wait_for_log('openingd-.*: Handed peer, entering loop')
subprocess.run(['kill', '-USR1', l1.subd_pid('openingd')])
l2.daemon.wait_for_log('openingd-{}.*: Handed peer, entering loop'.format(l3.info['id']))
subprocess.run(['kill', '-USR1', l2.subd_pid('openingd-{}'.format(l3.info['id']))])
# Make an announced-but-not-updated channel.
l3.fund_channel(l4, 10**5)
bitcoind.generate_block(5)
@ -731,8 +733,9 @@ def test_query_short_channel_id(node_factory, bitcoind):
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
# Need full IO logging so we can see gossip (from connectd and channeld)
subprocess.run(['kill', '-USR1', l1.subd_pid('connectd')])
# Need full IO logging so we can see gossip (from openingd and channeld)
l1.daemon.wait_for_log('openingd-.*: Handed peer, entering loop')
subprocess.run(['kill', '-USR1', l1.subd_pid('openingd')])
# Empty result tests.
reply = l1.rpc.dev_query_scids(l2.info['id'], ['1:1:1', '2:2:2'])

View File

@ -826,14 +826,14 @@ def test_forward_different_fees_and_cltv(node_factory, bitcoind):
ret = l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
assert ret['id'] == l2.info['id']
l1.daemon.wait_for_log('Handing back peer .* to master')
l2.daemon.wait_for_log('Handing back peer .* to master')
l1.daemon.wait_for_log('openingd-.*: Handed peer, entering loop')
l2.daemon.wait_for_log('openingd-.*: Handed peer, entering loop')
ret = l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
assert ret['id'] == l3.info['id']
l2.daemon.wait_for_log('Handing back peer .* to master')
l3.daemon.wait_for_log('Handing back peer .* to master')
l2.daemon.wait_for_log('openingd-.*: Handed peer, entering loop')
l3.daemon.wait_for_log('openingd-.*: Handed peer, entering loop')
c1 = l1.fund_channel(l2, 10**6)
c2 = l2.fund_channel(l3, 10**6)
@ -933,14 +933,14 @@ def test_forward_pad_fees_and_cltv(node_factory, bitcoind):
ret = l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
assert ret['id'] == l2.info['id']
l1.daemon.wait_for_log('Handing back peer .* to master')
l2.daemon.wait_for_log('Handing back peer .* to master')
l1.daemon.wait_for_log('openingd-.*: Handed peer, entering loop')
l2.daemon.wait_for_log('openingd-.*: Handed peer, entering loop')
ret = l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
assert ret['id'] == l3.info['id']
l2.daemon.wait_for_log('Handing back peer .* to master')
l3.daemon.wait_for_log('Handing back peer .* to master')
l2.daemon.wait_for_log('openingd-.*: Handed peer, entering loop')
l3.daemon.wait_for_log('openingd-.*: Handed peer, entering loop')
c1 = l1.fund_channel(l2, 10**6)
c2 = l2.fund_channel(l3, 10**6)

View File

@ -59,12 +59,6 @@ void command_still_pending(struct command *cmd UNNEEDED)
/* Generated stub for command_success */
void command_success(struct command *cmd UNNEEDED, struct json_result *response UNNEEDED)
{ fprintf(stderr, "command_success called!\n"); abort(); }
/* Generated stub for extract_channel_id */
bool extract_channel_id(const u8 *in_pkt UNNEEDED, struct channel_id *channel_id UNNEEDED)
{ fprintf(stderr, "extract_channel_id called!\n"); abort(); }
/* Generated stub for features_supported */
bool features_supported(const u8 *gfeatures UNNEEDED, const u8 *lfeatures UNNEEDED)
{ fprintf(stderr, "features_supported called!\n"); abort(); }
/* Generated stub for fromwire_connectctl_peer_disconnect_reply */
bool fromwire_connectctl_peer_disconnect_reply(const void *p UNNEEDED)
{ fprintf(stderr, "fromwire_connectctl_peer_disconnect_reply called!\n"); abort(); }
@ -83,20 +77,6 @@ bool fromwire_hsm_sign_commitment_tx_reply(const void *p UNNEEDED, secp256k1_ecd
/* Generated stub for get_feerate */
u32 get_feerate(const struct chain_topology *topo UNNEEDED, enum feerate feerate UNNEEDED)
{ fprintf(stderr, "get_feerate called!\n"); abort(); }
/* Generated stub for get_offered_global_features */
u8 *get_offered_global_features(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "get_offered_global_features called!\n"); abort(); }
/* Generated stub for get_offered_local_features */
u8 *get_offered_local_features(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "get_offered_local_features called!\n"); abort(); }
/* Generated stub for handle_opening_channel */
bool handle_opening_channel(struct lightningd *ld UNNEEDED,
const struct pubkey *id UNNEEDED,
const struct wireaddr_internal *addr UNNEEDED,
const struct crypto_state *cs UNNEEDED,
const u8 *gfeatures UNNEEDED, const u8 *lfeatures UNNEEDED,
int peer_fd UNNEEDED, int gossip_fd UNNEEDED)
{ fprintf(stderr, "handle_opening_channel called!\n"); abort(); }
/* Generated stub for invoices_autoclean_set */
void invoices_autoclean_set(struct invoices *invoices UNNEEDED,
u64 cycle_seconds UNNEEDED,
@ -304,17 +284,6 @@ void outpointfilter_remove(struct outpointfilter *of UNNEEDED,
bool param(struct command *cmd UNNEEDED, const char *buffer UNNEEDED,
const jsmntok_t params[] UNNEEDED, ...)
{ fprintf(stderr, "param called!\n"); abort(); }
/* Generated stub for peer_accept_channel */
u8 *peer_accept_channel(const tal_t *ctx UNNEEDED,
struct lightningd *ld UNNEEDED,
const struct pubkey *peer_id UNNEEDED,
const struct wireaddr_internal *addr UNNEEDED,
const struct crypto_state *cs UNNEEDED,
const u8 *gfeatures UNNEEDED, const u8 *lfeatures UNNEEDED,
int peer_fd UNNEEDED, int gossip_fd UNNEEDED,
const struct channel_id *channel_id UNNEEDED,
const u8 *open_msg UNNEEDED)
{ fprintf(stderr, "peer_accept_channel called!\n"); abort(); }
/* Generated stub for peer_start_channeld */
bool peer_start_channeld(struct channel *channel UNNEEDED,
const struct crypto_state *cs UNNEEDED,
@ -329,6 +298,12 @@ void peer_start_closingd(struct channel *channel UNNEEDED,
bool reconnected UNNEEDED,
const u8 *channel_reestablish UNNEEDED)
{ fprintf(stderr, "peer_start_closingd called!\n"); abort(); }
/* Generated stub for peer_start_openingd */
void peer_start_openingd(struct peer *peer UNNEEDED,
const struct crypto_state *cs UNNEEDED,
int peer_fd UNNEEDED, int gossip_fd UNNEEDED,
const u8 *msg UNNEEDED)
{ fprintf(stderr, "peer_start_openingd called!\n"); abort(); }
/* Generated stub for subd_release_channel */
void subd_release_channel(struct subd *owner UNNEEDED, void *channel UNNEEDED)
{ fprintf(stderr, "subd_release_channel called!\n"); abort(); }