script: consistently take the script length in identification functions

Standardizes the is_xxx script function all take a script length, and changes
their first-level callers to pass it. This has several knock on benefits:

- We remove the repeated tal_count/tal_bytelen calls on the script, in
  particular the redundant calls that result when we must check for multiple
  types of script - which is almost all cases.
- We remove the dependency on the memory being tal-allocated (It is, in
  all cases, but theres no reason we need to require that).
- We remove all cases where we create a copy of the script just to id it.
- We remove all allocations for non-interesting scripts while iterating block
  txs in process_getfilteredblock_step1().
- We remove all allocations *including for potentially interesting scripts* in
  topo_add_utxos().

Signed-off-by: Jon Griffiths <jon_p_griffiths@yahoo.com>
This commit is contained in:
Jon Griffiths 2024-02-22 10:03:07 +13:00 committed by Rusty Russell
parent 5dee5ce178
commit aa23c2a2b2
20 changed files with 128 additions and 115 deletions

View File

@ -476,10 +476,8 @@ u8 *p2wpkh_scriptcode(const tal_t *ctx, const struct pubkey *key)
return script;
}
bool is_p2pkh(const u8 *script, struct bitcoin_address *addr)
bool is_p2pkh(const u8 *script, size_t script_len, struct bitcoin_address *addr)
{
size_t script_len = tal_count(script);
if (script_len != BITCOIN_SCRIPTPUBKEY_P2PKH_LEN)
return false;
if (script[0] != OP_DUP)
@ -497,10 +495,8 @@ bool is_p2pkh(const u8 *script, struct bitcoin_address *addr)
return true;
}
bool is_p2sh(const u8 *script, struct ripemd160 *addr)
bool is_p2sh(const u8 *script, size_t script_len, struct ripemd160 *addr)
{
size_t script_len = tal_count(script);
if (script_len != BITCOIN_SCRIPTPUBKEY_P2SH_LEN)
return false;
if (script[0] != OP_HASH160)
@ -514,10 +510,8 @@ bool is_p2sh(const u8 *script, struct ripemd160 *addr)
return true;
}
bool is_p2wsh(const u8 *script, struct sha256 *addr)
bool is_p2wsh(const u8 *script, size_t script_len, struct sha256 *addr)
{
size_t script_len = tal_count(script);
if (script_len != BITCOIN_SCRIPTPUBKEY_P2WSH_LEN)
return false;
if (script[0] != OP_0)
@ -529,10 +523,8 @@ bool is_p2wsh(const u8 *script, struct sha256 *addr)
return true;
}
bool is_p2wpkh(const u8 *script, struct bitcoin_address *addr)
bool is_p2wpkh(const u8 *script, size_t script_len, struct bitcoin_address *addr)
{
size_t script_len = tal_count(script);
if (script_len != BITCOIN_SCRIPTPUBKEY_P2WPKH_LEN)
return false;
if (script[0] != OP_0)
@ -544,10 +536,8 @@ bool is_p2wpkh(const u8 *script, struct bitcoin_address *addr)
return true;
}
bool is_p2tr(const u8 *script, u8 xonly_pubkey[32])
bool is_p2tr(const u8 *script, size_t script_len, u8 xonly_pubkey[32])
{
size_t script_len = tal_count(script);
if (script_len != BITCOIN_SCRIPTPUBKEY_P2TR_LEN)
return false;
if (script[0] != OP_1)
@ -560,17 +550,20 @@ bool is_p2tr(const u8 *script, u8 xonly_pubkey[32])
return true;
}
bool is_known_scripttype(const u8 *script)
bool is_known_scripttype(const u8 *script, size_t script_len)
{
return is_p2wpkh(script, NULL) || is_p2wsh(script, NULL)
|| is_p2sh(script, NULL) || is_p2pkh(script, NULL)
|| is_p2tr(script, NULL);
return is_p2wpkh(script, script_len, NULL)
|| is_p2wsh(script, script_len, NULL)
|| is_p2sh(script, script_len, NULL)
|| is_p2pkh(script, script_len, NULL)
|| is_p2tr(script, script_len, NULL);
}
bool is_known_segwit_scripttype(const u8 *script)
bool is_known_segwit_scripttype(const u8 *script, size_t script_len)
{
return is_p2wpkh(script, NULL) || is_p2wsh(script, NULL)
|| is_p2tr(script, NULL);
return is_p2wpkh(script, script_len, NULL)
|| is_p2wsh(script, script_len, NULL)
|| is_p2tr(script, script_len, NULL);
}
u8 **bitcoin_witness_sig_and_element(const tal_t *ctx,

View File

@ -159,25 +159,25 @@ u8 *bitcoin_wscript_anchor(const tal_t *ctx,
const struct pubkey *funding_pubkey);
/* Is this a pay to pubkey hash? (extract addr if not NULL) */
bool is_p2pkh(const u8 *script, struct bitcoin_address *addr);
bool is_p2pkh(const u8 *script, size_t script_len, struct bitcoin_address *addr);
/* Is this a pay to script hash? (extract addr if not NULL) */
bool is_p2sh(const u8 *script, struct ripemd160 *addr);
bool is_p2sh(const u8 *script, size_t script_len, struct ripemd160 *addr);
/* Is this (version 0) pay to witness script hash? (extract addr if not NULL) */
bool is_p2wsh(const u8 *script, struct sha256 *addr);
bool is_p2wsh(const u8 *script, size_t script_len, struct sha256 *addr);
/* Is this (version 0) pay to witness pubkey hash? (extract addr if not NULL) */
bool is_p2wpkh(const u8 *script, struct bitcoin_address *addr);
bool is_p2wpkh(const u8 *script, size_t script_len, struct bitcoin_address *addr);
/* Is this a taproot output? (extract xonly_pubkey bytes if not NULL) */
bool is_p2tr(const u8 *script, u8 xonly_pubkey[32]);
bool is_p2tr(const u8 *script, size_t script_len, u8 xonly_pubkey[32]);
/* Is this one of the above script types? */
bool is_known_scripttype(const u8 *script);
bool is_known_scripttype(const u8 *script, size_t script_len);
/* Is this a witness script type? */
bool is_known_segwit_scripttype(const u8 *script);
bool is_known_segwit_scripttype(const u8 *script, size_t script_len);
/* Is this a to-remote witness script (used for option_anchor_outputs)? */
bool is_to_remote_anchored_witness_script(const u8 *script, size_t script_len);

View File

@ -80,8 +80,12 @@ penalty_tx_create(const tal_t *ctx,
bitcoin_tx_add_output(tx, final_scriptpubkey, NULL, to_them_sats);
assert((final_index == NULL) == (final_ext_key == NULL));
if (final_index)
psbt_add_keypath_to_last_output(tx, *final_index, final_ext_key, is_p2tr(final_scriptpubkey, NULL));
if (final_index) {
size_t script_len = tal_bytelen(final_scriptpubkey);
bool is_tr = is_p2tr(final_scriptpubkey, script_len, NULL);
psbt_add_keypath_to_last_output(tx, *final_index,
final_ext_key, is_tr);
}
/* Worst-case sig is 73 bytes */
weight = bitcoin_tx_weight(tx) + 1 + 3 + 73 + 0 + tal_count(wscript);

View File

@ -7,30 +7,31 @@
char *encode_scriptpubkey_to_addr(const tal_t *ctx,
const struct chainparams *chainparams,
const u8 *scriptPubkey)
const u8 *scriptpubkey)
{
char *out;
size_t scriptLen = tal_bytelen(scriptPubkey);
const size_t script_len = tal_bytelen(scriptpubkey);
struct bitcoin_address pkh;
struct ripemd160 sh;
int witver;
if (is_p2pkh(scriptPubkey, &pkh))
if (is_p2pkh(scriptpubkey, script_len, &pkh))
return bitcoin_to_base58(ctx, chainparams, &pkh);
if (is_p2sh(scriptPubkey, &sh))
if (is_p2sh(scriptpubkey, script_len, &sh))
return p2sh_to_base58(ctx, chainparams, &sh);
out = tal_arr(ctx, char, 73 + strlen(chainparams->onchain_hrp));
if (is_p2tr(scriptPubkey, NULL))
if (is_p2tr(scriptpubkey, script_len, NULL))
witver = 1;
else if (is_p2wpkh(scriptPubkey, NULL) || is_p2wsh(scriptPubkey, NULL))
else if (is_p2wpkh(scriptpubkey, script_len, NULL)
|| is_p2wsh(scriptpubkey, script_len, NULL))
witver = 0;
else {
return tal_free(out);
}
if (!segwit_addr_encode(out, chainparams->onchain_hrp, witver,
scriptPubkey + 2, scriptLen - 2))
scriptpubkey + 2, script_len - 2))
return tal_free(out);
return out;

View File

@ -6,6 +6,6 @@
/* Given a scriptPubkey, return an encoded address for p2pkh/p2w{pkh,sh}/p2tr */
char *encode_scriptpubkey_to_addr(const tal_t *ctx,
const struct chainparams *chainparams,
const u8 *scriptPubkey);
const u8 *scriptpubkey);
#endif /* LIGHTNING_COMMON_ADDR_H */

View File

@ -1133,6 +1133,7 @@ static void encode_f(u5 **data, const u8 *fallback)
struct bitcoin_address pkh;
struct ripemd160 sh;
struct sha256 wsh;
const size_t fallback_len = tal_bytelen(fallback);
/* BOLT #11:
*
@ -1140,15 +1141,15 @@ static void encode_f(u5 **data, const u8 *fallback)
* witness version and program, OR to `17` followed by a
* public key hash, OR to `18` followed by a script hash.
*/
if (is_p2pkh(fallback, &pkh)) {
if (is_p2pkh(fallback, fallback_len, &pkh)) {
push_fallback_addr(data, 17, &pkh, sizeof(pkh));
} else if (is_p2sh(fallback, &sh)) {
} else if (is_p2sh(fallback, fallback_len, &sh)) {
push_fallback_addr(data, 18, &sh, sizeof(sh));
} else if (is_p2wpkh(fallback, &pkh)) {
} else if (is_p2wpkh(fallback, fallback_len, &pkh)) {
push_fallback_addr(data, 0, &pkh, sizeof(pkh));
} else if (is_p2wsh(fallback, &wsh)) {
} else if (is_p2wsh(fallback, fallback_len, &wsh)) {
push_fallback_addr(data, 0, &wsh, sizeof(wsh));
} else if (tal_count(fallback) > 1
} else if (fallback_len > 1
&& fallback[0] >= 0x50
&& fallback[0] < (0x50+16)) {
/* Other (future) witness versions: turn OP_N into N */
@ -1157,7 +1158,7 @@ static void encode_f(u5 **data, const u8 *fallback)
} else {
/* Copy raw. */
push_field(data, 'f',
fallback, tal_count(fallback) * CHAR_BIT);
fallback, fallback_len * CHAR_BIT);
}
}

View File

@ -15,17 +15,18 @@ static void json_add_fallback(struct json_stream *response,
const struct chainparams *chain)
{
char *addr;
const size_t fallback_len = tal_bytelen(fallback);
json_object_start(response, fieldname);
if (is_p2pkh(fallback, NULL)) {
if (is_p2pkh(fallback, fallback_len, NULL)) {
json_add_string(response, "type", "P2PKH");
} else if (is_p2sh(fallback, NULL)) {
} else if (is_p2sh(fallback, fallback_len, NULL)) {
json_add_string(response, "type", "P2SH");
} else if (is_p2wpkh(fallback, NULL)) {
} else if (is_p2wpkh(fallback, fallback_len, NULL)) {
json_add_string(response, "type", "P2WPKH");
} else if (is_p2wsh(fallback, NULL)) {
} else if (is_p2wsh(fallback, fallback_len, NULL)) {
json_add_string(response, "type", "P2WSH");
} else if (is_p2tr(fallback, NULL)) {
} else if (is_p2tr(fallback, fallback_len, NULL)) {
json_add_string(response, "type", "P2TR");
}

View File

@ -50,9 +50,12 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx,
/* One output is to us. */
bitcoin_tx_add_output(tx, script, NULL, to_us);
assert((local_wallet_index == NULL) == (local_wallet_ext_key == NULL));
if (local_wallet_index)
if (local_wallet_index) {
size_t script_len = tal_bytelen(script);
psbt_add_keypath_to_last_output(
tx, *local_wallet_index, local_wallet_ext_key, is_p2tr(script, NULL));
tx, *local_wallet_index, local_wallet_ext_key,
is_p2tr(script, script_len, NULL));
}
num_outputs++;
}

View File

@ -80,13 +80,15 @@ static bool is_segwit_output(const tal_t *ctx,
struct wally_tx_output *output,
const u8 *redeemscript)
{
const u8 *maybe_witness;
if (tal_bytelen(redeemscript) > 0)
maybe_witness = redeemscript;
else
maybe_witness = cln_wally_tx_output_get_script(ctx, output);
const u8 *maybe_witness = redeemscript;
size_t script_len = tal_bytelen(maybe_witness);
return is_known_segwit_scripttype(maybe_witness);
if (!script_len) {
maybe_witness = output->script;
script_len = output->script_len;
}
return is_known_segwit_scripttype(maybe_witness, script_len);
}
/* Return first non-handled message or NULL if connection is aborted */
@ -627,7 +629,7 @@ char *process_interactivetx_updates(const tal_t *ctx,
* The receiving node: ...
* - MAY fail the negotiation if `script`
* is non-standard */
if (!is_known_scripttype(scriptpubkey))
if (!is_known_scripttype(scriptpubkey, tal_bytelen(scriptpubkey)))
return tal_fmt(ctx, "Script is not standard");
/*

View File

@ -382,6 +382,7 @@ bool psbt_has_required_fields(struct wally_psbt *psbt)
u64 serial_id;
for (size_t i = 0; i < psbt->num_inputs; i++) {
const struct wally_map_item *redeem_script;
const struct wally_tx_output *txout;
struct wally_psbt_input *input = &psbt->inputs[i];
if (!psbt_get_serial_id(&input->unknowns, &serial_id))
@ -391,13 +392,14 @@ bool psbt_has_required_fields(struct wally_psbt *psbt)
if (!input->utxo)
return false;
/* If is P2SH, redeemscript must be present */
assert(psbt->inputs[i].index < input->utxo->num_outputs);
const u8 *outscript =
cln_wally_tx_output_get_script(tmpctx,
&input->utxo->outputs[psbt->inputs[i].index]);
redeem_script = wally_map_get_integer(&psbt->inputs[i].psbt_fields, /* PSBT_IN_REDEEM_SCRIPT */ 0x04);
if (is_p2sh(outscript, NULL) && (!redeem_script || redeem_script->value_len == 0))
assert(input->index < input->utxo->num_outputs);
txout = &input->utxo->outputs[input->index];
if (!is_p2sh(txout->script, txout->script_len, NULL))
continue;
/* P2SH: redeemscript must be present */
const u32 key = 0x04; /* PSBT_IN_REDEEM_SCRIPT */
redeem_script = wally_map_get_integer(&input->psbt_fields, key);
if (!redeem_script || !redeem_script->value_len)
return false;
}

View File

@ -8,11 +8,11 @@
* push of 2 to 40 bytes
* (witness program versions 1 through 16)
*/
static bool is_valid_witnessprog(const u8 *scriptpubkey)
static bool is_valid_witnessprog(const u8 *scriptpubkey, size_t scriptpubkey_len)
{
size_t pushlen;
if (tal_bytelen(scriptpubkey) < 2)
if (scriptpubkey_len < 2)
return false;
switch (scriptpubkey[0]) {
@ -39,7 +39,7 @@ static bool is_valid_witnessprog(const u8 *scriptpubkey)
pushlen = scriptpubkey[1];
/* Must be all of the rest of scriptpubkey */
if (2 + pushlen != tal_bytelen(scriptpubkey)) {
if (2 + pushlen != scriptpubkey_len) {
return false;
}
@ -50,13 +50,14 @@ bool valid_shutdown_scriptpubkey(const u8 *scriptpubkey,
bool anysegwit,
bool allow_oldstyle)
{
const size_t script_len = tal_bytelen(scriptpubkey);
if (allow_oldstyle) {
if (is_p2pkh(scriptpubkey, NULL)
|| is_p2sh(scriptpubkey, NULL))
if (is_p2pkh(scriptpubkey, script_len, NULL)
|| is_p2sh(scriptpubkey, script_len, NULL))
return true;
}
return is_p2wpkh(scriptpubkey, NULL)
|| is_p2wsh(scriptpubkey, NULL)
|| (anysegwit && is_valid_witnessprog(scriptpubkey));
return is_p2wpkh(scriptpubkey, script_len, NULL)
|| is_p2wsh(scriptpubkey, script_len, NULL)
|| (anysegwit && is_valid_witnessprog(scriptpubkey, script_len));
}

View File

@ -123,23 +123,25 @@ int main(int argc, char *argv[])
struct bitcoin_address pkh;
struct ripemd160 sh;
struct sha256 wsh;
const u8 *fallback = b11->fallbacks[i];
const size_t fallback_len = tal_bytelen(fallback);
printf("fallback: %s\n", tal_hex(ctx, b11->fallbacks[i]));
if (is_p2pkh(b11->fallbacks[i], &pkh)) {
printf("fallback: %s\n", tal_hex(ctx, fallback));
if (is_p2pkh(fallback, fallback_len, &pkh)) {
printf("fallback-P2PKH: %s\n",
bitcoin_to_base58(ctx, b11->chain,
&pkh));
} else if (is_p2sh(b11->fallbacks[i], &sh)) {
} else if (is_p2sh(fallback, fallback_len, &sh)) {
printf("fallback-P2SH: %s\n",
p2sh_to_base58(ctx,
b11->chain,
&sh));
} else if (is_p2wpkh(b11->fallbacks[i], &pkh)) {
} else if (is_p2wpkh(fallback, fallback_len, &pkh)) {
char out[73 + strlen(b11->chain->onchain_hrp)];
if (segwit_addr_encode(out, b11->chain->onchain_hrp, 0,
(const u8 *)&pkh, sizeof(pkh)))
printf("fallback-P2WPKH: %s\n", out);
} else if (is_p2wsh(b11->fallbacks[i], &wsh)) {
} else if (is_p2wsh(fallback, fallback_len, &wsh)) {
char out[73 + strlen(b11->chain->onchain_hrp)];
if (segwit_addr_encode(out, b11->chain->onchain_hrp, 0,
(const u8 *)&wsh, sizeof(wsh)))

View File

@ -547,7 +547,9 @@ static void sign_our_inputs(struct utxo **utxos, struct wally_psbt *psbt)
* requires the HSM to find the pubkey, and we
* skip doing that until now as a bit of a reduction
* of complexity in the calling code */
psbt_input_add_pubkey(psbt, j, &pubkey, utxo->scriptPubkey && is_p2tr(utxo->scriptPubkey, NULL));
const size_t script_len = tal_bytelen(utxo->scriptPubkey);
psbt_input_add_pubkey(psbt, j, &pubkey,
is_p2tr(utxo->scriptPubkey, script_len, NULL));
/* It's actually a P2WSH in this case. */
if (utxo->close_info && utxo->close_info->option_anchors) {

View File

@ -756,19 +756,22 @@ static void process_getfilteredblock_step1(struct bitcoind *bitcoind,
for (size_t i = 0; i < tal_count(block->tx); i++) {
tx = block->tx[i];
for (size_t j = 0; j < tx->wtx->num_outputs; j++) {
const u8 *script = bitcoin_tx_output_get_script(NULL, tx, j);
struct amount_asset amount = bitcoin_tx_output_get_amount(tx, j);
if (amount_asset_is_main(&amount) && is_p2wsh(script, NULL)) {
const struct wally_tx_output *output;
output = &tx->wtx->outputs[j];
if (!is_p2wsh(output->script, output->script_len, NULL))
continue;
struct amount_asset amount = wally_tx_output_get_amount(output);
if (amount_asset_is_main(&amount)) {
/* This is an interesting output, remember it. */
o = tal(call->outpoints, struct filteredblock_outpoint);
bitcoin_txid(tx, &o->outpoint.txid);
o->outpoint.n = j;
o->amount = amount_asset_to_sat(&amount);
o->txindex = i;
o->scriptPubKey = tal_steal(o, script);
o->scriptPubKey = tal_dup_arr(o, u8, output->script, output->script_len, 0);
tal_arr_expand(&call->outpoints, o);
} else {
tal_free(script);
}
}
}

View File

@ -956,22 +956,21 @@ static void topo_add_utxos(struct chain_topology *topo, struct block *b)
for (size_t i = 0; i < num_txs; i++) {
const struct bitcoin_tx *tx = b->full_txs[i];
for (size_t n = 0; n < tx->wtx->num_outputs; n++) {
if (tx->wtx->outputs[n].features & skip_features)
const struct wally_tx_output *output;
output = &tx->wtx->outputs[n];
if (output->features & skip_features)
continue;
if (tx->wtx->outputs[n].script_len != BITCOIN_SCRIPTPUBKEY_P2WSH_LEN)
continue; /* Cannot possibly be a p2wsh utxo */
if (!is_p2wsh(output->script, output->script_len, NULL))
continue; /* We only care about p2wsh utxos */
struct amount_asset amt = bitcoin_tx_output_get_amount(tx, n);
if (!amount_asset_is_main(&amt))
continue; /* Ignore non-policy asset outputs */
const u8 *script = bitcoin_tx_output_get_script(tmpctx, tx, n);
if (!is_p2wsh(script, NULL))
continue; /* We only care about p2wsh utxos */
struct bitcoin_outpoint outpoint = { b->txids[i], n };
wallet_utxoset_add(topo->ld->wallet, &outpoint,
b->height, i, script,
b->height, i,
output->script, output->script_len,
amount_asset_to_sat(&amt));
}
}

View File

@ -2050,10 +2050,9 @@ static const size_t *match_htlc_output(const tal_t *ctx,
u8 **htlc_scripts)
{
size_t *matches = tal_arr(ctx, size_t, 0);
const u8 *script = tal_dup_arr(tmpctx, u8, out->script, out->script_len,
0);
/* Must be a p2wsh output */
if (!is_p2wsh(script, NULL))
if (!is_p2wsh(out->script, out->script_len, NULL))
return matches;
for (size_t i = 0; i < tal_count(htlc_scripts); i++) {
@ -2062,7 +2061,7 @@ static const size_t *match_htlc_output(const tal_t *ctx,
continue;
sha256(&sha, htlc_scripts[i], tal_count(htlc_scripts[i]));
if (memeq(script + 2, tal_count(script) - 2, &sha, sizeof(sha)))
if (memeq(out->script + 2, out->script_len - 2, &sha, sizeof(sha)))
tal_arr_expand(&matches, i);
}
return matches;

View File

@ -993,8 +993,7 @@ static char *check_balances(const tal_t *ctx,
static bool is_segwit_output(struct wally_tx_output *output)
{
const u8 *script = cln_wally_tx_output_get_script(tmpctx, output);
return is_known_segwit_scripttype(script);
return is_known_segwit_scripttype(output->script, output->script_len);
}
static void set_remote_upfront_shutdown(struct state *state,
@ -1973,7 +1972,7 @@ static bool run_tx_interactive(struct state *state,
* The receiving node: ...
* - MAY fail the negotiation if `script`
* is non-standard */
if (!is_known_scripttype(scriptpubkey)) {
if (!is_known_scripttype(scriptpubkey, tal_bytelen(scriptpubkey))) {
open_abort(state, "Script is not standard");
return false;
}

View File

@ -799,14 +799,15 @@ bool wallet_can_spend(struct wallet *w, const u8 *script,
{
struct ext_key ext;
u64 bip32_max_index = db_get_intvar(w->db, "bip32_max_index", 0);
size_t script_len = tal_bytelen(script);
u32 i;
/* If not one of these, can't be for us. */
if (is_p2sh(script, NULL))
if (is_p2sh(script, script_len, NULL))
*output_is_p2sh = true;
else if (is_p2wpkh(script, NULL))
else if (is_p2wpkh(script, script_len, NULL))
*output_is_p2sh = false;
else if (is_p2tr(script, NULL))
else if (is_p2tr(script, script_len, NULL))
*output_is_p2sh = false;
else
return false;
@ -4353,8 +4354,8 @@ bool wallet_outpoint_spend(struct wallet *w, const tal_t *ctx, const u32 blockhe
void wallet_utxoset_add(struct wallet *w,
const struct bitcoin_outpoint *outpoint,
const u32 blockheight,
const u32 txindex, const u8 *scriptpubkey,
const u32 blockheight, const u32 txindex,
const u8 *scriptpubkey, size_t scriptpubkey_len,
struct amount_sat sat)
{
struct db_stmt *stmt;
@ -4373,7 +4374,7 @@ void wallet_utxoset_add(struct wallet *w,
db_bind_int(stmt, blockheight);
db_bind_null(stmt);
db_bind_int(stmt, txindex);
db_bind_talarr(stmt, scriptpubkey);
db_bind_blob(stmt, scriptpubkey, scriptpubkey_len);
db_bind_amount_sat(stmt, &sat);
db_exec_prepared_v2(take(stmt));

View File

@ -1146,8 +1146,8 @@ struct outpoint *wallet_outpoint_for_scid(struct wallet *w, tal_t *ctx,
void wallet_utxoset_add(struct wallet *w,
const struct bitcoin_outpoint *outpoint,
const u32 blockheight,
const u32 txindex, const u8 *scriptpubkey,
const u32 blockheight, const u32 txindex,
const u8 *scriptpubkey, size_t scriptpubkey_len,
struct amount_sat sat);
/**

View File

@ -660,14 +660,13 @@ static void match_psbt_outputs_to_wallet(struct wally_psbt *psbt,
{
tal_wally_start();
for (size_t outndx = 0; outndx < psbt->num_outputs; ++outndx) {
struct ext_key ext;
const u8 *script = psbt->outputs[outndx].script;
const size_t script_len = psbt->outputs[outndx].script_len;
u32 index;
bool is_p2sh;
const u8 *script;
struct ext_key ext;
script = wally_psbt_output_get_script(tmpctx,
&psbt->outputs[outndx]);
if (!script)
if (!script_len)
continue;
if (!wallet_can_spend(w, script, &index, &is_p2sh))
@ -678,7 +677,8 @@ static void match_psbt_outputs_to_wallet(struct wally_psbt *psbt,
abort();
}
psbt_output_set_keypath(index, &ext, is_p2tr(script, NULL),
psbt_output_set_keypath(index, &ext,
is_p2tr(script, script_len, NULL),
&psbt->outputs[outndx]);
}
tal_wally_end(psbt);