From d651ce6f3bc0f66df88e1ed28db0d484d6d280fe Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Mon, 25 Mar 2019 11:35:56 +0100 Subject: [PATCH] wally: Migrate main daemon to use wally transactions Signed-off-by: Christian Decker --- bitcoin/signature.c | 2 +- bitcoin/tx.c | 34 ++++++++++++---------------------- channeld/test/run-commit_tx.c | 14 +++++++------- common/htlc_tx.c | 6 +++--- common/initial_commit_tx.c | 2 +- common/test/run-funding_tx.c | 5 ++++- lightningd/chaintopology.c | 27 ++++++++++++++++----------- lightningd/closing_control.c | 7 ++++--- lightningd/onchain_control.c | 7 ++++--- lightningd/opening_control.c | 14 ++++++++------ lightningd/peer_control.c | 6 +++--- wallet/txfilter.c | 4 ++-- wallet/wallet.c | 14 ++++++++------ 13 files changed, 73 insertions(+), 69 deletions(-) diff --git a/bitcoin/signature.c b/bitcoin/signature.c index 713d004d9..61dcfae73 100644 --- a/bitcoin/signature.c +++ b/bitcoin/signature.c @@ -144,7 +144,7 @@ bool check_tx_sig(const struct bitcoin_tx *tx, size_t input_num, if (sig->sighash_type != (SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)) return false; } - assert(input_num < tal_count(tx->input)); + assert(input_num < tx->wtx->num_inputs); wally_tx_get_btc_signature_hash( tx->wtx, input_num, script, tal_bytelen(script), diff --git a/bitcoin/tx.c b/bitcoin/tx.c index 153d97991..4030ccc71 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -164,23 +164,14 @@ void bitcoin_tx_input_get_txid(const struct bitcoin_tx *tx, int innum, memcpy(out, tx->wtx->inputs[innum].txhash, sizeof(struct bitcoin_txid)); } -/* BIP 141: - * It is followed by stack items, with each item starts with a var_int - * to indicate the length. */ -static void push_witness(const u8 *witness, - void (*push)(const void *, size_t, void *), void *pushp) -{ - push_varint_blob(witness, push, pushp); -} - /* 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; - for (i = 0; i < tal_count(tx->input); i++) { - if (tx->input[i].witness) + for (i = 0; i < tx->wtx->num_inputs; i++) { + if (tx->wtx->inputs[i].witness) return true; } return false; @@ -193,22 +184,21 @@ static bool uses_witness(const struct bitcoin_tx *tx) static void push_witnesses(const struct bitcoin_tx *tx, void (*push)(const void *, size_t, void *), void *pushp) { - size_t i; - for (i = 0; i < tal_count(tx->input); i++) { - size_t j, elements; + for (size_t i = 0; i < tx->wtx->num_inputs; i++) { + struct wally_tx_witness_stack *witness = tx->wtx->inputs[i].witness; /* Not every input needs a witness. */ - if (!tx->input[i].witness) { + if (!witness) { push_varint(0, push, pushp); continue; } - elements = tal_count(tx->input[i].witness); - push_varint(elements, push, pushp); - for (j = 0; - j < tal_count(tx->input[i].witness); - j++) { - push_witness(tx->input[i].witness[j], - push, pushp); + + 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); } } } diff --git a/channeld/test/run-commit_tx.c b/channeld/test/run-commit_tx.c index 8b24787d9..906981ee9 100644 --- a/channeld/test/run-commit_tx.c +++ b/channeld/test/run-commit_tx.c @@ -340,7 +340,7 @@ static void report(struct bitcoin_tx *tx, type_to_string(tmpctx, struct bitcoin_signature, &localsig)); witness = - bitcoin_witness_2of2(tx->input, &localsig, &remotesig, + bitcoin_witness_2of2(tx, &localsig, &remotesig, local_funding_pubkey, remote_funding_pubkey); bitcoin_tx_input_set_witness(tx, 0, witness); txhex = tal_hex(tmpctx, linearize_tx(tx, tx)); @@ -846,8 +846,8 @@ int main(void) "to_local_msat: %"PRIu64"\n" "to_remote_msat: %"PRIu64"\n" "local_feerate_per_kw: %u\n", - tal_count(tx->output), - tal_count(tx->output) > 1 ? "s" : "", + tx->wtx->num_outputs, + tx->wtx->num_outputs > 1 ? "s" : "", to_local.millisatoshis, to_remote.millisatoshis, feerate_per_kw-1); /* Recalc with verbosity on */ print_superverbose = true; @@ -882,8 +882,8 @@ int main(void) "to_local_msat: %"PRIu64"\n" "to_remote_msat: %"PRIu64"\n" "local_feerate_per_kw: %u\n", - tal_count(newtx->output), - tal_count(newtx->output) > 1 ? "s" : "", + newtx->wtx->num_outputs, + newtx->wtx->num_outputs > 1 ? "s" : "", to_local.millisatoshis, to_remote.millisatoshis, feerate_per_kw); /* Recalc with verbosity on */ print_superverbose = true; @@ -913,11 +913,11 @@ int main(void) feerate_per_kw, htlc_map); - assert(tal_count(newtx->output) != tal_count(tx->output)); + assert(newtx->wtx->num_outputs != tx->wtx->num_outputs); tal_free(tx); tx = newtx; - } while (tal_count(tx->output) > 1); + } while (tx->wtx->num_outputs > 1); /* Now make sure we cover case where funder can't afford the fee; * its output cannot go negative! */ diff --git a/common/htlc_tx.c b/common/htlc_tx.c index 6e248b788..cdbc791be 100644 --- a/common/htlc_tx.c +++ b/common/htlc_tx.c @@ -104,7 +104,7 @@ void htlc_success_tx_add_witness(struct bitcoin_tx *htlc_success, localhtlckey, remotehtlckey, &hash, revocationkey); - witness = bitcoin_witness_htlc_success_tx(htlc_success->input, + witness = bitcoin_witness_htlc_success_tx(htlc_success, localhtlcsig, remotehtlcsig, payment_preimage, wscript); bitcoin_tx_input_set_witness(htlc_success, 0, witness); @@ -145,8 +145,8 @@ void htlc_timeout_tx_add_witness(struct bitcoin_tx *htlc_timeout, localhtlckey, remotehtlckey, payment_hash, revocationkey); - witness = bitcoin_witness_htlc_timeout_tx( - htlc_timeout->input, localhtlcsig, remotehtlcsig, wscript); + witness = bitcoin_witness_htlc_timeout_tx(htlc_timeout, localhtlcsig, + remotehtlcsig, wscript); bitcoin_tx_input_set_witness(htlc_timeout, 0, witness); tal_free(wscript); } diff --git a/common/initial_commit_tx.c b/common/initial_commit_tx.c index 77a6933a7..7a24f0a63 100644 --- a/common/initial_commit_tx.c +++ b/common/initial_commit_tx.c @@ -197,7 +197,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx, n++; } - assert(n <= tal_count(tx->output)); + assert(n <= tx->wtx->num_outputs); tal_resize(&tx->output, n); /* BOLT #3: diff --git a/common/test/run-funding_tx.c b/common/test/run-funding_tx.c index 874944b9b..de49d2b2b 100644 --- a/common/test/run-funding_tx.c +++ b/common/test/run-funding_tx.c @@ -100,6 +100,7 @@ int main(void) u8 *subscript, *script; struct bitcoin_signature sig; struct bitcoin_address addr; + struct amount_sat tmpamt; secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); @@ -170,9 +171,11 @@ int main(void) &inputkey, NULL); printf("# fee: %s\n", type_to_string(tmpctx, struct amount_sat, &fee)); + + tmpamt = bitcoin_tx_output_get_amount(funding, !funding_outnum); printf("change: %s\n", type_to_string(tmpctx, struct amount_sat, - &funding->output[!funding_outnum].amount)); + &tmpamt)); printf("funding output: %u\n", funding_outnum); diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index 67299c6ef..4eaa93179 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -69,11 +69,11 @@ static void filter_block_txs(struct chain_topology *topo, struct block *b) size_t j; /* Tell them if it spends a txo we care about. */ - for (j = 0; j < tal_count(tx->input); j++) { + for (j = 0; j < tx->wtx->num_inputs; j++) { struct txwatch_output out; struct txowatch *txo; - out.txid = tx->input[j].txid; - out.index = tx->input[j].index; + bitcoin_tx_input_get_txid(tx, j, &out.txid); + out.index = tx->wtx->inputs[j].index; txo = txowatch_hash_get(&topo->txowatches, &out); if (txo) { @@ -571,10 +571,13 @@ static void topo_update_spends(struct chain_topology *topo, struct block *b) const struct short_channel_id *scid; for (size_t i = 0; i < tal_count(b->full_txs); i++) { const struct bitcoin_tx *tx = b->full_txs[i]; - for (size_t j = 0; j < tal_count(tx->input); j++) { - const struct bitcoin_tx_input *input = &tx->input[j]; + for (size_t j = 0; j < tx->wtx->num_inputs; j++) { + const struct wally_tx_input *input = &tx->wtx->inputs[j]; + struct bitcoin_txid txid; + bitcoin_tx_input_get_txid(tx, j, &txid); + scid = wallet_outpoint_spend(topo->ld->wallet, tmpctx, - b->height, &input->txid, + b->height, &txid, input->index); if (scid) { gossipd_notify_spend(topo->bitcoind->ld, scid); @@ -588,12 +591,14 @@ static void topo_add_utxos(struct chain_topology *topo, struct block *b) { for (size_t i = 0; i < tal_count(b->full_txs); i++) { const struct bitcoin_tx *tx = b->full_txs[i]; - for (size_t j = 0; j < tal_count(tx->output); j++) { - const struct bitcoin_tx_output *output = &tx->output[j]; - if (is_p2wsh(output->script, NULL)) { + for (size_t j = 0; j < tx->wtx->num_outputs; j++) { + const u8 *script = bitcoin_tx_output_get_script(tmpctx, tx, j); + struct amount_sat amt = bitcoin_tx_output_get_amount(tx, j); + + if (is_p2wsh(script, NULL)) { wallet_utxoset_add(topo->ld->wallet, tx, j, - b->height, i, output->script, - output->amount); + b->height, i, script, + amt); } } } diff --git a/lightningd/closing_control.c b/lightningd/closing_control.c index 54a23c342..d19ef94c6 100644 --- a/lightningd/closing_control.c +++ b/lightningd/closing_control.c @@ -20,9 +20,10 @@ static struct amount_sat calc_tx_fee(struct amount_sat sat_in, const struct bitcoin_tx *tx) { - struct amount_sat fee = sat_in; - for (size_t i = 0; i < tal_count(tx->output); i++) { - if (!amount_sat_sub(&fee, fee, tx->output[i].amount)) + struct amount_sat amt, fee = sat_in; + for (size_t i = 0; i < tx->wtx->num_outputs; i++) { + amt = bitcoin_tx_output_get_amount(tx, i); + if (!amount_sat_sub(&fee, fee, amt)) fatal("Tx spends more than input %s? %s", type_to_string(tmpctx, struct amount_sat, &sat_in), type_to_string(tmpctx, struct bitcoin_tx, tx)); diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index b643c89ef..8ae70cec9 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -157,7 +157,7 @@ static void watch_tx_and_outputs(struct channel *channel, txw = watch_tx(channel->owner, ld->topology, channel, tx, onchain_tx_watched); - for (size_t i = 0; i < tal_count(tx->output); i++) + for (size_t i = 0; i < tx->wtx->num_outputs; i++) watch_txo(txw, ld->topology, channel, &txid, i, onchain_txo_watched); } @@ -450,9 +450,10 @@ enum watch_result onchaind_funding_spent(struct channel *channel, if (!feerate) { /* We have at least one data point: the last tx's feerate. */ struct amount_sat fee = channel->funding; - for (size_t i = 0; i < tal_count(channel->last_tx->output); i++) + for (size_t i = 0; i < channel->last_tx->wtx->num_outputs; i++) if (!amount_sat_sub(&fee, fee, - channel->last_tx->output[i].amount)) { + bitcoin_tx_output_get_amount( + channel->last_tx, i))) { log_broken(channel->log, "Could not get fee" " funding %s tx %s", type_to_string(tmpctx, diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index 976b57359..2fb72b3e6 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -343,17 +343,19 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp, ld->wallet->bip32_base); log_debug(fc->uc->log, "Funding tx has %zi inputs, %zu outputs:", - tal_count(fundingtx->input), - tal_count(fundingtx->output)); + fundingtx->wtx->num_inputs, + fundingtx->wtx->num_outputs); - for (size_t i = 0; i < tal_count(fundingtx->input); i++) { + for (size_t i = 0; i < fundingtx->wtx->num_inputs; i++) { + struct bitcoin_txid tmptxid; + bitcoin_tx_input_get_txid(fundingtx, i, &tmptxid); log_debug(fc->uc->log, "%zi: %s (%s) %s\n", i, type_to_string(tmpctx, struct amount_sat, &fc->wtx.utxos[i]->amount), fc->wtx.utxos[i]->is_p2sh ? "P2SH" : "SEGWIT", type_to_string(tmpctx, struct bitcoin_txid, - &fundingtx->input[i].txid)); + &tmptxid)); } bitcoin_txid(fundingtx, &funding_txid); @@ -433,8 +435,8 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp, /* Make sure we recognize our change output by its scriptpubkey in * future. This assumes that we have only two outputs, may not be true * if we add support for multifundchannel */ - if (tal_count(fundingtx->output) == 2) - txfilter_add_scriptpubkey(ld->owned_txfilter, fundingtx->output[!funding_outnum].script); + if (fundingtx->wtx->num_outputs == 2) + txfilter_add_scriptpubkey(ld->owned_txfilter, bitcoin_tx_output_get_script(tmpctx, fundingtx, !funding_outnum)); /* We need these to compose cmd's response in funding_broadcast_success */ fc->hextx = tal_hex(fc, linearize_tx(fc->cmd, fundingtx)); diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index eae6cb5dd..debb69737 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -200,7 +200,7 @@ static void sign_last_tx(struct channel *channel) struct bitcoin_signature sig; u8 *msg, **witness; - assert(!channel->last_tx->input[0].witness); + assert(!channel->last_tx->wtx->inputs[0].witness); msg = towire_hsm_sign_commitment_tx(tmpctx, &channel->peer->id, @@ -219,7 +219,7 @@ static void sign_last_tx(struct channel *channel) tal_hex(tmpctx, msg)); witness = - bitcoin_witness_2of2(channel->last_tx->input, &channel->last_sig, + bitcoin_witness_2of2(channel->last_tx, &channel->last_sig, &sig, &channel->channel_info.remote_fundingkey, &channel->local_funding_pubkey); @@ -1532,7 +1532,7 @@ static struct command_result *json_sign_last_tx(struct command *cmd, response = json_stream_success(cmd); log_debug(channel->log, "dev-sign-last-tx: signing tx with %zu outputs", - tal_count(channel->last_tx->output)); + channel->last_tx->wtx->num_outputs); sign_last_tx(channel); linear = linearize_tx(cmd, channel->last_tx); remove_sig(channel->last_tx); diff --git a/wallet/txfilter.c b/wallet/txfilter.c index 581aa1dc3..801866b9c 100644 --- a/wallet/txfilter.c +++ b/wallet/txfilter.c @@ -73,8 +73,8 @@ void txfilter_add_derkey(struct txfilter *filter, bool txfilter_match(const struct txfilter *filter, const struct bitcoin_tx *tx) { - for (size_t i = 0; i < tal_count(tx->output); i++) { - u8 *oscript = tx->output[i].script; + for (size_t i = 0; i < tx->wtx->num_outputs; i++) { + const u8 *oscript = bitcoin_tx_output_get_script(tmpctx, tx, i); for (size_t j = 0; j < tal_count(filter->scriptpubkeys); j++) { if (scripteq(oscript, filter->scriptpubkeys[j])) diff --git a/wallet/wallet.c b/wallet/wallet.c index eb0ab5357..ad7e88f1c 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1163,19 +1163,21 @@ int wallet_extract_owned_outputs(struct wallet *w, const struct bitcoin_tx *tx, int num_utxos = 0; *total = AMOUNT_SAT(0); - for (size_t output = 0; output < tal_count(tx->output); output++) { + for (size_t output = 0; output < tx->wtx->num_outputs; output++) { struct utxo *utxo; u32 index; bool is_p2sh; + const u8 *script = bitcoin_tx_output_get_script(tmpctx, tx, output); - if (!wallet_can_spend(w, tx->output[output].script, &index, + + if (!wallet_can_spend(w, script, &index, &is_p2sh)) continue; utxo = tal(w, struct utxo); utxo->keyindex = index; utxo->is_p2sh = is_p2sh; - utxo->amount = tx->output[output].amount; + utxo->amount = bitcoin_tx_output_get_amount(tx, output); utxo->status = output_state_available; bitcoin_txid(tx, &utxo->txid); utxo->outnum = output; @@ -1183,12 +1185,12 @@ int wallet_extract_owned_outputs(struct wallet *w, const struct bitcoin_tx *tx, utxo->blockheight = blockheight ? blockheight : NULL; utxo->spendheight = NULL; - utxo->scriptPubkey = tx->output[output].script; + utxo->scriptPubkey = tal_dup_arr(utxo, u8, script, tal_bytelen(script), 0); log_debug(w->log, "Owning output %zu %s (%s) txid %s%s", output, type_to_string(tmpctx, struct amount_sat, - &tx->output[output].amount), + &utxo->amount), is_p2sh ? "P2SH" : "SEGWIT", type_to_string(tmpctx, struct bitcoin_txid, &utxo->txid), blockheight ? " CONFIRMED" : ""); @@ -1208,7 +1210,7 @@ int wallet_extract_owned_outputs(struct wallet *w, const struct bitcoin_tx *tx, if (!amount_sat_add(total, *total, utxo->amount)) fatal("Cannot add utxo output %zu/%zu %s + %s", - output, tal_count(tx->output), + output, tx->wtx->num_outputs, type_to_string(tmpctx, struct amount_sat, total), type_to_string(tmpctx, struct amount_sat, &utxo->amount));