mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
daemon: code to open channel and watch anchor.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
ecbe671688
commit
3c9fd4fbe6
@ -1,4 +1,5 @@
|
||||
#include "bitcoin/script.h"
|
||||
#include "bitcoin/tx.h"
|
||||
#include "find_p2sh_out.h"
|
||||
#include "lightningd.h"
|
||||
#include "log.h"
|
||||
@ -9,9 +10,29 @@
|
||||
#include "state.h"
|
||||
#include <ccan/crypto/sha256/sha256.h>
|
||||
#include <ccan/mem/mem.h>
|
||||
#include <ccan/str/hex/hex.h>
|
||||
|
||||
#define FIXME_STUB(peer) do { log_broken((peer)->dstate->base_log, "%s:%u: Implement %s!", __FILE__, __LINE__, __func__); abort(); } while(0)
|
||||
|
||||
static char *hex_of(const tal_t *ctx, const void *p, size_t n)
|
||||
{
|
||||
char *hex = tal_arr(ctx, char, hex_str_size(n));
|
||||
hex_encode(p, n, hex, hex_str_size(n));
|
||||
return hex;
|
||||
}
|
||||
|
||||
static void dump_tx(const char *str, const struct bitcoin_tx *tx)
|
||||
{
|
||||
u8 *linear = linearize_tx(NULL, tx);
|
||||
printf("%s:%s\n", str, hex_of(linear, linear, tal_count(linear)));
|
||||
tal_free(linear);
|
||||
}
|
||||
|
||||
static void dump_key(const char *str, const struct pubkey *key)
|
||||
{
|
||||
printf("%s:%s\n", str, hex_of(NULL, key->der, pubkey_derlen(key)));
|
||||
}
|
||||
|
||||
/* Wrap (and own!) member inside Pkt */
|
||||
static Pkt *make_pkt(const tal_t *ctx, Pkt__PktCase type, const void *msg)
|
||||
{
|
||||
@ -86,12 +107,26 @@ Pkt *pkt_anchor(const tal_t *ctx, const struct peer *peer)
|
||||
|
||||
Pkt *pkt_open_commit_sig(const tal_t *ctx, const struct peer *peer)
|
||||
{
|
||||
FIXME_STUB(peer);
|
||||
struct signature sig;
|
||||
OpenCommitSig *s = tal(ctx, OpenCommitSig);
|
||||
|
||||
open_commit_sig__init(s);
|
||||
|
||||
dump_tx("Creating sig for:", peer->them.commit);
|
||||
dump_key("Using key:", &peer->us.commitkey);
|
||||
|
||||
peer_sign_theircommit(peer, &sig);
|
||||
s->sig = signature_to_proto(s, &sig);
|
||||
|
||||
return make_pkt(ctx, PKT__PKT_OPEN_COMMIT_SIG, s);
|
||||
}
|
||||
|
||||
Pkt *pkt_open_complete(const tal_t *ctx, const struct peer *peer)
|
||||
{
|
||||
FIXME_STUB(peer);
|
||||
OpenComplete *o = tal(ctx, OpenComplete);
|
||||
|
||||
open_complete__init(o);
|
||||
return make_pkt(ctx, PKT__PKT_OPEN_COMPLETE, o);
|
||||
}
|
||||
|
||||
Pkt *pkt_htlc_update(const tal_t *ctx, const struct peer *peer,
|
||||
@ -252,7 +287,25 @@ Pkt *accept_pkt_anchor(const tal_t *ctx,
|
||||
Pkt *accept_pkt_open_commit_sig(const tal_t *ctx,
|
||||
struct peer *peer, const Pkt *pkt)
|
||||
{
|
||||
FIXME_STUB(peer);
|
||||
const OpenCommitSig *s = pkt->open_commit_sig;
|
||||
|
||||
peer->cur_commit_theirsig.stype = SIGHASH_ALL;
|
||||
if (!proto_to_signature(s->sig, &peer->cur_commit_theirsig.sig))
|
||||
return pkt_err(ctx, "Malformed signature");
|
||||
|
||||
dump_tx("Checking sig for:", peer->us.commit);
|
||||
dump_key("Using key:", &peer->them.commitkey);
|
||||
|
||||
/* 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_htlc_update(const tal_t *ctx,
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <ccan/io/io.h>
|
||||
#include <ccan/list/list.h>
|
||||
#include <ccan/noerr/noerr.h>
|
||||
#include <ccan/structeq/structeq.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <ccan/tal/tal.h>
|
||||
#include <errno.h>
|
||||
@ -439,7 +440,6 @@ const struct json_command connect_command = {
|
||||
};
|
||||
|
||||
struct anchor_watch {
|
||||
struct peer *peer;
|
||||
enum state_input depthok;
|
||||
enum state_input timeout;
|
||||
enum state_input unspent;
|
||||
@ -447,6 +447,71 @@ struct anchor_watch {
|
||||
enum state_input otherspent;
|
||||
};
|
||||
|
||||
static void anchor_depthchange(struct peer *peer, int depth,
|
||||
struct anchor_watch *w)
|
||||
{
|
||||
/* Still waiting for it to reach depth? */
|
||||
if (w->depthok != INPUT_NONE) {
|
||||
/* Beware sign! */
|
||||
if (depth >= (int)peer->us.mindepth) {
|
||||
enum state_input in = w->depthok;
|
||||
w->depthok = INPUT_NONE;
|
||||
update_state(peer, in, NULL);
|
||||
}
|
||||
} else {
|
||||
if (depth < 0 && w->unspent != INPUT_NONE) {
|
||||
enum state_input in = w->unspent;
|
||||
w->unspent = INPUT_NONE;
|
||||
update_state(peer, in, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We don't compare scriptSigs: we don't know them anyway! */
|
||||
static bool txmatch(const struct bitcoin_tx *txa, const struct bitcoin_tx *txb)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (txa->version != txb->version
|
||||
|| txa->input_count != txb->input_count
|
||||
|| txa->output_count != txb->output_count
|
||||
|| txa->lock_time != txb->lock_time)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < txa->input_count; i++) {
|
||||
if (!structeq(&txa->input[i].txid, &txb->input[i].txid)
|
||||
|| txa->input[i].index != txb->input[i].index
|
||||
|| txa->input[i].sequence_number != txb->input[i].sequence_number)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < txa->output_count; i++) {
|
||||
if (txa->output[i].amount != txb->output[i].amount
|
||||
|| txa->output[i].script_length != txb->output[i].script_length
|
||||
|| memcmp(txa->output[i].script, txb->output[i].script,
|
||||
txa->output[i].script_length != 0))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* We assume the tx is valid! Don't do a blockchain.info and feed this
|
||||
* invalid transactions! */
|
||||
static void anchor_spent(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
struct anchor_watch *w)
|
||||
{
|
||||
union input idata;
|
||||
|
||||
/* FIXME: change type in idata? */
|
||||
idata.btc = (struct bitcoin_event *)tx;
|
||||
if (txmatch(tx, peer->them.commit))
|
||||
update_state(peer, w->theyspent, &idata);
|
||||
else
|
||||
update_state(peer, w->otherspent, &idata);
|
||||
}
|
||||
|
||||
void peer_watch_anchor(struct peer *peer,
|
||||
enum state_input depthok,
|
||||
enum state_input timeout,
|
||||
@ -454,7 +519,20 @@ void peer_watch_anchor(struct peer *peer,
|
||||
enum state_input theyspent,
|
||||
enum state_input otherspent)
|
||||
{
|
||||
FIXME_STUB(peer);
|
||||
struct anchor_watch *w = tal(peer, struct anchor_watch);
|
||||
|
||||
w->depthok = depthok;
|
||||
w->timeout = timeout;
|
||||
w->unspent = unspent;
|
||||
w->theyspent = theyspent;
|
||||
w->otherspent = otherspent;
|
||||
|
||||
add_anchor_watch(peer, &peer->anchor.txid, peer->anchor.index,
|
||||
anchor_depthchange,
|
||||
anchor_spent,
|
||||
w);
|
||||
|
||||
/* FIXME: add timeout */
|
||||
}
|
||||
|
||||
void peer_unwatch_anchor_depth(struct peer *peer,
|
||||
|
Loading…
Reference in New Issue
Block a user