From eac3af06f14fb9fece2a0472522b5d8064f4ce8a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 29 Jul 2015 16:14:28 +0930 Subject: [PATCH] protocol: switch to single-funder anchor model. Most complex change was gather_updates(), which handles all the "what is the current state of the channel" logic for our dumb test utils. Signed-off-by: Rusty Russell --- Makefile | 4 +- anchor.c | 159 -------- anchor.h | 31 -- close_tx.c | 27 +- close_tx.h | 6 +- commit_tx.c | 54 +-- commit_tx.h | 7 +- funding.c | 58 +++ funding.h | 39 ++ lightning.pb-c.c | 588 ++++++++-------------------- lightning.pb-c.h | 271 ++++--------- lightning.proto | 75 ++-- pkt.c | 50 +-- pkt.h | 27 +- test-cli/check-anchor-scriptsigs.c | 61 --- test-cli/check-commit-sig.c | 82 ++-- test-cli/close-channel.c | 40 +- test-cli/create-anchor-tx.c | 189 +++++++++ test-cli/create-close-tx.c | 31 +- test-cli/create-commit-spend-tx.c | 31 +- test-cli/create-commit-tx.c | 63 +-- test-cli/create-steal-tx.c | 1 - test-cli/gather_updates.c | 149 +++++++ test-cli/gather_updates.h | 16 + test-cli/get-anchor-depth.c | 3 +- test-cli/open-anchor-scriptsigs.c | 98 ----- test-cli/open-channel.c | 124 +----- test-cli/open-commit-sig.c | 42 +- test-cli/scripts/getinput.sh | 23 +- test-cli/scripts/setup.sh | 7 +- test-cli/scripts/test.sh | 119 +++--- test-cli/update-channel-accept.c | 42 +- test-cli/update-channel-complete.c | 79 ++-- test-cli/update-channel-signature.c | 61 ++- test-cli/update-channel.c | 15 +- 35 files changed, 1071 insertions(+), 1601 deletions(-) delete mode 100644 anchor.c delete mode 100644 anchor.h create mode 100644 funding.c create mode 100644 funding.h delete mode 100644 test-cli/check-anchor-scriptsigs.c create mode 100644 test-cli/create-anchor-tx.c create mode 100644 test-cli/gather_updates.c create mode 100644 test-cli/gather_updates.h delete mode 100644 test-cli/open-anchor-scriptsigs.c diff --git a/Makefile b/Makefile index e3087faeb..dba21f545 100644 --- a/Makefile +++ b/Makefile @@ -8,11 +8,11 @@ FEATURES := -DHAS_CSV=1 -DALPHA_TXSTYLE=1 -DUSE_SCHNORR=1 # Bitcoin uses DER for signatures #FEATURES := -DSCRIPTS_USE_DER -PROGRAMS := test-cli/open-channel test-cli/open-anchor-scriptsigs test-cli/open-commit-sig test-cli/check-commit-sig test-cli/check-anchor-scriptsigs test-cli/get-anchor-depth test-cli/create-steal-tx test-cli/create-commit-spend-tx test-cli/close-channel test-cli/create-close-tx test-cli/update-channel test-cli/update-channel-accept test-cli/update-channel-signature test-cli/update-channel-complete test-cli/create-commit-tx test-cli/txid-of +PROGRAMS := test-cli/open-channel test-cli/create-anchor-tx test-cli/open-commit-sig test-cli/check-commit-sig test-cli/get-anchor-depth test-cli/create-steal-tx test-cli/create-commit-spend-tx test-cli/close-channel test-cli/create-close-tx test-cli/update-channel test-cli/update-channel-accept test-cli/update-channel-signature test-cli/update-channel-complete test-cli/create-commit-tx test-cli/txid-of test-cli/open-anchor BITCOIN_OBJS := bitcoin/address.o bitcoin/base58.o bitcoin/pubkey.o bitcoin/script.o bitcoin/shadouble.o bitcoin/signature.o bitcoin/tx.o -HELPER_OBJS := lightning.pb-c.o pkt.o permute_tx.o anchor.o commit_tx.o opt_bits.o close_tx.o find_p2sh_out.o protobuf_convert.o +HELPER_OBJS := lightning.pb-c.o pkt.o permute_tx.o commit_tx.o opt_bits.o close_tx.o find_p2sh_out.o protobuf_convert.o funding.o test-cli/gather_updates.o CCAN_OBJS := ccan-crypto-sha256.o ccan-crypto-shachain.o ccan-err.o ccan-tal.o ccan-tal-str.o ccan-take.o ccan-list.o ccan-str.o ccan-opt-helpers.o ccan-opt.o ccan-opt-parse.o ccan-opt-usage.o ccan-read_write_all.o ccan-str-hex.o ccan-tal-grab_file.o ccan-noerr.o ccan-crypto-ripemd160.o diff --git a/anchor.c b/anchor.c deleted file mode 100644 index 73097a78a..000000000 --- a/anchor.c +++ /dev/null @@ -1,159 +0,0 @@ -#include -#include "anchor.h" -#include "bitcoin/pubkey.h" -#include "bitcoin/script.h" -#include "bitcoin/tx.h" -#include "overflows.h" -#include "permute_tx.h" -#include "pkt.h" -#include "protobuf_convert.h" - -struct bitcoin_tx *anchor_tx_create(const tal_t *ctx, - const OpenChannel *o1, - const OpenChannel *o2, - size_t **inmapp, size_t **outmapp) -{ - uint64_t i, n_out; - struct bitcoin_tx *tx; - u8 *redeemscript; - size_t *inmap, *outmap; - struct pubkey key1, key2; - uint64_t total_in = 0, total_change = 0; - - if (add_overflows_size_t(o1->anchor->n_inputs, o2->anchor->n_inputs)) - return NULL; - - n_out = 1 + !!o1->anchor->change + !!o2->anchor->change; - tx = bitcoin_tx(ctx, o1->anchor->n_inputs+o2->anchor->n_inputs, n_out); - - /* Populate inputs. */ - for (i = 0; i < o1->anchor->n_inputs; i++) { - BitcoinInput *pb = o1->anchor->inputs[i]; - struct bitcoin_tx_input *in = &tx->input[i]; - proto_to_sha256(pb->txid, &in->txid.sha); - in->index = pb->output; - in->input_amount = pb->amount; - if (add_overflows_u64(total_in, in->input_amount)) - return tal_free(tx); - total_in += in->input_amount; - /* Leave inputs as stubs for now, for signing. */ - } - for (i = 0; i < o2->anchor->n_inputs; i++) { - BitcoinInput *pb = o2->anchor->inputs[i]; - struct bitcoin_tx_input *in - = &tx->input[o1->anchor->n_inputs + i]; - proto_to_sha256(pb->txid, &in->txid.sha); - in->index = pb->output; - in->input_amount = pb->amount; - if (add_overflows_u64(total_in, in->input_amount)) - return tal_free(tx); - total_in += in->input_amount; - /* Leave inputs as stubs for now, for signing. */ - } - - /* Populate outputs. */ - if (add_overflows_u64(o1->anchor->total, o2->anchor->total)) - return tal_free(tx); - - /* Pubkeys both valid, right? */ - if (!proto_to_pubkey(o1->commit_key, &key1) - || !proto_to_pubkey(o2->commit_key, &key2)) - return tal_free(tx); - - /* Make the 2 of 2 payment for the commitment txs. */ - redeemscript = bitcoin_redeem_2of2(tx, &key1, &key2); - tx->output[0].amount = o1->anchor->total + o2->anchor->total; - tx->output[0].script = scriptpubkey_p2sh(tx, redeemscript); - tx->output[0].script_length = tal_count(tx->output[0].script); - - /* Add change transactions (if any) */ - n_out = 1; - if (o1->anchor->change) { - struct bitcoin_tx_output *out = &tx->output[n_out++]; - struct pubkey key; - - if (!proto_to_pubkey(o1->anchor->change->pubkey, &key)) - return tal_free(tx); - - out->amount = o1->anchor->change->amount; - out->script = scriptpubkey_p2sh(tx, - bitcoin_redeem_single(tx, &key)); - out->script_length = tal_count(out->script); - total_change += out->amount; - } - if (o2->anchor->change) { - struct bitcoin_tx_output *out = &tx->output[n_out++]; - struct pubkey key; - - if (!proto_to_pubkey(o2->anchor->change->pubkey, &key)) - return tal_free(tx); - - out->amount = o2->anchor->change->amount; - out->script = scriptpubkey_p2sh(tx, - bitcoin_redeem_single(tx, &key)); - out->script_length = tal_count(out->script); - if (add_overflows_u64(total_change, out->amount)) - return tal_free(tx); - total_change += out->amount; - } - assert(n_out == tx->output_count); - - /* Figure out fee we're paying; check for over and underflow */ - if (add_overflows_u64(total_change, tx->output[0].amount)) - return tal_free(tx); - if (total_in < total_change + tx->output[0].amount) - return tal_free(tx); - tx->fee = total_in - (total_change + tx->output[0].amount); - - /* Check that the fees add up correctly. */ - if (add_overflows_u64(o1->anchor->fee, o2->anchor->fee)) - return tal_free(tx); - if (tx->fee != o1->anchor->fee + o2->anchor->fee) - return tal_free(tx); - - if (inmapp) - inmap = *inmapp = tal_arr(ctx, size_t, tx->input_count); - else - inmap = NULL; - - if (outmapp) - outmap = *outmapp = tal_arr(ctx, size_t, tx->output_count); - else - outmap = NULL; - - permute_inputs(tx->input, tx->input_count, inmap); - permute_outputs(tx->output, tx->output_count, outmap); - return tx; -} - -/* This may create an invalid anchor. That's actually OK, as the bitcoin - * network won't accept it and we'll ds our way out. */ -bool anchor_add_scriptsigs(struct bitcoin_tx *anchor, - OpenAnchorScriptsigs *ssigs1, - OpenAnchorScriptsigs *ssigs2, - const size_t *inmap) -{ - size_t i; - - if (ssigs1->n_script + ssigs2->n_script != anchor->input_count) - return NULL; - - for (i = 0; i < ssigs1->n_script; i++) { - size_t n = inmap[i]; - anchor->input[n].script = ssigs1->script[i].data; - anchor->input[n].script_length = ssigs1->script[i].len; - } - - for (i = 0; i < ssigs2->n_script; i++) { - size_t n = inmap[ssigs1->n_script + i]; - anchor->input[n].script = ssigs2->script[i].data; - anchor->input[n].script_length = ssigs2->script[i].len; - } - - return true; -} - -void anchor_txid(struct bitcoin_tx *anchor, struct sha256_double *txid) -{ - bitcoin_txid(anchor, txid); -} diff --git a/anchor.h b/anchor.h deleted file mode 100644 index e1bfe3cf7..000000000 --- a/anchor.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef LIGHTNING_ANCHOR_H -#define LIGHTNING_ANCHOR_H -#include -#include "lightning.pb-c.h" - -struct sha256_double; - -/* Create an anchor transaction based on both sides' requests. - * The scriptSigs are left empty. - * - * Allocate an input and output map (if non-NULL); the first - * o1->anchor->n_inputs of inmap are the location of o1's inputs, the - * next o2->anchor->n_inputs are o2's. outmap[0] is the location of - * output for the commitment tx, then o1's change (if - * o1->anchor->change), then o2's change if o2->anchor->change. - */ -struct bitcoin_tx *anchor_tx_create(const tal_t *ctx, - const OpenChannel *o1, - const OpenChannel *o2, - size_t **inmap, size_t **outmap); - -/* Add these scriptsigs to the anchor transaction. */ -bool anchor_add_scriptsigs(struct bitcoin_tx *anchor, - OpenAnchorScriptsigs *ssigs1, - OpenAnchorScriptsigs *ssigs2, - const size_t *inmap); - -/* We wouldn't need the leak files if we had normalized txids! */ -void anchor_txid(struct bitcoin_tx *anchor, - struct sha256_double *txid); -#endif /* LIGHTNING_ANCHOR_H */ diff --git a/close_tx.c b/close_tx.c index a382bb39e..67a3d834a 100644 --- a/close_tx.c +++ b/close_tx.c @@ -10,10 +10,8 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx, OpenChannel *ours, OpenChannel *theirs, - int64_t delta, - const struct sha256_double *anchor_txid, - uint64_t input_amount, - unsigned int anchor_output) + OpenAnchor *anchor, + uint64_t to_us, uint64_t to_them) { struct bitcoin_tx *tx; const u8 *redeemscript; @@ -24,9 +22,9 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx, tx = bitcoin_tx(ctx, 1, 2); /* Our input spends the anchor tx output. */ - tx->input[0].txid = *anchor_txid; - tx->input[0].index = anchor_output; - tx->input[0].input_amount = input_amount; + proto_to_sha256(anchor->txid, &tx->input[0].txid.sha); + tx->input[0].index = anchor->output_index; + tx->input[0].input_amount = anchor->amount; /* Outputs goes to final pubkey */ if (!proto_to_pubkey(ours->final_key, &ourkey)) @@ -34,27 +32,26 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx, if (!proto_to_pubkey(theirs->final_key, &theirkey)) return tal_free(tx); - /* delta must make sense. */ - if (delta < 0 && ours->anchor->total - ours->commitment_fee < -delta) - return tal_free(tx); - if (delta > 0 && theirs->anchor->total - theirs->commitment_fee < delta) - return tal_free(tx); proto_to_sha256(ours->revocation_hash, &redeem); /* One output is to us. */ - tx->output[0].amount = ours->anchor->total - ours->commitment_fee + delta; + tx->output[0].amount = to_us; redeemscript = bitcoin_redeem_single(tx, &ourkey); tx->output[0].script = scriptpubkey_p2sh(tx, redeemscript); tx->output[0].script_length = tal_count(tx->output[0].script); /* Other output is to them. */ - tx->output[1].amount = theirs->anchor->total - theirs->commitment_fee - delta; + tx->output[1].amount = to_them; redeemscript = bitcoin_redeem_single(tx, &theirkey); tx->output[1].script = scriptpubkey_p2sh(tx, redeemscript); tx->output[1].script_length = tal_count(tx->output[1].script); - tx->fee = ours->commitment_fee + theirs->commitment_fee; + assert(tx->output[0].amount + tx->output[1].amount + <= tx->input[0].input_amount); + tx->fee = tx->input[0].input_amount + - (tx->output[0].amount + tx->output[1].amount); + permute_outputs(tx->output, 2, NULL); return tx; } diff --git a/close_tx.h b/close_tx.h index feb81086c..52a9505f7 100644 --- a/close_tx.h +++ b/close_tx.h @@ -10,8 +10,6 @@ struct sha256_double; struct bitcoin_tx *create_close_tx(const tal_t *ctx, OpenChannel *ours, OpenChannel *theirs, - int64_t delta, - const struct sha256_double *anchor_txid, - uint64_t input_amount, - unsigned int anchor_output); + OpenAnchor *anchor, + uint64_t to_us, uint64_t to_them); #endif diff --git a/commit_tx.c b/commit_tx.c index 50bb07e69..588c727aa 100644 --- a/commit_tx.c +++ b/commit_tx.c @@ -8,13 +8,13 @@ #include "pkt.h" #include "protobuf_convert.h" +#include struct bitcoin_tx *create_commit_tx(const tal_t *ctx, OpenChannel *ours, OpenChannel *theirs, + OpenAnchor *anchor, const struct sha256 *rhash, - int64_t delta, - const struct sha256_double *anchor_txid, - unsigned int anchor_output) + uint64_t to_us, uint64_t to_them) { struct bitcoin_tx *tx; const u8 *redeemscript; @@ -25,11 +25,9 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx, tx = bitcoin_tx(ctx, 1, 2); /* Our input spends the anchor tx output. */ - tx->input[0].txid = *anchor_txid; - tx->input[0].index = anchor_output; - if (add_overflows_u64(ours->anchor->total, theirs->anchor->total)) - return tal_free(tx); - tx->input[0].input_amount = ours->anchor->total + theirs->anchor->total; + proto_to_sha256(anchor->txid, &tx->input[0].txid.sha); + tx->input[0].index = anchor->output_index; + tx->input[0].input_amount = anchor->amount; /* Output goes to our final pubkeys */ if (!proto_to_pubkey(ours->final_key, &ourkey)) @@ -47,15 +45,8 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx, rhash); tx->output[0].script = scriptpubkey_p2sh(tx, redeemscript); tx->output[0].script_length = tal_count(tx->output[0].script); + tx->output[0].amount = to_us; - if (ours->anchor->total < ours->commitment_fee) - return tal_free(tx); - tx->output[0].amount = ours->anchor->total - ours->commitment_fee; - /* Asking for more than we have? */ - if (delta < 0 && -delta > tx->output[0].amount) - return tal_free(tx); - tx->output[0].amount += delta; - /* Second output is a P2SH payment to them. */ if (!proto_to_pubkey(theirs->final_key, &to_me)) return tal_free(tx); @@ -63,19 +54,32 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx, bitcoin_redeem_single(ctx, &to_me)); tx->output[1].script_length = tal_count(tx->output[1].script); - - if (theirs->anchor->total < theirs->commitment_fee) - return tal_free(tx); - tx->output[1].amount = theirs->anchor->total - theirs->commitment_fee; - /* Asking for more than they have? */ - if (delta > 0 && delta > tx->output[1].amount) - return tal_free(tx); - tx->output[0].amount -= delta; + tx->output[1].amount = to_them; /* Calculate fee; difference of inputs and outputs. */ + assert(tx->output[0].amount + tx->output[1].amount + <= tx->input[0].input_amount); tx->fee = tx->input[0].input_amount - (tx->output[0].amount + tx->output[1].amount); - + + fprintf(stderr, "Created commit tx: anchor=%02x%02x%02x%02x/%u/%llu," + " out0=%02x%02x%02x%02x/%u/%02x%02x%02x%02x/%02x%02x%02x%02x/%llu, " + " out1=%02x%02x%02x%02x/%llu, fee=%llu\n", + tx->input[0].txid.sha.u.u8[0], + tx->input[0].txid.sha.u.u8[1], + tx->input[0].txid.sha.u.u8[2], + tx->input[0].txid.sha.u.u8[3], + tx->input[0].index, + (long long)tx->input[0].input_amount, + ourkey.key[0], ourkey.key[1], ourkey.key[2], ourkey.key[3], + locktime, + theirkey.key[0], theirkey.key[1], theirkey.key[2], theirkey.key[3], + rhash->u.u8[0], rhash->u.u8[1], rhash->u.u8[2], rhash->u.u8[3], + (long long)tx->output[0].amount, + to_me.key[0], to_me.key[1], to_me.key[2], to_me.key[3], + (long long)tx->output[1].amount, + (long long)tx->fee); + permute_outputs(tx->output, 2, NULL); return tx; } diff --git a/commit_tx.h b/commit_tx.h index e24c76cb1..cff79cad0 100644 --- a/commit_tx.h +++ b/commit_tx.h @@ -11,8 +11,7 @@ struct sha256; struct bitcoin_tx *create_commit_tx(const tal_t *ctx, OpenChannel *ours, OpenChannel *theirs, - const struct sha256 *revocation_hash, - int64_t delta, - const struct sha256_double *anchor_txid, - unsigned int anchor_output); + OpenAnchor *anchor, + const struct sha256 *rhash, + uint64_t to_us, uint64_t to_them); #endif diff --git a/funding.c b/funding.c new file mode 100644 index 000000000..2f536b13a --- /dev/null +++ b/funding.c @@ -0,0 +1,58 @@ +#include "funding.h" +#include + +/* FIXME: Fees! */ +bool funding_delta(const OpenChannel *a, + const OpenChannel *b, + const OpenAnchor *anchor, + uint64_t *channel_delta, + int64_t delta_a_to_b, + uint64_t *a_amount, + uint64_t *b_amount) +{ + uint64_t *funder_amount, *non_funder_amount; + int64_t delta_to_funder; + + assert(*channel_delta <= anchor->amount); + + if (a->anch == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR) { + if (b->anch != OPEN_CHANNEL__ANCHOR_OFFER__WONT_CREATE_ANCHOR) + return false; + funder_amount = a_amount; + non_funder_amount = b_amount; + delta_to_funder = delta_a_to_b; + } else { + if (a->anch != OPEN_CHANNEL__ANCHOR_OFFER__WONT_CREATE_ANCHOR) + return false; + if (b->anch != OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR) + return false; + funder_amount = b_amount; + non_funder_amount = a_amount; + delta_to_funder = -delta_a_to_b; + } + + /* Trying to spend more than non-funder has? */ + if (delta_to_funder > 0) { + if (delta_to_funder > *channel_delta) + return false; + /* Trying to spend more than funder has? */ + } else if (-delta_to_funder > anchor->amount - *channel_delta) + return false; + + *channel_delta -= delta_to_funder; + *funder_amount = anchor->amount - *channel_delta; + *non_funder_amount = *channel_delta; + return true; +} + +bool initial_funding(const OpenChannel *a, + const OpenChannel *b, + const OpenAnchor *anchor, + uint64_t *a_amount, + uint64_t *b_amount) +{ + uint64_t channel_delta = 0; + + return funding_delta(a, b, anchor, &channel_delta, 0, + a_amount, b_amount); +} diff --git a/funding.h b/funding.h new file mode 100644 index 000000000..5c1c0accb --- /dev/null +++ b/funding.h @@ -0,0 +1,39 @@ +#ifndef LIGHTNING_FUNDING_H +#define LIGHTNING_FUNDING_H +#include + +#include "lightning.pb-c.h" + +/** + * initial_funding: Given A, B, and anchor, what is initial state? + * @a: A's openchannel offer + * @b: B's openchannel offer + * @anchor: The anchor offer (A or B) + * @a_amount: amount commit tx will output to A. + * @b_amount: amount commit tx will output to B. + */ +bool initial_funding(const OpenChannel *a, + const OpenChannel *b, + const OpenAnchor *anchor, + uint64_t *a_amount, + uint64_t *b_amount); + +/** + * funding_delta: With this change, what's the new state? + * @a: A's openchannel offer + * @b: B's openchannel offer + * @anchor: The anchor offer (A or B) + * @channel_delta: In/out amount funder pays to non-funder (channel state) + * @delta_a_to_b: How much A pays to B (satoshi). + * @a_amount: amount commit tx will output to A. + * @b_amount: amount commit tx will output to B. + */ +bool funding_delta(const OpenChannel *a, + const OpenChannel *b, + const OpenAnchor *anchor, + uint64_t *channel_delta, + int64_t delta_a_to_b, + uint64_t *a_amount, + uint64_t *b_amount); + +#endif /* LIGHTNING_FUNDING_H */ diff --git a/lightning.pb-c.c b/lightning.pb-c.c index 20e257233..49c5060e3 100644 --- a/lightning.pb-c.c +++ b/lightning.pb-c.c @@ -93,49 +93,6 @@ void signature__free_unpacked assert(message->base.descriptor == &signature__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } -void bitcoin_input__init - (BitcoinInput *message) -{ - static BitcoinInput init_value = BITCOIN_INPUT__INIT; - *message = init_value; -} -size_t bitcoin_input__get_packed_size - (const BitcoinInput *message) -{ - assert(message->base.descriptor == &bitcoin_input__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); -} -size_t bitcoin_input__pack - (const BitcoinInput *message, - uint8_t *out) -{ - assert(message->base.descriptor == &bitcoin_input__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); -} -size_t bitcoin_input__pack_to_buffer - (const BitcoinInput *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &bitcoin_input__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); -} -BitcoinInput * - bitcoin_input__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (BitcoinInput *) - protobuf_c_message_unpack (&bitcoin_input__descriptor, - allocator, len, data); -} -void bitcoin_input__free_unpacked - (BitcoinInput *message, - ProtobufCAllocator *allocator) -{ - assert(message->base.descriptor == &bitcoin_input__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); -} void bitcoin_pubkey__init (BitcoinPubkey *message) { @@ -179,92 +136,6 @@ void bitcoin_pubkey__free_unpacked assert(message->base.descriptor == &bitcoin_pubkey__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } -void change__init - (Change *message) -{ - static Change init_value = CHANGE__INIT; - *message = init_value; -} -size_t change__get_packed_size - (const Change *message) -{ - assert(message->base.descriptor == &change__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); -} -size_t change__pack - (const Change *message, - uint8_t *out) -{ - assert(message->base.descriptor == &change__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); -} -size_t change__pack_to_buffer - (const Change *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &change__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); -} -Change * - change__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (Change *) - protobuf_c_message_unpack (&change__descriptor, - allocator, len, data); -} -void change__free_unpacked - (Change *message, - ProtobufCAllocator *allocator) -{ - assert(message->base.descriptor == &change__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); -} -void anchor__init - (Anchor *message) -{ - static Anchor init_value = ANCHOR__INIT; - *message = init_value; -} -size_t anchor__get_packed_size - (const Anchor *message) -{ - assert(message->base.descriptor == &anchor__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); -} -size_t anchor__pack - (const Anchor *message, - uint8_t *out) -{ - assert(message->base.descriptor == &anchor__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); -} -size_t anchor__pack_to_buffer - (const Anchor *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &anchor__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); -} -Anchor * - anchor__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (Anchor *) - protobuf_c_message_unpack (&anchor__descriptor, - allocator, len, data); -} -void anchor__free_unpacked - (Anchor *message, - ProtobufCAllocator *allocator) -{ - assert(message->base.descriptor == &anchor__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); -} void open_channel__init (OpenChannel *message) { @@ -308,90 +179,90 @@ void open_channel__free_unpacked assert(message->base.descriptor == &open_channel__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } -void open_commit_sig__init - (OpenCommitSig *message) +void open_anchor__init + (OpenAnchor *message) { - static OpenCommitSig init_value = OPEN_COMMIT_SIG__INIT; + static OpenAnchor init_value = OPEN_ANCHOR__INIT; *message = init_value; } -size_t open_commit_sig__get_packed_size - (const OpenCommitSig *message) +size_t open_anchor__get_packed_size + (const OpenAnchor *message) { - assert(message->base.descriptor == &open_commit_sig__descriptor); + assert(message->base.descriptor == &open_anchor__descriptor); return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); } -size_t open_commit_sig__pack - (const OpenCommitSig *message, +size_t open_anchor__pack + (const OpenAnchor *message, uint8_t *out) { - assert(message->base.descriptor == &open_commit_sig__descriptor); + assert(message->base.descriptor == &open_anchor__descriptor); return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); } -size_t open_commit_sig__pack_to_buffer - (const OpenCommitSig *message, +size_t open_anchor__pack_to_buffer + (const OpenAnchor *message, ProtobufCBuffer *buffer) { - assert(message->base.descriptor == &open_commit_sig__descriptor); + assert(message->base.descriptor == &open_anchor__descriptor); return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); } -OpenCommitSig * - open_commit_sig__unpack +OpenAnchor * + open_anchor__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data) { - return (OpenCommitSig *) - protobuf_c_message_unpack (&open_commit_sig__descriptor, + return (OpenAnchor *) + protobuf_c_message_unpack (&open_anchor__descriptor, allocator, len, data); } -void open_commit_sig__free_unpacked - (OpenCommitSig *message, +void open_anchor__free_unpacked + (OpenAnchor *message, ProtobufCAllocator *allocator) { - assert(message->base.descriptor == &open_commit_sig__descriptor); + assert(message->base.descriptor == &open_anchor__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } -void open_anchor_scriptsigs__init - (OpenAnchorScriptsigs *message) +void open_commit_sig__init + (OpenCommitSig *message) { - static OpenAnchorScriptsigs init_value = OPEN_ANCHOR_SCRIPTSIGS__INIT; + static OpenCommitSig init_value = OPEN_COMMIT_SIG__INIT; *message = init_value; } -size_t open_anchor_scriptsigs__get_packed_size - (const OpenAnchorScriptsigs *message) +size_t open_commit_sig__get_packed_size + (const OpenCommitSig *message) { - assert(message->base.descriptor == &open_anchor_scriptsigs__descriptor); + assert(message->base.descriptor == &open_commit_sig__descriptor); return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); } -size_t open_anchor_scriptsigs__pack - (const OpenAnchorScriptsigs *message, +size_t open_commit_sig__pack + (const OpenCommitSig *message, uint8_t *out) { - assert(message->base.descriptor == &open_anchor_scriptsigs__descriptor); + assert(message->base.descriptor == &open_commit_sig__descriptor); return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); } -size_t open_anchor_scriptsigs__pack_to_buffer - (const OpenAnchorScriptsigs *message, +size_t open_commit_sig__pack_to_buffer + (const OpenCommitSig *message, ProtobufCBuffer *buffer) { - assert(message->base.descriptor == &open_anchor_scriptsigs__descriptor); + assert(message->base.descriptor == &open_commit_sig__descriptor); return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); } -OpenAnchorScriptsigs * - open_anchor_scriptsigs__unpack +OpenCommitSig * + open_commit_sig__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data) { - return (OpenAnchorScriptsigs *) - protobuf_c_message_unpack (&open_anchor_scriptsigs__descriptor, + return (OpenCommitSig *) + protobuf_c_message_unpack (&open_commit_sig__descriptor, allocator, len, data); } -void open_anchor_scriptsigs__free_unpacked - (OpenAnchorScriptsigs *message, +void open_commit_sig__free_unpacked + (OpenCommitSig *message, ProtobufCAllocator *allocator) { - assert(message->base.descriptor == &open_anchor_scriptsigs__descriptor); + assert(message->base.descriptor == &open_commit_sig__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } void open_complete__init @@ -987,83 +858,6 @@ const ProtobufCMessageDescriptor signature__descriptor = (ProtobufCMessageInit) signature__init, NULL,NULL,NULL /* reserved[123] */ }; -static const ProtobufCFieldDescriptor bitcoin_input__field_descriptors[4] = -{ - { - "txid", - 1, - PROTOBUF_C_LABEL_REQUIRED, - PROTOBUF_C_TYPE_MESSAGE, - 0, /* quantifier_offset */ - offsetof(BitcoinInput, txid), - &sha256_hash__descriptor, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "output", - 2, - PROTOBUF_C_LABEL_REQUIRED, - PROTOBUF_C_TYPE_UINT32, - 0, /* quantifier_offset */ - offsetof(BitcoinInput, output), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "subscript", - 3, - PROTOBUF_C_LABEL_REQUIRED, - PROTOBUF_C_TYPE_BYTES, - 0, /* quantifier_offset */ - offsetof(BitcoinInput, subscript), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "amount", - 4, - PROTOBUF_C_LABEL_REQUIRED, - PROTOBUF_C_TYPE_UINT64, - 0, /* quantifier_offset */ - offsetof(BitcoinInput, amount), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, -}; -static const unsigned bitcoin_input__field_indices_by_name[] = { - 3, /* field[3] = amount */ - 1, /* field[1] = output */ - 2, /* field[2] = subscript */ - 0, /* field[0] = txid */ -}; -static const ProtobufCIntRange bitcoin_input__number_ranges[1 + 1] = -{ - { 1, 0 }, - { 0, 4 } -}; -const ProtobufCMessageDescriptor bitcoin_input__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "bitcoin_input", - "BitcoinInput", - "BitcoinInput", - "", - sizeof(BitcoinInput), - 4, - bitcoin_input__field_descriptors, - bitcoin_input__field_indices_by_name, - 1, bitcoin_input__number_ranges, - (ProtobufCMessageInit) bitcoin_input__init, - NULL,NULL,NULL /* reserved[123] */ -}; static const ProtobufCFieldDescriptor bitcoin_pubkey__field_descriptors[1] = { { @@ -1102,150 +896,35 @@ const ProtobufCMessageDescriptor bitcoin_pubkey__descriptor = (ProtobufCMessageInit) bitcoin_pubkey__init, NULL,NULL,NULL /* reserved[123] */ }; -static const ProtobufCFieldDescriptor change__field_descriptors[2] = +static const ProtobufCEnumValue open_channel__anchor_offer__enum_values_by_number[2] = { - { - "amount", - 1, - PROTOBUF_C_LABEL_REQUIRED, - PROTOBUF_C_TYPE_UINT64, - 0, /* quantifier_offset */ - offsetof(Change, amount), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "pubkey", - 2, - PROTOBUF_C_LABEL_REQUIRED, - PROTOBUF_C_TYPE_MESSAGE, - 0, /* quantifier_offset */ - offsetof(Change, pubkey), - &bitcoin_pubkey__descriptor, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, + { "WILL_CREATE_ANCHOR", "OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR", 1 }, + { "WONT_CREATE_ANCHOR", "OPEN_CHANNEL__ANCHOR_OFFER__WONT_CREATE_ANCHOR", 2 }, }; -static const unsigned change__field_indices_by_name[] = { - 0, /* field[0] = amount */ - 1, /* field[1] = pubkey */ +static const ProtobufCIntRange open_channel__anchor_offer__value_ranges[] = { +{1, 0},{0, 2} }; -static const ProtobufCIntRange change__number_ranges[1 + 1] = +static const ProtobufCEnumValueIndex open_channel__anchor_offer__enum_values_by_name[2] = { - { 1, 0 }, - { 0, 2 } + { "WILL_CREATE_ANCHOR", 0 }, + { "WONT_CREATE_ANCHOR", 1 }, }; -const ProtobufCMessageDescriptor change__descriptor = +const ProtobufCEnumDescriptor open_channel__anchor_offer__descriptor = { - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "change", - "Change", - "Change", + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "open_channel.anchor_offer", + "anchor_offer", + "OpenChannel__AnchorOffer", "", - sizeof(Change), 2, - change__field_descriptors, - change__field_indices_by_name, - 1, change__number_ranges, - (ProtobufCMessageInit) change__init, - NULL,NULL,NULL /* reserved[123] */ -}; -static const ProtobufCFieldDescriptor anchor__field_descriptors[5] = -{ - { - "inputs", - 1, - PROTOBUF_C_LABEL_REPEATED, - PROTOBUF_C_TYPE_MESSAGE, - offsetof(Anchor, n_inputs), - offsetof(Anchor, inputs), - &bitcoin_input__descriptor, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "change", - 2, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_MESSAGE, - 0, /* quantifier_offset */ - offsetof(Anchor, change), - &change__descriptor, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "total", - 4, - PROTOBUF_C_LABEL_REQUIRED, - PROTOBUF_C_TYPE_UINT64, - 0, /* quantifier_offset */ - offsetof(Anchor, total), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "fee", - 8, - PROTOBUF_C_LABEL_REQUIRED, - PROTOBUF_C_TYPE_UINT64, - 0, /* quantifier_offset */ - offsetof(Anchor, fee), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "min_confirms", - 10, - PROTOBUF_C_LABEL_REQUIRED, - PROTOBUF_C_TYPE_UINT32, - 0, /* quantifier_offset */ - offsetof(Anchor, min_confirms), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, -}; -static const unsigned anchor__field_indices_by_name[] = { - 1, /* field[1] = change */ - 3, /* field[3] = fee */ - 0, /* field[0] = inputs */ - 4, /* field[4] = min_confirms */ - 2, /* field[2] = total */ -}; -static const ProtobufCIntRange anchor__number_ranges[4 + 1] = -{ - { 1, 0 }, - { 4, 2 }, - { 8, 3 }, - { 10, 4 }, - { 0, 5 } -}; -const ProtobufCMessageDescriptor anchor__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "anchor", - "Anchor", - "Anchor", - "", - sizeof(Anchor), - 5, - anchor__field_descriptors, - anchor__field_indices_by_name, - 4, anchor__number_ranges, - (ProtobufCMessageInit) anchor__init, - NULL,NULL,NULL /* reserved[123] */ + open_channel__anchor_offer__enum_values_by_number, + 2, + open_channel__anchor_offer__enum_values_by_name, + 1, + open_channel__anchor_offer__value_ranges, + NULL,NULL,NULL,NULL /* reserved[1234] */ }; +static const uint32_t open_channel__min_depth__default_value = 0u; static const ProtobufCFieldDescriptor open_channel__field_descriptors[7] = { { @@ -1309,37 +988,37 @@ static const ProtobufCFieldDescriptor open_channel__field_descriptors[7] = 0,NULL,NULL /* reserved1,reserved2, etc */ }, { - "commitment_fee", + "anch", 6, PROTOBUF_C_LABEL_REQUIRED, - PROTOBUF_C_TYPE_UINT64, + PROTOBUF_C_TYPE_ENUM, 0, /* quantifier_offset */ - offsetof(OpenChannel, commitment_fee), - NULL, + offsetof(OpenChannel, anch), + &open_channel__anchor_offer__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { - "anchor", + "min_depth", 7, - PROTOBUF_C_LABEL_REQUIRED, - PROTOBUF_C_TYPE_MESSAGE, - 0, /* quantifier_offset */ - offsetof(OpenChannel, anchor), - &anchor__descriptor, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_UINT32, + offsetof(OpenChannel, has_min_depth), + offsetof(OpenChannel, min_depth), NULL, + &open_channel__min_depth__default_value, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, }; static const unsigned open_channel__field_indices_by_name[] = { - 6, /* field[6] = anchor */ + 5, /* field[5] = anch */ 4, /* field[4] = commit_key */ - 5, /* field[5] = commitment_fee */ 0, /* field[0] = final_key */ 2, /* field[2] = locktime_blocks */ 1, /* field[1] = locktime_seconds */ + 6, /* field[6] = min_depth */ 3, /* field[3] = revocation_hash */ }; static const ProtobufCIntRange open_channel__number_ranges[1 + 1] = @@ -1362,80 +1041,119 @@ const ProtobufCMessageDescriptor open_channel__descriptor = (ProtobufCMessageInit) open_channel__init, NULL,NULL,NULL /* reserved[123] */ }; -static const ProtobufCFieldDescriptor open_commit_sig__field_descriptors[1] = +static const ProtobufCFieldDescriptor open_anchor__field_descriptors[4] = { { - "sig", + "txid", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_MESSAGE, 0, /* quantifier_offset */ - offsetof(OpenCommitSig, sig), + offsetof(OpenAnchor, txid), + &sha256_hash__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "output_index", + 2, + PROTOBUF_C_LABEL_REQUIRED, + PROTOBUF_C_TYPE_UINT32, + 0, /* quantifier_offset */ + offsetof(OpenAnchor, output_index), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "amount", + 3, + PROTOBUF_C_LABEL_REQUIRED, + PROTOBUF_C_TYPE_UINT64, + 0, /* quantifier_offset */ + offsetof(OpenAnchor, amount), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "commit_sig", + 4, + PROTOBUF_C_LABEL_REQUIRED, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(OpenAnchor, commit_sig), &signature__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, }; -static const unsigned open_commit_sig__field_indices_by_name[] = { - 0, /* field[0] = sig */ +static const unsigned open_anchor__field_indices_by_name[] = { + 2, /* field[2] = amount */ + 3, /* field[3] = commit_sig */ + 1, /* field[1] = output_index */ + 0, /* field[0] = txid */ }; -static const ProtobufCIntRange open_commit_sig__number_ranges[1 + 1] = +static const ProtobufCIntRange open_anchor__number_ranges[1 + 1] = { { 1, 0 }, - { 0, 1 } + { 0, 4 } }; -const ProtobufCMessageDescriptor open_commit_sig__descriptor = +const ProtobufCMessageDescriptor open_anchor__descriptor = { PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "open_commit_sig", - "OpenCommitSig", - "OpenCommitSig", + "open_anchor", + "OpenAnchor", + "OpenAnchor", "", - sizeof(OpenCommitSig), - 1, - open_commit_sig__field_descriptors, - open_commit_sig__field_indices_by_name, - 1, open_commit_sig__number_ranges, - (ProtobufCMessageInit) open_commit_sig__init, + sizeof(OpenAnchor), + 4, + open_anchor__field_descriptors, + open_anchor__field_indices_by_name, + 1, open_anchor__number_ranges, + (ProtobufCMessageInit) open_anchor__init, NULL,NULL,NULL /* reserved[123] */ }; -static const ProtobufCFieldDescriptor open_anchor_scriptsigs__field_descriptors[1] = +static const ProtobufCFieldDescriptor open_commit_sig__field_descriptors[1] = { { - "script", + "sig", 1, - PROTOBUF_C_LABEL_REPEATED, - PROTOBUF_C_TYPE_BYTES, - offsetof(OpenAnchorScriptsigs, n_script), - offsetof(OpenAnchorScriptsigs, script), - NULL, + PROTOBUF_C_LABEL_REQUIRED, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(OpenCommitSig, sig), + &signature__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, }; -static const unsigned open_anchor_scriptsigs__field_indices_by_name[] = { - 0, /* field[0] = script */ +static const unsigned open_commit_sig__field_indices_by_name[] = { + 0, /* field[0] = sig */ }; -static const ProtobufCIntRange open_anchor_scriptsigs__number_ranges[1 + 1] = +static const ProtobufCIntRange open_commit_sig__number_ranges[1 + 1] = { { 1, 0 }, { 0, 1 } }; -const ProtobufCMessageDescriptor open_anchor_scriptsigs__descriptor = +const ProtobufCMessageDescriptor open_commit_sig__descriptor = { PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "open_anchor_scriptsigs", - "OpenAnchorScriptsigs", - "OpenAnchorScriptsigs", + "open_commit_sig", + "OpenCommitSig", + "OpenCommitSig", "", - sizeof(OpenAnchorScriptsigs), + sizeof(OpenCommitSig), 1, - open_anchor_scriptsigs__field_descriptors, - open_anchor_scriptsigs__field_indices_by_name, - 1, open_anchor_scriptsigs__number_ranges, - (ProtobufCMessageInit) open_anchor_scriptsigs__init, + open_commit_sig__field_descriptors, + open_commit_sig__field_indices_by_name, + 1, open_commit_sig__number_ranges, + (ProtobufCMessageInit) open_commit_sig__init, NULL,NULL,NULL /* reserved[123] */ }; static const ProtobufCFieldDescriptor open_complete__field_descriptors[1] = @@ -1845,25 +1563,25 @@ static const ProtobufCFieldDescriptor pkt__field_descriptors[11] = 0,NULL,NULL /* reserved1,reserved2, etc */ }, { - "open_commit_sig", + "open_anchor", 202, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_MESSAGE, offsetof(Pkt, pkt_case), - offsetof(Pkt, open_commit_sig), - &open_commit_sig__descriptor, + offsetof(Pkt, open_anchor), + &open_anchor__descriptor, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { - "open_anchor_scriptsigs", + "open_commit_sig", 203, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_MESSAGE, offsetof(Pkt, pkt_case), - offsetof(Pkt, open_anchor_scriptsigs), - &open_anchor_scriptsigs__descriptor, + offsetof(Pkt, open_commit_sig), + &open_commit_sig__descriptor, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ @@ -1922,8 +1640,8 @@ static const unsigned pkt__field_indices_by_name[] = { 9, /* field[9] = close_complete */ 10, /* field[10] = error */ 4, /* field[4] = open */ - 6, /* field[6] = open_anchor_scriptsigs */ - 5, /* field[5] = open_commit_sig */ + 5, /* field[5] = open_anchor */ + 6, /* field[6] = open_commit_sig */ 7, /* field[7] = open_complete */ 0, /* field[0] = update */ 1, /* field[1] = update_accept */ diff --git a/lightning.pb-c.h b/lightning.pb-c.h index 9f72fe799..37924b60e 100644 --- a/lightning.pb-c.h +++ b/lightning.pb-c.h @@ -17,13 +17,10 @@ PROTOBUF_C__BEGIN_DECLS typedef struct _Sha256Hash Sha256Hash; typedef struct _Signature Signature; -typedef struct _BitcoinInput BitcoinInput; typedef struct _BitcoinPubkey BitcoinPubkey; -typedef struct _Change Change; -typedef struct _Anchor Anchor; typedef struct _OpenChannel OpenChannel; +typedef struct _OpenAnchor OpenAnchor; typedef struct _OpenCommitSig OpenCommitSig; -typedef struct _OpenAnchorScriptsigs OpenAnchorScriptsigs; typedef struct _OpenComplete OpenComplete; typedef struct _Update Update; typedef struct _UpdateAccept UpdateAccept; @@ -37,6 +34,17 @@ typedef struct _Pkt Pkt; /* --- enums --- */ +typedef enum _OpenChannel__AnchorOffer { + /* + * I will create the anchor + */ + OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR = 1, + /* + * I won't create the anchor + */ + OPEN_CHANNEL__ANCHOR_OFFER__WONT_CREATE_ANCHOR = 2 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(OPEN_CHANNEL__ANCHOR_OFFER) +} OpenChannel__AnchorOffer; /* --- messages --- */ @@ -73,34 +81,6 @@ struct _Signature , 0, 0, 0, 0, 0, 0, 0, 0 } -/* - * Identifies consumption of a bitcoin output. - */ -struct _BitcoinInput -{ - ProtobufCMessage base; - /* - * This is the transaction ID. - */ - Sha256Hash *txid; - /* - * This is the output number. - */ - uint32_t output; - /* - * And the subscript we're signing. - */ - ProtobufCBinaryData subscript; - /* - * The amount this input is worth. - */ - uint64_t amount; -}; -#define BITCOIN_INPUT__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&bitcoin_input__descriptor) \ - , NULL, 0, {0,NULL}, 0 } - - /* * Pubkey for commitment transaction input. */ @@ -117,53 +97,6 @@ struct _BitcoinPubkey , {0,NULL} } -/* - * Change, if we want any. - */ -struct _Change -{ - ProtobufCMessage base; - uint64_t amount; - BitcoinPubkey *pubkey; -}; -#define CHANGE__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&change__descriptor) \ - , 0, NULL } - - -/* - * All about an anchor transaction. - */ -struct _Anchor -{ - ProtobufCMessage base; - /* - * 0 or more unspent inputs we want to use for anchor. - */ - size_t n_inputs; - BitcoinInput **inputs; - /* - * Any change from anchor (in case we don't want to use them all) - */ - Change *change; - /* - * How much transaction fee we'll pay in the anchor tx. - */ - uint64_t fee; - /* - * How much we'll be putting into channel (== sum(inputs) - change - fee) - */ - uint64_t total; - /* - * How many confirmations on anchor before we'll use channel. - */ - uint32_t min_confirms; -}; -#define ANCHOR__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&anchor__descriptor) \ - , 0,NULL, NULL, 0, 0, 0 } - - typedef enum { OPEN_CHANNEL__LOCKTIME__NOT_SET = 0, OPEN_CHANNEL__LOCKTIME_LOCKTIME_SECONDS = 2, @@ -177,25 +110,23 @@ struct _OpenChannel { ProtobufCMessage base; /* - * Hash seed for revoking commitment transactions. + * Hash for revoking first commitment transaction. */ Sha256Hash *revocation_hash; /* - * Pubkey for anchor to pay to for commitment tx (p2sh) + * Pubkey for anchor to pay into commitment tx. */ BitcoinPubkey *commit_key; /* * How to pay money to us from commit_tx. */ BitcoinPubkey *final_key; + OpenChannel__AnchorOffer anch; /* - * How much transaction fee we'll pay for commitment txs. + * How far must anchor be buried before we consider channel live? */ - uint64_t commitment_fee; - /* - * The anchor transaction details. - */ - Anchor *anchor; + protobuf_c_boolean has_min_depth; + uint32_t min_depth; OpenChannel__LocktimeCase locktime_case; union { uint32_t locktime_seconds; @@ -204,38 +135,52 @@ struct _OpenChannel }; #define OPEN_CHANNEL__INIT \ { PROTOBUF_C_MESSAGE_INIT (&open_channel__descriptor) \ - , NULL, NULL, NULL, 0, NULL, OPEN_CHANNEL__LOCKTIME__NOT_SET, {} } + , NULL, NULL, NULL, 0, 0,0u, OPEN_CHANNEL__LOCKTIME__NOT_SET, {} } /* - * Supply signature for commitment tx + * Whoever is supplying anchor sends this. */ -struct _OpenCommitSig +struct _OpenAnchor { ProtobufCMessage base; - Signature *sig; + /* + * Transaction ID of anchor. + */ + Sha256Hash *txid; + /* + * Which output is going to the 2 of 2. + */ + uint32_t output_index; + /* + * Amount of anchor output. + */ + uint64_t amount; + /* + * Signature for your initial commitment tx. + */ + Signature *commit_sig; }; -#define OPEN_COMMIT_SIG__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&open_commit_sig__descriptor) \ - , NULL } +#define OPEN_ANCHOR__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&open_anchor__descriptor) \ + , NULL, 0, 0, NULL } /* - * Supply ScriptSig for each anchor tx inputs. + * Reply: signature for your initial commitment tx */ -struct _OpenAnchorScriptsigs +struct _OpenCommitSig { ProtobufCMessage base; - size_t n_script; - ProtobufCBinaryData *script; + Signature *sig; }; -#define OPEN_ANCHOR_SCRIPTSIGS__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&open_anchor_scriptsigs__descriptor) \ - , 0,NULL } +#define OPEN_COMMIT_SIG__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&open_commit_sig__descriptor) \ + , NULL } /* - * Indicates we've seen transaction reach min-depth. + * Indicates we've seen anchor reach min-depth. */ struct _OpenComplete { @@ -382,8 +327,8 @@ struct _Error typedef enum { PKT__PKT__NOT_SET = 0, PKT__PKT_OPEN = 201, - PKT__PKT_OPEN_COMMIT_SIG = 202, - PKT__PKT_OPEN_ANCHOR_SCRIPTSIGS = 203, + PKT__PKT_OPEN_ANCHOR = 202, + PKT__PKT_OPEN_COMMIT_SIG = 203, PKT__PKT_OPEN_COMPLETE = 204, PKT__PKT_UPDATE = 1, PKT__PKT_UPDATE_ACCEPT = 2, @@ -406,8 +351,8 @@ struct _Pkt * Opening */ OpenChannel *open; + OpenAnchor *open_anchor; OpenCommitSig *open_commit_sig; - OpenAnchorScriptsigs *open_anchor_scriptsigs; OpenComplete *open_complete; /* * Updating (most common) @@ -470,25 +415,6 @@ Signature * void signature__free_unpacked (Signature *message, ProtobufCAllocator *allocator); -/* BitcoinInput methods */ -void bitcoin_input__init - (BitcoinInput *message); -size_t bitcoin_input__get_packed_size - (const BitcoinInput *message); -size_t bitcoin_input__pack - (const BitcoinInput *message, - uint8_t *out); -size_t bitcoin_input__pack_to_buffer - (const BitcoinInput *message, - ProtobufCBuffer *buffer); -BitcoinInput * - bitcoin_input__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void bitcoin_input__free_unpacked - (BitcoinInput *message, - ProtobufCAllocator *allocator); /* BitcoinPubkey methods */ void bitcoin_pubkey__init (BitcoinPubkey *message); @@ -508,44 +434,6 @@ BitcoinPubkey * void bitcoin_pubkey__free_unpacked (BitcoinPubkey *message, ProtobufCAllocator *allocator); -/* Change methods */ -void change__init - (Change *message); -size_t change__get_packed_size - (const Change *message); -size_t change__pack - (const Change *message, - uint8_t *out); -size_t change__pack_to_buffer - (const Change *message, - ProtobufCBuffer *buffer); -Change * - change__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void change__free_unpacked - (Change *message, - ProtobufCAllocator *allocator); -/* Anchor methods */ -void anchor__init - (Anchor *message); -size_t anchor__get_packed_size - (const Anchor *message); -size_t anchor__pack - (const Anchor *message, - uint8_t *out); -size_t anchor__pack_to_buffer - (const Anchor *message, - ProtobufCBuffer *buffer); -Anchor * - anchor__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void anchor__free_unpacked - (Anchor *message, - ProtobufCAllocator *allocator); /* OpenChannel methods */ void open_channel__init (OpenChannel *message); @@ -565,6 +453,25 @@ OpenChannel * void open_channel__free_unpacked (OpenChannel *message, ProtobufCAllocator *allocator); +/* OpenAnchor methods */ +void open_anchor__init + (OpenAnchor *message); +size_t open_anchor__get_packed_size + (const OpenAnchor *message); +size_t open_anchor__pack + (const OpenAnchor *message, + uint8_t *out); +size_t open_anchor__pack_to_buffer + (const OpenAnchor *message, + ProtobufCBuffer *buffer); +OpenAnchor * + open_anchor__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void open_anchor__free_unpacked + (OpenAnchor *message, + ProtobufCAllocator *allocator); /* OpenCommitSig methods */ void open_commit_sig__init (OpenCommitSig *message); @@ -584,25 +491,6 @@ OpenCommitSig * void open_commit_sig__free_unpacked (OpenCommitSig *message, ProtobufCAllocator *allocator); -/* OpenAnchorScriptsigs methods */ -void open_anchor_scriptsigs__init - (OpenAnchorScriptsigs *message); -size_t open_anchor_scriptsigs__get_packed_size - (const OpenAnchorScriptsigs *message); -size_t open_anchor_scriptsigs__pack - (const OpenAnchorScriptsigs *message, - uint8_t *out); -size_t open_anchor_scriptsigs__pack_to_buffer - (const OpenAnchorScriptsigs *message, - ProtobufCBuffer *buffer); -OpenAnchorScriptsigs * - open_anchor_scriptsigs__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void open_anchor_scriptsigs__free_unpacked - (OpenAnchorScriptsigs *message, - ProtobufCAllocator *allocator); /* OpenComplete methods */ void open_complete__init (OpenComplete *message); @@ -782,27 +670,18 @@ typedef void (*Sha256Hash_Closure) typedef void (*Signature_Closure) (const Signature *message, void *closure_data); -typedef void (*BitcoinInput_Closure) - (const BitcoinInput *message, - void *closure_data); typedef void (*BitcoinPubkey_Closure) (const BitcoinPubkey *message, void *closure_data); -typedef void (*Change_Closure) - (const Change *message, - void *closure_data); -typedef void (*Anchor_Closure) - (const Anchor *message, - void *closure_data); typedef void (*OpenChannel_Closure) (const OpenChannel *message, void *closure_data); +typedef void (*OpenAnchor_Closure) + (const OpenAnchor *message, + void *closure_data); typedef void (*OpenCommitSig_Closure) (const OpenCommitSig *message, void *closure_data); -typedef void (*OpenAnchorScriptsigs_Closure) - (const OpenAnchorScriptsigs *message, - void *closure_data); typedef void (*OpenComplete_Closure) (const OpenComplete *message, void *closure_data); @@ -838,13 +717,11 @@ typedef void (*Pkt_Closure) extern const ProtobufCMessageDescriptor sha256_hash__descriptor; extern const ProtobufCMessageDescriptor signature__descriptor; -extern const ProtobufCMessageDescriptor bitcoin_input__descriptor; extern const ProtobufCMessageDescriptor bitcoin_pubkey__descriptor; -extern const ProtobufCMessageDescriptor change__descriptor; -extern const ProtobufCMessageDescriptor anchor__descriptor; extern const ProtobufCMessageDescriptor open_channel__descriptor; +extern const ProtobufCEnumDescriptor open_channel__anchor_offer__descriptor; +extern const ProtobufCMessageDescriptor open_anchor__descriptor; extern const ProtobufCMessageDescriptor open_commit_sig__descriptor; -extern const ProtobufCMessageDescriptor open_anchor_scriptsigs__descriptor; extern const ProtobufCMessageDescriptor open_complete__descriptor; extern const ProtobufCMessageDescriptor update__descriptor; extern const ProtobufCMessageDescriptor update_accept__descriptor; diff --git a/lightning.proto b/lightning.proto index 467cfd257..c4688af55 100644 --- a/lightning.proto +++ b/lightning.proto @@ -24,44 +24,12 @@ message signature { required fixed64 s4 = 8; } -// Identifies consumption of a bitcoin output. -message bitcoin_input { - // This is the transaction ID. - required sha256_hash txid = 1; - // This is the output number. - required uint32 output = 2; - // And the subscript we're signing. - required bytes subscript = 3; - // The amount this input is worth. - required uint64 amount = 4; -} - // Pubkey for commitment transaction input. message bitcoin_pubkey { // Either 65 or 33 bytes. required bytes key = 1; }; -// Change, if we want any. -message change { - required uint64 amount = 1; - required bitcoin_pubkey pubkey = 2; -} - -// All about an anchor transaction. -message anchor { - // 0 or more unspent inputs we want to use for anchor. - repeated bitcoin_input inputs = 1; - // Any change from anchor (in case we don't want to use them all) - optional change change = 2; - // How much transaction fee we'll pay in the anchor tx. - required uint64 fee = 8; - // How much we'll be putting into channel (== sum(inputs) - change - fee) - required uint64 total = 4; - // How many confirmations on anchor before we'll use channel. - required uint32 min_confirms = 10; -} - // // Packet Types // @@ -73,29 +41,44 @@ message open_channel { uint32 locktime_seconds = 2; uint32 locktime_blocks = 3; } - // Hash seed for revoking commitment transactions. + // Hash for revoking first commitment transaction. required sha256_hash revocation_hash = 4; // Pubkey for anchor to pay into commitment tx. required bitcoin_pubkey commit_key = 5; // How to pay money to us from commit_tx. required bitcoin_pubkey final_key = 1; - // How much transaction fee we'll pay for commitment txs. - required uint64 commitment_fee = 6; - // The anchor transaction details. - required anchor anchor = 7; + + enum anchor_offer { + // I will create the anchor + WILL_CREATE_ANCHOR = 1; + // I won't create the anchor + WONT_CREATE_ANCHOR = 2; + } + required anchor_offer anch = 6; + + // How far must anchor be buried before we consider channel live? + optional uint32 min_depth = 7 [ default = 0 ]; } -// Supply signature for commitment tx -message open_commit_sig { - required signature sig = 1; +// Whoever is supplying anchor sends this. +message open_anchor { + // Transaction ID of anchor. + required sha256_hash txid = 1; + // Which output is going to the 2 of 2. + required uint32 output_index = 2; + // Amount of anchor output. + required uint64 amount = 3; + + // Signature for your initial commitment tx. + required signature commit_sig = 4; } -// Supply ScriptSig for each anchor tx inputs. -message open_anchor_scriptsigs { - repeated bytes script = 1; +// Reply: signature for your initial commitment tx +message open_commit_sig { + required signature sig = 1; } -// Indicates we've seen transaction reach min-depth. +// Indicates we've seen anchor reach min-depth. message open_complete { // Block it went into. optional sha256_hash blockid = 1; @@ -157,8 +140,8 @@ message pkt { oneof pkt { // Opening open_channel open = 201; - open_commit_sig open_commit_sig = 202; - open_anchor_scriptsigs open_anchor_scriptsigs = 203; + open_anchor open_anchor = 202; + open_commit_sig open_commit_sig = 203; open_complete open_complete = 204; // Updating (most common) update update = 1; diff --git a/pkt.c b/pkt.c index a3991e386..eeffef8fd 100644 --- a/pkt.c +++ b/pkt.c @@ -13,7 +13,7 @@ size_t pkt_totlen(const struct pkt *pkt) return sizeof(pkt->len) + le32_to_cpu(pkt->len); } -static struct pkt *to_pkt(const tal_t *ctx, Pkt__PktCase type, void *msg) +static struct pkt *to_pkt(const tal_t *ctx, Pkt__PktCase type, const void *msg) { struct pkt *ret; size_t len; @@ -21,7 +21,7 @@ static struct pkt *to_pkt(const tal_t *ctx, Pkt__PktCase type, void *msg) p.pkt_case = type; /* This is a union, so doesn't matter which we assign. */ - p.error = msg; + p.error = (Error *)msg; len = pkt__get_packed_size(&p); ret = (struct pkt *)tal_arr(ctx, u8, sizeof(ret->len) + len); @@ -31,37 +31,44 @@ static struct pkt *to_pkt(const tal_t *ctx, Pkt__PktCase type, void *msg) return ret; } -struct pkt *openchannel_pkt(const tal_t *ctx, - const struct sha256 *revocation_hash, - const struct pubkey *commit, - const struct pubkey *final, - u64 commitment_fee, - u32 rel_locktime_seconds, - Anchor *anchor) +struct pkt *open_channel_pkt(const tal_t *ctx, + const struct sha256 *revocation_hash, + const struct pubkey *commit, + const struct pubkey *final, + u32 rel_locktime_seconds, + bool offer_anchor, + u32 min_depth) { OpenChannel o = OPEN_CHANNEL__INIT; - /* Required fields must be set: pack functions don't check! */ - assert(anchor->inputs); - o.revocation_hash = sha256_to_proto(ctx, revocation_hash); o.commit_key = pubkey_to_proto(ctx, commit); o.final_key = pubkey_to_proto(ctx, final); - o.commitment_fee = commitment_fee; - o.anchor = anchor; o.locktime_case = OPEN_CHANNEL__LOCKTIME_LOCKTIME_SECONDS; o.locktime_seconds = rel_locktime_seconds; + if (offer_anchor) + o.anch = OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR; + else + o.anch = OPEN_CHANNEL__ANCHOR_OFFER__WONT_CREATE_ANCHOR; + + o.min_depth = min_depth; { size_t len = open_channel__get_packed_size(&o); unsigned char *pb = malloc(len); open_channel__pack(&o, pb); assert(open_channel__unpack(NULL, len, pb)); + free(pb); } return to_pkt(ctx, PKT__PKT_OPEN, &o); } +struct pkt *open_anchor_pkt(const tal_t *ctx, const OpenAnchor *oa_msg) +{ + return to_pkt(ctx, PKT__PKT_OPEN_ANCHOR, oa_msg); +} + Pkt *any_pkt_from_file(const char *filename) { struct pkt *pkt; @@ -93,21 +100,6 @@ Pkt *pkt_from_file(const char *filename, Pkt__PktCase expect) return ret; } -struct pkt *open_anchor_sig_pkt(const tal_t *ctx, u8 **sigs, size_t num_sigs) -{ - OpenAnchorScriptsigs o = OPEN_ANCHOR_SCRIPTSIGS__INIT; - size_t i; - - o.n_script = num_sigs; - o.script = tal_arr(ctx, ProtobufCBinaryData, num_sigs); - for (i = 0; i < num_sigs; i++) { - o.script[i].data = sigs[i]; - o.script[i].len = tal_count(sigs[i]); - } - - return to_pkt(ctx, PKT__PKT_OPEN_ANCHOR_SCRIPTSIGS, &o); -} - struct pkt *open_commit_sig_pkt(const tal_t *ctx, const struct signature *sig) { OpenCommitSig o = OPEN_COMMIT_SIG__INIT; diff --git a/pkt.h b/pkt.h index 575150a46..e081f21df 100644 --- a/pkt.h +++ b/pkt.h @@ -29,30 +29,29 @@ struct signature; struct pubkey; /** - * openchannel_pkt - create an openchannel message + * open_channel_pkt - create an openchannel message * @ctx: tal context to allocate off. * @revocation_hash: first hash value generated from seed. * @commit: the pubkey for the anchor transactions' P2SH output. * @final: the pubkey for the commit transactions' P2SH output. - * @commitment_fee: the fee to use for commitment tx. * @rel_locktime_seconds: relative seconds for commitment locktime. - * @anchor: the anchor transaction details. + * @offer_anchor: whether we will offer anchor. + * @min_depth: minimum depth to insist on (if non-zero) */ -struct pkt *openchannel_pkt(const tal_t *ctx, - const struct sha256 *revocation_hash, - const struct pubkey *commit, - const struct pubkey *final, - u64 commitment_fee, - u32 rel_locktime_seconds, - Anchor *anchor); +struct pkt *open_channel_pkt(const tal_t *ctx, + const struct sha256 *revocation_hash, + const struct pubkey *commit, + const struct pubkey *final, + u32 rel_locktime_seconds, + bool offer_anchor, + u32 min_depth); /** - * open_anchor_sig_pkt - create an open_anchor_sig message + * open_anchor_pkt - create an open_anchor message packet * @ctx: tal context to allocate off. - * @sigs: the der-encoded signatures (tal_count() gives len). - * @num_sigs: the number of sigs. + * @oa_msg: the OpenAnchor message. */ -struct pkt *open_anchor_sig_pkt(const tal_t *ctx, u8 **sigs, size_t num_sigs); +struct pkt *open_anchor_pkt(const tal_t *ctx, const OpenAnchor *oa_msg); /** * open_commit_sig_pkt - create an open_commit_sig message diff --git a/test-cli/check-anchor-scriptsigs.c b/test-cli/check-anchor-scriptsigs.c deleted file mode 100644 index 21e9b182b..000000000 --- a/test-cli/check-anchor-scriptsigs.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "lightning.pb-c.h" -#include "anchor.h" -#include "bitcoin/base58.h" -#include "pkt.h" -#include "bitcoin/script.h" -#include "permute_tx.h" -#include "bitcoin/signature.h" -#include "commit_tx.h" -#include "bitcoin/pubkey.h" -#include - -int main(int argc, char *argv[]) -{ - const tal_t *ctx = tal_arr(NULL, char, 0); - OpenChannel *o1, *o2; - OpenAnchorScriptsigs *ss1, *ss2; - struct bitcoin_tx *anchor; - struct sha256_double txid; - size_t *inmap, *outmap; - - err_set_progname(argv[0]); - - opt_register_noarg("--help|-h", opt_usage_and_exit, - " \n" - "Output the anchor transaction by merging the scriptsigs", - "Print this message."); - - opt_parse(&argc, argv, opt_log_stderr_exit); - - if (argc != 5) - opt_usage_exit_fail("Expected 6 arguments"); - - o1 = pkt_from_file(argv[1], PKT__PKT_OPEN)->open; - o2 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; - ss1 = pkt_from_file(argv[3], PKT__PKT_OPEN_ANCHOR_SCRIPTSIGS) - ->open_anchor_scriptsigs; - ss2 = pkt_from_file(argv[4], PKT__PKT_OPEN_ANCHOR_SCRIPTSIGS) - ->open_anchor_scriptsigs; - - anchor = anchor_tx_create(ctx, o1, o2, &inmap, &outmap); - if (!anchor) - errx(1, "Failed transaction merge"); - if (!anchor_add_scriptsigs(anchor, ss1, ss2, inmap)) - errx(1, "Wrong number of scriptsigs"); - - bitcoin_txid(anchor, &txid); - - if (!bitcoin_tx_write(STDOUT_FILENO, anchor)) - err(1, "Writing out anchor transaction"); - - tal_free(ctx); - return 0; -} - diff --git a/test-cli/check-commit-sig.c b/test-cli/check-commit-sig.c index b83578465..321214134 100644 --- a/test-cli/check-commit-sig.c +++ b/test-cli/check-commit-sig.c @@ -5,7 +5,6 @@ #include #include #include "lightning.pb-c.h" -#include "anchor.h" #include "bitcoin/base58.h" #include "pkt.h" #include "bitcoin/script.h" @@ -15,92 +14,73 @@ #include "bitcoin/pubkey.h" #include "bitcoin/privkey.h" #include "protobuf_convert.h" +#include "funding.h" #include int main(int argc, char *argv[]) { const tal_t *ctx = tal_arr(NULL, char, 0); OpenChannel *o1, *o2; - OpenCommitSig *cs2; - struct bitcoin_tx *anchor, *commit; - struct sha256_double txid; + OpenAnchor *a; + struct bitcoin_tx *commit; u8 *subscript; - size_t *inmap, *outmap; struct pubkey pubkey1, pubkey2; - struct bitcoin_signature sig1, sig2; + struct bitcoin_signature sig; struct privkey privkey; bool testnet; struct sha256 rhash; + u64 our_amount, their_amount; err_set_progname(argv[0]); opt_register_noarg("--help|-h", opt_usage_and_exit, - " \n" - "Output the commitment transaction if both signatures are valid", + " []\n" + "Check the commit sig is valid (either in open-anchor or commit-sig packet)", "Print this message."); opt_parse(&argc, argv, opt_log_stderr_exit); - if (argc != 5) - opt_usage_exit_fail("Expected 4 arguments"); + if (argc != 5 && argc != 6) + opt_usage_exit_fail("Expected 4 or 5 arguments"); o1 = pkt_from_file(argv[1], PKT__PKT_OPEN)->open; o2 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; - cs2 = pkt_from_file(argv[3], PKT__PKT_OPEN_COMMIT_SIG)->open_commit_sig; + a = pkt_from_file(argv[3], PKT__PKT_OPEN_ANCHOR)->open_anchor; if (!key_from_base58(argv[4], strlen(argv[4]), &testnet, &privkey, &pubkey1)) errx(1, "Invalid private key '%s'", argv[4]); if (!testnet) errx(1, "Private key '%s' not on testnet!", argv[4]); + sig.stype = SIGHASH_ALL; + if (argc == 6) { + OpenCommitSig *cs = pkt_from_file(argv[5], + PKT__PKT_OPEN_COMMIT_SIG) + ->open_commit_sig; + if (!proto_to_signature(cs->sig, &sig.sig)) + errx(1, "Bad signature in %s", argv[5]); + } else { + if (!proto_to_signature(a->commit_sig, &sig.sig)) + errx(1, "Bad signature in %s", argv[3]); + } + /* Pubkey well-formed? */ if (!proto_to_pubkey(o2->commit_key, &pubkey2)) errx(1, "Invalid o2 commit_key"); - /* Get the transaction ID of the anchor. */ - anchor = anchor_tx_create(ctx, o1, o2, &inmap, &outmap); - if (!anchor) - errx(1, "Failed transaction merge"); - anchor_txid(anchor, &txid); - + if (!initial_funding(o1, o2, a, &our_amount, &their_amount)) + errx(1, "Invalid open combination (need 1 anchor offer)"); + /* Now create our commitment tx. */ proto_to_sha256(o1->revocation_hash, &rhash); - commit = create_commit_tx(ctx, o1, o2, &rhash, 0, &txid, outmap[0]); + commit = create_commit_tx(ctx, o1, o2, a, &rhash, + our_amount, their_amount); - /* If contributions don't exceed fees, this fails. */ - if (!commit) - errx(1, "Contributions %llu & %llu vs fees %llu & %llu", - (long long)o1->anchor->total, - (long long)o2->anchor->total, - (long long)o1->commitment_fee, - (long long)o2->commitment_fee); - - /* FIXME: Creating out signature just to check the script we create - * is overkill: if their signature and pubkey signed the commit txin, - * we're happy. */ - sig1.stype = SIGHASH_ALL; + /* Check signature. */ subscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); - sign_tx_input(ctx, commit, 0, subscript, tal_count(subscript), - &privkey, &pubkey1, &sig1.sig); - - /* Signatures well-formed? */ - if (!proto_to_signature(cs2->sig, &sig2.sig)) - errx(1, "Invalid commit-sig-2"); - sig2.stype = SIGHASH_ALL; - - /* Combined signatures must validate correctly. */ - if (!check_2of2_sig(commit, 0, subscript, tal_count(subscript), - &pubkey1, &pubkey2, &sig1, &sig2)) - errx(1, "Signature failed"); - - /* Create p2sh input for commit */ - commit->input[0].script = scriptsig_p2sh_2of2(commit, &sig1, &sig2, - &pubkey1, &pubkey2); - commit->input[0].script_length = tal_count(commit->input[0].script); - - /* Print it out in hex. */ - if (!bitcoin_tx_write(STDOUT_FILENO, commit)) - err(1, "Writing out transaction"); + if (!check_tx_sig(commit, 0, subscript, tal_count(subscript), + &pubkey2, &sig)) + errx(1, "Their signature invalid"); tal_free(ctx); return 0; diff --git a/test-cli/close-channel.c b/test-cli/close-channel.c index ae32e61a8..03b1af69c 100644 --- a/test-cli/close-channel.c +++ b/test-cli/close-channel.c @@ -6,41 +6,40 @@ #include #include #include "lightning.pb-c.h" -#include "anchor.h" #include "bitcoin/base58.h" #include "pkt.h" #include "bitcoin/script.h" #include "permute_tx.h" +#include "funding.h" #include "bitcoin/signature.h" #include "bitcoin/pubkey.h" #include "bitcoin/privkey.h" #include "close_tx.h" #include "find_p2sh_out.h" #include "protobuf_convert.h" +#include "gather_updates.h" #include int main(int argc, char *argv[]) { const tal_t *ctx = tal_arr(NULL, char, 0); OpenChannel *o1, *o2; - struct bitcoin_tx *anchor, *close_tx; - struct sha256_double anchor_txid; + OpenAnchor *a; + struct bitcoin_tx *close_tx; struct pkt *pkt; struct signature sig; struct privkey privkey; bool testnet, complete = false; struct pubkey pubkey1, pubkey2; u8 *redeemscript; - int64_t delta; - size_t i, anchor_out; + uint64_t our_amount, their_amount; err_set_progname(argv[0]); - /* FIXME: Take update.pbs to adjust channel */ opt_register_noarg("--complete", opt_set_bool, &complete, "Create a close_transaction_complete msg instead"); opt_register_noarg("--help|-h", opt_usage_and_exit, - " [update-protobuf]...\n" + " [{+/-}update-protobuf]...\n" "Create the signature needed for the close transaction", "Print this message."); @@ -49,23 +48,17 @@ int main(int argc, char *argv[]) if (argc < 5) opt_usage_exit_fail("Expected 4+ arguments"); - anchor = bitcoin_tx_from_file(ctx, argv[1]); - o1 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; - o2 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open; + o1 = pkt_from_file(argv[1], PKT__PKT_OPEN)->open; + o2 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; + a = pkt_from_file(argv[3], PKT__PKT_OPEN_ANCHOR)->open_anchor; if (!key_from_base58(argv[4], strlen(argv[4]), &testnet, &privkey, &pubkey1)) errx(1, "Invalid private key '%s'", argv[4]); if (!testnet) errx(1, "Private key '%s' not on testnet!", argv[4]); - bitcoin_txid(anchor, &anchor_txid); - - /* Get delta by accumulting all the updates. */ - delta = 0; - for (i = 5; i < argc; i++) { - Update *u = pkt_from_file(argv[i], PKT__PKT_UPDATE)->update; - delta += u->delta; - } + gather_updates(o1, o2, a, argv + 5, &our_amount, &their_amount, + NULL, NULL, NULL); /* Get pubkeys */ if (!proto_to_pubkey(o1->commit_key, &pubkey2)) @@ -76,16 +69,11 @@ int main(int argc, char *argv[]) if (!proto_to_pubkey(o2->commit_key, &pubkey2)) errx(1, "Invalid o2 commit pubkey"); - /* This is what the anchor pays to; figure out whick output. */ + /* This is what the anchor pays to. */ redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); - /* Now create the close tx to spend 2/2 output of anchor. */ - /* Assumes that updates are all from closer -> closee */ - anchor_out = find_p2sh_out(anchor, redeemscript); - close_tx = create_close_tx(ctx, o1, o2, complete ? -delta : delta, - &anchor_txid, - anchor->output[anchor_out].amount, - anchor_out); + /* FIXME: Add fee! */ + close_tx = create_close_tx(ctx, o1, o2, a, our_amount, their_amount); /* Sign it for them. */ sign_tx_input(ctx, close_tx, 0, redeemscript, tal_count(redeemscript), diff --git a/test-cli/create-anchor-tx.c b/test-cli/create-anchor-tx.c new file mode 100644 index 000000000..2e6a9a130 --- /dev/null +++ b/test-cli/create-anchor-tx.c @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include +#include +#include +#include "lightning.pb-c.h" +#include "bitcoin/base58.h" +#include "pkt.h" +#include "bitcoin/script.h" +#include "bitcoin/address.h" +#include "bitcoin/tx.h" +#include "bitcoin/pubkey.h" +#include "bitcoin/privkey.h" +#include "bitcoin/shadouble.h" +#include "protobuf_convert.h" +#include +#include +#include "opt_bits.h" + +/* Bitcoin nodes are allowed to be 2 hours in the future. */ +#define LOCKTIME_MIN (2 * 60 * 60) + +struct input { + struct bitcoin_tx_input in; + struct privkey privkey; + struct pubkey pubkey; + struct bitcoin_signature sig; +}; + +static void parse_anchor_input(const char *spec, struct input *in) +{ + const char *slash; + char *end; + long l; + bool testnet; + + slash = strchr(spec, '/'); + if (!slash) + errx(1, "Expected / in ////"); + + if (!bitcoin_txid_from_hex(spec, slash - spec, &in->in.txid)) + errx(1, "Expected 256-bit hex txid before /"); + + in->in.index = l = strtol(slash + 1, &end, 10); + if (end == slash + 1 || *end != '/' || (int64_t)in->in.index != (int64_t)l) + errx(1, "Expected after /"); + + slash = end; + in->in.input_amount = l = strtol(slash + 1, &end, 10); + if (end == slash + 1 || *end != '/' || (int64_t)in->in.input_amount != (int64_t)l) + errx(1, "Expected after second /"); + + slash = end; + end = (char *)slash + 1 + strcspn(slash + 1, "/"); + in->in.script_length = hex_data_size(end - (slash + 1)); + in->in.script = tal_arr(in, u8, in->in.script_length); + if (!hex_decode(slash + 1, end - (slash + 1), + in->in.script, in->in.script_length)) + errx(1, "Expected hex string after third /"); + + if (*end != '/') + errx(1, "Expected / after hexscript"); + + if (!key_from_base58(end+1, strlen(end + 1), &testnet, + &in->privkey, &in->pubkey)) + errx(1, "Invalid private key '%s'", end+1); + if (!testnet) + errx(1, "Private key '%s' not on testnet!", end+1); +} + +int main(int argc, char *argv[]) +{ + OpenChannel *o1, *o2; + struct bitcoin_tx *anchor; + const tal_t *ctx = tal_arr(NULL, char, 0); + u64 anchor_fee, amount, total_in, change; + struct input *in; + u8 *redeemscript; + size_t i; + struct pubkey pubkey1, pubkey2; + + err_set_progname(argv[0]); + + anchor_fee = 10000; + + opt_register_noarg("--help|-h", opt_usage_and_exit, + " ////...\n" + "A test program to create an anchor tx on stdout.", + "Print this message."); + opt_register_arg("--anchor-fee=", + opt_set_bits, opt_show_bits, &anchor_fee, + "100's of satoshi to pay for anchor"); + + opt_parse(&argc, argv, opt_log_stderr_exit); + + if (argc < 6) + opt_usage_exit_fail("Expected 5 or more arguments"); + + o1 = pkt_from_file(argv[1], PKT__PKT_OPEN)->open; + o2 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; + if (!proto_to_pubkey(o1->commit_key, &pubkey1)) + errx(1, "Invalid o1 commit_key"); + if (!proto_to_pubkey(o2->commit_key, &pubkey2)) + errx(1, "Invalid o2 commit_key"); + + amount = atol(argv[3]); + if (!amount) + errx(1, "Invalid total: must be > 0"); + + in = tal_arr(ctx, struct input, argc - 5); + + total_in = 0; + for (i = 0; i < tal_count(in); i++) { + parse_anchor_input(argv[5+i], &in[i]); + total_in += in[i].in.input_amount; + } + + if (total_in < amount + anchor_fee) + errx(1, "Only %llu satoshi in, and %llu out (+%llu fee)", + (unsigned long long)total_in, + (unsigned long long)amount, + (unsigned long long)anchor_fee); + + change = total_in - (amount + anchor_fee); + + /* If there's change, we have an extra output. */ + anchor = bitcoin_tx(ctx, tal_count(in), change ? 2 : 1); + anchor->fee = anchor_fee; + + /* Commitment redeems this via 2 of 2 payment. */ + redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); + + /* Set up outputs. */ + anchor->output[0].amount = amount; + anchor->output[0].script = scriptpubkey_p2sh(anchor, redeemscript); + anchor->output[0].script_length = tal_count(anchor->output[0].script); + + if (change) { + struct pubkey change_key; + + if (!pubkey_from_hexstr(argv[4], &change_key)) + errx(1, "Invalid change key %s", argv[3]); + + redeemscript = bitcoin_redeem_single(anchor, &change_key); + anchor->output[1].amount = change; + anchor->output[1].script = scriptpubkey_p2sh(anchor, + redeemscript); + anchor->output[1].script_length + = tal_count(anchor->output[1].script); + } + + /* Set up inputs (leaving scripts empty for signing) */ + for (i = 0; i < tal_count(in); i++) { + anchor->input[i].input_amount = in[i].in.input_amount; + anchor->input[i].txid = in[i].in.txid; + anchor->input[i].index = in[i].in.index; + } + + /* Now, sign each input. */ + for (i = 0; i < tal_count(in); i++) { + in[i].sig.stype = SIGHASH_ALL; + if (!sign_tx_input(ctx, anchor, i, in[i].in.script, + in[i].in.script_length, + &in[i].privkey, &in[i].pubkey, + &in[i].sig.sig)) + errx(1, "Error signing input %zi", i); + } + + /* Finally, complete inputs using signatures. */ + for (i = 0; i < tal_count(in); i++) { + if (!is_pay_to_pubkey_hash(in[i].in.script, + in[i].in.script_length)) + errx(1, "FIXME: Don't know how to handle input %zi", i); + anchor->input[i].script + = scriptsig_pay_to_pubkeyhash(anchor, &in[i].pubkey, + &in[i].sig); + anchor->input[i].script_length + = tal_count(anchor->input[i].script); + } + + /* Print it out in hex. */ + if (!bitcoin_tx_write(STDOUT_FILENO, anchor)) + err(1, "Writing out transaction"); + + tal_free(ctx); + return 0; +} diff --git a/test-cli/create-close-tx.c b/test-cli/create-close-tx.c index 613038287..1c2de558c 100644 --- a/test-cli/create-close-tx.c +++ b/test-cli/create-close-tx.c @@ -5,7 +5,6 @@ #include #include #include "lightning.pb-c.h" -#include "anchor.h" #include "bitcoin/base58.h" #include "pkt.h" #include "bitcoin/script.h" @@ -15,27 +14,27 @@ #include "close_tx.h" #include "find_p2sh_out.h" #include "protobuf_convert.h" +#include "gather_updates.h" #include int main(int argc, char *argv[]) { const tal_t *ctx = tal_arr(NULL, char, 0); OpenChannel *o1, *o2; - struct bitcoin_tx *anchor, *close_tx; - struct sha256_double anchor_txid; + OpenAnchor *a; + struct bitcoin_tx *close_tx; struct bitcoin_signature sig1, sig2; struct pubkey pubkey1, pubkey2; u8 *redeemscript; CloseChannel *close; CloseChannelComplete *closecomplete; - size_t i, anchor_out; - int64_t delta; + uint64_t our_amount, their_amount; err_set_progname(argv[0]); /* FIXME: Take update.pbs to adjust channel */ opt_register_noarg("--help|-h", opt_usage_and_exit, - " [update-protobuf]...\n" + " [update-protobuf]...\n" "Create the close transaction from the signatures", "Print this message."); @@ -44,14 +43,12 @@ int main(int argc, char *argv[]) if (argc < 6) opt_usage_exit_fail("Expected 5+ arguments"); - anchor = bitcoin_tx_from_file(ctx, argv[1]); - o1 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; - o2 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open; + o1 = pkt_from_file(argv[1], PKT__PKT_OPEN)->open; + o2 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; + a = pkt_from_file(argv[3], PKT__PKT_OPEN_ANCHOR)->open_anchor; close = pkt_from_file(argv[4], PKT__PKT_CLOSE)->close; closecomplete = pkt_from_file(argv[5], PKT__PKT_CLOSE_COMPLETE)->close_complete; - bitcoin_txid(anchor, &anchor_txid); - /* Pubkeys well-formed? */ if (!proto_to_pubkey(o1->commit_key, &pubkey1)) errx(1, "Invalid o1 commit_key"); @@ -59,20 +56,14 @@ int main(int argc, char *argv[]) errx(1, "Invalid o2 commit_key"); /* Get delta by accumulting all the updates. */ - delta = 0; - for (i = 6; i < argc; i++) { - Update *u = pkt_from_file(argv[i], PKT__PKT_UPDATE)->update; - delta += u->delta; - } + gather_updates(o1, o2, a, argv + 6, &our_amount, &their_amount, + NULL, NULL, NULL); /* This is what the anchor pays to; figure out which output. */ redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); /* Now create the close tx to spend 2/2 output of anchor. */ - anchor_out = find_p2sh_out(anchor, redeemscript); - close_tx = create_close_tx(ctx, o1, o2, delta, &anchor_txid, - anchor->output[anchor_out].amount, - anchor_out); + close_tx = create_close_tx(ctx, o1, o2, a, our_amount, their_amount); /* Signatures well-formed? */ sig1.stype = sig2.stype = SIGHASH_ALL; diff --git a/test-cli/create-commit-spend-tx.c b/test-cli/create-commit-spend-tx.c index b6407e8e1..ca3ea2163 100644 --- a/test-cli/create-commit-spend-tx.c +++ b/test-cli/create-commit-spend-tx.c @@ -6,7 +6,6 @@ #include #include #include "lightning.pb-c.h" -#include "anchor.h" #include "bitcoin/base58.h" #include "pkt.h" #include "bitcoin/script.h" @@ -19,12 +18,14 @@ #include "opt_bits.h" #include "find_p2sh_out.h" #include "protobuf_convert.h" +#include "test-cli/gather_updates.h" #include int main(int argc, char *argv[]) { const tal_t *ctx = tal_arr(NULL, char, 0); OpenChannel *o1, *o2; + OpenAnchor *a; struct bitcoin_tx *commit, *tx; struct bitcoin_signature sig; struct privkey privkey; @@ -32,8 +33,8 @@ int main(int argc, char *argv[]) struct pubkey pubkey1, pubkey2, outpubkey; u8 *redeemscript; struct sha256 rhash; - size_t i, p2sh_out; - u64 fee = 10000; + size_t p2sh_out; + u64 fee = 10000, our_amount, their_amount; u32 locktime; err_set_progname(argv[0]); @@ -41,7 +42,7 @@ int main(int argc, char *argv[]) /* FIXME: If we've updated channel since, we need the final * revocation hash we sent (either update_accept or update_complete) */ opt_register_noarg("--help|-h", opt_usage_and_exit, - " [previous-updates]\n" + " [previous-updates]\n" "Create the transaction to spend our commit transaction", "Print this message."); opt_register_arg("--fee=", @@ -57,17 +58,18 @@ int main(int argc, char *argv[]) o1 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; o2 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open; + a = pkt_from_file(argv[4], PKT__PKT_OPEN_ANCHOR)->open_anchor; if (!proto_to_locktime(o2, &locktime)) errx(1, "Invalid locktime in o2"); /* We need our private key to spend commit output. */ - if (!key_from_base58(argv[4], strlen(argv[4]), &testnet, &privkey, &pubkey1)) - errx(1, "Invalid private key '%s'", argv[4]); + if (!key_from_base58(argv[5], strlen(argv[5]), &testnet, &privkey, &pubkey1)) + errx(1, "Invalid private key '%s'", argv[5]); if (!testnet) - errx(1, "Private key '%s' not on testnet!", argv[4]); + errx(1, "Private key '%s' not on testnet!", argv[5]); - if (!pubkey_from_hexstr(argv[5], &outpubkey)) - errx(1, "Invalid bitcoin pubkey '%s'", argv[5]); + if (!pubkey_from_hexstr(argv[6], &outpubkey)) + errx(1, "Invalid bitcoin pubkey '%s'", argv[6]); /* Get pubkeys */ if (!proto_to_pubkey(o1->final_key, &pubkey2)) @@ -78,14 +80,9 @@ int main(int argc, char *argv[]) if (!proto_to_pubkey(o2->final_key, &pubkey2)) errx(1, "Invalid o2 final pubkey"); - /* o1 gives us the revocation hash */ - proto_to_sha256(o1->revocation_hash, &rhash); - - /* Latest revocation hash comes from last update. */ - for (i = 6; i < argc; i++) { - Update *u = pkt_from_file(argv[i], PKT__PKT_UPDATE)->update; - proto_to_sha256(u->revocation_hash, &rhash); - } + /* We use this simply to get final revocation hash. */ + gather_updates(o1, o2, a, argv + 7, &our_amount, &their_amount, + &rhash, NULL, NULL); /* Create redeem script */ redeemscript = bitcoin_redeem_secret_or_delay(ctx, &pubkey1, locktime, diff --git a/test-cli/create-commit-tx.c b/test-cli/create-commit-tx.c index bd66f5ced..7c21c32e4 100644 --- a/test-cli/create-commit-tx.c +++ b/test-cli/create-commit-tx.c @@ -5,7 +5,6 @@ #include #include #include "lightning.pb-c.h" -#include "anchor.h" #include "bitcoin/base58.h" #include "pkt.h" #include "bitcoin/script.h" @@ -16,6 +15,7 @@ #include "bitcoin/privkey.h" #include "find_p2sh_out.h" #include "protobuf_convert.h" +#include "gather_updates.h" #include /* FIXME: this code doesn't work if we're not the ones proposing the delta */ @@ -23,34 +23,31 @@ int main(int argc, char *argv[]) { const tal_t *ctx = tal_arr(NULL, char, 0); OpenChannel *o1, *o2; - Pkt *pkt; - struct bitcoin_tx *anchor, *commit; - struct sha256_double anchor_txid; + OpenAnchor *a; + struct bitcoin_tx *commit; struct privkey privkey; bool testnet; struct bitcoin_signature sig1, sig2; - size_t i; struct pubkey pubkey1, pubkey2; u8 *redeemscript; - int64_t delta; + uint64_t our_amount, their_amount; struct sha256 rhash; err_set_progname(argv[0]); opt_register_noarg("--help|-h", opt_usage_and_exit, - " [final-update-accept|open-commit-sig] []\n" + " []\n" "Create the signature needed for the commit transaction", "Print this message."); opt_parse(&argc, argv, opt_log_stderr_exit); - if (argc < 6) - opt_usage_exit_fail("Expected 5+ arguments"); + if (argc < 5) + opt_usage_exit_fail("Expected 4+ arguments"); - anchor = bitcoin_tx_from_file(ctx, argv[1]); - bitcoin_txid(anchor, &anchor_txid); - o1 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; - o2 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open; + o1 = pkt_from_file(argv[1], PKT__PKT_OPEN)->open; + o2 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; + a = pkt_from_file(argv[3], PKT__PKT_OPEN_ANCHOR)->open_anchor; if (!key_from_base58(argv[4], strlen(argv[4]), &testnet, &privkey, &pubkey1)) errx(1, "Invalid private key '%s'", argv[4]); @@ -66,49 +63,27 @@ int main(int argc, char *argv[]) if (!proto_to_pubkey(o2->commit_key, &pubkey2)) errx(1, "Invalid o2 commit pubkey"); - /* Their signature comes from open-commit or from update-accept. */ sig2.stype = SIGHASH_ALL; - pkt = any_pkt_from_file(argv[5]); - - switch (pkt->pkt_case) { - case PKT__PKT_UPDATE_ACCEPT: - if (!proto_to_signature(pkt->update_accept->sig, &sig2.sig)) - errx(1, "Invalid update-accept sig"); - break; - case PKT__PKT_OPEN_COMMIT_SIG: - if (!proto_to_signature(pkt->open_commit_sig->sig, &sig2.sig)) - errx(1, "Invalid open-commit-sig sig"); - break; - default: - errx(1, "Unexpected packet type %u in %s", - pkt->pkt_case, argv[5]); - } - - /* Initial revocation hash comes from open. */ - proto_to_sha256(o1->revocation_hash, &rhash); - - delta = 0; - /* Figure out cumulative delta since anchor, update revocation hash */ - for (i = 6; i < argc; i++) { - Update *u = pkt_from_file(argv[i], PKT__PKT_UPDATE)->update; - delta += u->delta; - proto_to_sha256(u->revocation_hash, &rhash); - } + + gather_updates(o1, o2, a, argv + 5, &our_amount, &their_amount, + &rhash, NULL, &sig2.sig); + redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); /* Now create commitment tx to spend 2/2 output of anchor. */ - commit = create_commit_tx(ctx, o1, o2, &rhash, delta, &anchor_txid, - find_p2sh_out(anchor, redeemscript)); + commit = create_commit_tx(ctx, o1, o2, a, &rhash, + our_amount, their_amount); - /* If contributions don't exceed fees, this fails. */ + /* This only fails on malformed packets */ if (!commit) - errx(1, "Bad commit amounts"); + errx(1, "Malformed packets"); /* We generate our signature. */ sig1.stype = SIGHASH_ALL; sign_tx_input(ctx, commit, 0, redeemscript, tal_count(redeemscript), &privkey, &pubkey1, &sig1.sig); + /* Check it works with theirs... */ if (!check_2of2_sig(commit, 0, redeemscript, tal_count(redeemscript), &pubkey1, &pubkey2, &sig1, &sig2)) errx(1, "Signature failed"); diff --git a/test-cli/create-steal-tx.c b/test-cli/create-steal-tx.c index c414c3787..98f041f72 100644 --- a/test-cli/create-steal-tx.c +++ b/test-cli/create-steal-tx.c @@ -5,7 +5,6 @@ #include #include #include "lightning.pb-c.h" -#include "anchor.h" #include "bitcoin/base58.h" #include "pkt.h" #include "bitcoin/script.h" diff --git a/test-cli/gather_updates.c b/test-cli/gather_updates.c new file mode 100644 index 000000000..2579e6541 --- /dev/null +++ b/test-cli/gather_updates.c @@ -0,0 +1,149 @@ +#include +#include +#include +#include "test-cli/gather_updates.h" +#include "funding.h" +#include "pkt.h" +#include "protobuf_convert.h" + +static void check_preimage(const Sha256Hash *preimage, + const struct sha256 *old, + const struct sha256 *h, + const char *file) +{ + struct sha256 sha; + + if (!h) + return; + + proto_to_sha256(preimage, &sha); + sha256(&sha, &sha, sizeof(sha)); + if (!structeq(&sha, old)) + errx(1, "Invalid preimage in %s!", file); +} + +static void get_rhash(const Sha256Hash *rhash, struct sha256 *old, + struct sha256 *new) +{ + if (new) { + *old = *new; + proto_to_sha256(rhash, new); + } +} + +/* Takes complete update history, gets summary of last state. */ +uint64_t gather_updates(const OpenChannel *o1, const OpenChannel *o2, + const OpenAnchor *oa, + char **argv, + uint64_t *our_amount, uint64_t *their_amount, + struct sha256 *our_rhash, + struct sha256 *their_rhash, + struct signature *their_commit_sig) +{ + uint64_t cdelta = 0; + uint64_t num_updates = 0; + Signature *sig = NULL; + struct sha256 old_our_rhash, old_their_rhash; + + /* Start sanity check. */ + if (!initial_funding(o1, o2, oa, our_amount, their_amount)) + errx(1, "Invalid open combination (need 1 anchor offer)"); + + if (our_rhash) + proto_to_sha256(o1->revocation_hash, our_rhash); + + if (their_rhash) + proto_to_sha256(o2->revocation_hash, their_rhash); + + /* If o2 sent anchor, it contains their commit sig. */ + if (o2->anch == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR) + sig = oa->commit_sig; + + while (*argv) { + int64_t delta; + bool received; + Pkt *pkt; + + /* + marks messages sent by us, - for messages from them */ + if (strstarts(*argv, "+")) { + received = false; + } else if (strstarts(*argv, "-")) { + received = true; + } else + errx(1, "%s does not start with +/-", *argv); + + pkt = any_pkt_from_file(*argv + 1); + switch (pkt->pkt_case) { + case PKT__PKT_OPEN_COMMIT_SIG: + if (received) + sig = pkt->open_commit_sig->sig; + break; + case PKT__PKT_UPDATE: { + if (received) { + delta = -pkt->update->delta; + get_rhash(pkt->update->revocation_hash, + &old_their_rhash, their_rhash); + } else { + delta = pkt->update->delta; + get_rhash(pkt->update->revocation_hash, + &old_our_rhash, our_rhash); + } + if (!funding_delta(o1, o2, oa, &cdelta, delta, + our_amount, their_amount)) + errx(1, "Impossible funding update %lli %s", + (long long)delta, *argv); + num_updates++; + break; + } + case PKT__PKT_UPDATE_ACCEPT: + if (received) { + sig = pkt->update_accept->sig; + get_rhash(pkt->update_accept->revocation_hash, + &old_their_rhash, their_rhash); + } else { + get_rhash(pkt->update_accept->revocation_hash, + &old_our_rhash, our_rhash); + } + break; + case PKT__PKT_UPDATE_SIGNATURE: + if (received) { + sig = pkt->update_signature->sig; + check_preimage(pkt->update_signature + ->revocation_preimage, + &old_their_rhash, their_rhash, + *argv); + } else { + check_preimage(pkt->update_signature + ->revocation_preimage, + &old_our_rhash, our_rhash, + *argv); + } + break; + case PKT__PKT_UPDATE_COMPLETE: + if (received) { + check_preimage(pkt->update_complete + ->revocation_preimage, + &old_their_rhash, their_rhash, + *argv); + } else { + check_preimage(pkt->update_complete + ->revocation_preimage, + &old_our_rhash, our_rhash, + *argv); + } + break; + default: + errx(1, "Unexpected packet type %u", pkt->pkt_case); + } + argv++; + } + + if (their_commit_sig) { + if (!sig) + errx(1, "No commit signature message found"); + if (!proto_to_signature(sig, their_commit_sig)) + errx(1, "Invalid signature"); + } + + return num_updates; +} diff --git a/test-cli/gather_updates.h b/test-cli/gather_updates.h new file mode 100644 index 000000000..bfd183dad --- /dev/null +++ b/test-cli/gather_updates.h @@ -0,0 +1,16 @@ +#ifndef GATHER_UPDATES_H +#define GATHER_UPDATES_H +#include "lightning.pb-c.h" + +struct signature; +struct sha256; + +uint64_t gather_updates(const OpenChannel *o1, const OpenChannel *o2, + const OpenAnchor *oa, + char **argv, + uint64_t *our_amount, uint64_t *their_amount, + struct sha256 *our_rhash, + struct sha256 *their_rhash, + struct signature *their_commit_sig); + +#endif /* GATHER_UPDATES_H */ diff --git a/test-cli/get-anchor-depth.c b/test-cli/get-anchor-depth.c index 9717b65ac..5c99706a6 100644 --- a/test-cli/get-anchor-depth.c +++ b/test-cli/get-anchor-depth.c @@ -5,7 +5,6 @@ #include #include #include "lightning.pb-c.h" -#include "anchor.h" #include "bitcoin/base58.h" #include "pkt.h" #include "bitcoin/script.h" @@ -33,7 +32,7 @@ int main(int argc, char *argv[]) opt_usage_exit_fail("Expected one argument"); o = pkt_from_file(argv[1], PKT__PKT_OPEN)->open; - printf("%u\n", o->anchor->min_confirms); + printf("%u\n", o->min_depth); tal_free(ctx); return 0; diff --git a/test-cli/open-anchor-scriptsigs.c b/test-cli/open-anchor-scriptsigs.c deleted file mode 100644 index 2152f4979..000000000 --- a/test-cli/open-anchor-scriptsigs.c +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include -#include -#include "bitcoin/tx.h" -#include "bitcoin/signature.h" -#include "lightning.pb-c.h" -#include "pkt.h" -#include "bitcoin/script.h" -#include "bitcoin/address.h" -#include "bitcoin/base58.h" -#include "anchor.h" -#include "bitcoin/pubkey.h" -#include "bitcoin/privkey.h" - -#include - -/* All the input scripts are already set to 0. We just need to make this one. */ -static u8 *tx_scriptsig(const tal_t *ctx, - struct bitcoin_tx *tx, - unsigned int i, - const BitcoinInput *input, - struct privkey *privkey, - const struct pubkey *pubkey) -{ - struct bitcoin_signature sig; - - sig.stype = SIGHASH_ALL; - if (!sign_tx_input(ctx, tx, i, - input->subscript.data, input->subscript.len, - privkey, pubkey, &sig.sig)) - return NULL; - - if (!is_pay_to_pubkey_hash(input->subscript.data, input->subscript.len)) - errx(1, "FIXME: Don't know how to handle input"); - return scriptsig_pay_to_pubkeyhash(ctx, pubkey, &sig); -} - -int main(int argc, char *argv[]) -{ - OpenChannel *o1, *o2; - const tal_t *ctx = tal_arr(NULL, char, 0); - struct bitcoin_tx *anchor; - struct pkt *pkt; - size_t i; - u8 **sigs; - size_t *map; - - err_set_progname(argv[0]); - - opt_register_noarg("--help|-h", opt_usage_and_exit, - " ...\n" - "Create signatures for transactions, and output to stdout", - "Print this message."); - - opt_parse(&argc, argv, opt_log_stderr_exit); - - if (argc < 3) - opt_usage_exit_fail("Expected 2 or more arguments"); - - o1 = pkt_from_file(argv[1], PKT__PKT_OPEN)->open; - o2 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; - - /* FIXME: We should check that their locktime is sane here, - * since we're bound to it. Also min_confirms, etc. */ - - /* Create merged transaction */ - anchor = anchor_tx_create(ctx, o1, o2, &map, NULL); - if (!anchor) - errx(1, "Failed transaction merge"); - - /* Sign our inputs. */ - if (o1->anchor->n_inputs != argc - 3) - errx(1, "Expected %zu private keys", o1->anchor->n_inputs); - - sigs = tal_arr(ctx, u8 *, o1->anchor->n_inputs); - for (i = 0; i < o1->anchor->n_inputs; i++) { - struct pubkey pubkey; - struct privkey privkey; - bool testnet; - - if (!key_from_base58(argv[3+i], strlen(argv[3+i]), - &testnet, &privkey, &pubkey)) - errx(1, "Invalid private key '%s'", argv[3+i]); - if (!testnet) - errx(1, "Private key '%s' not on testnet!", argv[3+i]); - - sigs[i] = tx_scriptsig(sigs, anchor, map[i], - o1->anchor->inputs[i], - &privkey, &pubkey); - } - - pkt = open_anchor_sig_pkt(ctx, sigs, o1->anchor->n_inputs); - if (!write_all(STDOUT_FILENO, pkt, pkt_totlen(pkt))) - err(1, "Writing out packet"); - - tal_free(ctx); - return 0; -} diff --git a/test-cli/open-channel.c b/test-cli/open-channel.c index e8af836b1..fe3959994 100644 --- a/test-cli/open-channel.c +++ b/test-cli/open-channel.c @@ -22,145 +22,61 @@ /* Bitcoin nodes are allowed to be 2 hours in the future. */ #define LOCKTIME_MIN (2 * 60 * 60) -static BitcoinInput *parse_anchor_input(const tal_t *ctx, const char *spec) -{ - BitcoinInput *in = tal(ctx, BitcoinInput); - struct sha256_double txid; - const char *slash; - char *end; - long l; - - bitcoin_input__init(in); - - slash = strchr(spec, '/'); - if (!slash) - errx(1, "Expected / in ///"); - - if (!bitcoin_txid_from_hex(spec, slash - spec, &txid)) - errx(1, "Expected 256-bit hex txid before /"); - in->txid = sha256_to_proto(in, &txid.sha); - - in->output = l = strtol(slash + 1, &end, 10); - if (end == slash + 1 || *end != '/' || (int64_t)in->output != (int64_t)l) - errx(1, "Expected after /"); - - slash = end; - in->amount = l = strtol(slash + 1, &end, 10); - if (end == slash + 1 || *end != '/' || (int64_t)in->amount != (int64_t)l) - errx(1, "Expected after second /"); - - slash = end; - in->subscript.len = strlen(slash + 1) / 2; - in->subscript.data = tal_arr(in, u8, in->subscript.len); - if (!hex_decode(slash + 1, strlen(slash + 1), - in->subscript.data, in->subscript.len)) - errx(1, "Expected hex string after third /"); - - return in; -} - /* Simple helper to open a channel. */ int main(int argc, char *argv[]) { struct sha256 seed, revocation_hash; struct pkt *pkt; const tal_t *ctx = tal_arr(NULL, char, 0); - Anchor anchor = ANCHOR__INIT; - u64 commit_tx_fee, total_in; - unsigned int locktime_seconds; - bool testnet; - size_t i; - struct pubkey commitkey, outkey, changekey; - struct privkey commitprivkey, outprivkey; + unsigned int locktime_seconds, min_confirms; + bool offer_anchor = false; + struct pubkey commitkey, finalkey; err_set_progname(argv[0]); - /* Default values. */ - anchor.min_confirms = 3; - /* Remember, other side contributes to fee, too. */ - anchor.fee = 5000; - /* We only need this for involuntary close, so make it larger. */ - commit_tx_fee = 100000; /* This means we have ~1 day before they can steal our money. */ locktime_seconds = LOCKTIME_MIN + 24 * 60 * 60; + /* Zero, unless they set --offer-anchor or --min-anchor-confirms */ + min_confirms = 0; opt_register_noarg("--help|-h", opt_usage_and_exit, - " ///...\n" + " \n" "A test program to output openchannel on stdout.", "Print this message."); opt_register_arg("--min-anchor-confirms", - opt_set_uintval, opt_show_uintval, &anchor.min_confirms, + opt_set_uintval, opt_show_uintval, &min_confirms, "Number of anchor confirmations before channel is active"); - opt_register_arg("--anchor-fee=", - opt_set_bits, opt_show_bits, &anchor.fee, - "100's of satoshi to pay for anchor"); - opt_register_arg("--commitment-fee=", - opt_set_bits, opt_show_bits, &commit_tx_fee, - "100's of satoshi to pay for commitment"); opt_register_arg("--locktime=", opt_set_uintval, opt_show_uintval, &locktime_seconds, "Seconds to lock out our transaction redemption"); + opt_register_noarg("--offer-anchor", + opt_set_bool, &offer_anchor, + "Offer to create anchor transaction"); opt_parse(&argc, argv, opt_log_stderr_exit); - if (argc < 7) - opt_usage_exit_fail("Expected 6 or more arguments"); + if (argc != 4) + opt_usage_exit_fail("Expected 3 arguments"); if (!hex_decode(argv[1], strlen(argv[1]), &seed, sizeof(seed))) errx(1, "Invalid seed '%s' - need 256 hex bits", argv[1]); - anchor.total = atol(argv[2]); - if (!anchor.total) - errx(1, "Invalid total: must be > 0"); - - if (!pubkey_from_hexstr(argv[3], &changekey)) - errx(1, "Invalid bitcoin pubkey '%s'", argv[3]); - - /* We don't really need the privkey here, but it's the most - * convenient way to get the pubkey from bitcoind. */ - if (!key_from_base58(argv[4], strlen(argv[4]), &testnet, - &commitprivkey, &commitkey)) - errx(1, "Invalid private key '%s'", argv[4]); - if (!testnet) - errx(1, "Private key '%s' not on testnet!", argv[4]); - - if (!key_from_base58(argv[5], strlen(argv[5]), &testnet, - &outprivkey, &outkey)) - errx(1, "Invalid private key '%s'", argv[5]); - if (!testnet) - errx(1, "Private key '%s' not on testnet!", argv[5]); - - anchor.n_inputs = (argc - 6); - anchor.inputs = tal_arr(ctx, BitcoinInput *, anchor.n_inputs); - - total_in = 0; - for (i = 0; i < anchor.n_inputs; i++) { - anchor.inputs[i] = parse_anchor_input(anchor.inputs, argv[i+6]); - total_in += anchor.inputs[i]->amount; - } + if (!pubkey_from_hexstr(argv[2], &commitkey)) + errx(1, "Invalid commit key '%s'", argv[2]); - if (total_in < anchor.total + anchor.fee) - errx(1, "Only %llu satoshi in, and %llu out (+%llu fee)", - (unsigned long long)total_in, - (unsigned long long)anchor.total, - (unsigned long long)anchor.fee); + if (!pubkey_from_hexstr(argv[3], &finalkey)) + errx(1, "Invalid final key '%s'", argv[3]); - /* If there's change, say where to send it. */ - if (total_in != anchor.total + anchor.fee) { - anchor.change = tal(ctx, Change); - change__init(anchor.change); - anchor.change->pubkey = pubkey_to_proto(anchor.change, - &changekey); - anchor.change->amount = total_in - (anchor.total + anchor.fee); - } + if (offer_anchor && min_confirms == 0) + min_confirms = 3; /* Get first revocation hash. */ shachain_from_seed(&seed, 0, &revocation_hash); sha256(&revocation_hash, revocation_hash.u.u8, sizeof(revocation_hash.u.u8)); - pkt = openchannel_pkt(ctx, &revocation_hash, &commitkey, &outkey, - commit_tx_fee, locktime_seconds, &anchor); + pkt = open_channel_pkt(ctx, &revocation_hash, &commitkey, &finalkey, + locktime_seconds, offer_anchor, min_confirms); if (!write_all(STDOUT_FILENO, pkt, pkt_totlen(pkt))) err(1, "Writing out packet"); diff --git a/test-cli/open-commit-sig.c b/test-cli/open-commit-sig.c index 1367c0ea1..f3ee3c638 100644 --- a/test-cli/open-commit-sig.c +++ b/test-cli/open-commit-sig.c @@ -6,7 +6,6 @@ #include #include #include "lightning.pb-c.h" -#include "anchor.h" #include "bitcoin/base58.h" #include "pkt.h" #include "bitcoin/script.h" @@ -16,62 +15,55 @@ #include "bitcoin/pubkey.h" #include "bitcoin/privkey.h" #include "protobuf_convert.h" +#include "funding.h" #include int main(int argc, char *argv[]) { const tal_t *ctx = tal_arr(NULL, char, 0); OpenChannel *o1, *o2; - struct bitcoin_tx *anchor, *commit; - struct sha256_double txid; + OpenAnchor *a; + struct bitcoin_tx *commit; struct pkt *pkt; struct signature sig; - size_t *inmap, *outmap; struct privkey privkey; bool testnet; struct pubkey pubkey1, pubkey2; u8 *subscript; struct sha256 rhash; + uint64_t to_them, to_us; err_set_progname(argv[0]); opt_register_noarg("--help|-h", opt_usage_and_exit, - " \n" + " \n" "Create the signature needed for the commit transaction", "Print this message."); opt_parse(&argc, argv, opt_log_stderr_exit); - if (argc != 4) - opt_usage_exit_fail("Expected 3 arguments"); + if (argc != 5) + opt_usage_exit_fail("Expected 4 arguments"); o1 = pkt_from_file(argv[1], PKT__PKT_OPEN)->open; o2 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; - - if (!key_from_base58(argv[3], strlen(argv[3]), &testnet, &privkey, &pubkey1)) - errx(1, "Invalid private key '%s'", argv[3]); + a = pkt_from_file(argv[3], PKT__PKT_OPEN_ANCHOR)->open_anchor; + + if (!key_from_base58(argv[4], strlen(argv[4]), &testnet, &privkey, &pubkey1)) + errx(1, "Invalid private key '%s'", argv[4]); if (!testnet) - errx(1, "Private key '%s' not on testnet!", argv[3]); - - /* Create merged anchor transaction */ - anchor = anchor_tx_create(ctx, o1, o2, &inmap, &outmap); - if (!anchor) - errx(1, "Failed transaction merge"); - - /* Get the transaction ID of the anchor. */ - anchor_txid(anchor, &txid); + errx(1, "Private key '%s' not on testnet!", argv[4]); /* Now create THEIR commitment tx to spend 2/2 output of anchor. */ + if (!initial_funding(o1, o2, a, &to_us, &to_them)) + errx(1, "Invalid open combination (need 1 anchor offer)"); + proto_to_sha256(o2->revocation_hash, &rhash); - commit = create_commit_tx(ctx, o2, o1, &rhash, 0, &txid, outmap[0]); + commit = create_commit_tx(ctx, o2, o1, a, &rhash, to_them, to_us); /* If contributions don't exceed fees, this fails. */ if (!commit) - errx(1, "Contributions %llu & %llu vs fees %llu & %llu", - (long long)o1->anchor->total, - (long long)o2->anchor->total, - (long long)o1->commitment_fee, - (long long)o2->commitment_fee); + errx(1, "Invalid packets?"); /* Their pubkey must be valid */ if (!proto_to_pubkey(o2->commit_key, &pubkey2)) diff --git a/test-cli/scripts/getinput.sh b/test-cli/scripts/getinput.sh index 85195cc1a..c2f046f87 100755 --- a/test-cli/scripts/getinput.sh +++ b/test-cli/scripts/getinput.sh @@ -8,10 +8,6 @@ set -e . `dirname $0`/vars.sh -if [ n"$1" = n--privkey ]; then - KEY=1 - shift -fi NUM=1 if [ $# = 1 ]; then NUM=$1 @@ -19,18 +15,15 @@ if [ $# = 1 ]; then fi if [ $# -gt 0 ]; then - echo "Usage: getinput.sh [--privkey] [INPUT-INDEX]" + echo "Usage: getinput.sh [INPUT-INDEX]" exit 1 fi -if [ -n "$KEY" ]; then - ADDR=`$CLI listunspent | sed -n 's/^ *"address" *: *"\([0-9a-zA-Z]*\)",$/\1/p' | tail -n +$NUM | head -n1` - $CLI dumpprivkey $ADDR -else - TXID=`$CLI listunspent | sed -n 's/^ *"txid" *: *"\([0-9a-f]*\)",$/\1/p' | tail -n +$NUM | head -n1` - OUTNUM=`$CLI listunspent | sed -n 's/^ *"vout" *: *\([0-9]*\),$/\1/p' | tail -n +$NUM | head -n1` - AMOUNT=`$CLI listunspent | sed -n 's/^ *"amount" *: *\([0-9.]*\),$/\1/p' | tail -n +$NUM | head -n1 | tr -d . | sed 's/^0*//'` - SCRIPT=`$CLI listunspent | sed -n 's/^ *"scriptPubKey" *: *"\([0-9a-f]*\)",$/\1/p' | tail -n +$NUM | head -n1` +TXID=`$CLI listunspent | sed -n 's/^ *"txid" *: *"\([0-9a-f]*\)",$/\1/p' | tail -n +$NUM | head -n1` +OUTNUM=`$CLI listunspent | sed -n 's/^ *"vout" *: *\([0-9]*\),$/\1/p' | tail -n +$NUM | head -n1` +AMOUNT=`$CLI listunspent | sed -n 's/^ *"amount" *: *\([0-9.]*\),$/\1/p' | tail -n +$NUM | head -n1 | tr -d . | sed 's/^0*//'` +SCRIPT=`$CLI listunspent | sed -n 's/^ *"scriptPubKey" *: *"\([0-9a-f]*\)",$/\1/p' | tail -n +$NUM | head -n1` +ADDR=`$CLI listunspent | sed -n 's/^ *"address" *: *"\([0-9a-zA-Z]*\)",$/\1/p' | tail -n +$NUM | head -n1` +PRIVKEY=`$CLI dumpprivkey $ADDR` - echo $TXID/$OUTNUM/$AMOUNT/$SCRIPT -fi +echo $TXID/$OUTNUM/$AMOUNT/$SCRIPT/$PRIVKEY diff --git a/test-cli/scripts/setup.sh b/test-cli/scripts/setup.sh index 4f095f902..862206a16 100755 --- a/test-cli/scripts/setup.sh +++ b/test-cli/scripts/setup.sh @@ -24,11 +24,10 @@ done scripts/generate-block.sh init A1=`scripts/get-new-address.sh` -A2=`scripts/get-new-address.sh` -TX=`$CLI sendmany "" "{ \"$A1\":10, \"$A2\":10 }"` +TX=`$CLI sendmany "" "{ \"$A1\":10 }"` scripts/generate-block.sh -# Find the inputs numbers corresponding to those 10 btc outs -echo "Arguments to test.sh:" +# Find the inputs number corresponding to that 10 btc out +echo "Argument to test.sh:" for i in $(seq 1 $($CLI listunspent | grep -c txid) ); do scripts/getinput.sh $i | grep -q "$TX.*/1000000000/" && echo -n "$i "; done echo diff --git a/test-cli/scripts/test.sh b/test-cli/scripts/test.sh index fdf363e75..62a1d450d 100755 --- a/test-cli/scripts/test.sh +++ b/test-cli/scripts/test.sh @@ -36,18 +36,16 @@ send_after_delay() $CLI sendrawtransaction $1 } -if [ $# -lt 2 ]; then - echo Usage: "INPUT1" "INPUT2" "[--steal|--unilateral]" >&2 +if [ $# = 0 ]; then + echo Usage: "INPUT" "[--steal|--unilateral]" >&2 exit 1 fi A_INPUTNUM=$1 -B_INPUTNUM=$2 -shift 2 +shift #A_INPUTNUM=4 #B_INPUTNUM=1 A_AMOUNT=100000000 -B_AMOUNT=200000000 A_CHANGEADDR=`scripts/get-new-address.sh` A_TMPADDR=`scripts/get-new-address.sh` @@ -66,79 +64,104 @@ B_FINALADDR=`scripts/get-new-address.sh` #B_FINALADDR=mvQgfEX4iMSEYqD31524jASQviPwPwpvuv A_TXIN=`scripts/getinput.sh $A_INPUTNUM` -A_TXINKEY=`scripts/getinput.sh --privkey $A_INPUTNUM` -B_TXIN=`scripts/getinput.sh $B_INPUTNUM` -B_TXINKEY=`scripts/getinput.sh --privkey $B_INPUTNUM` A_SEED=00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff B_SEED=112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00 A_CHANGEPUBKEY=`getpubkey $A_CHANGEADDR` A_TMPKEY=`getprivkey $A_TMPADDR` +A_TMPPUBKEY=`getpubkey $A_TMPADDR` A_FINALKEY=`getprivkey $A_FINALADDR` +A_FINALPUBKEY=`getpubkey $A_FINALADDR` B_CHANGEPUBKEY=`getpubkey $B_CHANGEADDR` B_TMPKEY=`getprivkey $B_TMPADDR` +B_TMPPUBKEY=`getpubkey $B_TMPADDR` B_FINALKEY=`getprivkey $B_FINALADDR` +B_FINALPUBKEY=`getpubkey $B_FINALADDR` -# Both sides say what they want from channel -$PREFIX ./open-channel $A_SEED $A_AMOUNT $A_CHANGEPUBKEY $A_TMPKEY $A_FINALKEY $A_TXIN > A-open.pb +# Both sides say what they want from channel (A offers anchor) +$PREFIX ./open-channel --offer-anchor $A_SEED $A_TMPPUBKEY $A_FINALPUBKEY > A-open.pb # B asks for a (dangerously) short locktime, for testing unilateral close. -$PREFIX ./open-channel --locktime=60 $B_SEED $B_AMOUNT $B_CHANGEPUBKEY $B_TMPKEY $B_FINALKEY $B_TXIN > B-open.pb +$PREFIX ./open-channel --locktime=60 $B_SEED $B_TMPPUBKEY $B_FINALPUBKEY > B-open.pb -# Now sign anchor. -$PREFIX ./open-anchor-scriptsigs A-open.pb B-open.pb $A_TXINKEY > A-anchor-scriptsigs.pb -$PREFIX ./open-anchor-scriptsigs B-open.pb A-open.pb $B_TXINKEY > B-anchor-scriptsigs.pb +# Now A creates anchor (does not broadcast!) +$PREFIX ./create-anchor-tx A-open.pb B-open.pb $A_AMOUNT $A_CHANGEPUBKEY $A_TXIN > A-anchor.tx -# Now create commit signature -$PREFIX ./open-commit-sig A-open.pb B-open.pb $A_TMPKEY > A-commit-sig.pb +# Now A sends info about anchor output, and signature for commit tx. +$PREFIX ./open-anchor A-open.pb B-open.pb A-anchor.tx $A_TMPKEY > A-anchor.pb -$PREFIX ./open-commit-sig B-open.pb A-open.pb $B_TMPKEY > B-commit-sig.pb +# Now B signs commit sig for anchor. +$PREFIX ./open-commit-sig B-open.pb A-open.pb A-anchor.pb $B_TMPKEY > B-commit-sig.pb -# Now check it. -$PREFIX ./check-commit-sig A-open.pb B-open.pb B-commit-sig.pb $A_TMPKEY > A-commit.tx -$PREFIX ./check-commit-sig B-open.pb A-open.pb A-commit-sig.pb $B_TMPKEY > B-commit.tx +# Now check sigs. +$PREFIX ./check-commit-sig A-open.pb B-open.pb A-anchor.pb $A_TMPKEY B-commit-sig.pb +$PREFIX ./check-commit-sig B-open.pb A-open.pb A-anchor.pb $B_TMPKEY -# Now check anchor sigs and make sure they're the same. -$PREFIX ./check-anchor-scriptsigs A-open.pb B-open.pb A-anchor-scriptsigs.pb B-anchor-scriptsigs.pb > A-anchor.tx -$PREFIX ./check-anchor-scriptsigs B-open.pb A-open.pb B-anchor-scriptsigs.pb A-anchor-scriptsigs.pb > B-anchor.tx -cmp A-anchor.tx B-anchor.tx +# A broadcasts anchor +$CLI sendrawtransaction `cut -d: -f1 A-anchor.tx` > A-anchor.txid -# Broadcast -$CLI sendrawtransaction `cut -d: -f1 A-anchor.tx` > anchor.txid +# Wait for confirms +while [ 0$($CLI getrawtransaction $(cat A-anchor.txid) 1 | sed -n 's/.*"confirmations" : \([0-9]*\),/\1/p') -lt $($PREFIX ./get-anchor-depth A-open.pb) ]; do scripts/generate-block.sh; done -# # Wait for confirms -# while [ 0$($CLI getrawtransaction $(cat anchor.txid) 1 | sed -n 's/.*"confirmations" : \([0-9]*\),/\1/p') -lt $($PREFIX ./get-anchor-depth A-open.pb) ]; do scripts/generate-block.sh; done +while [ 0$($CLI getrawtransaction $(cat A-anchor.txid) 1 | sed -n 's/.*"confirmations" : \([0-9]*\),/\1/p') -lt $($PREFIX ./get-anchor-depth B-open.pb) ]; do scripts/generate-block.sh; done -# while [ 0$($CLI getrawtransaction $(cat anchor.txid) 1 | sed -n 's/.*"confirmations" : \([0-9]*\),/\1/p') -lt $($PREFIX ./get-anchor-depth B-open.pb) ]; do scripts/generate-block.sh; done +# Update traffic sent so far. +A_UPDATE_PKTS="-- -B-commit-sig.pb" +B_UPDATE_PKTS="-- +B-commit-sig.pb" -# Just for testing, generate the first transaction. -$PREFIX ./create-commit-tx A-anchor.tx A-open.pb B-open.pb $A_TMPKEY B-commit-sig.pb > A-commit-0.tx +# Just for testing, generate the first commit transactions. +$PREFIX ./create-commit-tx A-open.pb B-open.pb A-anchor.pb $A_TMPKEY $A_UPDATE_PKTS > A-commit-0.tx +$PREFIX ./create-commit-tx B-open.pb A-open.pb A-anchor.pb $B_TMPKEY $B_UPDATE_PKTS > B-commit-0.tx # Now, update the channel, so I pay you 500 satoshi. -$PREFIX ./update-channel --to-them=500 $A_SEED > A-update-1.pb -$PREFIX ./update-channel-accept $B_SEED B-anchor.tx B-open.pb A-open.pb $B_TMPKEY A-update-1.pb > B-update-accept-1.pb -$PREFIX ./update-channel-signature $A_SEED A-anchor.tx A-open.pb B-open.pb $A_TMPKEY A-update-1.pb B-update-accept-1.pb > A-update-sig-1.pb -$PREFIX ./update-channel-complete $B_SEED B-anchor.tx B-open.pb A-open.pb A-update-1.pb A-update-sig-1.pb > B-update-complete-1.pb +$PREFIX ./update-channel --to-them=500 $A_SEED 1 > A-update-1.pb +A_UPDATE_PKTS="$A_UPDATE_PKTS +A-update-1.pb" +B_UPDATE_PKTS="$B_UPDATE_PKTS -A-update-1.pb" + +$PREFIX ./update-channel-accept $B_SEED B-open.pb A-open.pb A-anchor.pb $B_TMPKEY $B_UPDATE_PKTS > B-update-accept-1.pb +A_UPDATE_PKTS="$A_UPDATE_PKTS -B-update-accept-1.pb" +B_UPDATE_PKTS="$B_UPDATE_PKTS +B-update-accept-1.pb" + +$PREFIX ./update-channel-signature $A_SEED A-open.pb B-open.pb A-anchor.pb $A_TMPKEY $A_UPDATE_PKTS > A-update-sig-1.pb +A_UPDATE_PKTS="$A_UPDATE_PKTS +A-update-sig-1.pb" +B_UPDATE_PKTS="$B_UPDATE_PKTS -A-update-sig-1.pb" + +$PREFIX ./update-channel-complete $B_SEED B-open.pb A-open.pb A-anchor.pb $B_UPDATE_PKTS > B-update-complete-1.pb +A_UPDATE_PKTS="$A_UPDATE_PKTS -B-update-complete-1.pb" +B_UPDATE_PKTS="$B_UPDATE_PKTS +B-update-complete-1.pb" # Just for testing, generate second transaction -$PREFIX ./create-commit-tx A-anchor.tx A-open.pb B-open.pb $A_TMPKEY B-update-accept-1.pb A-update-1.pb > A-commit-1.tx +$PREFIX ./create-commit-tx A-open.pb B-open.pb A-anchor.pb $A_TMPKEY $A_UPDATE_PKTS > A-commit-1.tx +$PREFIX ./create-commit-tx B-open.pb A-open.pb A-anchor.pb $B_TMPKEY $B_UPDATE_PKTS > B-commit-1.tx + +# Now you pay me 250. +$PREFIX ./update-channel --to-them=250 $B_SEED 2 > B-update-2.pb +A_UPDATE_PKTS="$A_UPDATE_PKTS -B-update-2.pb" +B_UPDATE_PKTS="$B_UPDATE_PKTS +B-update-2.pb" + +$PREFIX ./update-channel-accept $A_SEED A-open.pb B-open.pb A-anchor.pb $A_TMPKEY $A_UPDATE_PKTS > A-update-accept-2.pb +A_UPDATE_PKTS="$A_UPDATE_PKTS +A-update-accept-2.pb" +B_UPDATE_PKTS="$B_UPDATE_PKTS -A-update-accept-2.pb" + +$PREFIX ./update-channel-signature $B_SEED B-open.pb A-open.pb A-anchor.pb $B_TMPKEY $B_UPDATE_PKTS > B-update-sig-2.pb +A_UPDATE_PKTS="$A_UPDATE_PKTS -B-update-sig-2.pb" +B_UPDATE_PKTS="$B_UPDATE_PKTS +B-update-sig-2.pb" -# Now you pay me 1000. -$PREFIX ./update-channel --from-them=1000 $A_SEED A-update-1.pb > A-update-2.pb -$PREFIX ./update-channel-accept $B_SEED B-anchor.tx B-open.pb A-open.pb $B_TMPKEY A-update-2.pb A-update-1.pb > B-update-accept-2.pb 2>/dev/null -$PREFIX ./update-channel-signature $A_SEED A-anchor.tx A-open.pb B-open.pb $A_TMPKEY A-update-2.pb B-update-accept-2.pb A-update-1.pb > A-update-sig-2.pb -$PREFIX ./update-channel-complete $B_SEED B-anchor.tx B-open.pb A-open.pb A-update-2.pb A-update-sig-2.pb A-update-1.pb > B-update-complete-2.pb +$PREFIX ./update-channel-complete $A_SEED A-open.pb B-open.pb A-anchor.pb $A_UPDATE_PKTS > A-update-complete-2.pb +A_UPDATE_PKTS="$A_UPDATE_PKTS +A-update-complete-2.pb" +B_UPDATE_PKTS="$B_UPDATE_PKTS -A-update-complete-2.pb" # Just for testing, generate third transaction -$PREFIX ./create-commit-tx A-anchor.tx A-open.pb B-open.pb $A_TMPKEY B-update-accept-2.pb A-update-1.pb A-update-2.pb > A-commit-2.tx +$PREFIX ./create-commit-tx A-open.pb B-open.pb A-anchor.pb $A_TMPKEY $A_UPDATE_PKTS > A-commit-2.tx +$PREFIX ./create-commit-tx B-open.pb A-open.pb A-anchor.pb $B_TMPKEY $B_UPDATE_PKTS > B-commit-2.tx if [ x"$1" = x--steal ]; then # A stupidly broadcasts a revoked transaction. $CLI sendrawtransaction `cut -d: -f1 A-commit-1.tx` > A-commit-1.txid - # B uses the preimage from A-update-sig-2 to cash in. - $PREFIX ./create-steal-tx A-commit-1.tx A-update-sig-2.pb $B_FINALKEY B-open.pb A-open.pb $B_CHANGEPUBKEY > B-commit-steal.tx + # B uses the preimage from A-update-complete-2 to cash in. + $PREFIX ./create-steal-tx A-commit-1.tx A-update-complete-2.pb $B_FINALKEY B-open.pb A-open.pb $B_CHANGEPUBKEY > B-commit-steal.tx $CLI sendrawtransaction `cut -d: -f1 B-commit-steal.tx` > B-commit-steal.txid exit 0 @@ -146,14 +169,14 @@ fi if [ x"$1" = x--unilateral ]; then $CLI sendrawtransaction `cut -d: -f1 A-commit-2.tx` > A-commit-2.txid - $PREFIX ./create-commit-spend-tx A-commit-2.tx A-open.pb B-open.pb $A_FINALKEY $A_CHANGEPUBKEY A-update-1.pb A-update-2.pb > A-spend.tx + $PREFIX ./create-commit-spend-tx A-commit-2.tx A-open.pb B-open.pb A-anchor.pb $A_FINALKEY $A_CHANGEPUBKEY $A_UPDATE_PKTS > A-spend.tx send_after_delay `cut -d: -f1 A-spend.tx` > A-spend.txid exit 0 fi # Now close channel by mutual consent. -$PREFIX ./close-channel A-anchor.tx A-open.pb B-open.pb $A_TMPKEY A-update-1.pb A-update-2.pb > A-close.pb -$PREFIX ./close-channel --complete B-anchor.tx B-open.pb A-open.pb $B_TMPKEY A-update-1.pb A-update-2.pb > B-close-complete.pb -$PREFIX ./create-close-tx A-anchor.tx A-open.pb B-open.pb A-close.pb B-close-complete.pb A-update-1.pb A-update-2.pb > A-close.tx +$PREFIX ./close-channel A-open.pb B-open.pb A-anchor.pb $A_TMPKEY $A_UPDATE_PKTS > A-close.pb +$PREFIX ./close-channel --complete B-open.pb A-open.pb A-anchor.pb $B_TMPKEY $B_UPDATE_PKTS > B-close-complete.pb +$PREFIX ./create-close-tx A-open.pb B-open.pb A-anchor.pb A-close.pb B-close-complete.pb $A_UPDATE_PKTS > A-close.tx $CLI sendrawtransaction `cut -d: -f1 A-close.tx` > close.txid diff --git a/test-cli/update-channel-accept.c b/test-cli/update-channel-accept.c index a36333dfe..e589b05e4 100644 --- a/test-cli/update-channel-accept.c +++ b/test-cli/update-channel-accept.c @@ -6,7 +6,6 @@ #include #include #include "lightning.pb-c.h" -#include "anchor.h" #include "bitcoin/base58.h" #include "pkt.h" #include "bitcoin/script.h" @@ -17,6 +16,7 @@ #include "bitcoin/privkey.h" #include "find_p2sh_out.h" #include "protobuf_convert.h" +#include "gather_updates.h" #include int main(int argc, char *argv[]) @@ -24,54 +24,48 @@ int main(int argc, char *argv[]) const tal_t *ctx = tal_arr(NULL, char, 0); struct sha256 seed, revocation_hash, their_rhash; OpenChannel *o1, *o2; - Update *update; - struct bitcoin_tx *anchor, *commit; - struct sha256_double anchor_txid; + OpenAnchor *a; + struct bitcoin_tx *commit; struct pkt *pkt; struct bitcoin_signature sig; struct privkey privkey; bool testnet; + uint64_t num_updates; struct pubkey pubkey1, pubkey2; u8 *redeemscript; - int64_t delta; - size_t i, p2sh_out; + uint64_t our_amount, their_amount; err_set_progname(argv[0]); opt_register_noarg("--help|-h", opt_usage_and_exit, - " [previous-updates]\n" + " \n" "Accept a new update message", "Print this message."); opt_parse(&argc, argv, opt_log_stderr_exit); - if (argc < 6) - opt_usage_exit_fail("Expected 5+ arguments"); + if (argc < 7) + opt_usage_exit_fail("Expected 6+ arguments"); if (!hex_decode(argv[1], strlen(argv[1]), &seed, sizeof(seed))) errx(1, "Invalid seed '%s' - need 256 hex bits", argv[1]); - anchor = bitcoin_tx_from_file(ctx, argv[2]); - bitcoin_txid(anchor, &anchor_txid); - o1 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open; - o2 = pkt_from_file(argv[4], PKT__PKT_OPEN)->open; + o1 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; + o2 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open; + a = pkt_from_file(argv[4], PKT__PKT_OPEN_ANCHOR)->open_anchor; if (!key_from_base58(argv[5], strlen(argv[5]), &testnet, &privkey, &pubkey1)) errx(1, "Invalid private key '%s'", argv[5]); if (!testnet) errx(1, "Private key '%s' not on testnet!", argv[5]); - update = pkt_from_file(argv[6], PKT__PKT_UPDATE)->update; - /* Figure out cumulative delta since anchor. */ - delta = update->delta; - for (i = 7; i < argc; i++) { - Update *u = pkt_from_file(argv[i], PKT__PKT_UPDATE)->update; - delta += u->delta; - } + num_updates = gather_updates(o1, o2, a, argv + 6, + &our_amount, &their_amount, + NULL, &their_rhash, NULL); /* Get next revocation hash. */ - shachain_from_seed(&seed, argc - 6, &revocation_hash); + shachain_from_seed(&seed, num_updates, &revocation_hash); sha256(&revocation_hash, revocation_hash.u.u8, sizeof(revocation_hash.u.u8)); @@ -86,12 +80,10 @@ int main(int argc, char *argv[]) /* This is what the anchor pays to; figure out whick output. */ redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); - p2sh_out = find_p2sh_out(anchor, redeemscript); /* Now create THEIR new commitment tx to spend 2/2 output of anchor. */ - proto_to_sha256(update->revocation_hash, &their_rhash); - commit = create_commit_tx(ctx, o2, o1, &their_rhash, delta, - &anchor_txid, p2sh_out); + commit = create_commit_tx(ctx, o2, o1, a, &their_rhash, + their_amount, our_amount); /* If contributions don't exceed fees, this fails. */ if (!commit) diff --git a/test-cli/update-channel-complete.c b/test-cli/update-channel-complete.c index dcbd35b62..b709ddaa0 100644 --- a/test-cli/update-channel-complete.c +++ b/test-cli/update-channel-complete.c @@ -7,7 +7,6 @@ #include #include #include "lightning.pb-c.h" -#include "anchor.h" #include "bitcoin/base58.h" #include "pkt.h" #include "bitcoin/script.h" @@ -17,28 +16,28 @@ #include "bitcoin/pubkey.h" #include "find_p2sh_out.h" #include "protobuf_convert.h" +#include "gather_updates.h" +#include "funding.h" #include int main(int argc, char *argv[]) { const tal_t *ctx = tal_arr(NULL, char, 0); - struct sha256 seed, revocation_hash, our_rhash, their_rhash, preimage; + struct sha256 seed, our_rhash, their_rhash, preimage; OpenChannel *o1, *o2; - UpdateSignature *us; - Update *update; + OpenAnchor *a; struct pkt *pkt; - struct bitcoin_tx *anchor, *commit; + struct bitcoin_tx *commit; struct pubkey pubkey1, pubkey2; - size_t i, num_updates, p2sh_out; - struct sha256_double anchor_txid; + size_t num_updates; struct bitcoin_signature sig; - int64_t delta; + uint64_t our_amount, their_amount; u8 *redeemscript; err_set_progname(argv[0]); opt_register_noarg("--help|-h", opt_usage_and_exit, - " [previous-updates]\n" + " \n" "Create a new update-complete message", "Print this message."); @@ -50,43 +49,18 @@ int main(int argc, char *argv[]) if (!hex_decode(argv[1], strlen(argv[1]), &seed, sizeof(seed))) errx(1, "Invalid seed '%s' - need 256 hex bits", argv[1]); - anchor = bitcoin_tx_from_file(ctx, argv[2]); - bitcoin_txid(anchor, &anchor_txid); - o1 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open; - o2 = pkt_from_file(argv[4], PKT__PKT_OPEN)->open; - update = pkt_from_file(argv[5], PKT__PKT_UPDATE)->update; - us = pkt_from_file(argv[6], PKT__PKT_UPDATE_SIGNATURE)->update_signature; - - /* We need last revocation hash (either in update or update-accept), - * and the delta */ - proto_to_sha256(o2->revocation_hash, &revocation_hash); - num_updates = 0; - delta = update->delta; - for (i = 7; i < argc; i++) { - Pkt *p = any_pkt_from_file(argv[i]); - switch (p->pkt_case) { - case PKT__PKT_UPDATE: - proto_to_sha256(p->update->revocation_hash, - &revocation_hash); - delta += p->update->delta; - num_updates++; - break; - case PKT__PKT_UPDATE_ACCEPT: - if (i != argc - 1) - errx(1, "Only need last update_accept"); - proto_to_sha256(p->update_accept->revocation_hash, - &revocation_hash); - break; - default: - errx(1, "Expected update/update-accept in %s", argv[i]); - } - } + o1 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; + o2 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open; + a = pkt_from_file(argv[4], PKT__PKT_OPEN_ANCHOR)->open_anchor; + + sig.stype = SIGHASH_ALL; - /* They gave us right preimage to match rhash of previous commit tx? */ - proto_to_sha256(us->revocation_preimage, &preimage); - sha256(&their_rhash, preimage.u.u8, sizeof(preimage.u.u8)); - if (!structeq(&their_rhash, &revocation_hash)) - errx(1, "Their preimage was incorrect"); + /* This also checks that preimage is correct! */ + num_updates = gather_updates(o1, o2, a, argv + 5, + &our_amount, &their_amount, + &our_rhash, &their_rhash, &sig.sig); + if (num_updates < 1) + errx(1, "Expected at least one update!"); /* Get pubkeys */ if (!proto_to_pubkey(o1->commit_key, &pubkey1)) @@ -94,28 +68,21 @@ int main(int argc, char *argv[]) if (!proto_to_pubkey(o2->commit_key, &pubkey2)) errx(1, "Invalid o2 commit pubkey"); - /* This is what the anchor pays to; figure out whick output. */ + /* This is what the anchor pays to. */ redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); - p2sh_out = find_p2sh_out(anchor, redeemscript); /* Check their signature signs our new commit tx correctly. */ - shachain_from_seed(&seed, num_updates + 1, &preimage); - sha256(&our_rhash, &preimage, sizeof(preimage)); - commit = create_commit_tx(ctx, o1, o2, &our_rhash, delta, - &anchor_txid, p2sh_out); + commit = create_commit_tx(ctx, o1, o2, a, &our_rhash, + our_amount, their_amount); if (!commit) errx(1, "Delta too large"); - sig.stype = SIGHASH_ALL; - if (!proto_to_signature(us->sig, &sig.sig)) - errx(1, "Invalid update-signature signature"); - if (!check_tx_sig(commit, 0, redeemscript, tal_count(redeemscript), &pubkey2, &sig)) errx(1, "Invalid signature."); /* Hand over our preimage for previous tx. */ - shachain_from_seed(&seed, num_updates, &preimage); + shachain_from_seed(&seed, num_updates - 1, &preimage); pkt = update_complete_pkt(ctx, &preimage); if (!write_all(STDOUT_FILENO, pkt, pkt_totlen(pkt))) err(1, "Writing out packet"); diff --git a/test-cli/update-channel-signature.c b/test-cli/update-channel-signature.c index 5248a2519..08f1a0799 100644 --- a/test-cli/update-channel-signature.c +++ b/test-cli/update-channel-signature.c @@ -6,7 +6,6 @@ #include #include #include "lightning.pb-c.h" -#include "anchor.h" #include "bitcoin/base58.h" #include "pkt.h" #include "bitcoin/script.h" @@ -17,30 +16,29 @@ #include "bitcoin/privkey.h" #include "find_p2sh_out.h" #include "protobuf_convert.h" +#include "gather_updates.h" #include int main(int argc, char *argv[]) { const tal_t *ctx = tal_arr(NULL, char, 0); - struct sha256 seed, revocation_hash, preimage; + struct sha256 seed, preimage, our_rhash, their_rhash; OpenChannel *o1, *o2; - UpdateAccept *ua; - Update *update; - struct bitcoin_tx *anchor, *commit; - struct sha256_double anchor_txid; + OpenAnchor *a; + struct bitcoin_tx *commit; struct pkt *pkt; struct bitcoin_signature sig; struct privkey privkey; bool testnet; struct pubkey pubkey1, pubkey2; u8 *redeemscript; - int64_t delta; - size_t i, p2sh_out; + uint64_t our_amount, their_amount; + uint64_t num_updates; err_set_progname(argv[0]); opt_register_noarg("--help|-h", opt_usage_and_exit, - " [previous-updates]...\n" + " ...\n" "Create a new update-channel-signature message", "Print this message."); @@ -52,32 +50,27 @@ int main(int argc, char *argv[]) if (!hex_decode(argv[1], strlen(argv[1]), &seed, sizeof(seed))) errx(1, "Invalid seed '%s' - need 256 hex bits", argv[1]); - anchor = bitcoin_tx_from_file(ctx, argv[2]); - bitcoin_txid(anchor, &anchor_txid); - o1 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open; - o2 = pkt_from_file(argv[4], PKT__PKT_OPEN)->open; + o1 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; + o2 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open; + a = pkt_from_file(argv[4], PKT__PKT_OPEN_ANCHOR)->open_anchor; if (!key_from_base58(argv[5], strlen(argv[5]), &testnet, &privkey, &pubkey1)) errx(1, "Invalid private key '%s'", argv[5]); if (!testnet) errx(1, "Private key '%s' not on testnet!", argv[5]); - update = pkt_from_file(argv[6], PKT__PKT_UPDATE)->update; - ua = pkt_from_file(argv[7], PKT__PKT_UPDATE_ACCEPT)->update_accept; - sig.stype = SIGHASH_ALL; - if (!proto_to_signature(ua->sig, &sig.sig)) - errx(1, "Invalid update signature"); /* Figure out cumulative delta since anchor. */ - delta = 0; - for (i = 8; i < argc; i++) { - Update *u = pkt_from_file(argv[i], PKT__PKT_UPDATE)->update; - delta += u->delta; - } + num_updates = gather_updates(o1, o2, a, argv + 6, + &our_amount, &their_amount, + &our_rhash, &their_rhash, &sig.sig); + if (num_updates < 1) + errx(1, "Expected at least one update!"); /* Give up revocation preimage for old tx. */ - shachain_from_seed(&seed, argc - 7 - 1, &preimage); + fprintf(stderr, "Giving up preimage %u\n", (unsigned)num_updates - 1); + shachain_from_seed(&seed, num_updates - 1, &preimage); /* Get pubkeys */ if (!proto_to_pubkey(o1->commit_key, &pubkey2)) @@ -88,16 +81,14 @@ int main(int argc, char *argv[]) if (!proto_to_pubkey(o2->commit_key, &pubkey2)) errx(1, "Invalid o2 commit pubkey"); - /* This is what the anchor pays to; figure out whick output. */ + /* This is what the anchor pays to. */ redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); - p2sh_out = find_p2sh_out(anchor, redeemscript); /* Check our new commit is signed correctly by them. */ - proto_to_sha256(update->revocation_hash, &revocation_hash); - commit = create_commit_tx(ctx, o1, o2, &revocation_hash, delta, - &anchor_txid, p2sh_out); + commit = create_commit_tx(ctx, o1, o2, a, &our_rhash, + our_amount, their_amount); if (!commit) - errx(1, "Delta too large"); + errx(1, "Invalid packets"); /* Check their signature signs this input correctly. */ if (!check_tx_sig(commit, 0, redeemscript, tal_count(redeemscript), @@ -105,14 +96,10 @@ int main(int argc, char *argv[]) errx(1, "Invalid signature."); /* Now create THEIR new commitment tx to spend 2/2 output of anchor. */ - proto_to_sha256(ua->revocation_hash, &revocation_hash); - commit = create_commit_tx(ctx, o2, o1, &revocation_hash, -delta, - &anchor_txid, - find_p2sh_out(anchor, redeemscript)); - - /* If contributions don't exceed fees, this fails. */ + commit = create_commit_tx(ctx, o2, o1, a, &their_rhash, + their_amount, our_amount); if (!commit) - errx(1, "Delta too large"); + errx(1, "Invalid packets"); /* Their pubkey must be valid */ if (!proto_to_pubkey(o2->commit_key, &pubkey2)) diff --git a/test-cli/update-channel.c b/test-cli/update-channel.c index be2ed6cf4..8608ec33a 100644 --- a/test-cli/update-channel.c +++ b/test-cli/update-channel.c @@ -6,7 +6,6 @@ #include #include #include "lightning.pb-c.h" -#include "anchor.h" #include "bitcoin/base58.h" #include "pkt.h" #include "bitcoin/script.h" @@ -24,11 +23,12 @@ int main(int argc, char *argv[]) struct pkt *pkt; unsigned long long to_them = 0, from_them = 0; int64_t this_delta; + unsigned update_num; err_set_progname(argv[0]); opt_register_noarg("--help|-h", opt_usage_and_exit, - " [previous-updates]\n" + " \n" "Create a new update message", "Print this message."); opt_register_arg("--to-them=", @@ -43,18 +43,21 @@ int main(int argc, char *argv[]) if (!from_them && !to_them) opt_usage_exit_fail("Must use --to-them or --from-them"); - if (argc < 2) - opt_usage_exit_fail("Expected 1+ arguments"); + if (argc != 3) + opt_usage_exit_fail("Expected 2 arguments"); if (!hex_decode(argv[1], strlen(argv[1]), &seed, sizeof(seed))) errx(1, "Invalid seed '%s' - need 256 hex bits", argv[1]); - + update_num = atoi(argv[2]); + if (!update_num) + errx(1, "Update number %s invalid", argv[2]); + this_delta = from_them - to_them; if (!this_delta) errx(1, "Delta must not be zero"); /* Get next revocation hash. */ - shachain_from_seed(&seed, argc - 2 + 1, &revocation_hash); + shachain_from_seed(&seed, update_num, &revocation_hash); sha256(&revocation_hash, revocation_hash.u.u8, sizeof(revocation_hash.u.u8));