openingd: get told if we can't let them open a new channel.

Previously master would fail once the channel has been negotiated,
which is terrible, since the funder will have already broadcast tx.

Now we tell them if we have an active channel, and update if it goes away.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2018-08-09 09:55:29 +09:30 committed by Christian Decker
parent 9ad2b26224
commit 909cd4136b
6 changed files with 49 additions and 17 deletions

View File

@ -12,6 +12,7 @@
#include <lightningd/jsonrpc.h>
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/opening_control.h>
#include <lightningd/peer_control.h>
#include <lightningd/subd.h>
#include <wire/wire_sync.h>
@ -300,6 +301,8 @@ void channel_set_state(struct channel *channel,
enum channel_state old_state,
enum channel_state state)
{
bool was_active = channel_active(channel);
log_info(channel->log, "State changed from %s to %s",
channel_state_name(channel), channel_state_str(state));
if (channel->state != old_state)
@ -310,6 +313,11 @@ void channel_set_state(struct channel *channel,
/* TODO(cdecker) Selectively save updated fields to DB */
wallet_channel_save(channel->peer->ld->wallet, channel);
/* If openingd is running, it might want to know we're no longer
* active */
if (was_active && !channel_active(channel))
opening_peer_no_active_channels(channel->peer);
}
void channel_fail_permanent(struct channel *channel, const char *fmt, ...)

View File

@ -463,26 +463,11 @@ 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. */
/* openingd should never accept them funding channel in this case. */
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");
log_broken(uc->log, "openingd accepted peer funding 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;
}
@ -663,6 +648,7 @@ static unsigned int openingd_msg(struct subd *openingd,
/* We send these! */
case WIRE_OPENING_INIT:
case WIRE_OPENING_FUNDER:
case WIRE_OPENING_CAN_ACCEPT_CHANNEL:
break;
}
log_broken(openingd->log, "Unexpected msg %s: %s",
@ -727,10 +713,20 @@ void peer_start_openingd(struct peer *peer,
&uc->local_funding_pubkey,
uc->minimum_depth,
feerate_min(peer->ld), feerate_max(peer->ld),
!peer_active_channel(peer),
send_msg);
subd_send_msg(uc->openingd, take(msg));
}
void opening_peer_no_active_channels(struct peer *peer)
{
assert(!peer_active_channel(peer));
if (peer->uncommitted_channel) {
subd_send_msg(peer->uncommitted_channel->openingd,
take(towire_opening_can_accept_channel(NULL)));
}
}
/**
* json_fund_channel - Entrypoint for funding a channel
*/

View File

@ -17,6 +17,8 @@ void peer_start_openingd(struct peer *peer,
int peer_fd, int gossip_fd,
const u8 *msg);
void opening_peer_no_active_channels(struct peer *peer);
void kill_uncommitted_channel(struct uncommitted_channel *uc,
const char *why);

View File

@ -69,6 +69,7 @@ struct state {
struct channel *channel;
bool can_accept_channel;
const struct chainparams *chainparams;
};
@ -601,6 +602,17 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
"Bad open_channel %s",
tal_hex(open_channel_msg, open_channel_msg));
/* We can't handle talking about more than one channel at once. */
if (!state->can_accept_channel) {
u8 *errmsg;
errmsg = towire_errorfmt(NULL, &state->channel_id,
"Already have active channel");
sync_crypto_write(&state->cs, PEER_FD, take(errmsg));
state->remoteconf = tal_free(state->remoteconf);
return NULL;
}
/* BOLT #2:
*
* The receiver:
@ -951,6 +963,12 @@ static u8 *handle_master_in(struct state *state)
"Funding channel: opening negotiation succeeded");
return msg;
case WIRE_OPENING_CAN_ACCEPT_CHANNEL:
if (!fromwire_opening_can_accept_channel(msg))
master_badmsg(WIRE_OPENING_CAN_ACCEPT_CHANNEL, msg);
state->can_accept_channel = true;
return NULL;
case WIRE_OPENING_INIT:
case WIRE_OPENING_FUNDER_REPLY:
case WIRE_OPENING_FUNDEE:
@ -986,6 +1004,7 @@ int main(int argc, char *argv[])
&state->our_funding_pubkey,
&state->minimum_depth,
&state->min_feerate, &state->max_feerate,
&state->can_accept_channel,
&inner))
master_badmsg(WIRE_OPENING_INIT, msg);

View File

@ -17,10 +17,14 @@ opening_init,,our_funding_pubkey,struct pubkey
opening_init,,minimum_depth,u32
opening_init,,min_feerate,u32
opening_init,,max_feerate,u32
opening_init,,can_open_channel,bool
# Optional msg to send.
opening_init,,len,u16
opening_init,,msg,len*u8
# Master->openingd: they can now open a channel if they want.
opening_can_accept_channel,6002
#include <common/bip32.h>
#include <common/htlc_wire.h>
# Master->openingd: please fund a channel.

1 #include <common/cryptomsg.h>
17 opening_init,,min_feerate,u32
18 opening_init,,max_feerate,u32
19 # Optional msg to send. opening_init,,can_open_channel,bool
20 # Optional msg to send.
21 opening_init,,len,u16
22 opening_init,,msg,len*u8
23 #include <common/bip32.h> # Master->openingd: they can now open a channel if they want.
24 #include <common/htlc_wire.h> opening_can_accept_channel,6002
25 #include <common/bip32.h>
26 #include <common/htlc_wire.h>
27 # Master->openingd: please fund a channel.
28 # Master->openingd: please fund a channel. opening_funder,6001
29 opening_funder,6001 opening_funder,,funding_satoshis,u64
30 opening_funder,,funding_satoshis,u64 opening_funder,,push_msat,u64

View File

@ -256,6 +256,9 @@ enum watch_result onchaind_funding_spent(struct channel *channel UNNEEDED,
const struct bitcoin_tx *tx UNNEEDED,
u32 blockheight UNNEEDED)
{ fprintf(stderr, "onchaind_funding_spent called!\n"); abort(); }
/* Generated stub for opening_peer_no_active_channels */
void opening_peer_no_active_channels(struct peer *peer UNNEEDED)
{ fprintf(stderr, "opening_peer_no_active_channels called!\n"); abort(); }
/* Generated stub for outpointfilter_add */
void outpointfilter_add(struct outpointfilter *of UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED, const u32 outnum UNNEEDED)