mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
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:
parent
4220362692
commit
c2cfc3dd69
@ -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,
|
||||
|
@ -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
|
||||
|
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user