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 sha256_double;
struct sha256;
struct pubkey;
struct rel_locktime;

View File

@ -1,3 +1,5 @@
#include "bitcoin/script.h"
#include "find_p2sh_out.h"
#include "lightningd.h"
#include "log.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)
{
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)
@ -149,7 +163,7 @@ Pkt *accept_pkt_open(const tal_t *ctx,
struct peer *peer, const Pkt *pkt)
{
struct rel_locktime locktime;
OpenChannel *o = pkt->open;
const OpenChannel *o = pkt->open;
if (!proto_to_rel_locktime(o->delay, &locktime))
return pkt_err(ctx, "Invalid delay");
@ -184,6 +198,10 @@ Pkt *accept_pkt_open(const tal_t *ctx,
return pkt_err(ctx, "Bad finalkey");
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;
}
@ -191,7 +209,44 @@ Pkt *accept_pkt_anchor(const tal_t *ctx,
struct peer *peer,
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,

View File

@ -1,6 +1,8 @@
#include "bitcoind.h"
#include "commit_tx.h"
#include "cryptopkt.h"
#include "dns.h"
#include "find_p2sh_out.h"
#include "jsonrpc.h"
#include "lightningd.h"
#include "log.h"
@ -8,6 +10,8 @@
#include "peer.h"
#include "secrets.h"
#include "state.h"
#include <bitcoin/base58.h>
#include <bitcoin/script.h>
#include <bitcoin/tx.h>
#include <ccan/array_size/array_size.h>
#include <ccan/io/io.h>
@ -246,6 +250,8 @@ static struct peer *new_peer(struct lightningd_state *dstate,
/* FIXME: Make this dynamic. */
peer->us.commit_fee = dstate->config.commitment_fee;
peer->us.commit = peer->them.commit = NULL;
/* FIXME: Attach IO logging for this 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",
connect->name, connect->port);
peer->anchor.satoshis = connect->satoshis;
peer->jsoncmd = NULL;
command_success(connect->cmd, null_response(connect));
@ -678,25 +685,101 @@ const struct bitcoin_tx *bitcoin_htlc_spend(const tal_t *ctx,
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. */
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.
* If done != INPUT_NONE, remove existing create_anchor too. */
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. */
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: Show status of peers! */
static void json_getpeers(struct command *cmd,

View File

@ -3,6 +3,9 @@
#include "config.h"
#include "bitcoin/locktime.h"
#include "bitcoin/pubkey.h"
#include "bitcoin/script.h"
#include "bitcoin/shadouble.h"
#include "funding.h"
#include "lightning.pb-c.h"
#include "netaddr.h"
#include "state.h"
@ -22,6 +25,8 @@ struct peer_visible_state {
u64 commit_fee;
/* Revocation hash for latest commit tx. */
struct sha256 revocation_hash;
/* Current commit tx. */
struct bitcoin_tx *commit;
};
struct peer {
@ -45,6 +50,9 @@ struct peer {
/* Global state. */
struct lightningd_state *dstate;
/* Funding status for current commit tx (from our PoV). */
struct channel_state *cstate;
/* The other end's address. */
struct netaddr addr;
@ -57,7 +65,20 @@ struct peer {
/* Queue of output packets. */
Pkt *outpkt[5];
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 */
struct io_data *io_data;
@ -76,4 +97,6 @@ struct peer {
void setup_listeners(struct lightningd_state *dstate, unsigned int portnum);
void peer_make_commit_txs(struct peer *peer);
#endif /* LIGHTNING_DAEMON_PEER_H */