2016-01-21 21:08:08 +01:00
|
|
|
#include <assert.h>
|
2017-08-28 18:02:01 +02:00
|
|
|
#include <bitcoin/block.h>
|
|
|
|
#include <bitcoin/pullpush.h>
|
|
|
|
#include <bitcoin/tx.h>
|
2016-01-21 21:11:46 +01:00
|
|
|
#include <ccan/cast/cast.h>
|
2015-05-28 23:38:27 +02:00
|
|
|
#include <ccan/crypto/sha256/sha256.h>
|
2015-06-12 04:56:59 +02:00
|
|
|
#include <ccan/endian/endian.h>
|
2015-10-26 11:35:28 +01:00
|
|
|
#include <ccan/mem/mem.h>
|
2015-07-01 06:14:31 +02:00
|
|
|
#include <ccan/read_write_all/read_write_all.h>
|
2015-06-04 06:18:11 +02:00
|
|
|
#include <ccan/str/hex/hex.h>
|
2017-08-28 18:02:01 +02:00
|
|
|
#include <common/type_to_string.h>
|
2016-01-21 21:11:46 +01:00
|
|
|
#include <stdio.h>
|
2019-06-21 02:11:41 +02:00
|
|
|
#include <wire/wire.h>
|
2015-05-28 23:38:27 +02:00
|
|
|
|
2016-04-11 09:09:53 +02:00
|
|
|
#define SEGREGATED_WITNESS_FLAG 0x1
|
|
|
|
|
2019-04-16 22:30:25 +02:00
|
|
|
static u8 bitcoin_asset[] =
|
|
|
|
{
|
|
|
|
0x01, 0x5c, 0xe7, 0xb9, 0x63, 0xd3, 0x7f, 0x8f, 0x2d, 0x51, 0xca,
|
|
|
|
0xfb, 0xba, 0x92, 0x8a, 0xaa, 0x9e, 0x22, 0x0b, 0x8b, 0xbc, 0x66,
|
|
|
|
0x05, 0x71, 0x49, 0x9c, 0x03, 0x62, 0x8a, 0x38, 0x51, 0xb8, 0xce,
|
|
|
|
};
|
|
|
|
|
2019-06-05 07:28:55 +02:00
|
|
|
int bitcoin_tx_add_output(struct bitcoin_tx *tx, const u8 *script,
|
2019-08-21 05:52:44 +02:00
|
|
|
struct amount_sat amount)
|
2019-03-14 16:20:03 +01:00
|
|
|
{
|
2019-03-25 17:08:29 +01:00
|
|
|
size_t i = tx->wtx->num_outputs;
|
2019-03-14 16:20:03 +01:00
|
|
|
struct wally_tx_output *output;
|
2019-05-06 15:20:47 +02:00
|
|
|
int ret;
|
|
|
|
u64 satoshis = amount.satoshis; /* Raw: low-level helper */
|
2019-03-25 13:52:31 +01:00
|
|
|
assert(i < tx->wtx->outputs_allocation_len);
|
2019-03-14 16:20:03 +01:00
|
|
|
|
|
|
|
assert(tx->wtx != NULL);
|
2019-05-06 15:20:47 +02:00
|
|
|
|
|
|
|
if (is_elements) {
|
|
|
|
u8 value[9];
|
|
|
|
ret = wally_tx_confidential_value_from_satoshi(satoshis, value,
|
|
|
|
sizeof(value));
|
|
|
|
assert(ret == WALLY_OK);
|
|
|
|
ret = wally_tx_elements_output_init_alloc(
|
|
|
|
script, tal_bytelen(script), bitcoin_asset,
|
|
|
|
sizeof(bitcoin_asset), value, sizeof(value), NULL, 0, NULL,
|
|
|
|
0, NULL, 0, &output);
|
|
|
|
assert(ret == WALLY_OK);
|
|
|
|
/* Cheat a bit by also setting the numeric satoshi value,
|
|
|
|
* otherwise we end up converting a number of times */
|
|
|
|
output->satoshi = satoshis;
|
|
|
|
} else {
|
|
|
|
ret = wally_tx_output_init_alloc(satoshis, script,
|
|
|
|
tal_bytelen(script), &output);
|
|
|
|
}
|
|
|
|
ret = wally_tx_add_output(tx->wtx, output);
|
|
|
|
assert(ret == WALLY_OK);
|
|
|
|
|
2019-03-14 16:20:03 +01:00
|
|
|
wally_tx_output_free(output);
|
2019-05-06 15:20:47 +02:00
|
|
|
bitcoin_tx_output_set_amount(tx, i, amount);
|
2019-03-14 16:20:03 +01:00
|
|
|
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
2019-08-12 21:02:06 +02:00
|
|
|
int bitcoin_tx_add_multi_outputs(struct bitcoin_tx *tx,
|
|
|
|
struct bitcoin_tx_output **outputs)
|
|
|
|
{
|
|
|
|
for (size_t j = 0; j < tal_count(outputs); j++)
|
|
|
|
bitcoin_tx_add_output(tx, outputs[j]->script,
|
|
|
|
outputs[j]->amount);
|
|
|
|
|
|
|
|
return tx->wtx->num_outputs;
|
|
|
|
}
|
|
|
|
|
2019-03-14 16:20:03 +01:00
|
|
|
int bitcoin_tx_add_input(struct bitcoin_tx *tx, const struct bitcoin_txid *txid,
|
|
|
|
u32 outnum, u32 sequence,
|
2019-08-21 05:52:44 +02:00
|
|
|
struct amount_sat amount, u8 *script)
|
2019-03-14 16:20:03 +01:00
|
|
|
{
|
2019-03-25 17:08:29 +01:00
|
|
|
size_t i = tx->wtx->num_inputs;
|
2019-03-14 16:20:03 +01:00
|
|
|
struct wally_tx_input *input;
|
2019-03-25 13:52:31 +01:00
|
|
|
assert(i < tx->wtx->inputs_allocation_len);
|
2019-03-14 16:20:03 +01:00
|
|
|
|
|
|
|
assert(tx->wtx != NULL);
|
|
|
|
wally_tx_input_init_alloc(txid->shad.sha.u.u8,
|
|
|
|
sizeof(struct bitcoin_txid), outnum, sequence,
|
|
|
|
script, tal_bytelen(script),
|
|
|
|
NULL /* Empty witness stack */, &input);
|
|
|
|
wally_tx_add_input(tx->wtx, input);
|
|
|
|
wally_tx_input_free(input);
|
|
|
|
|
2019-03-22 14:01:16 +01:00
|
|
|
/* Now store the input amount if we know it, so we can sign later */
|
|
|
|
tx->input_amounts[i] = tal_free(tx->input_amounts[i]);
|
2019-08-21 05:52:44 +02:00
|
|
|
tx->input_amounts[i] = tal_dup(tx, struct amount_sat, &amount);
|
2019-03-22 14:01:16 +01:00
|
|
|
|
2019-03-14 16:20:03 +01:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
2019-03-15 14:09:11 +01:00
|
|
|
bool bitcoin_tx_check(const struct bitcoin_tx *tx)
|
|
|
|
{
|
|
|
|
u8 *newtx;
|
|
|
|
size_t written;
|
|
|
|
|
|
|
|
if (wally_tx_get_length(tx->wtx, WALLY_TX_FLAG_USE_WITNESS, &written) !=
|
|
|
|
WALLY_OK)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
newtx = tal_arr(tmpctx, u8, written);
|
2019-03-25 13:52:31 +01:00
|
|
|
if (wally_tx_to_bytes(tx->wtx, WALLY_TX_FLAG_USE_WITNESS, newtx,
|
|
|
|
written, &written) != WALLY_OK)
|
2019-03-15 14:09:11 +01:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if (written != tal_bytelen(newtx))
|
|
|
|
return false;
|
|
|
|
|
2019-03-25 13:52:31 +01:00
|
|
|
return true;
|
2019-03-15 14:09:11 +01:00
|
|
|
}
|
|
|
|
|
2019-03-20 16:41:29 +01:00
|
|
|
void bitcoin_tx_output_set_amount(struct bitcoin_tx *tx, int outnum,
|
2019-08-21 05:52:44 +02:00
|
|
|
struct amount_sat amount)
|
2019-03-20 16:41:29 +01:00
|
|
|
{
|
2019-04-16 22:30:25 +02:00
|
|
|
u64 satoshis = amount.satoshis; /* Raw: low-level helper */
|
|
|
|
struct wally_tx_output *output = &tx->wtx->outputs[outnum];
|
2019-03-25 17:08:29 +01:00
|
|
|
assert(outnum < tx->wtx->num_outputs);
|
2019-04-16 22:30:25 +02:00
|
|
|
if (is_elements) {
|
2019-05-06 15:20:47 +02:00
|
|
|
int ret = wally_tx_confidential_value_from_satoshi(satoshis, output->value,
|
|
|
|
output->value_len);
|
|
|
|
assert(ret == WALLY_OK);
|
2019-04-16 22:30:25 +02:00
|
|
|
} else {
|
|
|
|
output->satoshi = satoshis;
|
|
|
|
}
|
2019-03-20 16:41:29 +01:00
|
|
|
}
|
|
|
|
|
2019-03-22 22:45:41 +01:00
|
|
|
const u8 *bitcoin_tx_output_get_script(const tal_t *ctx,
|
|
|
|
const struct bitcoin_tx *tx, int outnum)
|
|
|
|
{
|
|
|
|
const struct wally_tx_output *output;
|
|
|
|
u8 *res;
|
|
|
|
assert(outnum < tx->wtx->num_outputs);
|
|
|
|
output = &tx->wtx->outputs[outnum];
|
2019-04-13 19:14:07 +02:00
|
|
|
if (output->features & WALLY_TX_IS_COINBASE)
|
|
|
|
return NULL;
|
|
|
|
|
2019-03-22 22:45:41 +01:00
|
|
|
res = tal_arr(ctx, u8, output->script_len);
|
|
|
|
memcpy(res, output->script, output->script_len);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct amount_sat bitcoin_tx_output_get_amount(const struct bitcoin_tx *tx,
|
|
|
|
int outnum)
|
|
|
|
{
|
|
|
|
struct amount_sat amount;
|
2019-04-16 22:30:25 +02:00
|
|
|
struct wally_tx_output *output;
|
|
|
|
u64 satoshis;
|
2019-03-22 22:45:41 +01:00
|
|
|
assert(outnum < tx->wtx->num_outputs);
|
2019-04-16 22:30:25 +02:00
|
|
|
output = &tx->wtx->outputs[outnum];
|
|
|
|
|
|
|
|
if (is_elements && !memeq(output->asset, output->asset_len,
|
|
|
|
bitcoin_asset, sizeof(bitcoin_asset))) {
|
|
|
|
/* If this is an asset based tx, and we don't know the asset
|
|
|
|
* type, i.e., it's not bitcoin, return a 0 amount */
|
|
|
|
satoshis = 0;
|
|
|
|
} else if (is_elements) {
|
|
|
|
be64 raw;
|
|
|
|
memcpy(&raw, output->value + 1, sizeof(raw));
|
|
|
|
satoshis = be64_to_cpu(raw);
|
|
|
|
}else {
|
|
|
|
satoshis = tx->wtx->outputs[outnum].satoshi;
|
|
|
|
}
|
|
|
|
|
|
|
|
amount.satoshis = satoshis; /* Raw: helper */
|
2019-03-22 22:45:41 +01:00
|
|
|
return amount;
|
|
|
|
}
|
|
|
|
|
2019-03-20 16:41:29 +01:00
|
|
|
void bitcoin_tx_input_set_witness(struct bitcoin_tx *tx, int innum,
|
|
|
|
u8 **witness)
|
|
|
|
{
|
|
|
|
struct wally_tx_witness_stack *stack = NULL;
|
|
|
|
size_t stack_size = tal_count(witness);
|
|
|
|
|
|
|
|
/* Free any lingering witness */
|
|
|
|
if (witness) {
|
|
|
|
wally_tx_witness_stack_init_alloc(stack_size, &stack);
|
|
|
|
for (size_t i = 0; i < stack_size; i++)
|
|
|
|
wally_tx_witness_stack_add(stack, witness[i],
|
|
|
|
tal_bytelen(witness[i]));
|
|
|
|
}
|
|
|
|
wally_tx_set_input_witness(tx->wtx, innum, stack);
|
|
|
|
if (stack)
|
|
|
|
wally_tx_witness_stack_free(stack);
|
2019-08-21 05:52:42 +02:00
|
|
|
if (taken(witness))
|
|
|
|
tal_free(witness);
|
2019-03-20 16:41:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void bitcoin_tx_input_set_script(struct bitcoin_tx *tx, int innum, u8 *script)
|
|
|
|
{
|
|
|
|
wally_tx_set_input_script(tx->wtx, innum, script, tal_bytelen(script));
|
|
|
|
}
|
|
|
|
|
2019-03-22 22:45:41 +01:00
|
|
|
const u8 *bitcoin_tx_input_get_witness(const tal_t *ctx,
|
|
|
|
const struct bitcoin_tx *tx, int innum,
|
|
|
|
int witnum)
|
|
|
|
{
|
|
|
|
const u8 *witness_item;
|
|
|
|
struct wally_tx_witness_item *item;
|
|
|
|
assert(innum < tx->wtx->num_inputs);
|
|
|
|
assert(witnum < tx->wtx->inputs[innum].witness->num_items);
|
|
|
|
item = &tx->wtx->inputs[innum].witness->items[witnum];
|
|
|
|
witness_item =
|
|
|
|
tal_dup_arr(ctx, u8, item->witness, item->witness_len, 0);
|
|
|
|
return witness_item;
|
|
|
|
}
|
|
|
|
|
|
|
|
void bitcoin_tx_input_get_txid(const struct bitcoin_tx *tx, int innum,
|
|
|
|
struct bitcoin_txid *out)
|
|
|
|
{
|
|
|
|
assert(innum < tx->wtx->num_inputs);
|
|
|
|
assert(sizeof(struct bitcoin_txid) ==
|
|
|
|
sizeof(tx->wtx->inputs[innum].txhash));
|
|
|
|
memcpy(out, tx->wtx->inputs[innum].txhash, sizeof(struct bitcoin_txid));
|
|
|
|
}
|
|
|
|
|
2016-04-11 09:09:53 +02:00
|
|
|
/* BIP144:
|
|
|
|
* If the witness is empty, the old serialization format should be used. */
|
|
|
|
static bool uses_witness(const struct bitcoin_tx *tx)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
2019-03-25 11:35:56 +01:00
|
|
|
for (i = 0; i < tx->wtx->num_inputs; i++) {
|
|
|
|
if (tx->wtx->inputs[i].witness)
|
2016-04-11 09:09:53 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-04-24 12:23:35 +02:00
|
|
|
/* BIP 141: The witness is a serialization of all witness data of the
|
|
|
|
* transaction. Each txin is associated with a witness field. A
|
|
|
|
* witness field starts with a var_int to indicate the number of stack
|
|
|
|
* items for the txin. */
|
2016-08-18 06:53:45 +02:00
|
|
|
static void push_witnesses(const struct bitcoin_tx *tx,
|
|
|
|
void (*push)(const void *, size_t, void *), void *pushp)
|
2016-04-24 12:23:35 +02:00
|
|
|
{
|
2019-03-25 11:35:56 +01:00
|
|
|
for (size_t i = 0; i < tx->wtx->num_inputs; i++) {
|
|
|
|
struct wally_tx_witness_stack *witness = tx->wtx->inputs[i].witness;
|
2016-04-24 12:23:35 +02:00
|
|
|
|
|
|
|
/* Not every input needs a witness. */
|
2019-03-25 11:35:56 +01:00
|
|
|
if (!witness) {
|
2016-08-18 06:53:45 +02:00
|
|
|
push_varint(0, push, pushp);
|
2016-04-24 12:23:35 +02:00
|
|
|
continue;
|
|
|
|
}
|
2019-03-25 11:35:56 +01:00
|
|
|
|
|
|
|
push_varint(witness->num_items, push, pushp);
|
|
|
|
for (size_t j = 0; j < witness->num_items; j++) {
|
|
|
|
size_t witlen = witness->items[j].witness_len;
|
|
|
|
const u8 *wit = witness->items[j].witness;
|
|
|
|
push_varint(witlen, push, pushp);
|
|
|
|
push(wit, witlen, pushp);
|
2016-04-24 12:23:35 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-03 00:07:06 +01:00
|
|
|
/* For signing, we ignore input scripts on other inputs, and pretend
|
|
|
|
* the current input has a certain script: this is indicated by a
|
2018-12-03 00:15:06 +01:00
|
|
|
* non-NULL override_script.
|
|
|
|
*
|
|
|
|
* For this (and other signing weirdness like SIGHASH_SINGLE), we
|
|
|
|
* also need the current input being signed; that's in input_num.
|
|
|
|
* We also need sighash_type.
|
|
|
|
*/
|
2016-08-18 06:53:45 +02:00
|
|
|
static void push_tx(const struct bitcoin_tx *tx,
|
2018-12-03 00:07:06 +01:00
|
|
|
const u8 *override_script,
|
2018-12-03 00:15:06 +01:00
|
|
|
size_t input_num,
|
2018-12-03 00:07:06 +01:00
|
|
|
void (*push)(const void *, size_t, void *), void *pushp,
|
|
|
|
bool bip144)
|
2015-05-28 23:38:27 +02:00
|
|
|
{
|
2019-03-22 17:52:15 +01:00
|
|
|
int res;
|
|
|
|
size_t len, written;
|
|
|
|
u8 *serialized;;
|
2016-04-11 09:09:53 +02:00
|
|
|
u8 flag = 0;
|
2015-05-28 23:38:27 +02:00
|
|
|
|
2018-02-01 22:18:46 +01:00
|
|
|
if (bip144 && uses_witness(tx))
|
2019-03-22 17:52:15 +01:00
|
|
|
flag |= WALLY_TX_FLAG_USE_WITNESS;
|
2016-04-11 09:09:53 +02:00
|
|
|
|
2019-04-13 19:14:07 +02:00
|
|
|
if (is_elements)
|
|
|
|
flag |= WALLY_TX_FLAG_USE_ELEMENTS;
|
|
|
|
|
|
|
|
res = wally_tx_get_length(tx->wtx, flag & WALLY_TX_FLAG_USE_WITNESS, &len);
|
2019-06-21 02:11:41 +02:00
|
|
|
assert(res == WALLY_OK);
|
2019-03-22 17:52:15 +01:00
|
|
|
serialized = tal_arr(tmpctx, u8, len);
|
2016-04-24 12:23:35 +02:00
|
|
|
|
2019-03-22 17:52:15 +01:00
|
|
|
res = wally_tx_to_bytes(tx->wtx, flag, serialized, len, &written);
|
2019-06-21 02:11:00 +02:00
|
|
|
assert(res == WALLY_OK);
|
|
|
|
assert(len == written);
|
2019-03-22 17:52:15 +01:00
|
|
|
push(serialized, len, pushp);
|
|
|
|
tal_free(serialized);
|
2015-06-02 05:46:05 +02:00
|
|
|
}
|
|
|
|
|
2016-08-18 06:53:45 +02:00
|
|
|
static void push_sha(const void *data, size_t len, void *shactx_)
|
2015-06-02 05:46:05 +02:00
|
|
|
{
|
|
|
|
struct sha256_ctx *ctx = shactx_;
|
2015-10-26 11:35:28 +01:00
|
|
|
sha256_update(ctx, memcheck(data, len), len);
|
2015-06-02 05:46:05 +02:00
|
|
|
}
|
|
|
|
|
2016-08-18 06:53:45 +02:00
|
|
|
static void push_linearize(const void *data, size_t len, void *pptr_)
|
2015-06-02 05:46:05 +02:00
|
|
|
{
|
|
|
|
u8 **pptr = pptr_;
|
|
|
|
size_t oldsize = tal_count(*pptr);
|
|
|
|
|
|
|
|
tal_resize(pptr, oldsize + len);
|
2015-10-26 11:35:28 +01:00
|
|
|
memcpy(*pptr + oldsize, memcheck(data, len), len);
|
2015-06-02 05:46:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
u8 *linearize_tx(const tal_t *ctx, const struct bitcoin_tx *tx)
|
|
|
|
{
|
|
|
|
u8 *arr = tal_arr(ctx, u8, 0);
|
2018-12-03 00:07:06 +01:00
|
|
|
push_tx(tx, NULL, 0, push_linearize, &arr, true);
|
2015-06-02 05:46:05 +02:00
|
|
|
return arr;
|
2015-05-28 23:38:27 +02:00
|
|
|
}
|
2015-05-29 04:03:18 +02:00
|
|
|
|
2018-02-21 16:06:07 +01:00
|
|
|
static void push_measure(const void *data UNUSED, size_t len, void *lenp)
|
2016-04-12 05:37:04 +02:00
|
|
|
{
|
|
|
|
*(size_t *)lenp += len;
|
|
|
|
}
|
|
|
|
|
2018-02-03 01:16:23 +01:00
|
|
|
size_t measure_tx_weight(const struct bitcoin_tx *tx)
|
2016-04-24 12:23:35 +02:00
|
|
|
{
|
|
|
|
size_t non_witness_len = 0, witness_len = 0;
|
2018-12-03 00:07:06 +01:00
|
|
|
push_tx(tx, NULL, 0, push_measure, &non_witness_len, false);
|
2018-02-03 01:16:23 +01:00
|
|
|
if (uses_witness(tx)) {
|
2016-08-18 06:53:45 +02:00
|
|
|
push_witnesses(tx, push_measure, &witness_len);
|
2018-02-03 01:16:23 +01:00
|
|
|
/* Include BIP 144 marker and flag bytes in witness length */
|
|
|
|
witness_len += 2;
|
|
|
|
}
|
2016-04-24 12:23:35 +02:00
|
|
|
|
2018-02-03 01:16:23 +01:00
|
|
|
/* Normal bytes weigh 4 times more than Witness bytes */
|
2016-04-24 12:23:35 +02:00
|
|
|
return non_witness_len * 4 + witness_len;
|
|
|
|
}
|
|
|
|
|
2017-12-18 07:41:52 +01:00
|
|
|
void bitcoin_txid(const struct bitcoin_tx *tx, struct bitcoin_txid *txid)
|
2015-06-02 05:29:13 +02:00
|
|
|
{
|
|
|
|
struct sha256_ctx ctx = SHA256_INIT;
|
|
|
|
|
2016-04-11 09:09:53 +02:00
|
|
|
/* For TXID, we never use extended form. */
|
2018-12-03 00:07:06 +01:00
|
|
|
push_tx(tx, NULL, 0, push_sha, &ctx, false);
|
2017-12-18 07:41:52 +01:00
|
|
|
sha256_double_done(&ctx, &txid->shad);
|
2015-06-02 05:29:13 +02:00
|
|
|
}
|
|
|
|
|
2019-03-01 13:23:22 +01:00
|
|
|
/* Use the bitcoin_tx destructor to also free the wally_tx */
|
|
|
|
static void bitcoin_tx_destroy(struct bitcoin_tx *tx)
|
|
|
|
{
|
|
|
|
wally_tx_free(tx->wtx);
|
|
|
|
}
|
|
|
|
|
2019-07-30 16:14:43 +02:00
|
|
|
struct bitcoin_tx *bitcoin_tx(const tal_t *ctx,
|
|
|
|
const struct chainparams *chainparams,
|
|
|
|
varint_t input_count, varint_t output_count)
|
2015-05-29 04:03:18 +02:00
|
|
|
{
|
|
|
|
struct bitcoin_tx *tx = tal(ctx, struct bitcoin_tx);
|
2019-07-30 22:04:55 +02:00
|
|
|
assert(chainparams);
|
2019-07-30 16:14:43 +02:00
|
|
|
|
2019-03-01 13:23:22 +01:00
|
|
|
wally_tx_init_alloc(WALLY_TX_VERSION_2, 0, input_count, output_count,
|
|
|
|
&tx->wtx);
|
|
|
|
tal_add_destructor(tx, bitcoin_tx_destroy);
|
|
|
|
|
2019-03-22 14:01:16 +01:00
|
|
|
tx->input_amounts = tal_arrz(tx, struct amount_sat*, input_count);
|
2019-03-05 14:28:29 +01:00
|
|
|
tx->wtx->locktime = 0;
|
|
|
|
tx->wtx->version = 2;
|
2019-07-30 16:14:43 +02:00
|
|
|
tx->chainparams = chainparams;
|
2015-05-29 04:03:18 +02:00
|
|
|
return tx;
|
|
|
|
}
|
2015-06-04 06:18:11 +02:00
|
|
|
|
2018-02-08 02:25:12 +01:00
|
|
|
struct bitcoin_tx *pull_bitcoin_tx(const tal_t *ctx, const u8 **cursor,
|
|
|
|
size_t *max)
|
2015-06-04 06:18:11 +02:00
|
|
|
{
|
2019-03-21 19:02:44 +01:00
|
|
|
size_t wsize;
|
2019-04-13 17:15:02 +02:00
|
|
|
int flags = WALLY_TX_FLAG_USE_WITNESS;
|
2018-02-08 02:25:12 +01:00
|
|
|
struct bitcoin_tx *tx = tal(ctx, struct bitcoin_tx);
|
2019-04-13 17:15:02 +02:00
|
|
|
|
|
|
|
if (is_elements)
|
|
|
|
flags |= WALLY_TX_FLAG_USE_ELEMENTS;
|
|
|
|
|
|
|
|
if (wally_tx_from_bytes(*cursor, *max, flags, &tx->wtx) != WALLY_OK) {
|
2019-06-21 02:11:41 +02:00
|
|
|
fromwire_fail(cursor, max);
|
2019-03-01 13:23:22 +01:00
|
|
|
return tal_free(tx);
|
|
|
|
}
|
2019-04-13 17:15:02 +02:00
|
|
|
|
2019-03-01 13:23:22 +01:00
|
|
|
tal_add_destructor(tx, bitcoin_tx_destroy);
|
2019-04-13 17:15:02 +02:00
|
|
|
|
|
|
|
/* For whatever reason the length computation gets upset if we tell it
|
|
|
|
* that we are using elements. It wants to discover it on its own, NO
|
|
|
|
* CLUES! (Ms. Doyle)
|
|
|
|
*
|
|
|
|
* https://github.com/ElementsProject/libwally-core/issues/139
|
|
|
|
*/
|
|
|
|
wally_tx_get_length(tx->wtx, flags & ~WALLY_TX_FLAG_USE_ELEMENTS,
|
|
|
|
&wsize);
|
2019-03-25 13:52:31 +01:00
|
|
|
|
|
|
|
/* We don't know the input amounts yet, so set them all to NULL */
|
2019-03-22 14:01:16 +01:00
|
|
|
tx->input_amounts =
|
|
|
|
tal_arrz(tx, struct amount_sat *, tx->wtx->inputs_allocation_len);
|
2019-07-30 16:14:43 +02:00
|
|
|
tx->chainparams = NULL;
|
2015-06-04 06:18:11 +02:00
|
|
|
|
2019-03-25 13:52:31 +01:00
|
|
|
*cursor += wsize;
|
|
|
|
*max -= wsize;
|
2015-06-04 06:18:11 +02:00
|
|
|
return tx;
|
|
|
|
}
|
|
|
|
|
2016-01-21 21:11:47 +01:00
|
|
|
struct bitcoin_tx *bitcoin_tx_from_hex(const tal_t *ctx, const char *hex,
|
|
|
|
size_t hexlen)
|
2015-06-04 06:18:11 +02:00
|
|
|
{
|
2016-07-01 03:57:57 +02:00
|
|
|
const char *end;
|
2015-06-04 06:18:11 +02:00
|
|
|
u8 *linear_tx;
|
|
|
|
const u8 *p;
|
|
|
|
struct bitcoin_tx *tx;
|
|
|
|
size_t len;
|
|
|
|
|
2016-04-11 09:02:43 +02:00
|
|
|
end = memchr(hex, '\n', hexlen);
|
|
|
|
if (!end)
|
2016-07-01 03:57:57 +02:00
|
|
|
end = hex + hexlen;
|
2016-01-21 21:11:46 +01:00
|
|
|
|
2015-07-01 06:14:31 +02:00
|
|
|
len = hex_data_size(end - hex);
|
2016-01-21 21:11:46 +01:00
|
|
|
p = linear_tx = tal_arr(ctx, u8, len);
|
2015-07-01 06:14:31 +02:00
|
|
|
if (!hex_decode(hex, end - hex, linear_tx, len))
|
2016-01-21 21:11:46 +01:00
|
|
|
goto fail;
|
2015-06-04 06:18:11 +02:00
|
|
|
|
|
|
|
tx = pull_bitcoin_tx(ctx, &p, &len);
|
|
|
|
if (!tx)
|
2016-01-21 21:11:46 +01:00
|
|
|
goto fail;
|
2015-07-01 06:14:31 +02:00
|
|
|
|
2016-04-24 12:10:29 +02:00
|
|
|
if (len)
|
|
|
|
goto fail_free_tx;
|
2016-11-11 00:02:04 +01:00
|
|
|
|
2016-01-21 21:11:46 +01:00
|
|
|
tal_free(linear_tx);
|
2015-06-04 06:18:11 +02:00
|
|
|
return tx;
|
2016-01-21 21:11:46 +01:00
|
|
|
|
|
|
|
fail_free_tx:
|
|
|
|
tal_free(tx);
|
|
|
|
fail:
|
|
|
|
tal_free(linear_tx);
|
|
|
|
return NULL;
|
2015-06-04 06:18:11 +02:00
|
|
|
}
|
2015-06-05 05:05:46 +02:00
|
|
|
|
2017-12-18 07:41:52 +01:00
|
|
|
/* <sigh>. Bitcoind represents hashes as little-endian for RPC. */
|
2015-06-05 05:05:46 +02:00
|
|
|
static void reverse_bytes(u8 *arr, size_t len)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i = 0; i < len / 2; i++) {
|
|
|
|
unsigned char tmp = arr[i];
|
|
|
|
arr[i] = arr[len - 1 - i];
|
|
|
|
arr[len - 1 - i] = tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool bitcoin_txid_from_hex(const char *hexstr, size_t hexstr_len,
|
2017-12-18 07:41:52 +01:00
|
|
|
struct bitcoin_txid *txid)
|
2015-06-05 05:05:46 +02:00
|
|
|
{
|
|
|
|
if (!hex_decode(hexstr, hexstr_len, txid, sizeof(*txid)))
|
|
|
|
return false;
|
2017-12-18 07:41:52 +01:00
|
|
|
reverse_bytes(txid->shad.sha.u.u8, sizeof(txid->shad.sha.u.u8));
|
2015-06-05 05:05:46 +02:00
|
|
|
return true;
|
|
|
|
}
|
2015-07-01 06:14:31 +02:00
|
|
|
|
2017-12-18 07:41:52 +01:00
|
|
|
bool bitcoin_txid_to_hex(const struct bitcoin_txid *txid,
|
2015-07-24 08:30:10 +02:00
|
|
|
char *hexstr, size_t hexstr_len)
|
|
|
|
{
|
2017-12-18 07:41:52 +01:00
|
|
|
struct sha256_double rev = txid->shad;
|
2015-07-24 08:30:10 +02:00
|
|
|
reverse_bytes(rev.sha.u.u8, sizeof(rev.sha.u.u8));
|
|
|
|
return hex_encode(&rev, sizeof(rev), hexstr, hexstr_len);
|
|
|
|
}
|
2017-01-04 04:37:15 +01:00
|
|
|
|
|
|
|
static char *fmt_bitcoin_tx(const tal_t *ctx, const struct bitcoin_tx *tx)
|
|
|
|
{
|
|
|
|
u8 *lin = linearize_tx(ctx, tx);
|
2017-01-10 05:49:25 +01:00
|
|
|
char *s = tal_hex(ctx, lin);
|
2017-01-04 04:37:15 +01:00
|
|
|
tal_free(lin);
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2017-12-18 07:41:52 +01:00
|
|
|
static char *fmt_bitcoin_txid(const tal_t *ctx, const struct bitcoin_txid *txid)
|
|
|
|
{
|
|
|
|
char *hexstr = tal_arr(ctx, char, hex_str_size(sizeof(*txid)));
|
|
|
|
|
|
|
|
bitcoin_txid_to_hex(txid, hexstr, hex_str_size(sizeof(*txid)));
|
|
|
|
return hexstr;
|
|
|
|
}
|
|
|
|
|
2017-01-04 04:37:15 +01:00
|
|
|
REGISTER_TYPE_TO_STRING(bitcoin_tx, fmt_bitcoin_tx);
|
2017-12-18 07:41:52 +01:00
|
|
|
REGISTER_TYPE_TO_STRING(bitcoin_txid, fmt_bitcoin_txid);
|