From f39d2ee0869986061f37a91a65f76f07e1d55b67 Mon Sep 17 00:00:00 2001 From: Jon Griffiths Date: Thu, 22 Feb 2024 10:04:37 +1300 Subject: [PATCH] tx: remove allocating script fetchers The pattern of making tal-allocated copies of wally data to pass around was made redundant after these calls were added by the use of tal_wally_start/tal_wally_end to parent wally allocations. We can thus just pass the data directly and avoid the allocations. Removes redundant allocations when checking tx filters and computing fees. Signed-off-by: Jon Griffiths --- bitcoin/tx.c | 22 ---------------------- bitcoin/tx.h | 19 ------------------- lightningd/chaintopology.c | 10 ++++++---- lightningd/closing_control.c | 12 ++++-------- wallet/txfilter.c | 10 ++++------ 5 files changed, 14 insertions(+), 59 deletions(-) diff --git a/bitcoin/tx.c b/bitcoin/tx.c index d86b53c94..a416a4546 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -302,28 +302,6 @@ void bitcoin_tx_output_set_amount(struct bitcoin_tx *tx, int outnum, wally_psbt_output_set_amount(&tx->psbt->outputs[outnum], satoshis); } -const u8 *cln_wally_tx_output_get_script(const tal_t *ctx, - const struct wally_tx_output *output) -{ - if (output->script == NULL) { - /* This can happen for coinbase transactions and pegin - * transactions */ - return NULL; - } - - return tal_dup_arr(ctx, u8, output->script, output->script_len, 0); -} - -const u8 *bitcoin_tx_output_get_script(const tal_t *ctx, - const struct bitcoin_tx *tx, int outnum) -{ - const struct wally_tx_output *output; - assert(outnum < tx->wtx->num_outputs); - output = &tx->wtx->outputs[outnum]; - - return cln_wally_tx_output_get_script(ctx, output); -} - u8 *bitcoin_tx_output_get_witscript(const tal_t *ctx, const struct bitcoin_tx *tx, int outnum) { diff --git a/bitcoin/tx.h b/bitcoin/tx.h index 091ecb476..21797cee5 100644 --- a/bitcoin/tx.h +++ b/bitcoin/tx.h @@ -144,25 +144,6 @@ wally_tx_output_get_amount(const struct wally_tx_output *output); void bitcoin_tx_output_set_amount(struct bitcoin_tx *tx, int outnum, struct amount_sat amount); -/** - * Helper to get the script of a script's output as a tal_arr - * - * Internally we use a `wally_tx` to represent the transaction. The script - * attached to a `wally_tx_output` is not a `tal_arr`, so in order to keep the - * comfort of being able to call `tal_bytelen` and similar on a script we just - * return a `tal_arr` clone of the original script. - */ -const u8 *bitcoin_tx_output_get_script(const tal_t *ctx, const struct bitcoin_tx *tx, int outnum); - -/** - * Helper to get the script of a script's output as a tal_arr - * - * The script attached to a `wally_tx_output` is not a `tal_arr`, so in order to keep the - * comfort of being able to call `tal_bytelen` and similar on a script we just - * return a `tal_arr` clone of the original script. - */ -const u8 *cln_wally_tx_output_get_script(const tal_t *ctx, - const struct wally_tx_output *output); /** * Helper to get a witness script for an output. */ diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index aeffa1983..d5b121f5b 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -61,6 +61,7 @@ static bool we_broadcast(const struct chain_topology *topo, static void filter_block_txs(struct chain_topology *topo, struct block *b) { + struct txfilter *filter = topo->bitcoind->ld->owned_txfilter; size_t i; struct amount_sat owned; @@ -89,21 +90,22 @@ static void filter_block_txs(struct chain_topology *topo, struct block *b) owned = AMOUNT_SAT(0); txid = b->txids[i]; - if (txfilter_match(topo->bitcoind->ld->owned_txfilter, tx)) { + if (txfilter_match(filter, tx)) { wallet_extract_owned_outputs(topo->bitcoind->ld->wallet, tx->wtx, is_coinbase, &b->height, &owned); wallet_transaction_add(topo->ld->wallet, tx->wtx, b->height, i); // invoice_check_onchain_payment(tx); for (size_t k = 0; k < tx->wtx->num_outputs; k++) { - const u8 *oscript = bitcoin_tx_output_get_script(tmpctx, tx, k); - if (txfilter_scriptpubkey_matches(topo->bitcoind->ld->owned_txfilter, oscript)) { + const struct wally_tx_output *txout; + txout = &tx->wtx->outputs[k]; + if (txfilter_scriptpubkey_matches(filter, txout->script)) { struct amount_sat amount; struct bitcoin_outpoint outpoint; outpoint.txid = txid; outpoint.n = k; bitcoin_tx_output_get_amount_sat(tx, k, &amount); - invoice_check_onchain_payment(topo->ld, oscript, amount, &outpoint); + invoice_check_onchain_payment(topo->ld, txout->script, amount, &outpoint); } } diff --git a/lightningd/closing_control.c b/lightningd/closing_control.c index 5d9bd74ae..2ac534109 100644 --- a/lightningd/closing_control.c +++ b/lightningd/closing_control.c @@ -179,19 +179,15 @@ static struct amount_sat calc_tx_fee(struct amount_sat sat_in, { struct amount_asset amt; struct amount_sat fee = sat_in; - const u8 *oscript; - size_t scriptlen; - for (size_t i = 0; i < tx->wtx->num_outputs; i++) { - amt = bitcoin_tx_output_get_amount(tx, i); - oscript = bitcoin_tx_output_get_script(NULL, tx, i); - scriptlen = tal_bytelen(oscript); - tal_free(oscript); - if (chainparams->is_elements && scriptlen == 0) + for (size_t i = 0; i < tx->wtx->num_outputs; i++) { + const struct wally_tx_output *txout = &tx->wtx->outputs[i]; + if (chainparams->is_elements && !txout->script_len) continue; /* Ignore outputs that are not denominated in our main * currency. */ + amt = bitcoin_tx_output_get_amount(tx, i); if (!amount_asset_is_main(&amt)) continue; diff --git a/wallet/txfilter.c b/wallet/txfilter.c index f5dd83868..b7c4eaa2e 100644 --- a/wallet/txfilter.c +++ b/wallet/txfilter.c @@ -84,12 +84,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 < tx->wtx->num_outputs; i++) { - const u8 *oscript = bitcoin_tx_output_get_script(tmpctx, tx, i); - - if (!oscript) - continue; - - if (scriptpubkeyset_get(&filter->scriptpubkeyset, oscript)) + const struct wally_tx_output *txout = &tx->wtx->outputs[i]; + if (txfilter_scriptpubkey_matches(filter, txout->script)) return true; } return false; @@ -97,6 +93,8 @@ bool txfilter_match(const struct txfilter *filter, const struct bitcoin_tx *tx) bool txfilter_scriptpubkey_matches(const struct txfilter *filter, const u8 *scriptPubKey) { + if (!scriptPubKey) + return false; return scriptpubkeyset_get(&filter->scriptpubkeyset, scriptPubKey) != NULL; }