Browse Source

lightningd/opening: fix theoretical race.

We should start watching for the transaction before we send the
signature; we might miss it otherwise.  In practice, we only see
transactions as they enter a block, so it won't happen, but be
thorough.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 8 years ago
parent
commit
5f07e8405a
  1. 35
      lightningd/opening/opening.c
  2. 25
      lightningd/opening/opening_control_wire.csv
  3. 56
      lightningd/peer_control.c

35
lightningd/opening/opening.c

@ -656,6 +656,20 @@ static u8 *recv_channel(struct state *state, const struct points *ours,
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_BAD_PARAM, peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_BAD_PARAM,
"could not create channel with given config"); "could not create channel with given config");
/* Now, ask master to watch. */
status_trace("asking master to watch funding %s",
type_to_string(trc, struct sha256_double, &state->funding_txid));
msg = towire_opening_accept_resp(state, &state->funding_txid);
wire_sync_write(REQ_FD, msg);
msg = wire_sync_read(state, REQ_FD);
if (!fromwire_opening_accept_finish(msg, NULL))
status_failed(WIRE_OPENING_BAD_PARAM,
"Expected valid opening_accept_finish: %s",
tal_hex(trc, msg));
status_trace("master said to finish");
/* BOLT #2: /* BOLT #2:
* *
* The recipient MUST fail the channel if `signature` is incorrect. * The recipient MUST fail the channel if `signature` is incorrect.
@ -703,17 +717,16 @@ static u8 *recv_channel(struct state *state, const struct points *ours,
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_WRITE_FAILED, peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_WRITE_FAILED,
"Writing funding_signed"); "Writing funding_signed");
return towire_opening_accept_resp(state, return towire_opening_accept_finish_resp(state,
&state->funding_txid, state->funding_txout,
state->funding_txout, state->remoteconf,
state->remoteconf, &theirsig,
&theirsig, &state->cs,
&state->cs, &theirs.funding_pubkey,
&theirs.funding_pubkey, &theirs.revocation_basepoint,
&theirs.revocation_basepoint, &theirs.payment_basepoint,
&theirs.payment_basepoint, &theirs.delayed_payment_basepoint,
&theirs.delayed_payment_basepoint, &state->next_per_commit[REMOTE]);
&state->next_per_commit[REMOTE]);
} }
#ifndef TESTING #ifndef TESTING

25
lightningd/opening/opening_control_wire.csv

@ -44,18 +44,23 @@ opening_accept,4,max_feerate,4
opening_accept,8,len,2 opening_accept,8,len,2
opening_accept,10,msg,len,u8 opening_accept,10,msg,len,u8
# This gives the txid of their funding tx: we're done. # This gives the txid of their funding tx to watch.
opening_accept_resp,103 opening_accept_resp,103
opening_accept_resp,0,funding_txid,32,struct sha256_double opening_accept_resp,0,funding_txid,32,struct sha256_double
opening_accept_resp,32,funding_txout,2,u16
opening_accept_resp,33,their_config,36,struct channel_config # Acknowledge watch is in place, now can send sig.
opening_accept_resp,69,first_commit_sig,64,secp256k1_ecdsa_signature opening_accept_finish,4
opening_accept_resp,133,crypto_state,144,struct crypto_state
opening_accept_resp,277,remote_fundingkey,33 opening_accept_finish_resp,104
opening_accept_resp,310,revocation_basepoint,33 opening_accept_finish_resp,32,funding_txout,2,u16
opening_accept_resp,343,payment_basepoint,33 opening_accept_finish_resp,0,their_config,36,struct channel_config
opening_accept_resp,376,delayed_payment_basepoint,33 opening_accept_finish_resp,36,first_commit_sig,64,secp256k1_ecdsa_signature
opening_accept_resp,409,their_per_commit_point,33 opening_accept_finish_resp,100,crypto_state,144,struct crypto_state
opening_accept_finish_resp,244,remote_fundingkey,33
opening_accept_finish_resp,277,revocation_basepoint,33
opening_accept_finish_resp,310,payment_basepoint,33
opening_accept_finish_resp,343,delayed_payment_basepoint,33
opening_accept_finish_resp,377,their_per_commit_point,33
# You're OK to exit. # You're OK to exit.
opening_exit_req,99 opening_exit_req,99

Can't render this file because it has a wrong number of fields in line 3.

56
lightningd/peer_control.c

@ -531,13 +531,15 @@ static enum watch_result funding_depth_cb(struct peer *peer,
const struct sha256_double *txid, const struct sha256_double *txid,
void *unused) void *unused)
{ {
const char *txidstr = type_to_string(peer, struct sha256_double, txid);
log_debug(peer->log, "Funding tx %s depth %u of %u",
txidstr, depth, peer->ld->dstate.config.anchor_confirms);
if (depth >= peer->ld->dstate.config.anchor_confirms) { if (depth >= peer->ld->dstate.config.anchor_confirms) {
peer_set_condition(peer, "Funding tx reached depth %u", depth); peer_set_condition(peer, "Funding tx reached depth %u", depth);
/* FIXME! Start channel proper... */ /* FIXME! Start channel proper... */
return DELETE_WATCH; return DELETE_WATCH;
} }
log_debug(peer->log, "Funding tx depth %u of %u", depth,
peer->ld->dstate.config.anchor_confirms);
return KEEP_WATCHING; return KEEP_WATCHING;
} }
@ -642,10 +644,10 @@ static void opening_gen_funding(struct subdaemon *opening, const u8 *resp,
opening_release_tx, fc); opening_release_tx, fc);
} }
static void opening_accept_response(struct subdaemon *opening, const u8 *resp, static void opening_accept_finish_response(struct subdaemon *opening,
struct peer *peer) const u8 *resp,
struct peer *peer)
{ {
struct sha256_double funding_txid;
u16 funding_txout; u16 funding_txout;
struct channel_config their_config; struct channel_config their_config;
secp256k1_ecdsa_signature first_commit_sig; secp256k1_ecdsa_signature first_commit_sig;
@ -654,23 +656,47 @@ static void opening_accept_response(struct subdaemon *opening, const u8 *resp,
payment_basepoint, delayed_payment_basepoint, payment_basepoint, delayed_payment_basepoint,
their_per_commit_point; their_per_commit_point;
log_debug(peer->log, "Got opening_accept_response"); log_debug(peer->log, "Got opening_accept_finish_response");
if (!fromwire_opening_accept_resp(resp, NULL, if (!fromwire_opening_accept_finish_resp(resp, NULL,
&funding_txid, &funding_txout, &funding_txout,
&their_config, &first_commit_sig, &their_config,
&crypto_state, &remote_fundingkey, &first_commit_sig,
&revocation_basepoint, &crypto_state,
&payment_basepoint, &remote_fundingkey,
&delayed_payment_basepoint, &revocation_basepoint,
&their_per_commit_point)) { &payment_basepoint,
log_broken(peer->log, "bad OPENING_ACCEPT_RESP %s", &delayed_payment_basepoint,
&their_per_commit_point)) {
log_broken(peer->log, "bad OPENING_ACCEPT_FINISH_RESP %s",
tal_hex(resp, resp)); tal_hex(resp, resp));
tal_free(peer); tal_free(peer);
return;
} }
/* FIXME: Start normal channel daemon... */ /* FIXME: Start normal channel daemon... */
}
static void opening_accept_response(struct subdaemon *opening, const u8 *resp,
struct peer *peer)
{
struct sha256_double funding_txid;
if (!fromwire_opening_accept_resp(resp, NULL, &funding_txid)) {
log_broken(peer->log, "bad OPENING_ACCEPT_RESP %s",
tal_hex(resp, resp));
tal_free(peer);
return;
}
log_debug(peer->log, "Watching funding tx %s",
type_to_string(resp, struct sha256_double, &funding_txid));
watch_txid(peer, peer->ld->topology, peer, &funding_txid, watch_txid(peer, peer->ld->topology, peer, &funding_txid,
funding_depth_cb, NULL); funding_depth_cb, NULL);
/* Tell it we're watching. */
subdaemon_req(peer->owner, towire_opening_accept_finish(resp),
-1, NULL,
opening_accept_finish_response, peer);
} }
static void channel_config(struct lightningd *ld, static void channel_config(struct lightningd *ld,

Loading…
Cancel
Save