diff --git a/lightningd/opening/opening.c b/lightningd/opening/opening.c index 7b3074f88..4a644f1e7 100644 --- a/lightningd/opening/opening.c +++ b/lightningd/opening/opening.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -194,17 +196,28 @@ static u8 *read_next_peer_msg(struct state *state, const tal_t *ctx) static u8 *funder_channel(struct state *state, const struct pubkey *our_funding_pubkey, const struct basepoints *ours, - u32 max_minimum_depth) + u32 max_minimum_depth, + u64 change_satoshis, u32 change_keyindex, + const struct utxo *utxos, + const u8 *bip32_seed) { const tal_t *tmpctx = tal_tmpctx(state); struct channel_id channel_id, id_in; u8 *msg; struct bitcoin_tx **txs; struct basepoints theirs; - struct pubkey their_funding_pubkey; + struct pubkey their_funding_pubkey, changekey; secp256k1_ecdsa_signature sig; u32 minimum_depth; const u8 **wscripts; + struct bitcoin_tx *funding; + struct ext_key bip32_base; + const struct utxo **utxomap; + + if (bip32_key_unserialize(bip32_seed, tal_len(bip32_seed), &bip32_base) + != WALLY_OK) + status_failed(WIRE_OPENING_BAD_PARAM, + "Bad BIP32 key %s", tal_hex(trc, bip32_seed)); set_reserve(&state->localconf.channel_reserve_satoshis, state->funding_satoshis); @@ -302,20 +315,21 @@ static u8 *funder_channel(struct state *state, minimum_depth, max_minimum_depth); check_config_bounds(state, state->remoteconf); - /* Now, ask master create a transaction to pay those two addresses. */ - msg = towire_opening_funder_reply(tmpctx, our_funding_pubkey, - &their_funding_pubkey); - wire_sync_write(REQ_FD, msg); + /* Now, ask create funding transaction to pay those two addresses. */ + if (change_satoshis) { + if (!bip32_pubkey(&bip32_base, &changekey, change_keyindex)) + status_failed(WIRE_OPENING_BAD_PARAM, + "Bad change key %u", change_keyindex); + } - /* Expect funding tx. */ - msg = wire_sync_read(tmpctx, REQ_FD); - if (!fromwire_opening_funder_funding(msg, NULL, - &state->funding_txid, - &state->funding_txout)) - peer_failed(PEER_FD, &state->cs, NULL, - WIRE_OPENING_PEER_READ_FAILED, - "Expected valid opening_funder_funding: %s", - tal_hex(trc, msg)); + utxomap = to_utxoptr_arr(state, utxos); + funding = funding_tx(state, &state->funding_txout, + utxomap, state->funding_satoshis, + our_funding_pubkey, + &their_funding_pubkey, + change_satoshis, &changekey, + &bip32_base); + bitcoin_txid(funding, &state->funding_txid); state->channel = new_channel(state, &state->funding_txid, @@ -420,15 +434,17 @@ static u8 *funder_channel(struct state *state, * Once the channel funder receives the `funding_signed` message, they * must broadcast the funding transaction to the Bitcoin network. */ - return towire_opening_funder_funding_reply(state, - state->remoteconf, - &sig, - &state->cs, - &theirs.revocation, - &theirs.payment, - &theirs.delayed_payment, - &state->next_per_commit[REMOTE], - minimum_depth); + return towire_opening_funder_reply(state, + state->remoteconf, + &sig, + &state->cs, + &theirs.revocation, + &theirs.payment, + &theirs.delayed_payment, + &state->next_per_commit[REMOTE], + minimum_depth, + &their_funding_pubkey, + &state->funding_txid); } /* This is handed the message the peer sent which caused gossip to stop: @@ -671,6 +687,10 @@ int main(int argc, char *argv[]) struct pubkey our_funding_pubkey; u32 minimum_depth, max_minimum_depth; u32 min_feerate, max_feerate; + u64 change_satoshis; + u32 change_keyindex; + struct utxo *utxos; + u8 *bip32_seed; if (argc == 2 && streq(argv[1], "--version")) { printf("%s\n", version()); @@ -711,12 +731,15 @@ int main(int argc, char *argv[]) type_to_string(trc, struct pubkey, &state->next_per_commit[LOCAL])); msg = wire_sync_read(state, REQ_FD); - if (fromwire_opening_funder(msg, NULL, + if (fromwire_opening_funder(state, msg, NULL, &state->funding_satoshis, &state->push_msat, - &state->feerate_per_kw, &max_minimum_depth)) + &state->feerate_per_kw, &max_minimum_depth, + &change_satoshis, &change_keyindex, + &utxos, &bip32_seed)) msg = funder_channel(state, &our_funding_pubkey, &our_points, - max_minimum_depth); + max_minimum_depth, change_satoshis, + change_keyindex, utxos, bip32_seed); else if (fromwire_opening_fundee(state, msg, NULL, &minimum_depth, &min_feerate, &max_feerate, &peer_msg)) msg = fundee_channel(state, &our_funding_pubkey, &our_points, diff --git a/lightningd/opening/opening_wire.csv b/lightningd/opening/opening_wire.csv index 625186344..5d4edbabf 100644 --- a/lightningd/opening/opening_wire.csv +++ b/lightningd/opening/opening_wire.csv @@ -29,27 +29,26 @@ opening_funder,0,funding_satoshis,8 opening_funder,8,push_msat,8 opening_funder,16,feerate_per_kw,4 opening_funder,20,max_minimum_depth,4 - -# Reply asks for txid of funding transaction. -opening_funder_reply,101 -opening_funder_reply,0,local_fundingkey,33 -opening_funder_reply,0,remote_fundingkey,33 - -# Now we give the funding txid and outnum. -opening_funder_funding,2 -opening_funder_funding,0,txid,struct sha256_double -opening_funder_funding,32,txout,u16 +opening_funder,24,change_satoshis,u64 +opening_funder,32,change_keyindex,u32 +#include +opening_funder,0,num_inputs,u16 +opening_funder,0,inputs,num_inputs*struct utxo +opening_funder,0,bip32_len,u16 +opening_funder,0,bip32_seed,bip32_len*u8 # This gives their sig, means we can broadcast tx: we're done. -opening_funder_funding_reply,102 -opening_funder_funding_reply,0,their_config,struct channel_config -opening_funder_funding_reply,36,first_commit_sig,secp256k1_ecdsa_signature -opening_funder_funding_reply,100,crypto_state,struct crypto_state -opening_funder_funding_reply,244,revocation_basepoint,33 -opening_funder_funding_reply,277,payment_basepoint,33 -opening_funder_funding_reply,310,delayed_payment_basepoint,33 -opening_funder_funding_reply,343,their_per_commit_point,33 -opening_funder_funding_reply,376,minimum_depth,4 +opening_funder_reply,101 +opening_funder_reply,0,their_config,struct channel_config +opening_funder_reply,36,first_commit_sig,secp256k1_ecdsa_signature +opening_funder_reply,100,crypto_state,struct crypto_state +opening_funder_reply,244,revocation_basepoint,33 +opening_funder_reply,277,payment_basepoint,33 +opening_funder_reply,310,delayed_payment_basepoint,33 +opening_funder_reply,343,their_per_commit_point,33 +opening_funder_reply,376,minimum_depth,4 +opening_funder_reply,0,remote_fundingkey,33 +opening_funder_reply,0,funding_txid,struct sha256_double # This means they offer the open (contains their offer packet) opening_fundee,3 diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 4bda8cd8e..a88732ff6 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -426,12 +427,13 @@ struct peer *peer_from_json(struct lightningd *ld, struct funding_channel { struct peer *peer; struct command *cmd; - u64 satoshi; + + /* Details we sent to openingd to create funding. */ const struct utxo **utxomap; u64 change; u32 change_keyindex; - struct pubkey local_fundingkey, remote_fundingkey; + /* Funding tx once we're ready to sign and send. */ struct bitcoin_tx *funding_tx; /* We prepare this when channeld exits, and hold until HSM replies. */ @@ -522,7 +524,8 @@ static enum watch_result funding_lockin_cb(struct peer *peer, } /* FIXME: Reshuffle. */ -static void peer_start_channeld(struct peer *peer, const u8 *initmsg); +static void peer_start_channeld(struct peer *peer, const u8 *initmsg, + enum peer_state oldstate); static bool opening_got_hsm_funding_sig(struct subd *hsm, const u8 *resp, const int *fds, @@ -554,9 +557,6 @@ static bool opening_got_hsm_funding_sig(struct subd *hsm, const u8 *resp, = bitcoin_witness_p2wpkh(tx, &sigs[i], &key); } - peer_set_condition(fc->peer, - GETTING_SIG_FROM_HSM, OPENINGD_AWAITING_LOCKIN); - /* Send it out and watch for confirms. */ broadcast_tx(hsm->ld->topology, fc->peer, tx, funding_broadcast_failed); watch_tx(fc->peer, fc->peer->ld->topology, fc->peer, tx, @@ -568,7 +568,7 @@ static bool opening_got_hsm_funding_sig(struct subd *hsm, const u8 *resp, command_success(fc->cmd, null_response(fc->cmd)); /* Start normal channel daemon. */ - peer_start_channeld(fc->peer, fc->channel_init_msg); + peer_start_channeld(fc->peer, fc->channel_init_msg, GETTING_SIG_FROM_HSM); tal_free(fc); return true; @@ -1348,7 +1348,8 @@ static bool peer_start_channeld_hsmfd(struct subd *hsm, const u8 *resp, * Steals initmsg: caller prepares it because it has the information to * construct it. */ -static void peer_start_channeld(struct peer *peer, const u8 *initmsg) +static void peer_start_channeld(struct peer *peer, const u8 *initmsg, + enum peer_state oldstate) { struct channeld_start *cds = tal(peer, struct channeld_start); /* Unowned: back to being owned by main daemon. */ @@ -1364,7 +1365,7 @@ static void peer_start_channeld(struct peer *peer, const u8 *initmsg) cds->peer = peer; cds->initmsg = tal_steal(cds, initmsg); - peer_set_condition(peer, OPENINGD_AWAITING_LOCKIN, GETTING_HSMFD); + peer_set_condition(peer, oldstate, GETTING_HSMFD); /* Get fd from hsm. */ subd_req(peer, peer->ld->hsm, @@ -1372,9 +1373,9 @@ static void peer_start_channeld(struct peer *peer, const u8 *initmsg) -1, 1, peer_start_channeld_hsmfd, cds); } -static bool opening_release_tx(struct subd *opening, const u8 *resp, - const int *fds, - struct funding_channel *fc) +static bool opening_funder_finished(struct subd *opening, const u8 *resp, + const int *fds, + struct funding_channel *fc) { u8 *msg; struct channel_config their_config; @@ -1383,33 +1384,68 @@ static bool opening_release_tx(struct subd *opening, const u8 *resp, struct basepoints theirbase; struct config *cfg = &fc->peer->ld->dstate.config; struct utxo *utxos; + struct sha256_double funding_txid; + struct pubkey changekey; + struct pubkey remote_fundingkey, local_fundingkey; assert(tal_count(fds) == 1); fc->peer->fd = fds[0]; fc->peer->cs = tal(fc->peer, struct crypto_state); - if (!fromwire_opening_funder_funding_reply(resp, NULL, - &their_config, - &commit_sig, - fc->peer->cs, - &theirbase.revocation, - &theirbase.payment, - &theirbase.delayed_payment, - &their_per_commit_point, - &fc->peer->minimum_depth)) { - log_broken(fc->peer->log, "bad OPENING_OPEN_FUNDING_REPLY %s", + if (!fromwire_opening_funder_reply(resp, NULL, + &their_config, + &commit_sig, + fc->peer->cs, + &theirbase.revocation, + &theirbase.payment, + &theirbase.delayed_payment, + &their_per_commit_point, + &fc->peer->minimum_depth, + &remote_fundingkey, + &funding_txid)) { + log_broken(fc->peer->log, "bad OPENING_FUNDER_REPLY %s", tal_hex(resp, resp)); tal_free(fc->peer); return false; } - log_debug(fc->peer->log, "Getting HSM to sign funding tx"); + + /* Generate the funding tx. */ + if (fc->change + && !bip32_pubkey(fc->peer->ld->bip32_base, + &changekey, fc->change_keyindex)) + fatal("Error deriving change key %u", fc->change_keyindex); + + derive_basepoints(fc->peer->seed, &local_fundingkey, + NULL, NULL, NULL, NULL, 0); + + fc->funding_tx = funding_tx(fc, &fc->peer->funding_outnum, + fc->utxomap, fc->peer->funding_satoshi, + &local_fundingkey, + &remote_fundingkey, + fc->change, &changekey, + fc->peer->ld->bip32_base); + fc->peer->funding_txid = tal(fc->peer, struct sha256_double); + bitcoin_txid(fc->funding_tx, fc->peer->funding_txid); + + if (!structeq(fc->peer->funding_txid, &funding_txid)) { + peer_fail(fc->peer, "Funding txid mismatch:" + " satoshi %"PRIu64" change %"PRIu64" changeidx %u" + " localkey %s remotekey %s", + fc->peer->funding_satoshi, + fc->change, fc->change_keyindex, + type_to_string(fc, struct pubkey, &local_fundingkey), + type_to_string(fc, struct pubkey, &remote_fundingkey)); + return false; + } /* Get HSM to sign the funding tx. */ + log_debug(fc->peer->log, "Getting HSM to sign funding tx"); + utxos = from_utxoptr_arr(fc, fc->utxomap); - msg = towire_hsmctl_sign_funding(fc, fc->satoshi, fc->change, - fc->change_keyindex, - &fc->local_fundingkey, - &fc->remote_fundingkey, + msg = towire_hsmctl_sign_funding(fc, fc->peer->funding_satoshi, + fc->change, fc->change_keyindex, + &local_fundingkey, + &remote_fundingkey, utxos); tal_free(utxos); @@ -1421,12 +1457,12 @@ static bool opening_release_tx(struct subd *opening, const u8 *resp, &their_config, &commit_sig, fc->peer->cs, - &fc->remote_fundingkey, + &remote_fundingkey, &theirbase.revocation, &theirbase.payment, &theirbase.delayed_payment, &their_per_commit_point, - fc->peer->funder == LOCAL, + true, /* we are funder */ cfg->fee_base, cfg->fee_per_satoshi, fc->peer->funding_satoshi, @@ -1446,42 +1482,6 @@ static bool opening_release_tx(struct subd *opening, const u8 *resp, return false; } -static bool opening_gen_funding(struct subd *opening, const u8 *reply, - const int *fds, struct funding_channel *fc) -{ - u8 *msg; - struct pubkey changekey; - - log_debug(fc->peer->log, "Created funding transaction for channel"); - if (!fromwire_opening_funder_reply(reply, NULL, - &fc->local_fundingkey, - &fc->remote_fundingkey)) { - log_broken(fc->peer->log, "Bad opening_open_reply %s", - tal_hex(fc, reply)); - /* Free openingd and peer */ - return false; - } - - if (fc->change - && !bip32_pubkey(fc->peer->ld->bip32_base, - &changekey, fc->change_keyindex)) - fatal("Error deriving change key %u", fc->change_keyindex); - - fc->funding_tx = funding_tx(fc, &fc->peer->funding_outnum, - fc->utxomap, fc->satoshi, - &fc->local_fundingkey, - &fc->remote_fundingkey, - fc->change, &changekey, - fc->peer->ld->bip32_base); - fc->peer->funding_txid = tal(fc->peer, struct sha256_double); - bitcoin_txid(fc->funding_tx, fc->peer->funding_txid); - - msg = towire_opening_funder_funding(fc, fc->peer->funding_txid, - fc->peer->funding_outnum); - subd_req(fc, fc->peer->owner, take(msg), -1, 1, opening_release_tx, fc); - return true; -} - static bool opening_fundee_finish_response(struct subd *opening, const u8 *reply, const int *fds, @@ -1541,7 +1541,7 @@ static bool opening_fundee_finish_response(struct subd *opening, /* On to normal operation! */ peer->owner = NULL; - peer_start_channeld(peer, initmsg); + peer_start_channeld(peer, initmsg, OPENINGD_AWAITING_LOCKIN); /* Tell opening daemon to exit. */ return false; @@ -1694,6 +1694,8 @@ static bool gossip_peer_released(struct subd *gossip, u64 id; u8 *msg; struct subd *opening; + struct utxo *utxos; + u8 *bip32_base; assert(tal_count(fds) == 2); fc->peer->fd = fds[0]; @@ -1737,18 +1739,24 @@ static bool gossip_peer_released(struct subd *gossip, min_effective_htlc_capacity_msat, fc->peer->cs, fc->peer->seed); - fc->peer->funding_satoshi = fc->satoshi; - /* FIXME: Support push_msat? */ - fc->peer->push_msat = 0; - fc->peer->cs = tal_free(fc->peer->cs); subd_send_msg(opening, take(msg)); + + utxos = from_utxoptr_arr(fc, fc->utxomap); + bip32_base = tal_arr(fc, u8, BIP32_SERIALIZED_LEN); + if (bip32_key_serialize(fc->peer->ld->bip32_base, BIP32_FLAG_KEY_PUBLIC, + bip32_base, tal_len(bip32_base)) + != WALLY_OK) + fatal("Can't serialize bip32 public key"); + /* FIXME: Real feerate! */ msg = towire_opening_funder(fc, fc->peer->funding_satoshi, fc->peer->push_msat, - 15000, max_minimum_depth); - subd_req(fc, opening, take(msg), -1, 0, opening_gen_funding, fc); + 15000, max_minimum_depth, + fc->change, fc->change_keyindex, + utxos, bip32_base); + subd_req(fc, opening, take(msg), -1, 1, opening_funder_finished, fc); return true; } @@ -1779,14 +1787,17 @@ static void json_fund_channel(struct command *cmd, return; } - if (!json_tok_u64(buffer, satoshitok, &fc->satoshi)) { + if (!json_tok_u64(buffer, satoshitok, &fc->peer->funding_satoshi)) { command_fail(cmd, "Invalid satoshis"); return; } + /* FIXME: Support push_msat? */ + fc->peer->push_msat = 0; + /* Try to do this now, so we know if insufficient funds. */ /* FIXME: Feerate & dustlimit */ - fc->utxomap = build_utxos(fc, ld, fc->satoshi, 15000, 600, + fc->utxomap = build_utxos(fc, ld, fc->peer->funding_satoshi, 15000, 600, &fc->change, &fc->change_keyindex); if (!fc->utxomap) { command_fail(cmd, "Cannot afford funding transaction");