From c04d20e01906d12a57b4e9c43dc72bea9d859962 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 30 May 2015 20:44:00 +0930 Subject: [PATCH] commit_tx: new file containing logic to create initial commitment transaction. Signed-off-by: Rusty Russell --- Makefile | 2 +- commit_tx.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ commit_tx.h | 15 +++++++++++++++ open-commit-sig.c | 37 ++++++++----------------------------- 4 files changed, 69 insertions(+), 30 deletions(-) create mode 100644 commit_tx.c create mode 100644 commit_tx.h diff --git a/Makefile b/Makefile index ab6030cfa..8bee0683f 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ PROTOCC:=protoc-c PROGRAMS := open-channel open-anchor-sig leak-anchor-sigs open-commit-sig -HELPER_OBJS := base58.o lightning.pb-c.o shadouble.o pkt.o bitcoin_script.o permute_tx.o signature.o bitcoin_tx.o bitcoin_address.o anchor.o +HELPER_OBJS := base58.o lightning.pb-c.o shadouble.o pkt.o bitcoin_script.o permute_tx.o signature.o bitcoin_tx.o bitcoin_address.o anchor.o commit_tx.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 diff --git a/commit_tx.c b/commit_tx.c new file mode 100644 index 000000000..153f6403f --- /dev/null +++ b/commit_tx.c @@ -0,0 +1,45 @@ +#include "commit_tx.h" +#include "shadouble.h" +#include "bitcoin_tx.h" +#include "bitcoin_script.h" +#include "permute_tx.h" + +struct bitcoin_tx *create_commit_tx(const tal_t *ctx, + OpenChannel *ours, + OpenChannel *theirs, + const struct sha256_double *anchor_txid, + unsigned int anchor_output) +{ + struct bitcoin_tx *tx; + const u8 *redeemscript; + + /* Now create commitment tx: one input, two outputs. */ + 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; + + /* First output is a P2SH to a complex redeem script (usu. for me) */ + redeemscript = bitcoin_redeem_revocable(tx, ours->anchor->pubkey, + ours->locktime_seconds, + theirs->anchor->pubkey, + ours->revocation_hash); + tx->output[0].script = scriptpubkey_p2sh(tx, redeemscript); + tx->output[0].script_length = tal_count(tx->output[0].script); + + if (ours->anchor->total < ours->commitment_fee) + return tal_free(tx); + tx->output[0].amount = ours->anchor->total - ours->commitment_fee; + + /* Second output is a simple payment to them. */ + tx->output[1].script = theirs->script_to_me.data; + tx->output[1].script_length = theirs->script_to_me.len; + + if (theirs->anchor->total < theirs->commitment_fee) + return tal_free(tx); + tx->output[1].amount = theirs->anchor->total - theirs->commitment_fee; + + permute_outputs(ours->seed, theirs->seed, 1, tx->output, 2, NULL); + return tx; +} diff --git a/commit_tx.h b/commit_tx.h new file mode 100644 index 000000000..c5afe6a12 --- /dev/null +++ b/commit_tx.h @@ -0,0 +1,15 @@ +#ifndef LIGHTNING_COMMIT_TX_H +#define LIGHTNING_COMMIT_TX_H +#include +#include "lightning.pb-c.h" + +struct sha256_double; + +/* Create commitment tx to spend the anchor tx output; doesn't fill in + * input scriptsig. */ +struct bitcoin_tx *create_commit_tx(const tal_t *ctx, + OpenChannel *ours, + OpenChannel *theirs, + const struct sha256_double *anchor_txid, + unsigned int anchor_output); +#endif diff --git a/open-commit-sig.c b/open-commit-sig.c index 1ff842b69..5b6c50fb9 100644 --- a/open-commit-sig.c +++ b/open-commit-sig.c @@ -16,6 +16,7 @@ #include "bitcoin_script.h" #include "permute_tx.h" #include "signature.h" +#include "commit_tx.h" #include #include @@ -26,7 +27,7 @@ int main(int argc, char *argv[]) struct bitcoin_tx *anchor, *commit; struct sha256_double txid; struct pkt *pkt; - u8 *redeemscript, *sig; + u8 *sig; size_t *inmap, *outmap; EC_KEY *privkey; bool testnet; @@ -61,38 +62,16 @@ int main(int argc, char *argv[]) /* Get the transaction ID of the anchor. */ anchor_txid(anchor, argv[4], argv[5], inmap, &txid); - /* Now create commitment tx: one input, two outputs. */ - commit = bitcoin_tx(ctx, 1, 2); + /* Now create commitment tx to spend 2/2 output of anchor. */ + commit = create_commit_tx(ctx, o1, o2, &txid, outmap[0]); - /* Our input spends the anchor tx output. */ - commit->input[0].txid = txid; - commit->input[0].index = outmap[0]; - - /* First output is a P2SH to a complex redeem script */ - redeemscript = bitcoin_redeem_revocable(ctx, o1->anchor->pubkey, - o1->locktime_seconds, - o2->anchor->pubkey, - o1->revocation_hash); - commit->output[0].script = scriptpubkey_p2sh(ctx, redeemscript); - commit->output[0].script_length = tal_count(commit->output[0].script); - - if (o1->anchor->total < o1->commitment_fee) - errx(1, "Our contribution to channel %llu < fee %llu", + /* 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)o1->commitment_fee); - commit->output[0].amount = o1->anchor->total - o1->commitment_fee; - - /* Second output is a simple payment to them. */ - commit->output[1].script = o2->script_to_me.data; - commit->output[1].script_length = o2->script_to_me.len; - - if (o2->anchor->total < o2->commitment_fee) - errx(1, "Their contribution to channel %llu < fee %llu", (long long)o2->anchor->total, + (long long)o1->commitment_fee, (long long)o2->commitment_fee); - commit->output[1].amount = o2->anchor->total - o2->commitment_fee; - - permute_outputs(o1->seed, o2->seed, 1, commit->output, 2, NULL); sig = sign_tx_input(ctx, commit, 0, anchor->output[outmap[0]].script, anchor->output[outmap[0]].script_length, privkey);