mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-21 16:14:23 +01:00
tx: prepare for Elements Alpha.
They sign, hash, and serialize differently. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
5
Makefile
5
Makefile
@@ -3,6 +3,9 @@
|
|||||||
# Needs to have oneof support: Ubuntu vivid's is too old :(
|
# Needs to have oneof support: Ubuntu vivid's is too old :(
|
||||||
PROTOCC:=protoc-c
|
PROTOCC:=protoc-c
|
||||||
|
|
||||||
|
# Alpha has segregated witness, checksequenceverify
|
||||||
|
#FEATURES := -DHAS_CSV=1 -DALPHA_TXSTYLE=1
|
||||||
|
|
||||||
PROGRAMS := test-cli/open-channel test-cli/open-anchor-scriptsigs test-cli/leak-anchor-sigs 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
|
PROGRAMS := test-cli/open-channel test-cli/open-anchor-scriptsigs test-cli/leak-anchor-sigs 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
|
||||||
|
|
||||||
BITCOIN_OBJS := bitcoin/address.o bitcoin/base58.o bitcoin/pubkey.o bitcoin/script.o bitcoin/shadouble.o bitcoin/signature.o bitcoin/tx.o
|
BITCOIN_OBJS := bitcoin/address.o bitcoin/base58.o bitcoin/pubkey.o bitcoin/script.o bitcoin/shadouble.o bitcoin/signature.o bitcoin/tx.o
|
||||||
@@ -14,7 +17,7 @@ CCAN_OBJS := ccan-crypto-sha256.o ccan-crypto-shachain.o ccan-err.o ccan-tal.o c
|
|||||||
HEADERS := $(wildcard *.h)
|
HEADERS := $(wildcard *.h)
|
||||||
|
|
||||||
CCANDIR := ccan/
|
CCANDIR := ccan/
|
||||||
CFLAGS := -g -Wall -I $(CCANDIR) -DVALGRIND_HEADERS=1
|
CFLAGS := -g -Wall -I $(CCANDIR) -DVALGRIND_HEADERS=1 $(FEATURES)
|
||||||
LDLIBS := -lcrypto -lprotobuf-c
|
LDLIBS := -lcrypto -lprotobuf-c
|
||||||
$(PROGRAMS): CFLAGS+=-I.
|
$(PROGRAMS): CFLAGS+=-I.
|
||||||
|
|
||||||
|
|||||||
28
anchor.c
28
anchor.c
@@ -18,6 +18,7 @@ struct bitcoin_tx *anchor_tx_create(const tal_t *ctx,
|
|||||||
u8 *redeemscript;
|
u8 *redeemscript;
|
||||||
size_t *inmap, *outmap;
|
size_t *inmap, *outmap;
|
||||||
struct pubkey key1, key2;
|
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))
|
if (add_overflows_size_t(o1->anchor->n_inputs, o2->anchor->n_inputs))
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -37,6 +38,10 @@ struct bitcoin_tx *anchor_tx_create(const tal_t *ctx,
|
|||||||
struct bitcoin_tx_input *in = &tx->input[i];
|
struct bitcoin_tx_input *in = &tx->input[i];
|
||||||
proto_to_sha256(pb->txid, &in->txid.sha);
|
proto_to_sha256(pb->txid, &in->txid.sha);
|
||||||
in->index = pb->output;
|
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. */
|
/* Leave inputs as stubs for now, for signing. */
|
||||||
}
|
}
|
||||||
for (i = 0; i < o2->anchor->n_inputs; i++) {
|
for (i = 0; i < o2->anchor->n_inputs; i++) {
|
||||||
@@ -45,6 +50,10 @@ struct bitcoin_tx *anchor_tx_create(const tal_t *ctx,
|
|||||||
= &tx->input[o1->anchor->n_inputs + i];
|
= &tx->input[o1->anchor->n_inputs + i];
|
||||||
proto_to_sha256(pb->txid, &in->txid.sha);
|
proto_to_sha256(pb->txid, &in->txid.sha);
|
||||||
in->index = pb->output;
|
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. */
|
/* Leave inputs as stubs for now, for signing. */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +85,7 @@ struct bitcoin_tx *anchor_tx_create(const tal_t *ctx,
|
|||||||
out->script = scriptpubkey_p2sh(tx,
|
out->script = scriptpubkey_p2sh(tx,
|
||||||
bitcoin_redeem_single(tx, &key));
|
bitcoin_redeem_single(tx, &key));
|
||||||
out->script_length = tal_count(out->script);
|
out->script_length = tal_count(out->script);
|
||||||
|
total_change += out->amount;
|
||||||
}
|
}
|
||||||
if (o2->anchor->change) {
|
if (o2->anchor->change) {
|
||||||
struct bitcoin_tx_output *out = &tx->output[n_out++];
|
struct bitcoin_tx_output *out = &tx->output[n_out++];
|
||||||
@@ -88,9 +98,25 @@ struct bitcoin_tx *anchor_tx_create(const tal_t *ctx,
|
|||||||
out->script = scriptpubkey_p2sh(tx,
|
out->script = scriptpubkey_p2sh(tx,
|
||||||
bitcoin_redeem_single(tx, &key));
|
bitcoin_redeem_single(tx, &key));
|
||||||
out->script_length = tal_count(out->script);
|
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);
|
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)
|
if (inmapp)
|
||||||
inmap = *inmapp = tal_arr(ctx, size_t, tx->input_count);
|
inmap = *inmapp = tal_arr(ctx, size_t, tx->input_count);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -125,8 +125,9 @@ static void sha256_tx_one_input(struct bitcoin_tx *tx,
|
|||||||
tx->input[input_num].script = cast_const(u8 *, script);
|
tx->input[input_num].script = cast_const(u8 *, script);
|
||||||
|
|
||||||
sha256_init(&ctx);
|
sha256_init(&ctx);
|
||||||
sha256_tx(&ctx, tx);
|
sha256_tx_for_sig(&ctx, tx);
|
||||||
sha256_le32(&ctx, SIGHASH_ALL);
|
sha256_le32(&ctx, SIGHASH_ALL);
|
||||||
|
|
||||||
sha256_double_done(&ctx, hash);
|
sha256_double_done(&ctx, hash);
|
||||||
|
|
||||||
/* Reset it for next time. */
|
/* Reset it for next time. */
|
||||||
|
|||||||
203
bitcoin/tx.c
203
bitcoin/tx.c
@@ -7,8 +7,50 @@
|
|||||||
#include "tx.h"
|
#include "tx.h"
|
||||||
#include "valgrind.h"
|
#include "valgrind.h"
|
||||||
|
|
||||||
|
enum styles {
|
||||||
|
/* Add the CT padding stuff to amount. */
|
||||||
|
TX_AMOUNT_CT_STYLE = 1,
|
||||||
|
/* Whether to process CT rangeproof and noncecommitment. */
|
||||||
|
TX_AMOUNT_INCLUDE_CT = 2,
|
||||||
|
/* Process the txfee field. */
|
||||||
|
TX_FEE = 4,
|
||||||
|
/* Process the input script sig. */
|
||||||
|
TX_INPUT_SCRIPTSIG = 8,
|
||||||
|
/* Process the amounts for each input. */
|
||||||
|
TX_INPUT_AMOUNT = 16,
|
||||||
|
/* Process hash of rangeproof and noncecommitment in *output* amount,
|
||||||
|
* instead of rangeproof and noncecommitment themselves. */
|
||||||
|
TX_OUTPUT_AMOUNT_HASHPROOF = 32
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef ALPHA_TXSTYLE
|
||||||
|
/* Linearizing has everything, except input amount (which is implied) */
|
||||||
|
#define LINEARIZE_STYLE (TX_AMOUNT_CT_STYLE | TX_AMOUNT_INCLUDE_CT | TX_FEE | TX_INPUT_SCRIPTSIG)
|
||||||
|
|
||||||
|
/* Alpha txids don't include input scripts, or rangeproof/txcommit in output */
|
||||||
|
#define TXID_STYLE (TX_AMOUNT_CT_STYLE | TX_FEE)
|
||||||
|
|
||||||
|
/* Alpha signatures sign the input script (assuming others are set to
|
||||||
|
* 0-len), as well as the input fee.
|
||||||
|
|
||||||
|
* They sign a hash of the rangeproof and noncecommitment for inputs,
|
||||||
|
* rather than the non rangeproof and noncecommitment themselves.
|
||||||
|
*
|
||||||
|
* For some reason they skip the txfee. */
|
||||||
|
#define SIG_STYLE (TX_AMOUNT_CT_STYLE | TX_AMOUNT_INCLUDE_CT | TX_INPUT_SCRIPTSIG | TX_INPUT_AMOUNT | TX_OUTPUT_AMOUNT_HASHPROOF)
|
||||||
|
|
||||||
|
#else /* BITCOIN */
|
||||||
|
|
||||||
|
/* Process all the bitcoin fields. Works for txid, serialization and signing */
|
||||||
|
#define LINEARIZE_STYLE (TX_INPUT_SCRIPTSIG)
|
||||||
|
#define TXID_STYLE (TX_INPUT_SCRIPTSIG)
|
||||||
|
#define SIG_STYLE (TX_INPUT_SCRIPTSIG)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void add_varint(varint_t v,
|
static void add_varint(varint_t v,
|
||||||
void (*add)(const void *, size_t, void *), void *addp)
|
void (*add)(const void *, size_t, void *), void *addp,
|
||||||
|
enum styles style)
|
||||||
{
|
{
|
||||||
u8 buf[9], *p = buf;
|
u8 buf[9], *p = buf;
|
||||||
|
|
||||||
@@ -39,50 +81,109 @@ static void add_varint(varint_t v,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void add_le32(u32 v,
|
static void add_le32(u32 v,
|
||||||
void (*add)(const void *, size_t, void *), void *addp)
|
void (*add)(const void *, size_t, void *), void *addp,
|
||||||
|
enum styles style)
|
||||||
{
|
{
|
||||||
le32 l = cpu_to_le32(v);
|
le32 l = cpu_to_le32(v);
|
||||||
add(&l, sizeof(l), addp);
|
add(&l, sizeof(l), addp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_le64(u64 v,
|
static void add_le64(u64 v,
|
||||||
void (*add)(const void *, size_t, void *), void *addp)
|
void (*add)(const void *, size_t, void *), void *addp,
|
||||||
|
enum styles style)
|
||||||
{
|
{
|
||||||
le64 l = cpu_to_le64(v);
|
le64 l = cpu_to_le64(v);
|
||||||
add(&l, sizeof(l), addp);
|
add(&l, sizeof(l), addp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_value(u64 amount,
|
||||||
|
void (*add)(const void *, size_t, void *),
|
||||||
|
void *addp,
|
||||||
|
bool output,
|
||||||
|
enum styles style)
|
||||||
|
{
|
||||||
|
if (style & TX_AMOUNT_CT_STYLE) {
|
||||||
|
/* The input is hashed as a 33 byte value (for CT); 25 0, then
|
||||||
|
* the big-endian value. */
|
||||||
|
static u8 zeroes[25];
|
||||||
|
be64 b = cpu_to_be64(amount);
|
||||||
|
add(zeroes, sizeof(zeroes), addp);
|
||||||
|
add(&b, sizeof(b), addp);
|
||||||
|
if (style & TX_AMOUNT_INCLUDE_CT) {
|
||||||
|
/* Two more zeroes: Rangeproof and Noncecommitment */
|
||||||
|
if (output && (style & TX_OUTPUT_AMOUNT_HASHPROOF)) {
|
||||||
|
struct sha256_double h;
|
||||||
|
sha256_double(&h, zeroes, 2);
|
||||||
|
add(&h, sizeof(h), addp);
|
||||||
|
} else {
|
||||||
|
add_varint(0, add, addp, style);
|
||||||
|
add_varint(0, add, addp, style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
add_le64(amount, add, addp, style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_input_value(u64 amount,
|
||||||
|
void (*add)(const void *, size_t, void *),
|
||||||
|
void *addp,
|
||||||
|
enum styles style)
|
||||||
|
{
|
||||||
|
return add_value(amount, add, addp, false, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_output_value(u64 amount,
|
||||||
|
void (*add)(const void *, size_t, void *),
|
||||||
|
void *addp,
|
||||||
|
enum styles style)
|
||||||
|
{
|
||||||
|
return add_value(amount, add, addp, true, style);
|
||||||
|
}
|
||||||
|
|
||||||
static void add_tx_input(const struct bitcoin_tx_input *input,
|
static void add_tx_input(const struct bitcoin_tx_input *input,
|
||||||
void (*add)(const void *, size_t, void *), void *addp)
|
void (*add)(const void *, size_t, void *), void *addp,
|
||||||
|
enum styles style)
|
||||||
{
|
{
|
||||||
add(&input->txid, sizeof(input->txid), addp);
|
add(&input->txid, sizeof(input->txid), addp);
|
||||||
add_le32(input->index, add, addp);
|
add_le32(input->index, add, addp, style);
|
||||||
add_varint(input->script_length, add, addp);
|
if (style & TX_INPUT_AMOUNT) {
|
||||||
add(input->script, input->script_length, addp);
|
add_input_value(input->input_amount, add, addp, style);
|
||||||
add_le32(input->sequence_number, add, addp);
|
}
|
||||||
|
if (style & TX_INPUT_SCRIPTSIG) {
|
||||||
|
add_varint(input->script_length, add, addp, style);
|
||||||
|
add(input->script, input->script_length, addp);
|
||||||
|
}
|
||||||
|
add_le32(input->sequence_number, add, addp, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_tx_output(const struct bitcoin_tx_output *output,
|
static void add_tx_output(const struct bitcoin_tx_output *output,
|
||||||
void (*add)(const void *, size_t, void *), void *addp)
|
void (*add)(const void *, size_t, void *), void *addp,
|
||||||
|
enum styles style)
|
||||||
{
|
{
|
||||||
add_le64(output->amount, add, addp);
|
add_output_value(output->amount, add, addp, style);
|
||||||
add_varint(output->script_length, add, addp);
|
add_varint(output->script_length, add, addp, style);
|
||||||
add(output->script, output->script_length, addp);
|
add(output->script, output->script_length, addp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_tx(const struct bitcoin_tx *tx,
|
static void add_tx(const struct bitcoin_tx *tx,
|
||||||
void (*add)(const void *, size_t, void *), void *addp)
|
void (*add)(const void *, size_t, void *), void *addp,
|
||||||
|
enum styles style)
|
||||||
{
|
{
|
||||||
varint_t i;
|
varint_t i;
|
||||||
|
|
||||||
add_le32(tx->version, add, addp);
|
add_le32(tx->version, add, addp, style);
|
||||||
add_varint(tx->input_count, add, addp);
|
add_varint(tx->input_count, add, addp, style);
|
||||||
for (i = 0; i < tx->input_count; i++)
|
for (i = 0; i < tx->input_count; i++)
|
||||||
add_tx_input(&tx->input[i], add, addp);
|
add_tx_input(&tx->input[i], add, addp, style);
|
||||||
add_varint(tx->output_count, add, addp);
|
|
||||||
|
if (style & TX_FEE)
|
||||||
|
add_le64(tx->fee, add, addp, style);
|
||||||
|
|
||||||
|
add_varint(tx->output_count, add, addp, style);
|
||||||
for (i = 0; i < tx->output_count; i++)
|
for (i = 0; i < tx->output_count; i++)
|
||||||
add_tx_output(&tx->output[i], add, addp);
|
add_tx_output(&tx->output[i], add, addp, style);
|
||||||
add_le32(tx->lock_time, add, addp);
|
add_le32(tx->lock_time, add, addp, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_sha(const void *data, size_t len, void *shactx_)
|
static void add_sha(const void *data, size_t len, void *shactx_)
|
||||||
@@ -91,9 +192,9 @@ static void add_sha(const void *data, size_t len, void *shactx_)
|
|||||||
sha256_update(ctx, check_mem(data, len), len);
|
sha256_update(ctx, check_mem(data, len), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sha256_tx(struct sha256_ctx *ctx, const struct bitcoin_tx *tx)
|
void sha256_tx_for_sig(struct sha256_ctx *ctx, const struct bitcoin_tx *tx)
|
||||||
{
|
{
|
||||||
add_tx(tx, add_sha, ctx);
|
add_tx(tx, add_sha, ctx, SIG_STYLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_linearize(const void *data, size_t len, void *pptr_)
|
static void add_linearize(const void *data, size_t len, void *pptr_)
|
||||||
@@ -108,7 +209,7 @@ static void add_linearize(const void *data, size_t len, void *pptr_)
|
|||||||
u8 *linearize_tx(const tal_t *ctx, const struct bitcoin_tx *tx)
|
u8 *linearize_tx(const tal_t *ctx, const struct bitcoin_tx *tx)
|
||||||
{
|
{
|
||||||
u8 *arr = tal_arr(ctx, u8, 0);
|
u8 *arr = tal_arr(ctx, u8, 0);
|
||||||
add_tx(tx, add_linearize, &arr);
|
add_tx(tx, add_linearize, &arr, LINEARIZE_STYLE);
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +217,7 @@ void bitcoin_txid(const struct bitcoin_tx *tx, struct sha256_double *txid)
|
|||||||
{
|
{
|
||||||
struct sha256_ctx ctx = SHA256_INIT;
|
struct sha256_ctx ctx = SHA256_INIT;
|
||||||
|
|
||||||
sha256_tx(&ctx, tx);
|
add_tx(tx, add_sha, &ctx, TXID_STYLE);
|
||||||
sha256_double_done(&ctx, txid);
|
sha256_double_done(&ctx, txid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,21 +320,67 @@ static bool pull_sha256_double(const u8 **cursor, size_t *max,
|
|||||||
return pull(cursor, max, h, sizeof(*h));
|
return pull(cursor, max, h, sizeof(*h));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u64 pull_value(const u8 **cursor, size_t *max)
|
||||||
|
{
|
||||||
|
u64 amount;
|
||||||
|
|
||||||
|
if (LINEARIZE_STYLE & TX_AMOUNT_CT_STYLE) {
|
||||||
|
/* The input is hashed as a 33 byte value (for CT); 25 0, then
|
||||||
|
* the big-endian value. */
|
||||||
|
u8 zeroes[25];
|
||||||
|
be64 b;
|
||||||
|
|
||||||
|
if (!pull(cursor, max, zeroes, sizeof(zeroes)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* We don't handle CT amounts. */
|
||||||
|
if (zeroes[0] != 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (!pull(cursor, max, &b, sizeof(b)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
amount = be64_to_cpu(b);
|
||||||
|
if (LINEARIZE_STYLE & TX_AMOUNT_INCLUDE_CT) {
|
||||||
|
varint_t rp, nc;
|
||||||
|
|
||||||
|
rp = pull_varint(cursor, max);
|
||||||
|
nc = pull_varint(cursor, max);
|
||||||
|
if (rp != 0 || nc != 0)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
amount = pull_le64(cursor, max);
|
||||||
|
}
|
||||||
|
return amount;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
/* Simulate EOF */
|
||||||
|
*cursor = NULL;
|
||||||
|
*max = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void pull_input(const tal_t *ctx, const u8 **cursor, size_t *max,
|
static void pull_input(const tal_t *ctx, const u8 **cursor, size_t *max,
|
||||||
struct bitcoin_tx_input *input)
|
struct bitcoin_tx_input *input)
|
||||||
{
|
{
|
||||||
pull_sha256_double(cursor, max, &input->txid);
|
pull_sha256_double(cursor, max, &input->txid);
|
||||||
input->index = pull_le32(cursor, max);
|
input->index = pull_le32(cursor, max);
|
||||||
input->script_length = pull_varint(cursor, max);
|
if (LINEARIZE_STYLE & TX_INPUT_AMOUNT) {
|
||||||
input->script = tal_arr(ctx, u8, input->script_length);
|
input->input_amount = pull_value(cursor, max);
|
||||||
pull(cursor, max, input->script, input->script_length);
|
}
|
||||||
|
if (LINEARIZE_STYLE & TX_INPUT_SCRIPTSIG) {
|
||||||
|
input->script_length = pull_varint(cursor, max);
|
||||||
|
input->script = tal_arr(ctx, u8, input->script_length);
|
||||||
|
pull(cursor, max, input->script, input->script_length);
|
||||||
|
}
|
||||||
input->sequence_number = pull_le32(cursor, max);
|
input->sequence_number = pull_le32(cursor, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pull_output(const tal_t *ctx, const u8 **cursor, size_t *max,
|
static void pull_output(const tal_t *ctx, const u8 **cursor, size_t *max,
|
||||||
struct bitcoin_tx_output *output)
|
struct bitcoin_tx_output *output)
|
||||||
{
|
{
|
||||||
output->amount = pull_le64(cursor, max);
|
output->amount = pull_value(cursor, max);
|
||||||
output->script_length = pull_varint(cursor, max);
|
output->script_length = pull_varint(cursor, max);
|
||||||
output->script = tal_arr(ctx, u8, output->script_length);
|
output->script = tal_arr(ctx, u8, output->script_length);
|
||||||
pull(cursor, max, output->script, output->script_length);
|
pull(cursor, max, output->script, output->script_length);
|
||||||
@@ -250,6 +397,10 @@ static struct bitcoin_tx *pull_bitcoin_tx(const tal_t *ctx,
|
|||||||
tx->input = tal_arr(tx, struct bitcoin_tx_input, tx->input_count);
|
tx->input = tal_arr(tx, struct bitcoin_tx_input, tx->input_count);
|
||||||
for (i = 0; i < tx->input_count; i++)
|
for (i = 0; i < tx->input_count; i++)
|
||||||
pull_input(tx, cursor, max, tx->input + i);
|
pull_input(tx, cursor, max, tx->input + i);
|
||||||
|
|
||||||
|
if (LINEARIZE_STYLE & TX_FEE)
|
||||||
|
tx->fee = pull_le64(cursor, max);
|
||||||
|
|
||||||
tx->output_count = pull_varint(cursor, max);
|
tx->output_count = pull_varint(cursor, max);
|
||||||
tx->output = tal_arr(ctx, struct bitcoin_tx_output, tx->output_count);
|
tx->output = tal_arr(ctx, struct bitcoin_tx_output, tx->output_count);
|
||||||
for (i = 0; i < tx->output_count; i++)
|
for (i = 0; i < tx->output_count; i++)
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ struct bitcoin_tx {
|
|||||||
u32 version;
|
u32 version;
|
||||||
varint_t input_count;
|
varint_t input_count;
|
||||||
struct bitcoin_tx_input *input;
|
struct bitcoin_tx_input *input;
|
||||||
|
|
||||||
|
/* Only in alpha. */
|
||||||
|
u64 fee;
|
||||||
|
|
||||||
varint_t output_count;
|
varint_t output_count;
|
||||||
struct bitcoin_tx_output *output;
|
struct bitcoin_tx_output *output;
|
||||||
u32 lock_time;
|
u32 lock_time;
|
||||||
@@ -25,6 +29,9 @@ struct bitcoin_tx_output {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct bitcoin_tx_input {
|
struct bitcoin_tx_input {
|
||||||
|
/* In alpha, this is hashed for signature */
|
||||||
|
u64 input_amount;
|
||||||
|
|
||||||
struct sha256_double txid;
|
struct sha256_double txid;
|
||||||
u32 index; /* output number referred to by above */
|
u32 index; /* output number referred to by above */
|
||||||
varint_t script_length;
|
varint_t script_length;
|
||||||
@@ -37,7 +44,7 @@ struct bitcoin_tx_input {
|
|||||||
void bitcoin_txid(const struct bitcoin_tx *tx, struct sha256_double *txid);
|
void bitcoin_txid(const struct bitcoin_tx *tx, struct sha256_double *txid);
|
||||||
|
|
||||||
/* Useful for signature code. */
|
/* Useful for signature code. */
|
||||||
void sha256_tx(struct sha256_ctx *ctx, const struct bitcoin_tx *tx);
|
void sha256_tx_for_sig(struct sha256_ctx *ctx, const struct bitcoin_tx *tx);
|
||||||
|
|
||||||
/* Linear bytes of tx. */
|
/* Linear bytes of tx. */
|
||||||
u8 *linearize_tx(const tal_t *ctx, const struct bitcoin_tx *tx);
|
u8 *linearize_tx(const tal_t *ctx, const struct bitcoin_tx *tx);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "bitcoin/shadouble.h"
|
#include "bitcoin/shadouble.h"
|
||||||
#include "bitcoin/tx.h"
|
#include "bitcoin/tx.h"
|
||||||
#include "commit_tx.h"
|
#include "commit_tx.h"
|
||||||
|
#include "overflows.h"
|
||||||
#include "permute_tx.h"
|
#include "permute_tx.h"
|
||||||
#include "pkt.h"
|
#include "pkt.h"
|
||||||
#include "protobuf_convert.h"
|
#include "protobuf_convert.h"
|
||||||
@@ -26,6 +27,9 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
|
|||||||
/* Our input spends the anchor tx output. */
|
/* Our input spends the anchor tx output. */
|
||||||
tx->input[0].txid = *anchor_txid;
|
tx->input[0].txid = *anchor_txid;
|
||||||
tx->input[0].index = anchor_output;
|
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;
|
||||||
|
|
||||||
/* Output goes to our final pubkeys */
|
/* Output goes to our final pubkeys */
|
||||||
if (!proto_to_pubkey(ours->final, &ourkey))
|
if (!proto_to_pubkey(ours->final, &ourkey))
|
||||||
@@ -68,6 +72,10 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
|
|||||||
return tal_free(tx);
|
return tal_free(tx);
|
||||||
tx->output[0].amount -= delta;
|
tx->output[0].amount -= delta;
|
||||||
|
|
||||||
|
/* Calculate fee; difference of inputs and outputs. */
|
||||||
|
tx->fee = tx->input[0].input_amount
|
||||||
|
- (tx->output[0].amount + tx->output[1].amount);
|
||||||
|
|
||||||
permute_outputs(ours->seed, theirs->seed, 1, tx->output, 2, NULL);
|
permute_outputs(ours->seed, theirs->seed, 1, tx->output, 2, NULL);
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user