diff --git a/bitcoin/tx.c b/bitcoin/tx.c index f49f1addb..e7540d648 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -79,6 +79,33 @@ static bool uses_witness(const struct bitcoin_tx *tx) return false; } +/* 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. */ +static void add_witnesses(const struct bitcoin_tx *tx, + void (*add)(const void *, size_t, void *), void *addp) +{ + size_t i; + for (i = 0; i < tx->input_count; i++) { + size_t j, elements; + + /* Not every input needs a witness. */ + if (!tx->input[i].witness) { + add_varint(0, add, addp); + continue; + } + elements = tal_count(tx->input[i].witness); + add_varint(elements, add, addp); + for (j = 0; + j < tal_count(tx->input[i].witness); + j++) { + add_witness(tx->input[i].witness[j], + add, addp); + } + } +} + static void add_tx(const struct bitcoin_tx *tx, void (*add)(const void *, size_t, void *), void *addp, bool extended) @@ -115,31 +142,9 @@ static void add_tx(const struct bitcoin_tx *tx, for (i = 0; i < tx->output_count; i++) add_tx_output(&tx->output[i], add, addp); - if (flag & SEGREGATED_WITNESS_FLAG) { - /* 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. */ - for (i = 0; i < tx->input_count; i++) { - size_t j, elements; - - /* Not every input needs a witness. */ - if (!tx->input[i].witness) { - add_varint(0, add, addp); - continue; - } - elements = tal_count(tx->input[i].witness); - add_varint(elements, add, addp); - for (j = 0; - j < tal_count(tx->input[i].witness); - j++) { - add_witness(tx->input[i].witness[j], - add, addp); - } - } - } + if (flag & SEGREGATED_WITNESS_FLAG) + add_witnesses(tx, add, addp); + add_le32(tx->lock_time, add, addp); } @@ -308,6 +313,17 @@ size_t measure_tx_len(const struct bitcoin_tx *tx) return len; } +size_t measure_tx_cost(const struct bitcoin_tx *tx) +{ + size_t non_witness_len = 0, witness_len = 0; + add_tx(tx, add_measure, &non_witness_len, false); + if (uses_witness(tx)) + add_witnesses(tx, add_measure, &witness_len); + + /* Witness bytes only add 1/4 of normal bytes, for cost. */ + return non_witness_len * 4 + witness_len; +} + void bitcoin_txid(const struct bitcoin_tx *tx, struct sha256_double *txid) { struct sha256_ctx ctx = SHA256_INIT; diff --git a/bitcoin/tx.h b/bitcoin/tx.h index 097ddb667..798df29d2 100644 --- a/bitcoin/tx.h +++ b/bitcoin/tx.h @@ -56,6 +56,9 @@ u8 *linearize_tx_force_extended(const tal_t *ctx, /* Get length of tx in bytes. */ size_t measure_tx_len(const struct bitcoin_tx *tx); +/* Get cost of tx in (x4 of non-witness bytecount). */ +size_t measure_tx_cost(const struct bitcoin_tx *tx); + /* Allocate a tx: you just need to fill in inputs and outputs (they're * zeroed with inputs' sequence_number set to FFFFFFFF) */ struct bitcoin_tx *bitcoin_tx(const tal_t *ctx, varint_t input_count,