opening: funder: don't ask master for TXID, calculate it ourselves.

Simplifies state machine.  Master still has to calculate the tx to get
the signature and broadcast, but now the opening daemon funding path
is a simple request/response.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2017-05-23 20:37:42 +09:30
parent 4220362692
commit c2cfc3dd69
3 changed files with 153 additions and 120 deletions

View File

@ -12,6 +12,7 @@
#include <lightningd/crypto_sync.h>
#include <lightningd/debug.h>
#include <lightningd/derive_basepoints.h>
#include <lightningd/funding_tx.h>
#include <lightningd/key_derive.h>
#include <lightningd/opening/gen_opening_wire.h>
#include <lightningd/peer_failed.h>
@ -22,6 +23,7 @@
#include <stdio.h>
#include <type_to_string.h>
#include <version.h>
#include <wally_bip32.h>
#include <wire/gen_peer_wire.h>
#include <wire/peer_wire.h>
#include <wire/wire.h>
@ -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,7 +434,7 @@ 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,
return towire_opening_funder_reply(state,
state->remoteconf,
&sig,
&state->cs,
@ -428,7 +442,9 @@ static u8 *funder_channel(struct state *state,
&theirs.payment,
&theirs.delayed_payment,
&state->next_per_commit[REMOTE],
minimum_depth);
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,

View File

@ -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 <lightningd/utxo.h>
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

1 # These shouldn't happen
29 # Reply asks for txid of funding transaction. opening_funder,24,change_satoshis,u64
30 opening_funder_reply,101 opening_funder,32,change_keyindex,u32
31 opening_funder_reply,0,local_fundingkey,33 #include <lightningd/utxo.h>
32 opening_funder_reply,0,remote_fundingkey,33 opening_funder,0,num_inputs,u16
33 # Now we give the funding txid and outnum. opening_funder,0,inputs,num_inputs*struct utxo
34 opening_funder_funding,2 opening_funder,0,bip32_len,u16
35 opening_funder_funding,0,txid,struct sha256_double opening_funder,0,bip32_seed,bip32_len*u8
36 opening_funder_funding,32,txout,u16 # This gives their sig, means we can broadcast tx: we're done.
37 # This gives their sig, means we can broadcast tx: we're done. opening_funder_reply,101
38 opening_funder_funding_reply,102 opening_funder_reply,0,their_config,struct channel_config
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
39 opening_funder_funding_reply,244,revocation_basepoint,33 opening_funder_reply,36,first_commit_sig,secp256k1_ecdsa_signature
40 opening_funder_funding_reply,277,payment_basepoint,33 opening_funder_reply,100,crypto_state,struct crypto_state
41 opening_funder_funding_reply,310,delayed_payment_basepoint,33 opening_funder_reply,244,revocation_basepoint,33
42 opening_funder_funding_reply,343,their_per_commit_point,33 opening_funder_reply,277,payment_basepoint,33
43 opening_funder_funding_reply,376,minimum_depth,4 opening_funder_reply,310,delayed_payment_basepoint,33
44 # This means they offer the open (contains their offer packet) opening_funder_reply,343,their_per_commit_point,33
45 opening_fundee,3 opening_funder_reply,376,minimum_depth,4
46 opening_fundee,0,minimum_depth,4 opening_funder_reply,0,remote_fundingkey,33
47 opening_fundee,0,min_feerate,4 opening_funder_reply,0,funding_txid,struct sha256_double
48 opening_fundee,4,max_feerate,4 # This means they offer the open (contains their offer packet)
49 opening_fundee,8,len,2 opening_fundee,3
50 opening_fundee,0,minimum_depth,4
51 opening_fundee,0,min_feerate,4
52 opening_fundee,10,msg,len*u8 opening_fundee,4,max_feerate,4
53 # This gives the txid of their funding tx to watch. opening_fundee,8,len,2
54 opening_fundee_reply,103 opening_fundee,10,msg,len*u8

View File

@ -31,6 +31,7 @@
#include <overflows.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <wally_bip32.h>
#include <wire/gen_onion_wire.h>
#include <wire/gen_peer_wire.h>
@ -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,7 +1373,7 @@ 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,
static bool opening_funder_finished(struct subd *opening, const u8 *resp,
const int *fds,
struct funding_channel *fc)
{
@ -1383,12 +1384,15 @@ 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,
if (!fromwire_opening_funder_reply(resp, NULL,
&their_config,
&commit_sig,
fc->peer->cs,
@ -1396,20 +1400,52 @@ static bool opening_release_tx(struct subd *opening, const u8 *resp,
&theirbase.payment,
&theirbase.delayed_payment,
&their_per_commit_point,
&fc->peer->minimum_depth)) {
log_broken(fc->peer->log, "bad OPENING_OPEN_FUNDING_REPLY %s",
&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");