peer: keep current commit txs, anchor state, channel funding and their sig.

This lets us implement accept_pkt_anchor().

Also had to predeclare sha256 in commit_tx.h, revealed by the new
includes.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2016-01-22 06:44:27 +10:30
parent 871e4d5172
commit ecbe671688
4 changed files with 169 additions and 7 deletions

View File

@@ -6,6 +6,7 @@
struct channel_state; struct channel_state;
struct sha256_double; struct sha256_double;
struct sha256;
struct pubkey; struct pubkey;
struct rel_locktime; struct rel_locktime;

View File

@@ -1,3 +1,5 @@
#include "bitcoin/script.h"
#include "find_p2sh_out.h"
#include "lightningd.h" #include "lightningd.h"
#include "log.h" #include "log.h"
#include "names.h" #include "names.h"
@@ -67,7 +69,19 @@ Pkt *pkt_open(const tal_t *ctx, const struct peer *peer,
Pkt *pkt_anchor(const tal_t *ctx, const struct peer *peer) Pkt *pkt_anchor(const tal_t *ctx, const struct peer *peer)
{ {
FIXME_STUB(peer); struct signature sig;
OpenAnchor *a = tal(ctx, OpenAnchor);
open_anchor__init(a);
a->txid = sha256_to_proto(a, &peer->anchor.txid.sha);
a->output_index = peer->anchor.index;
a->amount = peer->anchor.satoshis;
/* Sign their commit sig */
peer_sign_theircommit(peer, &sig);
a->commit_sig = signature_to_proto(a, &sig);
return make_pkt(ctx, PKT__PKT_OPEN_ANCHOR, a);
} }
Pkt *pkt_open_commit_sig(const tal_t *ctx, const struct peer *peer) Pkt *pkt_open_commit_sig(const tal_t *ctx, const struct peer *peer)
@@ -149,7 +163,7 @@ Pkt *accept_pkt_open(const tal_t *ctx,
struct peer *peer, const Pkt *pkt) struct peer *peer, const Pkt *pkt)
{ {
struct rel_locktime locktime; struct rel_locktime locktime;
OpenChannel *o = pkt->open; const OpenChannel *o = pkt->open;
if (!proto_to_rel_locktime(o->delay, &locktime)) if (!proto_to_rel_locktime(o->delay, &locktime))
return pkt_err(ctx, "Invalid delay"); return pkt_err(ctx, "Invalid delay");
@@ -184,6 +198,10 @@ Pkt *accept_pkt_open(const tal_t *ctx,
return pkt_err(ctx, "Bad finalkey"); return pkt_err(ctx, "Bad finalkey");
proto_to_sha256(o->revocation_hash, &peer->them.revocation_hash); proto_to_sha256(o->revocation_hash, &peer->them.revocation_hash);
/* Redeemscript for anchor. */
peer->anchor.redeemscript
= bitcoin_redeem_2of2(peer, &peer->us.commitkey,
&peer->them.commitkey);
return NULL; return NULL;
} }
@@ -191,7 +209,44 @@ Pkt *accept_pkt_anchor(const tal_t *ctx,
struct peer *peer, struct peer *peer,
const Pkt *pkt) const Pkt *pkt)
{ {
FIXME_STUB(peer); const OpenAnchor *a = pkt->open_anchor;
u64 commitfee;
/* They must be offering anchor for us to try accepting */
assert(peer->us.offer_anchor == CMD_OPEN_WITHOUT_ANCHOR);
assert(peer->them.offer_anchor == CMD_OPEN_WITH_ANCHOR);
proto_to_sha256(a->txid, &peer->anchor.txid.sha);
peer->anchor.index = a->output_index;
peer->anchor.satoshis = a->amount;
/* Create funder's cstate, invert to get ours. */
commitfee = commit_fee(peer->them.commit_fee, peer->us.commit_fee);
peer->cstate = initial_funding(peer,
peer->us.offer_anchor,
peer->anchor.satoshis,
commitfee);
if (!peer->cstate)
return pkt_err(ctx, "Insufficient funds for fee");
invert_cstate(peer->cstate);
/* Now we can make initial (unsigned!) commit txs. */
peer_make_commit_txs(peer);
peer->cur_commit_theirsig.stype = SIGHASH_ALL;
if (!proto_to_signature(a->commit_sig, &peer->cur_commit_theirsig.sig))
return pkt_err(ctx, "Malformed signature");
/* Their sig should sign our commit tx. */
if (!check_tx_sig(peer->dstate->secpctx,
peer->us.commit, 0,
peer->anchor.redeemscript,
tal_count(peer->anchor.redeemscript),
&peer->them.commitkey,
&peer->cur_commit_theirsig))
return pkt_err(ctx, "Bad signature");
return NULL;
} }
Pkt *accept_pkt_open_commit_sig(const tal_t *ctx, Pkt *accept_pkt_open_commit_sig(const tal_t *ctx,

View File

@@ -1,6 +1,8 @@
#include "bitcoind.h" #include "bitcoind.h"
#include "commit_tx.h"
#include "cryptopkt.h" #include "cryptopkt.h"
#include "dns.h" #include "dns.h"
#include "find_p2sh_out.h"
#include "jsonrpc.h" #include "jsonrpc.h"
#include "lightningd.h" #include "lightningd.h"
#include "log.h" #include "log.h"
@@ -8,6 +10,8 @@
#include "peer.h" #include "peer.h"
#include "secrets.h" #include "secrets.h"
#include "state.h" #include "state.h"
#include <bitcoin/base58.h>
#include <bitcoin/script.h>
#include <bitcoin/tx.h> #include <bitcoin/tx.h>
#include <ccan/array_size/array_size.h> #include <ccan/array_size/array_size.h>
#include <ccan/io/io.h> #include <ccan/io/io.h>
@@ -246,6 +250,8 @@ static struct peer *new_peer(struct lightningd_state *dstate,
/* FIXME: Make this dynamic. */ /* FIXME: Make this dynamic. */
peer->us.commit_fee = dstate->config.commitment_fee; peer->us.commit_fee = dstate->config.commitment_fee;
peer->us.commit = peer->them.commit = NULL;
/* FIXME: Attach IO logging for this peer. */ /* FIXME: Attach IO logging for this peer. */
tal_add_destructor(peer, destroy_peer); tal_add_destructor(peer, destroy_peer);
@@ -278,6 +284,7 @@ static struct io_plan *peer_connected_out(struct io_conn *conn,
} }
log_info(peer->log, "Connected out to %s:%s", log_info(peer->log, "Connected out to %s:%s",
connect->name, connect->port); connect->name, connect->port);
peer->anchor.satoshis = connect->satoshis;
peer->jsoncmd = NULL; peer->jsoncmd = NULL;
command_success(connect->cmd, null_response(connect)); command_success(connect->cmd, null_response(connect));
@@ -678,23 +685,99 @@ const struct bitcoin_tx *bitcoin_htlc_spend(const tal_t *ctx,
FIXME_STUB(peer); FIXME_STUB(peer);
} }
static void created_anchor(struct lightningd_state *dstate,
const struct bitcoin_tx *tx,
struct peer *peer)
{
size_t commitfee;
bitcoin_txid(tx, &peer->anchor.txid);
peer->anchor.index = find_p2sh_out(tx, peer->anchor.redeemscript);
assert(peer->anchor.satoshis == tx->output[peer->anchor.index].amount);
/* We'll need this later, when we're told to broadcast it. */
peer->anchor.tx = tal_steal(peer, tx);
commitfee = commit_fee(peer->them.commit_fee, peer->us.commit_fee);
peer->cstate = initial_funding(peer,
peer->us.offer_anchor,
peer->anchor.satoshis,
commitfee);
if (!peer->cstate)
fatal("Insufficient anchor funds for commitfee");
/* Now we can make initial (unsigned!) commit txs. */
peer_make_commit_txs(peer);
update_state(peer, BITCOIN_ANCHOR_CREATED, NULL);
}
/* Start creation of the bitcoin anchor tx. */ /* Start creation of the bitcoin anchor tx. */
void bitcoin_create_anchor(struct peer *peer, enum state_input done) void bitcoin_create_anchor(struct peer *peer, enum state_input done)
{ {
/* FIXME */ struct sha256 h;
struct ripemd160 redeemhash;
char *p2shaddr;
/* We must be offering anchor for us to try creating it */
assert(peer->us.offer_anchor);
sha256(&h, peer->anchor.redeemscript,
tal_count(peer->anchor.redeemscript));
ripemd160(&redeemhash, h.u.u8, sizeof(h));
p2shaddr = p2sh_to_base58(peer, peer->dstate->config.testnet,
&redeemhash);
assert(done == BITCOIN_ANCHOR_CREATED);
bitcoind_create_payment(peer->dstate, p2shaddr, peer->anchor.satoshis,
created_anchor, peer);
} }
/* We didn't end up broadcasting the anchor: release the utxos. /* We didn't end up broadcasting the anchor: release the utxos.
* If done != INPUT_NONE, remove existing create_anchor too. */ * If done != INPUT_NONE, remove existing create_anchor too. */
void bitcoin_release_anchor(struct peer *peer, enum state_input done) void bitcoin_release_anchor(struct peer *peer, enum state_input done)
{ {
FIXME_STUB(peer);
/* FIXME: stop bitcoind command */
log_unusual(peer->log, "Anchor not spent, please -zapwallettxs");
} }
/* Get the bitcoin anchor tx. */ /* Get the bitcoin anchor tx. */
const struct bitcoin_tx *bitcoin_anchor(const tal_t *ctx, struct peer *peer) const struct bitcoin_tx *bitcoin_anchor(const tal_t *ctx, struct peer *peer)
{ {
FIXME_STUB(peer); return peer->anchor.tx;
}
void peer_make_commit_txs(struct peer *peer)
{
struct channel_state their_cstate;
tal_free(peer->us.commit);
tal_free(peer->them.commit);
/* FIXME: Where do we update revocation_hash fields? */
peer->us.commit = create_commit_tx(peer,
&peer->us.finalkey,
&peer->them.finalkey,
&peer->them.locktime,
&peer->anchor.txid,
peer->anchor.index,
peer->anchor.satoshis,
&peer->us.revocation_hash,
peer->cstate);
their_cstate = *peer->cstate;
invert_cstate(&their_cstate);
peer->them.commit = create_commit_tx(peer,
&peer->them.finalkey,
&peer->us.finalkey,
&peer->us.locktime,
&peer->anchor.txid,
peer->anchor.index,
peer->anchor.satoshis,
&peer->them.revocation_hash,
&their_cstate);
} }
/* FIXME: Somehow we should show running DNS lookups! */ /* FIXME: Somehow we should show running DNS lookups! */

View File

@@ -3,6 +3,9 @@
#include "config.h" #include "config.h"
#include "bitcoin/locktime.h" #include "bitcoin/locktime.h"
#include "bitcoin/pubkey.h" #include "bitcoin/pubkey.h"
#include "bitcoin/script.h"
#include "bitcoin/shadouble.h"
#include "funding.h"
#include "lightning.pb-c.h" #include "lightning.pb-c.h"
#include "netaddr.h" #include "netaddr.h"
#include "state.h" #include "state.h"
@@ -22,6 +25,8 @@ struct peer_visible_state {
u64 commit_fee; u64 commit_fee;
/* Revocation hash for latest commit tx. */ /* Revocation hash for latest commit tx. */
struct sha256 revocation_hash; struct sha256 revocation_hash;
/* Current commit tx. */
struct bitcoin_tx *commit;
}; };
struct peer { struct peer {
@@ -45,6 +50,9 @@ struct peer {
/* Global state. */ /* Global state. */
struct lightningd_state *dstate; struct lightningd_state *dstate;
/* Funding status for current commit tx (from our PoV). */
struct channel_state *cstate;
/* The other end's address. */ /* The other end's address. */
struct netaddr addr; struct netaddr addr;
@@ -58,6 +66,19 @@ struct peer {
Pkt *outpkt[5]; Pkt *outpkt[5];
size_t num_outpkt; size_t num_outpkt;
/* Anchor tx output */
struct {
struct sha256_double txid;
unsigned int index;
u64 satoshis;
u8 *redeemscript;
/* If we created it, we keep entire tx. */
const struct bitcoin_tx *tx;
} anchor;
/* Their signature for our current commit sig. */
struct bitcoin_signature cur_commit_theirsig;
/* Current ongoing packetflow */ /* Current ongoing packetflow */
struct io_data *io_data; struct io_data *io_data;
@@ -76,4 +97,6 @@ struct peer {
void setup_listeners(struct lightningd_state *dstate, unsigned int portnum); void setup_listeners(struct lightningd_state *dstate, unsigned int portnum);
void peer_make_commit_txs(struct peer *peer);
#endif /* LIGHTNING_DAEMON_PEER_H */ #endif /* LIGHTNING_DAEMON_PEER_H */