core-lightning/bitcoin/script.h
Christian Decker c329756723 core: Add a function check if a script is P2WSH without allocating
Processing blocks is rather slow at the moment, but one thing we can
do, is to prevent copying all output scripts, when really all we are
interested in are the couple of outputs that are P2WSH.

This builds the foundation of that by adding a method to introspect
the script without having to clone it first, saving us some
allocations, and deallocations.

Changelog-Changed: core: Processing blocks should now be faster
2024-02-21 11:59:31 +01:00

212 lines
8 KiB
C

#ifndef LIGHTNING_BITCOIN_SCRIPT_H
#define LIGHTNING_BITCOIN_SCRIPT_H
#include "config.h"
#include "signature.h"
#include "tx.h"
#include <wally_script.h>
struct bitcoin_address;
struct preimage;
struct pubkey;
struct sha256;
struct ripemd160;
struct rel_locktime;
struct abs_locktime;
/* To push 0-75 bytes onto stack. */
#define OP_PUSHBYTES(val) (val)
/* tal_count() gives the length of the script. */
u8 *bitcoin_redeem_2of2(const tal_t *ctx,
const struct pubkey *key1,
const struct pubkey *key2);
/* Create an output script using p2sh for this redeem script. */
u8 *scriptpubkey_p2sh(const tal_t *ctx, const u8 *redeemscript);
/* Create an output script using p2sh for this hash. */
u8 *scriptpubkey_p2sh_hash(const tal_t *ctx, const struct ripemd160 *redeemhash);
/* Create an output script using p2pkh */
u8 *scriptpubkey_p2pkh(const tal_t *ctx, const struct bitcoin_address *addr);
/* Create a prunable output script with 20 random bytes.
* This is needed since a spend from a p2wpkh to an `OP_RETURN` without
* any other outputs would result in a transaction smaller than the
* minimum size. */
u8 *scriptpubkey_opreturn_padded(const tal_t *ctx);
/* Create an input script which spends p2pkh */
u8 *bitcoin_redeem_p2pkh(const tal_t *ctx, const struct pubkey *pubkey,
const struct bitcoin_signature *sig);
/* Create the redeemscript for a P2SH + P2WPKH. */
u8 *bitcoin_redeem_p2sh_p2wpkh(const tal_t *ctx, const struct pubkey *key);
/* Create the scriptsig for a redeemscript */
u8 *bitcoin_scriptsig_redeem(const tal_t *ctx,
const u8 *redeemscript TAKES);
/* Create scriptsig for p2sh-p2wpkh */
u8 *bitcoin_scriptsig_p2sh_p2wpkh(const tal_t *ctx, const struct pubkey *key);
/* Create scriptcode (fake witness, basically) for P2WPKH */
u8 *p2wpkh_scriptcode(const tal_t *ctx, const struct pubkey *key);
/* Create an output script for a 32-byte witness program. */
u8 *scriptpubkey_p2wsh(const tal_t *ctx, const u8 *witnessscript);
/* Create an output script for a 20-byte witness program. */
u8 *scriptpubkey_p2wpkh(const tal_t *ctx, const struct pubkey *key);
/* Same as above, but compressed key is already DER-encoded. */
u8 *scriptpubkey_p2wpkh_derkey(const tal_t *ctx, const u8 der[33]);
/* Encode an arbitrary witness as <version> <push:wprog> */
u8 *scriptpubkey_witness_raw(const tal_t *ctx, u8 version,
const u8 *wprog, size_t wprog_size);
/* Create an output script for a "raw"(perhaps already tweaked) taproot output pubkey */
u8 *scriptpubkey_raw_p2tr(const tal_t *ctx, const struct pubkey *output_pubkey);
/* Same as above, but compressed key is DER-encoded. */
u8 *scriptpubkey_raw_p2tr_derkey(const tal_t *ctx, const u8 output_der[33]);
/* Create an output script for an internal taproot pubkey. Results in different script than
* scriptpubkey_raw_p2tr! TODO support merkle root tweaking */
u8 *scriptpubkey_p2tr(const tal_t *ctx, const struct pubkey *inner_pubkey);
/* Same as above, but compressed key is DER-encoded. TODO support merkle root tweaking */
u8 *scriptpubkey_p2tr_derkey(const tal_t *ctx, const u8 inner_der[33]);
/* To-remotekey with csv max(lease_expiry - blockheight, 1) delay. */
u8 *bitcoin_wscript_to_remote_anchored(const tal_t *ctx,
const struct pubkey *remote_key,
u32 csv_lock);
/* Create a witness which spends the 2of2. */
u8 **bitcoin_witness_2of2(const tal_t *ctx,
const struct bitcoin_signature *sig1,
const struct bitcoin_signature *sig2,
const struct pubkey *key1,
const struct pubkey *key2);
/* Create a witness which spends a p2wpkh. */
u8 **bitcoin_witness_p2wpkh(const tal_t *ctx,
const struct bitcoin_signature *sig,
const struct pubkey *key);
/* Create a witness which contains sig, another entry, and the witnessscript */
u8 **bitcoin_witness_sig_and_element(const tal_t *ctx,
const struct bitcoin_signature *sig,
const void *elem, size_t elemsize,
const u8 *witnessscript);
/* BOLT #3 to-local output */
u8 *bitcoin_wscript_to_local(const tal_t *ctx, u16 to_self_delay,
u32 lease_remaining,
const struct pubkey *revocation_pubkey,
const struct pubkey *local_delayedkey);
/* BOLT #3 offered/accepted HTLC outputs */
u8 *bitcoin_wscript_htlc_offer(const tal_t *ctx,
const struct pubkey *localhtlckey,
const struct pubkey *remotehtlckey,
const struct sha256 *payment_hash,
const struct pubkey *revocationkey,
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
u8 **bitcoin_witness_htlc_timeout_tx(const tal_t *ctx,
const struct bitcoin_signature *localsig,
const struct bitcoin_signature *remotesig,
const u8 *wscript);
u8 *bitcoin_wscript_htlc_receive(const tal_t *ctx,
const struct abs_locktime *htlc_abstimeout,
const struct pubkey *localkey,
const struct pubkey *remotekey,
const struct sha256 *payment_hash,
const struct pubkey *revocationkey,
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
u8 **bitcoin_witness_htlc_success_tx(const tal_t *ctx,
const struct bitcoin_signature *localsig,
const struct bitcoin_signature *remotesig,
const struct preimage *preimage,
const u8 *wscript);
/* Underlying functions for penalties, where we only keep ripemd160 */
u8 *bitcoin_wscript_htlc_offer_ripemd160(const tal_t *ctx,
const struct pubkey *localhtlckey,
const struct pubkey *remotehtlckey,
const struct ripemd160 *payment_ripemd,
const struct pubkey *revocationkey,
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
u8 *bitcoin_wscript_htlc_receive_ripemd(const tal_t *ctx,
const struct abs_locktime *htlc_abstimeout,
const struct pubkey *localkey,
const struct pubkey *remotekey,
const struct ripemd160 *payment_ripemd,
const struct pubkey *revocationkey,
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
/* BOLT #3 HTLC-success/HTLC-timeout output */
u8 *bitcoin_wscript_htlc_tx(const tal_t *ctx,
u16 to_self_delay,
const struct pubkey *revocation_pubkey,
const struct pubkey *local_delayedkey);
/* Anchor outputs */
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);
/* Is this a pay to script hash? (extract addr if not NULL) */
bool is_p2sh(const u8 *script, 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);
/* Is this (version 0) pay to witness pubkey hash? (extract addr if not NULL) */
bool is_p2wpkh(const u8 *script, 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]);
/* Is this one of the above script types? */
bool is_known_scripttype(const u8 *script);
/* Is this a witness script type? */
bool is_known_segwit_scripttype(const u8 *script);
/* 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);
/* Is this an anchor witness script? */
bool is_anchor_witness_script(const u8 *script, size_t script_len);
/* Are these two scripts equal? */
bool scripteq(const u8 *s1, const u8 *s2);
/* Raw "push these bytes" accessor. */
void script_push_bytes(u8 **scriptp, const void *mem, size_t len);
/* OP_DUP + OP_HASH160 + PUSH(20-byte-hash) + OP_EQUALVERIFY + OP_CHECKSIG */
#define BITCOIN_SCRIPTPUBKEY_P2PKH_LEN (1 + 1 + 1 + 20 + 1 + 1)
/* OP_HASH160 + PUSH(20-byte-hash) + OP_EQUAL */
#define BITCOIN_SCRIPTPUBKEY_P2SH_LEN (1 + 1 + 20 + 1)
/* OP_0 + PUSH(20-byte-hash) */
#define BITCOIN_SCRIPTPUBKEY_P2WPKH_LEN (1 + 1 + 20)
/* OP_0 + PUSH(32-byte-hash) */
#define BITCOIN_SCRIPTPUBKEY_P2WSH_LEN (1 + 1 + 32)
/* OP_1 + PUSH(32-byte-key) */
#define BITCOIN_SCRIPTPUBKEY_P2TR_LEN (1 + 1 + 32)
#endif /* LIGHTNING_BITCOIN_SCRIPT_H */