From ae31431168c77a532c5a468d2d670b3866c084f0 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 1 Jul 2015 13:44:31 +0930 Subject: [PATCH] tx: centralize transaction writing, append amounts for alpha. Signed-off-by: Rusty Russell --- bitcoin/tx.c | 63 ++++++++++++++++++++++++++++-- bitcoin/tx.h | 2 + test-cli/check-anchor-scriptsigs.c | 10 +---- test-cli/check-commit-sig.c | 10 +---- test-cli/create-close-tx.c | 10 +---- test-cli/create-commit-spend-tx.c | 10 +---- test-cli/create-commit-tx.c | 10 +---- test-cli/create-steal-tx.c | 10 +---- test-cli/get-anchor-depth.c | 1 - 9 files changed, 72 insertions(+), 54 deletions(-) diff --git a/bitcoin/tx.c b/bitcoin/tx.c index 5c07d3f03..afe4054e9 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -416,7 +417,7 @@ static struct bitcoin_tx *pull_bitcoin_tx(const tal_t *ctx, struct bitcoin_tx *bitcoin_tx_from_file(const tal_t *ctx, const char *filename) { - char *hex; + char *hex, *end; u8 *linear_tx; const u8 *p; struct bitcoin_tx *tx; @@ -429,14 +430,36 @@ struct bitcoin_tx *bitcoin_tx_from_file(const tal_t *ctx, if (strends(hex, "\n")) hex[strlen(hex)-1] = '\0'; - len = hex_data_size(strlen(hex)); + + end = strchr(hex, ':'); + if (!end) + end = hex + strlen(hex); + + len = hex_data_size(end - hex); p = linear_tx = tal_arr(hex, u8, len); - if (!hex_decode(hex, strlen(hex), linear_tx, len)) + if (!hex_decode(hex, end - hex, linear_tx, len)) errx(1, "Bad hex string in %s", filename); tx = pull_bitcoin_tx(ctx, &p, &len); if (!tx) errx(1, "Bad transaction in %s", filename); + + /* Optional appended [:input-amount]* */ + for (len = 0; len < tx->input_count; len++) { + if (*end != ':') + break; + tx->input[len].input_amount = strtoull(end + 1, &end, 10); + } + if (len == tx->input_count) { + if (*end != '\0') + errx(1, "Additional input amounts appended to %s", + filename); + } else { + /* Input amounts are compulsory for alpha, to generate sigs */ +#ifdef ALPHA_TXSTYLE + errx(1, "No input amount #%zu in %s", len, filename); +#endif + } tal_free(hex); return tx; @@ -464,4 +487,36 @@ bool bitcoin_txid_from_hex(const char *hexstr, size_t hexstr_len, reverse_bytes(txid->sha.u.u8, sizeof(txid->sha.u.u8)); return true; } - + +static bool write_input_amounts(int fd, const struct bitcoin_tx *tx) +{ + /* Alpha required input amounts, so append them */ +#ifdef ALPHA_TXSTYLE + size_t i; + + for (i = 0; i < tx->input_count; i++) { + char str[1 + STR_MAX_CHARS(tx->input[i].input_amount)]; + sprintf(str, ":%llu", + (unsigned long long)tx->input[i].input_amount); + if (!write_all(fd, str, strlen(str))) + return false; + } +#endif + return true; +} + +bool bitcoin_tx_write(int fd, const struct bitcoin_tx *tx) +{ + u8 *tx_arr; + char *tx_hex; + bool ok; + + tx_arr = linearize_tx(NULL, tx); + tx_hex = tal_arr(tx_arr, char, hex_str_size(tal_count(tx_arr))); + hex_encode(tx_arr, tal_count(tx_arr), tx_hex, tal_count(tx_hex)); + + ok = write_all(fd, tx_hex, strlen(tx_hex)) + && write_input_amounts(fd, tx); + tal_free(tx_arr); + return ok; +} diff --git a/bitcoin/tx.h b/bitcoin/tx.h index a2cb78576..34434b5b5 100644 --- a/bitcoin/tx.h +++ b/bitcoin/tx.h @@ -57,6 +57,8 @@ struct bitcoin_tx *bitcoin_tx(const tal_t *ctx, varint_t input_count, struct bitcoin_tx *bitcoin_tx_from_file(const tal_t *ctx, const char *filename); +bool bitcoin_tx_write(int fd, const struct bitcoin_tx *tx); + /* Parse hex string to get txid (reversed, a-la bitcoind). */ bool bitcoin_txid_from_hex(const char *hexstr, size_t hexstr_len, struct sha256_double *txid); diff --git a/test-cli/check-anchor-scriptsigs.c b/test-cli/check-anchor-scriptsigs.c index 5fda228ae..21e9b182b 100644 --- a/test-cli/check-anchor-scriptsigs.c +++ b/test-cli/check-anchor-scriptsigs.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include "lightning.pb-c.h" #include "anchor.h" @@ -24,9 +23,7 @@ int main(int argc, char *argv[]) OpenAnchorScriptsigs *ss1, *ss2; struct bitcoin_tx *anchor; struct sha256_double txid; - u8 *tx_arr; size_t *inmap, *outmap; - char *tx_hex; err_set_progname(argv[0]); @@ -55,12 +52,7 @@ int main(int argc, char *argv[]) bitcoin_txid(anchor, &txid); - /* Print it out in hex. */ - tx_arr = linearize_tx(ctx, anchor); - tx_hex = tal_arr(tx_arr, char, hex_str_size(tal_count(tx_arr))); - hex_encode(tx_arr, tal_count(tx_arr), tx_hex, tal_count(tx_hex)); - - if (!write_all(STDOUT_FILENO, tx_hex, strlen(tx_hex))) + if (!bitcoin_tx_write(STDOUT_FILENO, anchor)) err(1, "Writing out anchor transaction"); tal_free(ctx); diff --git a/test-cli/check-commit-sig.c b/test-cli/check-commit-sig.c index 8106966d5..f722b1af0 100644 --- a/test-cli/check-commit-sig.c +++ b/test-cli/check-commit-sig.c @@ -4,7 +4,6 @@ #include #include #include -#include #include "lightning.pb-c.h" #include "anchor.h" #include "bitcoin/base58.h" @@ -25,11 +24,10 @@ int main(int argc, char *argv[]) OpenCommitSig *cs2; struct bitcoin_tx *anchor, *commit; struct sha256_double txid; - u8 *tx_arr, *subscript; + u8 *subscript; size_t *inmap, *outmap; struct pubkey pubkey1, pubkey2; struct bitcoin_signature sig1, sig2; - char *tx_hex; struct privkey privkey; bool testnet; struct sha256 rhash; @@ -101,11 +99,7 @@ int main(int argc, char *argv[]) commit->input[0].script_length = tal_count(commit->input[0].script); /* Print it out in hex. */ - tx_arr = linearize_tx(ctx, commit); - tx_hex = tal_arr(tx_arr, char, hex_str_size(tal_count(tx_arr))); - hex_encode(tx_arr, tal_count(tx_arr), tx_hex, tal_count(tx_hex)); - - if (!write_all(STDOUT_FILENO, tx_hex, strlen(tx_hex))) + if (!bitcoin_tx_write(STDOUT_FILENO, commit)) err(1, "Writing out transaction"); tal_free(ctx); diff --git a/test-cli/create-close-tx.c b/test-cli/create-close-tx.c index 7f13cf974..f5a924c31 100644 --- a/test-cli/create-close-tx.c +++ b/test-cli/create-close-tx.c @@ -4,7 +4,6 @@ #include #include #include -#include #include "lightning.pb-c.h" #include "anchor.h" #include "bitcoin/base58.h" @@ -26,8 +25,7 @@ int main(int argc, char *argv[]) struct sha256_double anchor_txid; struct bitcoin_signature sig1, sig2; struct pubkey pubkey1, pubkey2; - u8 *redeemscript, *tx_arr; - char *tx_hex; + u8 *redeemscript; CloseChannel *close; CloseChannelComplete *closecomplete; size_t i; @@ -92,11 +90,7 @@ int main(int argc, char *argv[]) close_tx->input[0].script_length = tal_count(close_tx->input[0].script); /* Print it out in hex. */ - tx_arr = linearize_tx(ctx, close_tx); - tx_hex = tal_arr(tx_arr, char, hex_str_size(tal_count(tx_arr))); - hex_encode(tx_arr, tal_count(tx_arr), tx_hex, tal_count(tx_hex)); - - if (!write_all(STDOUT_FILENO, tx_hex, strlen(tx_hex))) + if (!bitcoin_tx_write(STDOUT_FILENO, close_tx)) err(1, "Writing out transaction"); tal_free(ctx); diff --git a/test-cli/create-commit-spend-tx.c b/test-cli/create-commit-spend-tx.c index 80eff9ac2..5b4b216af 100644 --- a/test-cli/create-commit-spend-tx.c +++ b/test-cli/create-commit-spend-tx.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include "lightning.pb-c.h" #include "anchor.h" @@ -31,8 +30,7 @@ int main(int argc, char *argv[]) struct privkey privkey; bool testnet; struct pubkey pubkey1, pubkey2, outpubkey; - u8 *redeemscript, *tx_arr; - char *tx_hex; + u8 *redeemscript; struct sha256 rhash; size_t i, p2sh_out; u64 fee = 10000; @@ -120,11 +118,7 @@ int main(int argc, char *argv[]) tx->input[0].script_length = tal_count(tx->input[0].script); /* Print it out in hex. */ - tx_arr = linearize_tx(ctx, tx); - tx_hex = tal_arr(tx_arr, char, hex_str_size(tal_count(tx_arr))); - hex_encode(tx_arr, tal_count(tx_arr), tx_hex, tal_count(tx_hex)); - - if (!write_all(STDOUT_FILENO, tx_hex, strlen(tx_hex))) + if (!bitcoin_tx_write(STDOUT_FILENO, tx)) err(1, "Writing out transaction"); tal_free(ctx); diff --git a/test-cli/create-commit-tx.c b/test-cli/create-commit-tx.c index ab962e586..a93e1d0a9 100644 --- a/test-cli/create-commit-tx.c +++ b/test-cli/create-commit-tx.c @@ -4,7 +4,6 @@ #include #include #include -#include #include "lightning.pb-c.h" #include "anchor.h" #include "bitcoin/base58.h" @@ -32,8 +31,7 @@ int main(int argc, char *argv[]) struct bitcoin_signature sig1, sig2; size_t i; struct pubkey pubkey1, pubkey2; - u8 *redeemscript, *tx_arr; - char *tx_hex; + u8 *redeemscript; int64_t delta; struct sha256 rhash; @@ -121,11 +119,7 @@ int main(int argc, char *argv[]) commit->input[0].script_length = tal_count(commit->input[0].script); /* Print it out in hex. */ - tx_arr = linearize_tx(ctx, commit); - tx_hex = tal_arr(tx_arr, char, hex_str_size(tal_count(tx_arr))); - hex_encode(tx_arr, tal_count(tx_arr), tx_hex, tal_count(tx_hex)); - - if (!write_all(STDOUT_FILENO, tx_hex, strlen(tx_hex))) + if (!bitcoin_tx_write(STDOUT_FILENO, commit)) err(1, "Writing out transaction"); tal_free(ctx); diff --git a/test-cli/create-steal-tx.c b/test-cli/create-steal-tx.c index 275395dc8..d8aefa983 100644 --- a/test-cli/create-steal-tx.c +++ b/test-cli/create-steal-tx.c @@ -4,7 +4,6 @@ #include #include #include -#include #include "lightning.pb-c.h" #include "anchor.h" #include "bitcoin/base58.h" @@ -25,11 +24,10 @@ int main(int argc, char *argv[]) OpenChannel *o1, *o2; Pkt *pkt; struct bitcoin_tx *commit, *tx; - u8 *tx_arr, *redeemscript, *p2sh; + u8 *redeemscript, *p2sh; size_t i; struct pubkey pubkey1, pubkey2, outpubkey; struct bitcoin_signature sig; - char *tx_hex; struct privkey privkey; bool testnet; u32 locktime_seconds; @@ -123,11 +121,7 @@ int main(int argc, char *argv[]) tx->input[0].script_length = tal_count(tx->input[0].script); /* Print it out in hex. */ - tx_arr = linearize_tx(ctx, tx); - tx_hex = tal_arr(tx_arr, char, hex_str_size(tal_count(tx_arr))); - hex_encode(tx_arr, tal_count(tx_arr), tx_hex, tal_count(tx_hex)); - - if (!write_all(STDOUT_FILENO, tx_hex, strlen(tx_hex))) + if (!bitcoin_tx_write(STDOUT_FILENO, tx)) err(1, "Writing out transaction"); tal_free(ctx); diff --git a/test-cli/get-anchor-depth.c b/test-cli/get-anchor-depth.c index 65c32b302..9717b65ac 100644 --- a/test-cli/get-anchor-depth.c +++ b/test-cli/get-anchor-depth.c @@ -4,7 +4,6 @@ #include #include #include -#include #include "lightning.pb-c.h" #include "anchor.h" #include "bitcoin/base58.h"