From 2dc86b90a4bc0ec20cf4f59bddda6bccda429ece Mon Sep 17 00:00:00 2001 From: libbitc Date: Sun, 23 Jul 2017 02:44:04 +0000 Subject: [PATCH 1/3] ccoin: Implement SegWit in script functionality and tests --- external/secp256k1 | 2 +- include/ccoin/buffer.h | 3 +- include/ccoin/core.h | 20 +- include/ccoin/script.h | 121 +++++- lib/Makefile.am | 2 +- lib/script.c | 73 +++- lib/script_eval.c | 658 +++++++++++++++++++++--------- lib/script_names.c | 4 +- lib/script_sign.c | 4 +- src/brd.c | 8 +- test/Makefile.am | 2 +- test/base58.c | 8 +- test/chain-verf.c | 40 +- test/data/script_tests.json | 792 +++++++++++++++++++++++++++++++++++- test/script.c | 229 ++++++----- test/sighash.c | 12 +- test/tx-valid.c | 7 +- 17 files changed, 1612 insertions(+), 373 deletions(-) diff --git a/external/secp256k1 b/external/secp256k1 index c5b32e16..f532bdc9 160000 --- a/external/secp256k1 +++ b/external/secp256k1 @@ -1 +1 @@ -Subproject commit c5b32e16c4d2560ce829caf88a413fc06fd83d09 +Subproject commit f532bdc9f77f7bbf7e93faabfbe9c483f0a9f75f diff --git a/include/ccoin/buffer.h b/include/ccoin/buffer.h index 33791ba9..62056ab5 100644 --- a/include/ccoin/buffer.h +++ b/include/ccoin/buffer.h @@ -5,7 +5,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php. */ -#include +#include // for bool +#include // for size_t #ifdef __cplusplus extern "C" { diff --git a/include/ccoin/core.h b/include/ccoin/core.h index 3fdfc1e0..cd018130 100644 --- a/include/ccoin/core.h +++ b/include/ccoin/core.h @@ -5,15 +5,16 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include // for const_buffer +#include // for bu256_t, bu256_equal, etc +#include // for ::COIN +#include // for cstring +#include // for bitc_hashtab_get, etc +#include // for parr, parr_idx + +#include // for bool, false, true +#include // for uint32_t, int64_t, uint16_t, etc +#include // for memcpy, memset, NULL #ifdef __cplusplus extern "C" { @@ -116,6 +117,7 @@ static inline void bp_outpt_copy(struct bp_outpt *dest, struct bp_txin { struct bp_outpt prevout; + parr* scriptWitness; cstring *scriptSig; uint32_t nSequence; }; diff --git a/include/ccoin/script.h b/include/ccoin/script.h index 746d16f0..ade60c45 100644 --- a/include/ccoin/script.h +++ b/include/ccoin/script.h @@ -5,15 +5,17 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include // for const_buffer +#include // for bu256_t +#include // for clist +#include // for bp_tx +#include // for cstring, cstr_append_buf +#include // for bp_keystore +#include // for parr + +#include // for bool, false +#include // for size_t +#include // for uint8_t, int64_t, uint64_t #ifdef __cplusplus extern "C" { @@ -31,6 +33,9 @@ static const int MAX_PUBKEYS_PER_MULTISIG = 20; // Maximum script length in bytes static const int MAX_SCRIPT_SIZE = 10000; +// Maximum number of values on script interpreter stack +static const int MAX_STACK_SIZE = 1000; + // Threshold for nLockTime: below this value it is interpreted as block number, // otherwise as UNIX timestamp. static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC @@ -45,20 +50,88 @@ enum }; /** Script verification flags */ -enum -{ +enum { SCRIPT_VERIFY_NONE = 0, + + // Evaluate P2SH subscripts (softfork safe, BIP16). SCRIPT_VERIFY_P2SH = (1U << 0), + + // Passing a non-strict-DER signature or one with undefined hashtype to a checksig operation causes script failure. + // Evaluating a pubkey that is not (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) by checksig causes script failure. + // (softfork safe, but not used or intended as a consensus rule). SCRIPT_VERIFY_STRICTENC = (1U << 1), + + // Passing a non-strict-DER signature to a checksig operation causes script failure (softfork safe, BIP62 rule 1) SCRIPT_VERIFY_DERSIG = (1U << 2), + + // Passing a non-strict-DER signature or one with S > order/2 to a checksig operation causes script failure + // (softfork safe, BIP62 rule 5). SCRIPT_VERIFY_LOW_S = (1U << 3), + + // verify dummy stack item consumed by CHECKMULTISIG is of zero-length (softfork safe, BIP62 rule 7). SCRIPT_VERIFY_NULLDUMMY = (1U << 4), + + // Using a non-push operator in the scriptSig causes script failure (softfork safe, BIP62 rule 2). SCRIPT_VERIFY_SIGPUSHONLY = (1U << 5), + + // Require minimal encodings for all push operations (OP_0... OP_16, OP_1NEGATE where possible, direct + // pushes up to 75 bytes, OP_PUSHDATA up to 255 bytes, OP_PUSHDATA2 for anything larger). Evaluating + // any other push causes the script to fail (BIP62 rule 3). + // In addition, whenever a stack element is interpreted as a number, it must be of minimal length (BIP62 rule 4). + // (softfork safe) SCRIPT_VERIFY_MINIMALDATA = (1U << 6), - SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7), + + // Discourage use of NOPs reserved for upgrades (NOP1-10) + // + // Provided so that nodes can avoid accepting or mining transactions + // containing executed NOP's whose meaning may change after a soft-fork, + // thus rendering the script invalid; with this flag set executing + // discouraged NOPs fails the script. This verification flag will never be + // a mandatory flag applied to scripts in a block. NOPs that are not + // executed, e.g. within an unexecuted IF ENDIF block, are *not* rejected. + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7), + + // Require that only a single stack element remains after evaluation. This changes the success criterion from + // "At least one stack element must remain, and when interpreted as a boolean, it must be true" to + // "Exactly one stack element must remain, and when interpreted as a boolean, it must be true". + // (softfork safe, BIP62 rule 6) + // Note: CLEANSTACK should never be used without P2SH or WITNESS. SCRIPT_VERIFY_CLEANSTACK = (1U << 8), + + // Verify CHECKLOCKTIMEVERIFY + // + // See BIP65 for details. SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), + + // support CHECKSEQUENCEVERIFY opcode + // + // See BIP112 for details SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10), + + // Support segregated witness + // + SCRIPT_VERIFY_WITNESS = (1U << 11), + + // Making v1-v16 witness program non-standard + // + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM = (1U << 12), + + // Segwit script only: Require the argument of OP_IF/NOTIF to be exactly 0x01 or empty vector + // + SCRIPT_VERIFY_MINIMALIF = (1U << 13), + + // Signature(s) must be empty vector if an CHECK(MULTI)SIG operation failed + // + SCRIPT_VERIFY_NULLFAIL = (1U << 14), + + // Public keys in segregated witness scripts must be compressed + // + SCRIPT_VERIFY_WITNESS_PUBKEYTYPE = (1U << 15), +}; + +enum SigVersion { + SIGVERSION_BASE = 0, + SIGVERSION_WITNESS_V0 = 1, }; enum txnouttype @@ -209,7 +282,6 @@ enum opcodetype OP_NOP10 = 0xb9, - // template matching params OP_SMALLINTEGER = 0xfa, OP_PUBKEYS = 0xfb, @@ -244,11 +316,13 @@ extern enum opcodetype GetOpType(const char *opname); */ extern bool bsp_getop(struct bscript_op *op, struct bscript_parser *bp); +extern unsigned int bsp_get_sigopcount(struct const_buffer* buf, bool fAccurate); extern parr *bsp_parse_all(const void *data_, size_t data_len); extern enum txnouttype bsp_classify(parr *ops); extern bool bsp_addr_parse(struct bscript_addr *addr, const void *data, size_t data_len); extern void bsp_addr_free(struct bscript_addr *addr); +extern bool is_bsp_witnessprogram(const cstring* s, int* version, cstring* program); extern bool is_bsp_pushonly(struct const_buffer *buf); extern bool is_bsp_pubkey(parr *ops); extern bool is_bsp_pubkeyhash(parr *ops); @@ -275,6 +349,12 @@ static inline bool is_bsp_p2sh_str(const cstring *s) return is_bsp_p2sh(&buf); } +static inline bool is_bsp_p2wsh(struct const_buffer* buf) +{ + const unsigned char* vch = (const unsigned char*)(buf->p); + return (buf->len == 34 && vch[0] == OP_0 && vch[1] == 0x20); +} + static inline void bsp_start(struct bscript_parser *bp, struct const_buffer *buf) { @@ -286,14 +366,13 @@ static inline void bsp_start(struct bscript_parser *bp, * script validation and signing */ -extern void bp_tx_sighash(bu256_t *hash, const cstring *scriptCode, - const struct bp_tx *txTo, unsigned int nIn, - int nHashType); -extern bool bp_script_verify(const cstring *scriptSig, const cstring *scriptPubKey, - const struct bp_tx *txTo, unsigned int nIn, - unsigned int flags, int nHashType); -extern bool bp_verify_sig(const struct bp_utxo *txFrom, const struct bp_tx *txTo, - unsigned int nIn, unsigned int flags, int nHashType); +extern void bp_tx_sighash(bu256_t* hash, const cstring* scriptCode, const struct bp_tx* txTo, + unsigned int nIn, int nHashType, int64_t amount, enum SigVersion sigversion); +extern bool bp_script_verify(const cstring* scriptSig, const cstring* scriptPubKey, + parr* witness, const struct bp_tx* txTo, unsigned int nIn, + unsigned int flags, int nHashType, int64_t amount); +extern bool bp_verify_sig(const struct bp_utxo* txFrom,const struct bp_tx* txTo, + unsigned int nIn, unsigned int flags, int nHashType, int64_t amount); extern bool bp_script_sign(struct bp_keystore *ks, const cstring *fromPubKey, const struct bp_tx *txTo, unsigned int nIn, diff --git a/lib/Makefile.am b/lib/Makefile.am index 707c73b7..3d1567d0 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -6,7 +6,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include \ lib_LTLIBRARIES= libccoin.la -libccoin_la_LIBADD= -lm \ +libccoin_la_LIBADD = @MATH_LIBS@ \ $(top_builddir)/external/secp256k1/libsecp256k1.la libccoin_la_SOURCES= \ diff --git a/lib/script.c b/lib/script.c index 555ae62b..365a8f78 100644 --- a/lib/script.c +++ b/lib/script.c @@ -4,12 +4,31 @@ */ #include "picocoin-config.h" -#include -#include -#include -#include -#include -#include +#include // for const_buffer, buffer_copy, etc +#include // for htole16, htole32 +#include // for bscript_op, bscript_parser, etc +#include // for deser_bytes, deser_skip, etc +#include // for bn_getvch, memdup + +#include // for assert + + +/** Encode/decode small integers: */ +static int DecodeOP_N(enum opcodetype opcode) +{ + if (opcode == OP_0) + return 0; + assert(opcode >= OP_1 && opcode <= OP_16); + return (int)opcode - (int)(OP_1 - 1); +} + +static enum opcodetype EncodeOP_N(int n) +{ + assert(n >= 0 && n <= 16); + if (n == 0) + return OP_0; + return (enum opcodetype)(OP_1 + n - 1); +} bool bsp_getop(struct bscript_op *op, struct bscript_parser *bp) { @@ -83,6 +102,48 @@ parr *bsp_parse_all(const void *data_, size_t data_len) return NULL; } +unsigned int bsp_get_sigopcount(struct const_buffer* buf, bool fAccurate) +{ + unsigned int n = 0; + struct bscript_parser bp; + struct bscript_op op; + + bsp_start(&bp, buf); + enum opcodetype lastOpcode = OP_INVALIDOPCODE; + while (bsp_getop(&op, &bp)) { + enum opcodetype opcode; + + if (op.op == OP_CHECKSIG || op.op == OP_CHECKSIGVERIFY) + n++; + else if (op.op == OP_CHECKMULTISIG || op.op == OP_CHECKMULTISIGVERIFY) { + if (fAccurate && lastOpcode >= OP_1 && lastOpcode <= OP_16) + n += DecodeOP_N(lastOpcode); + else + n += MAX_PUBKEYS_PER_MULTISIG; + } + lastOpcode = op.op; + } + return n; +} + +// A witness program is any valid script that consists of a 1-byte push opcode +// followed by a data push between 2 and 40 bytes. +bool is_bsp_witnessprogram(const cstring* s, int* version, cstring* program) +{ + if (s->len < 4 || s->len > 42) { + return false; + } + if (s->str[0] != OP_0 && (s->str[0] < OP_1 || s->str[0] > OP_16)) { + return false; + } + if ((size_t)(s->str[1] + 2) == s->len) { + *version = DecodeOP_N((enum opcodetype)s->str[0]); + cstr_append_buf(program, s->str + 2, s->len - 2); + return true; + } + return false; +} + bool is_bsp_pushonly(struct const_buffer *buf) { struct bscript_parser bp; diff --git a/lib/script_eval.c b/lib/script_eval.c index ffaa50d1..581ec52b 100644 --- a/lib/script_eval.c +++ b/lib/script_eval.c @@ -1,18 +1,24 @@ +/* Copyright 2017 BitPay, Inc. + * Distributed under the MIT/X11 software license, see the accompanying + * file COPYING or http://www.opensource.org/licenses/mit-license.php. + */ #include "picocoin-config.h" -#define _GNU_SOURCE /* for memmem */ -#include -#include -#include -#include -#include -#include -#include -#include /* for parr_new */ -#include -#include -#include +#define _GNU_SOURCE // for memmem + +#include // for parr_new +#include // for RIPEMD160_DIGEST_LENGTH, etc +#include // for sha1_Raw, etc +#include // for SHA256_DIGEST_LENGTH, etc +#include // for bo_key_free, etc +#include // for bscript_op, etc +#include // for ser_u32, ser_varlen, etc +#include // for bn_getvch, bu_Hash, etc + +#include // for assert +#include // for int64_t, uint8_t, uint32_t, etc +#include // for NULL, memmove, memcpy, etc static const size_t nDefaultMaxNumSize = 4; @@ -43,29 +49,29 @@ void bp_tx_sigserializer(cstring *s, const cstring *scriptCode, const struct bp_tx *txTo, unsigned int nIn, int nHashType) { - const bool fAnyoneCanPay = (!!(nHashType & SIGHASH_ANYONECANPAY)); - const bool fHashSingle = ((nHashType & 0x1f) == SIGHASH_SINGLE); - const bool fHashNone = ((nHashType & 0x1f) == SIGHASH_NONE); - - /** Serialize txTo */ - // Serialize nVersion - ser_u32(s, txTo->nVersion); - - // Serialize vin - unsigned int nInputs = fAnyoneCanPay ? 1 : txTo->vin->len; - ser_varlen(s, nInputs); - - unsigned int nInput; - for (nInput = 0; nInput < nInputs; nInput++) { - /** Serialize an input of txTo */ - // In case of SIGHASH_ANYONECANPAY, only the input being signed is serialized + const bool fAnyoneCanPay = (!!(nHashType & SIGHASH_ANYONECANPAY)); + const bool fHashSingle = ((nHashType & 0x1f) == SIGHASH_SINGLE); + const bool fHashNone = ((nHashType & 0x1f) == SIGHASH_NONE); + + /** Serialize txTo */ + // Serialize nVersion + ser_u32(s, txTo->nVersion); + + // Serialize vin + unsigned int nInputs = fAnyoneCanPay ? 1 : txTo->vin->len; + ser_varlen(s, nInputs); + + unsigned int nInput; + for (nInput = 0; nInput < nInputs; nInput++) { + /** Serialize an input of txTo */ + // In case of SIGHASH_ANYONECANPAY, only the input being signed is serialized if (fAnyoneCanPay) nInput = nIn; - struct bp_txin *txin = parr_idx(txTo->vin, nInput); + struct bp_txin *txin = parr_idx(txTo->vin, nInput); - // Serialize the prevout - ser_bp_outpt(s, &txin->prevout); + // Serialize the prevout + ser_bp_outpt(s, &txin->prevout); // Serialize the script if (nInput != nIn) @@ -115,47 +121,118 @@ void bp_tx_sigserializer(cstring *s, const cstring *scriptCode, unsigned int nOutputs = fHashNone ? 0 : (fHashSingle ? (nIn + 1) : txTo->vout->len); ser_varlen(s, nOutputs); - unsigned int nOutput; + unsigned int nOutput; for (nOutput = 0; nOutput < nOutputs; nOutput++) { struct bp_txout *txout = parr_idx(txTo->vout, nOutput); - if (fHashSingle && (nOutput != nIn)) - // Do not lock-in the txout payee at other indices as txin; - bp_txout_set_null(txout); - - ser_bp_txout(s, txout); + if (fHashSingle && (nOutput != nIn)) { + // Do not lock-in the txout payee at other indices as txin + ser_s64(s, (int)-1); + ser_varlen(s, 0); + } else { + ser_bp_txout(s, txout); + } } // Serialize nLockTime ser_u32(s, txTo->nLockTime); } -void bp_tx_sighash(bu256_t *hash, const cstring *scriptCode, - const struct bp_tx *txTo, unsigned int nIn, - int nHashType) +void bp_tx_sighash(bu256_t* hash, const cstring* scriptCode, const struct bp_tx* txTo, + unsigned int nIn, int nHashType,int64_t amount, enum SigVersion sigversion) { - if (nIn >= txTo->vin->len) { - // nIn out of range - bu256_set_u64(hash, 1); - return; - } - - // Check for invalid use of SIGHASH_SINGLE - if ((nHashType & 0x1f) == SIGHASH_SINGLE) { - if (nIn >= txTo->vout->len) { - // nOut out of range - bu256_set_u64(hash, 1); - return; - } - } - - cstring *s = cstr_new_sz(512); - - // Serialize only the necessary parts of the transaction being signed - bp_tx_sigserializer(s, scriptCode, txTo, nIn, nHashType); + cstring* s = cstr_new_sz(512); + + if (sigversion == SIGVERSION_WITNESS_V0) { + bu256_t hashPrevouts; + bu256_t hashSequence; + bu256_t hashOutputs; + + if (!(nHashType & SIGHASH_ANYONECANPAY)) { + cstring* s_prevout = cstr_new_sz(512); + struct bp_txin* txin; + unsigned int i; + for (i = 0; i < txTo->vin->len; i++) { + txin = parr_idx(txTo->vin, i); + // Serialize the prevout + ser_bp_outpt(s_prevout, &txin->prevout); + } + bu_Hash((unsigned char*)&hashPrevouts, s_prevout->str, s_prevout->len); + cstr_free(s_prevout, true); + } + + if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && + (nHashType & 0x1f) != SIGHASH_NONE) { + cstring* s_seq = cstr_new_sz(512); + struct bp_txin* txin; + unsigned int i; + for (i = 0; i < txTo->vin->len; i++) { + txin = parr_idx(txTo->vin, i); + // Serialize the nSequence + ser_u32(s_seq, txin->nSequence); + } + bu_Hash((unsigned char*)&hashSequence, s_seq->str, s_seq->len); + cstr_free(s_seq, true); + } + + if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { + cstring* s_out = cstr_new_sz(512); + struct bp_txout* txout; + unsigned int i; + for (i = 0; i < txTo->vout->len; i++) { + txout = parr_idx(txTo->vout, i); + ser_bp_txout(s_out, txout); + } + bu_Hash((unsigned char*)&hashOutputs, s_out->str, s_out->len); + cstr_free(s_out, true); + } else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo->vout->len) { + cstring* s_out = cstr_new_sz(512); + struct bp_txout* txout = parr_idx(txTo->vout, nIn); + ser_bp_txout(s_out, txout); + bu_Hash((unsigned char*)&hashOutputs, s_out->str, s_out->len); + cstr_free(s_out, true); + } + + // Version + ser_u32(s, txTo->nVersion); + // Input prevouts/nSequence (none/all, depending on flags) + ser_u256(s, &hashPrevouts); + ser_u256(s, &hashSequence); + // The input being signed (replacing the scriptSig with scriptCode + amount) + // The prevout may already be contained in hashPrevout, and the nSequence + // may already be contain in hashSequence. + struct bp_txin* txin = parr_idx(txTo->vin, nIn); + ser_bp_outpt(s, &txin->prevout); + ser_varstr(s, (struct cstring*)scriptCode); + ser_s64(s, amount); + ser_u32(s, txin->nSequence); + // Outputs (none/one/all, depending on flags) + ser_u256(s, &hashOutputs); + // Locktime + ser_u32(s, txTo->nLockTime); + } else { + if (nIn >= txTo->vin->len) { + // nIn out of range + bu256_set_u64(hash, 1); + goto out; + } + + // Check for invalid use of SIGHASH_SINGLE + if ((nHashType & 0x1f) == SIGHASH_SINGLE) { + if (nIn >= txTo->vout->len) { + // nOut out of range + bu256_set_u64(hash, 1); + goto out; + } + } + // Serialize only the necessary parts of the transaction being signed + bp_tx_sigserializer(s, scriptCode, txTo, nIn, nHashType); + } - ser_s32(s, nHashType); - bu_Hash((unsigned char *) hash, s->str, s->len); + // Sighash type + ser_s32(s, nHashType); + bu_Hash((unsigned char*)hash, s->str, s->len); - cstr_free(s, true); +out: + cstr_free(s, true); } static const unsigned char disabled_op[256] = { @@ -232,7 +309,7 @@ static void stack_insert(parr *stack, const struct buffer *buf, int index_) static void stack_push(parr *stack, const struct buffer *buf) { - parr_add(stack, buffer_copy(buf->p, buf->len)); + parr_add(stack, buffer_copy(buf->p, buf->len)); } static void stack_push_nocopy(parr *stack, struct buffer *buf) @@ -313,10 +390,9 @@ static unsigned int count_false(cstring *vfExec) return count; } -static bool bp_checksig(const struct buffer *vchSigIn, - const struct buffer *vchPubKey, - const cstring *scriptCode, - const struct bp_tx *txTo, unsigned int nIn) +static bool bp_checksig(const struct buffer* vchSigIn, const struct buffer* vchPubKey, + const cstring* scriptCode, const struct bp_tx* txTo, unsigned int nIn, + int64_t amount, enum SigVersion sigversion) { if (!vchSigIn || !vchPubKey || !scriptCode || !txTo || !vchSigIn->len || !vchPubKey->len || !scriptCode->len) @@ -329,10 +405,10 @@ static bool bp_checksig(const struct buffer *vchSigIn, /* calculate signature hash of transaction */ bu256_t sighash; - bp_tx_sighash(&sighash, scriptCode, txTo, nIn, nHashType); + bp_tx_sighash(&sighash, scriptCode, txTo, nIn, nHashType, amount, sigversion); - /* verify signature hash */ - struct bp_key pubkey; + /* verify signature hash */ + struct bp_key pubkey; bp_key_init(&pubkey); bool rc = false; if (!bp_pubkey_set(&pubkey, vchPubKey->p, vchPubKey->len)) @@ -372,6 +448,31 @@ bool static IsCompressedOrUncompressedPubKey(const struct buffer *vchPubKey) { return true; } +bool static IsCompressedPubKey(const struct buffer* vchPubKey) +{ + const unsigned char* pubkey = vchPubKey->p; + + if (vchPubKey->len != 33) { + // Non-canonical public key: invalid length for compressed key + return false; + } + if (pubkey[0] != 0x02 && pubkey[0] != 0x03) { + // Non-canonical public key: invalid prefix for compressed key + return false; + } + return true; +} + +/** + * A canonical signature exists of: <30> <02> <02> + * Where R and S are not negative (their first byte has its highest bit not set), and not + * excessively padded (do not start with a 0 byte, unless an otherwise negative number follows, + * in which case a single 0 byte is necessary and even required). + * + * See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623 + * + * This function is consensus-critical since BIP66. + */ static bool IsValidSignatureEncoding(const struct buffer *vch) { // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash] @@ -478,10 +579,17 @@ static bool CheckSignatureEncoding(const struct buffer *vchSig, unsigned int fla return true; } -static bool CheckPubKeyEncoding(const struct buffer *vchPubKey, unsigned int flags) { +static bool CheckPubKeyEncoding(const struct buffer* vchPubKey, + unsigned int flags, + enum SigVersion sigversion) +{ if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchPubKey)) return false; - + // Only compressed keys are accepted in segwit + if ((flags & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE) != 0 && sigversion == SIGVERSION_WITNESS_V0 && + !IsCompressedPubKey(vchPubKey)) { + return false; + } return true; } @@ -597,9 +705,9 @@ bool CheckSequence(const unsigned int nSequence, const struct bp_tx *txTo, unsig return true; } -static bool bp_script_eval(parr *stack, const cstring *script, - const struct bp_tx *txTo, unsigned int nIn, - unsigned int flags, int nHashType) +static bool bp_script_eval(parr* stack, const cstring* script, + const struct bp_tx* txTo, unsigned int nIn, unsigned int flags, + int nHashType, int64_t amount, enum SigVersion sigversion) { struct const_buffer pc = { script->str, script->len }; struct const_buffer pend = { script->str + script->len, 0 }; @@ -770,8 +878,16 @@ static bool bp_script_eval(parr *stack, const cstring *script, if (stack->len < 1) goto out; struct buffer *vch = stacktop(stack, -1); - fValue = CastToBool(vch); - if (opcode == OP_NOTIF) + if ((sigversion == SIGVERSION_WITNESS_V0) && + (flags & SCRIPT_VERIFY_MINIMALIF)) { + if (vch->len > 1) + goto out; + const unsigned char* _vch = vch->p; + if (vch->len == 1 && _vch[0] != 1) + goto out; + } + fValue = CastToBool(vch); + if (opcode == OP_NOTIF) fValue = !fValue; popstack(stack); } @@ -1209,25 +1325,25 @@ static bool bp_script_eval(parr *stack, const cstring *script, switch (opcode) { case OP_RIPEMD160: - hashlen = 20; - ripemd160(vch->p, vch->len, md); - break; + hashlen = RIPEMD160_DIGEST_LENGTH; + ripemd160(vch->p, vch->len, md); + break; case OP_SHA1: - hashlen = 20; - sha1_Raw(vch->p, vch->len, md); - break; - case OP_SHA256: - hashlen = 32; - sha256_Raw(vch->p, vch->len, md); - break; + hashlen = SHA1_DIGEST_LENGTH; + sha1_Raw(vch->p, vch->len, md); + break; + case OP_SHA256: + hashlen = SHA256_DIGEST_LENGTH; + sha256_Raw(vch->p, vch->len, md); + break; case OP_HASH160: - hashlen = 20; - bu_Hash160(md, vch->p, vch->len); - break; + hashlen = RIPEMD160_DIGEST_LENGTH; + bu_Hash160(md, vch->p, vch->len); + break; case OP_HASH256: - hashlen = 32; - bu_Hash(md, vch->p, vch->len); - break; + hashlen = SHA256_DIGEST_LENGTH; + bu_Hash(md, vch->p, vch->len); + break; default: // impossible goto out; @@ -1257,22 +1373,26 @@ static bool bp_script_eval(parr *stack, const cstring *script, cstring *scriptCode = cstr_new_buf(pbegincodehash.p, pbegincodehash.len); - // Drop the signature, since there's no way for - // a signature to sign itself - string_find_del(scriptCode, vchSig); + // Drop the signature in pre-segwit scripts but not segwit scripts + if (sigversion == SIGVERSION_BASE) { + string_find_del(scriptCode, vchSig); + } - if (!CheckSignatureEncoding(vchSig, flags) || !CheckPubKeyEncoding(vchPubKey, flags)) { - cstr_free(scriptCode, true); - goto out; - } + if (!CheckSignatureEncoding(vchSig, flags) || + !CheckPubKeyEncoding(vchPubKey, flags, sigversion)) { + cstr_free(scriptCode, true); + goto out; + } - bool fSuccess = bp_checksig(vchSig, vchPubKey, - scriptCode, - txTo, nIn); + bool fSuccess = bp_checksig( + vchSig, vchPubKey, scriptCode, txTo, nIn, amount, sigversion); - cstr_free(scriptCode, true); + cstr_free(scriptCode, true); - popstack(stack); + if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && vchSig->len) + goto out; + + popstack(stack); popstack(stack); stack_push_str(stack, fSuccess ? bn_getvch(bn_One) : bn_getvch(bn_Zero)); if (opcode == OP_CHECKSIGVERIFY) @@ -1300,7 +1420,11 @@ static bool bp_script_eval(parr *stack, const cstring *script, if (nOpCount > MAX_OPS_PER_SCRIPT) goto out; int ikey = ++i; - i += nKeysCount; + // ikey2 is the position of last non-signature item in the stack. Top stack + // item = 1. + // With SCRIPT_VERIFY_NULLFAIL, this is used for cleanup if operation fails. + int ikey2 = nKeysCount + 2; + i += nKeysCount; if ((int)stack->len < i) goto out; @@ -1314,18 +1438,19 @@ static bool bp_script_eval(parr *stack, const cstring *script, // Subset of script starting at the most recent codeseparator cstring *scriptCode = cstr_new_buf(pbegincodehash.p, - pbegincodehash.len); + pbegincodehash.len); - // Drop the signatures, since there's no way for - // a signature to sign itself - int k; - for (k = 0; k < nSigsCount; k++) + // Drop the signature in pre-segwit scripts but not segwit scripts + int k; + for (k = 0; k < nSigsCount; k++) { - struct buffer *vchSig =stacktop(stack, -isig-k); - string_find_del(scriptCode, vchSig); - } + struct buffer* vchSig = stacktop(stack, -isig - k); + if (sigversion == SIGVERSION_BASE) { + string_find_del(scriptCode, vchSig); + } + } - bool fSuccess = true; + bool fSuccess = true; while (fSuccess && nSigsCount > 0) { struct buffer *vchSig = stacktop(stack, -isig); @@ -1334,18 +1459,19 @@ static bool bp_script_eval(parr *stack, const cstring *script, // Note how this makes the exact order of pubkey/signature evaluation // distinguishable by CHECKMULTISIG NOT if the STRICTENC flag is set. // See the script_(in)valid tests for details. - if (!CheckSignatureEncoding(vchSig, flags) || !CheckPubKeyEncoding(vchPubKey, flags)) { - cstr_free(scriptCode, true); - goto out; - } + if (!CheckSignatureEncoding(vchSig, flags) || + !CheckPubKeyEncoding(vchPubKey, flags, sigversion)) { + cstr_free(scriptCode, true); + goto out; + } // Check signature - bool fOk = bp_checksig(vchSig, vchPubKey, - scriptCode, txTo, nIn); + bool fOk = bp_checksig( + vchSig, vchPubKey, scriptCode, txTo, nIn, amount, sigversion); - if (fOk) { - isig++; - nSigsCount--; + if (fOk) { + isig++; + nSigsCount--; } ikey++; nKeysCount--; @@ -1359,10 +1485,18 @@ static bool bp_script_eval(parr *stack, const cstring *script, cstr_free(scriptCode, true); // Clean up stack of actual arguments - while (i-- > 1) - popstack(stack); - - // A bug causes CHECKMULTISIG to consume one extra argument + while (i-- > 1) { + // If the operation failed, we require that all signatures must be empty + // vector + if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && !ikey2 && + stacktop(stack, -1)->len) + goto out; + if (ikey2 > 0) + ikey2--; + popstack(stack); + } + + // A bug causes CHECKMULTISIG to consume one extra argument // whose contents were not checked in any way. // // Unfortunately this is a potential source of mutability, @@ -1391,8 +1525,8 @@ static bool bp_script_eval(parr *stack, const cstring *script, } // Size limits - if (stack->len + altstack->len > 1000) - goto out; + if (stack->len + altstack->len > MAX_STACK_SIZE) + goto out; } rc = (vfExec->len == 0 && bp.error == false); @@ -1404,84 +1538,224 @@ static bool bp_script_eval(parr *stack, const cstring *script, return rc; } -bool bp_script_verify(const cstring *scriptSig, const cstring *scriptPubKey, - const struct bp_tx *txTo, unsigned int nIn, - unsigned int flags, int nHashType) +static bool bp_witnessprogram_verify(parr* witness, + int witversion, + cstring* program, + const struct bp_tx* txTo, + unsigned int flags, + int64_t amount) { - bool rc = false; - parr *stack = parr_new(0, buffer_freep); - parr *stackCopy = NULL; + parr* stack = parr_new(0, buffer_freep); + cstring* scriptPubKey; + bool rc = false; + + if (witversion == 0) { + if (program->len == SHA256_DIGEST_LENGTH) { + // Version 0 segregated witness program: SHA256(Script) inside the program, Script + + // inputs in witness + if (witness->len == 0) { + goto out; + } + + struct buffer* buf = stacktop(witness, -1); + scriptPubKey = cstr_new_buf(buf->p, buf->len); + stack_copy(stack, witness); + popstack(stack); + + unsigned char hashScriptPubKey[SHA256_DIGEST_LENGTH]; + sha256_Raw(scriptPubKey->str, scriptPubKey->len, hashScriptPubKey); + + if (memcmp(hashScriptPubKey, program->str, SHA256_DIGEST_LENGTH)) { + goto out; + } + } else if (program->len == RIPEMD160_DIGEST_LENGTH) { + // Special case for pay-to-pubkeyhash; signature + pubkey in witness + if (witness->len != 2) { + goto out; // 2 items in witness + } + scriptPubKey = bsp_make_pubkeyhash(program); + stack_copy(stack, witness); + } else { + goto out; + } + } else if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM) { + goto out; + } else { + // Higher version witness scripts return true for future softfork compatibility + rc = true; + goto out; + } - struct const_buffer sigbuf = { scriptSig->str, scriptSig->len }; - if ((flags & SCRIPT_VERIFY_SIGPUSHONLY) != 0 && !is_bsp_pushonly(&sigbuf)) - goto out; + // Disallow stack item size > MAX_SCRIPT_ELEMENT_SIZE in witness stack + unsigned int i; + for (i = 0; i < stack->len; i++) { + struct buffer* buf = stack->data[i]; + if (buf && (buf->len > MAX_SCRIPT_ELEMENT_SIZE)) + goto out; + } - if (!bp_script_eval(stack, scriptSig, txTo, nIn, flags, nHashType)) - goto out; + if (!bp_script_eval(stack, scriptPubKey, txTo, 0, flags, 0, amount, SIGVERSION_WITNESS_V0)) { + goto out; + } - if (flags & SCRIPT_VERIFY_P2SH) { - stackCopy = parr_new(stack->len, buffer_freep); - stack_copy(stackCopy, stack); - } + // Scripts inside witness implicitly require cleanstack behaviour + if (stack->len != 1) + goto out; - if (!bp_script_eval(stack, scriptPubKey, txTo, nIn, flags, nHashType)) - goto out; - if (stack->len == 0) - goto out; + if (!CastToBool(stacktop(stack, -1))) + goto out; - if (CastToBool(stacktop(stack, -1)) == false) - goto out; + rc = true; - if ((flags & SCRIPT_VERIFY_P2SH) && is_bsp_p2sh_str(scriptPubKey)) { - // scriptSig must be literals-only or validation fails - if (!is_bsp_pushonly(&sigbuf)) - goto out; - // stack cannot be empty here, because if it was the - // P2SH HASH <> EQUAL scriptPubKey would be evaluated with - // an empty stack and the script_eval above would return false. - if (stackCopy->len < 1) - goto out; +out: + parr_free(stack, true); + return rc; +} - struct buffer *pubKeySerialized = stack_take(stackCopy, -1); - popstack(stackCopy); +bool bp_script_verify(const cstring* scriptSig, const cstring* scriptPubKey, + parr* witness, const struct bp_tx* txTo, unsigned int nIn, + unsigned int flags, int nHashType, int64_t amount) +{ + cstring* witnessprogram = NULL; + if (witness == NULL) { + witness = parr_new(0, buffer_freep); + } + bool hadWitness = false; - cstring *pubkey2 = cstr_new_buf(pubKeySerialized->p, pubKeySerialized->len); + cstring* pubkey2 = NULL; + struct buffer* pubKeySerialized = NULL; - buffer_freep(pubKeySerialized); + bool rc = false; + parr* stack = parr_new(0, buffer_freep); + parr* stackCopy = NULL; + struct const_buffer sigbuf = {scriptSig->str, scriptSig->len}; - bool rc2 = bp_script_eval(stackCopy, pubkey2, txTo, nIn, - flags, nHashType); - cstr_free(pubkey2, true); + if ((flags & SCRIPT_VERIFY_SIGPUSHONLY) != 0 && !is_bsp_pushonly(&sigbuf)) + goto out; - if (!rc2) - goto out; - if (stackCopy->len == 0) - goto out; - if (CastToBool(stacktop(stackCopy, -1)) == false) - goto out; - } - // The CLEANSTACK check is only performed after potential P2SH evaluation, - // as the non-P2SH evaluation of a P2SH script will obviously not result in - // a clean stack (the P2SH inputs remain). - if ((flags & SCRIPT_VERIFY_CLEANSTACK) != 0) { - // Disallow CLEANSTACK without P2SH, as otherwise a switch CLEANSTACK->P2SH+CLEANSTACK - // would be possible, which is not a softfork (and P2SH should be one). - assert((flags & SCRIPT_VERIFY_P2SH) != 0); - if (stackCopy->len != 1) - goto out; - } + if (!bp_script_eval(stack, scriptSig, txTo, nIn, flags, nHashType, amount, SIGVERSION_BASE)) + goto out; + if (flags & SCRIPT_VERIFY_P2SH) { + stackCopy = parr_new(stack->len, buffer_freep); + stack_copy(stackCopy, stack); + } + if (!bp_script_eval(stack, scriptPubKey, txTo, nIn, flags, nHashType, amount, SIGVERSION_BASE)) + goto out; + if (stack->len == 0) + goto out; + ; + if (CastToBool(stacktop(stack, -1)) == false) + goto out; + + // Bare witness programs + int witnessversion; + if (flags & SCRIPT_VERIFY_WITNESS) { + witnessprogram = cstr_new_sz(0); + + if (is_bsp_witnessprogram(scriptPubKey, &witnessversion, witnessprogram)) { + hadWitness = true; + if (scriptSig->len != 0) { + // The scriptSig must be _exactly_ 0, otherwise we reintroduce malleability. + goto out; + } + if (!bp_witnessprogram_verify( + witness, witnessversion, witnessprogram, txTo, flags, amount)) { + goto out; + } + // Bypass the cleanstack check at the end. The actual stack is obviously not clean + // for witness programs. + parr_resize(stack, 1); + } + } - rc = true; + // Additional validation for spend-to-script-hash transactions: + if ((flags & SCRIPT_VERIFY_P2SH) && is_bsp_p2sh_str(scriptPubKey)) { + // scriptSig must be literals-only or validation fails + if (!is_bsp_pushonly(&sigbuf)) + goto out; + + // stack cannot be empty here, because if it was the + // P2SH HASH <> EQUAL scriptPubKey would be evaluated with + // an empty stack and the script_eval above would return false. + if (stack->len < 1) + goto out; + + pubKeySerialized = stack_take(stackCopy, -1); + pubkey2 = cstr_new_buf(pubKeySerialized->p, pubKeySerialized->len); + popstack(stackCopy); + + if (!bp_script_eval( + stackCopy, pubkey2, txTo, nIn, flags, nHashType, amount, SIGVERSION_BASE)) + goto out; + if (stackCopy->len == 0) + goto out; + if (CastToBool(stacktop(stackCopy, -1)) == false) + goto out; + + // P2SH witness program + if (flags & SCRIPT_VERIFY_WITNESS) { + if (is_bsp_witnessprogram(pubkey2, &witnessversion, witnessprogram)) { + hadWitness = true; + cstr_resize(pubkey2, 0); + bsp_push_data(pubkey2, pubKeySerialized->p, pubKeySerialized->len); + if (!cstr_equal(scriptSig, pubkey2)) { + // The scriptSig must be _exactly_ a single push of the redeemScript. Otherwise + // we + // reintroduce malleability. + goto out; + } + if (!bp_witnessprogram_verify( + witness, witnessversion, witnessprogram, txTo, flags, amount)) { + goto out; + } + // Bypass the cleanstack check at the end. The actual stack is obviously not + // clean + // for witness programs. + parr_resize(stackCopy, 1); + } + } + } + + // The CLEANSTACK check is only performed after potential P2SH evaluation, + // as the non-P2SH evaluation of a P2SH script will obviously not result in + // a clean stack (the P2SH inputs remain). + if ((flags & SCRIPT_VERIFY_CLEANSTACK) != 0) { + // Disallow CLEANSTACK without P2SH, as otherwise a switch CLEANSTACK->P2SH+CLEANSTACK + // would be possible, which is not a softfork (and P2SH should be one). + if ((flags & SCRIPT_VERIFY_P2SH) == 0) + goto out; + // if ((flags & SCRIPT_VERIFY_WITNESS) == 0) + // goto out; + if (stackCopy->len != 1) + goto out; + } + + if (flags & SCRIPT_VERIFY_WITNESS) { + // We can't check for correct unexpected witness data if P2SH was off, so require + // that WITNESS implies P2SH. Otherwise, going from WITNESS->P2SH+WITNESS would be + // possible, which is not a softfork. + if ((flags & SCRIPT_VERIFY_P2SH) == 0) + goto out; + if (!hadWitness && (witness->len != 0)) + goto out; + } + rc = true; out: parr_free(stack, true); - if (stackCopy) - parr_free(stackCopy, true); - return rc; + if (stackCopy) + parr_free(stackCopy, true); + if (pubkey2) + cstr_free(pubkey2, true); + if (pubKeySerialized) + buffer_freep(pubKeySerialized); + if (witnessprogram) + cstr_free(witnessprogram, true); + return rc; } -bool bp_verify_sig(const struct bp_utxo *txFrom, const struct bp_tx *txTo, - unsigned int nIn, unsigned int flags, int nHashType) +bool bp_verify_sig(const struct bp_utxo* txFrom, const struct bp_tx* txTo, + unsigned int nIn, unsigned int flags, int nHashType, int64_t amount) { if (!txFrom || !txFrom->vout || !txFrom->vout->len || !txTo || !txTo->vin || !txTo->vin->len || @@ -1497,6 +1771,6 @@ bool bp_verify_sig(const struct bp_utxo *txFrom, const struct bp_tx *txTo, if (!txout) return false; - return bp_script_verify(txin->scriptSig, txout->scriptPubKey, - txTo, nIn, flags, nHashType); + return bp_script_verify(txin->scriptSig, txout->scriptPubKey, NULL, + txTo, nIn, flags, nHashType, amount); } diff --git a/lib/script_names.c b/lib/script_names.c index bb340276..e95d5750 100644 --- a/lib/script_names.c +++ b/lib/script_names.c @@ -154,9 +154,9 @@ const char *GetOpName(enum opcodetype opcode_) enum opcodetype GetOpType(const char *opname) { unsigned int i; - char tmpname[64]; + char tmpname[256]; - for (i = 0; i < ARRAY_SIZE(opnames); i++) { + for (i = 0; i < ARRAY_SIZE(opnames); i++) { if (opnames[i]) { if (!strcmp(opname, opnames[i])) return (enum opcodetype) i; diff --git a/lib/script_sign.c b/lib/script_sign.c index 0b6bd7b2..5247a6b2 100644 --- a/lib/script_sign.c +++ b/lib/script_sign.c @@ -56,9 +56,9 @@ bool bp_script_sign(struct bp_keystore *ks, const cstring *fromPubKey, /* get signature hash */ bu256_t hash; - bp_tx_sighash(&hash, fromPubKey, txTo, nIn, nHashType); + bp_tx_sighash(&hash, fromPubKey, txTo, nIn, nHashType, 0, 0); - /* match fromPubKey against templates, to find what pubkey[hashes] + /* match fromPubKey against templates, to find what pubkey[hashes] * are required for signing */ struct bscript_addr addrs; diff --git a/src/brd.c b/src/brd.c index 3dae68d0..b87ede25 100644 --- a/src/brd.c +++ b/src/brd.c @@ -339,10 +339,10 @@ static bool spend_tx(struct bp_utxo_set *uset, const struct bp_tx *tx, txout = parr_idx(coin->vout, txin->prevout.n); total_in += txout->nValue; - if (script_verf && - !bp_verify_sig(coin, tx, i, - /* SCRIPT_VERIFY_P2SH */ 0, 0)) - return false; + if (script_verf && + !bp_verify_sig(coin, tx, i, SCRIPT_VERIFY_NONE, + SIGHASH_NONE, 0)) + return false; if (!bp_utxo_spend(uset, &txin->prevout)) return false; diff --git a/test/Makefile.am b/test/Makefile.am index 7247128a..da903621 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -10,7 +10,7 @@ AM_CPPFLAGS = -DTEST_SRCDIR=\"$(top_srcdir)/test\" \ -I$(top_srcdir)/include \ -I$(top_srcdir)/external/secp256k1/include -noinst_LIBRARIES= libtest.a +noinst_LIBRARIES = libtest.a libtest_a_SOURCES= libtest.h libtest.c chisq.c randtest.c diff --git a/test/base58.c b/test/base58.c index dd18320b..c6c65c95 100644 --- a/test/base58.c +++ b/test/base58.c @@ -4,10 +4,10 @@ */ #include // for base58_decode_check, etc -#include // for bitc_address_type, etc +#include // for bp_address_type, etc #include // for cstring, cstr_free, etc #include // for hex2str, decode_hex -#include // for bitc_key_static_shutdown +#include // for bp_key_static_shutdown #include // for RIPEMD160_DIGEST_LENGTH #include "libtest.h" // for dumphex, read_json, etc @@ -331,8 +331,8 @@ static void runtest_keys_invalid(const char *json_base_fn) else if ((addrtype == PRIVKEY_ADDRESS_TEST) || (addrtype == PRIVKEY_ADDRESS)) - is_valid = (payload->len == 32 || payload->len == 33 && payload->str[32] == 1); - else is_valid = false; + is_valid = (payload->len == 32 || (payload->len == 33 && payload->str[32] == 1)); + else is_valid = false; cstr_free(payload, true); assert(!is_valid); diff --git a/test/chain-verf.c b/test/chain-verf.c index a946434b..5868e206 100644 --- a/test/chain-verf.c +++ b/test/chain-verf.c @@ -1,21 +1,26 @@ #include "picocoin-config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "libtest.h" +#include // for blkinfo, blkdb_reorg, etc +#include // for const_buffer +#include // for bu256_hex, BU256_STRSZ, etc +#include // for bp_ckpt_last +#include // for bp_block, bp_tx, bp_utxo, etc +#include // for chain_info, etc +#include // for bp_key_static_shutdown +#include // for fread_block +#include // for p2p_message, etc +#include // for parr, parr_idx +#include // for bp_verify_sig, etc +#include // for file_seq_open + +#include // for assert +#include // for true, false, bool +#include // for fprintf, stderr, perror, etc +#include // for getenv, calloc, free +#include // for memcmp, strncmp +#include // for int64_t +#include // for close + static bool no_script_verf = false; static bool force_script_verf = false; @@ -67,8 +72,7 @@ static bool spend_tx(struct bp_utxo_set *uset, const struct bp_tx *tx, check_script = true; if (check_script && - !bp_verify_sig(coin, tx, i, - /* SCRIPT_VERIFY_P2SH */ 0, 0)) + !bp_verify_sig(coin, tx, i, SCRIPT_VERIFY_NONE, SIGHASH_NONE, 0)) return false; if (!bp_utxo_spend(uset, &txin->prevout)) diff --git a/test/data/script_tests.json b/test/data/script_tests.json index 81134e12..698e8982 100644 --- a/test/data/script_tests.json +++ b/test/data/script_tests.json @@ -1,5 +1,5 @@ [ -["Format is: [scriptSig, scriptPubKey, flags, expected_scripterror, ... comments]"], +["Format is: [[wit..., amount]?, scriptSig, scriptPubKey, flags, expected_scripterror, ... comments]"], ["It is evaluated as if there was a crediting coinbase transaction with two 0"], ["pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,"], ["followed by a spending transaction which spends this output as only input (and"], @@ -240,7 +240,7 @@ ["0", "IF NOP10 ENDIF 1", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "OK", "Discouraged NOPs are allowed if not executed"], -["0", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "OK", "opcodes above NOP10 invalid if executed"], +["0", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "OK", "opcodes above MAX_OPCODE invalid if executed"], ["0", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], ["0", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], ["0", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], @@ -349,7 +349,7 @@ ["2147483647", "0x04 0xFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], ["2147483648", "0x05 0x0000008000 EQUAL", "P2SH,STRICTENC", "OK"], ["549755813887", "0x05 0xFFFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], -["549755813888", "0x06 0xFFFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], +["549755813888", "0x06 0x000000008000 EQUAL", "P2SH,STRICTENC", "OK"], ["9223372036854775807", "0x08 0xFFFFFFFFFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], ["-1", "0x01 0x81 EQUAL", "P2SH,STRICTENC", "OK", "Numbers are little-endian with the MSB being a sign bit"], ["-127", "0x01 0xFF EQUAL", "P2SH,STRICTENC", "OK"], @@ -878,7 +878,7 @@ "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in redeemScript"], ["0x50","1", "P2SH,STRICTENC", "BAD_OPCODE", "opcode 0x50 is reserved"], -["1", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "opcodes above NOP10 invalid if executed"], +["1", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "opcodes above MAX_OPCODE invalid if executed"], ["1", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], ["1", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], ["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], @@ -1001,7 +1001,7 @@ ["1","RESERVED", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED is reserved"], ["1","RESERVED1", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED1 is reserved"], ["1","RESERVED2", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED2 is reserved"], -["1","0xba", "P2SH,STRICTENC", "BAD_OPCODE", "0xba == OP_NOP10 + 1"], +["1","0xba", "P2SH,STRICTENC", "BAD_OPCODE", "0xba == MAX_OPCODE + 1"], ["2147483648", "1ADD 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers"], ["2147483648", "NEGATE 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers"], @@ -1100,7 +1100,7 @@ "NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG", "P2SH,STRICTENC", "OP_COUNT", -"Fails due to 201 sig op limit"], +"Fails due to 201 script operation limit"], ["1", "NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY", @@ -1253,6 +1253,12 @@ ["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Zero-length S is incorrectly encoded for DERSIG"], ["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Negative S is incorrectly encoded for DERSIG"], +["Some basic segwit checks"], +[["00", 0.00000000 ], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "P2SH,WITNESS", "EVAL_FALSE", "Invalid witness script"], +[["51", 0.00000000 ], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "P2SH,WITNESS", "WITNESS_PROGRAM_MISMATCH", "Witness script hash mismatch"], +[["00", 0.00000000 ], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "", "OK", "Invalid witness script without WITNESS"], +[["51", 0.00000000 ], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "", "OK", "Witness script hash mismatch without WITNESS"], + ["Automatically generated test cases"], [ "0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", @@ -1310,6 +1316,13 @@ "EVAL_FALSE", "P2SH(P2PK), bad redeemscript" ], +[ + "0x47 0x30440220781ba4f59a7b207a10db87628bc2168df4d59b844b397d2dbc9a5835fb2f2b7602206ed8fbcc1072fe2dfc5bb25909269e5dc42ffcae7ec2bc81d59692210ff30c2b01 0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 0x19 0x76a91491b24bf9f5288532960ac687abb035127b1d28a588ac", + "HASH160 0x14 0x7f67f0521934a57d3039f77f9f32cf313f3ac74b EQUAL", + "P2SH", + "OK", + "P2SH(P2PKH)" +], [ "0x47 0x304402204e2eb034be7b089534ac9e798cf6a2c79f38bcb34d1b179efd6f2de0841735db022071461beb056b5a7be1819da6a3e3ce3662831ecc298419ca101eb6887b5dd6a401 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL", @@ -1478,6 +1491,27 @@ "OK", "BIP66 example 4, with DERSIG" ], +[ + "0x09 0x300602010102010101", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "DERSIG", + "OK", + "BIP66 example 4, with DERSIG, non-null DER-compliant signature" +], +[ + "0", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "DERSIG,NULLFAIL", + "OK", + "BIP66 example 4, with DERSIG and NULLFAIL" +], +[ + "0x09 0x300602010102010101", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "DERSIG,NULLFAIL", + "NULLFAIL", + "BIP66 example 4, with DERSIG and NULLFAIL, non-null DER-compliant signature" +], [ "1", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", @@ -1822,12 +1856,754 @@ "P2SH with CLEANSTACK" ], -["CHECKSEQUENCEVERIFY tests"], -["", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on a empty stack"], +["Testing with uncompressed keys in witness v0 without WITNESS_PUBKEYTYPE"], +[ + [ + "304402200d461c140cfdfcf36b94961db57ae8c18d1cb80e9d95a9e47ac22470c1bf125502201c8dc1cbfef6a3ef90acbbb992ca22fe9466ee6f9d4898eda277a7ac3ab4b25101", + "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + 0.00000001 + ], + "", + "0 0x20 0xb95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", + "P2SH,WITNESS", + "OK", + "Basic P2WSH" +], +[ + [ + "304402201e7216e5ccb3b61d46946ec6cc7e8c4e0117d13ac2fd4b152197e4805191c74202203e9903e33e84d9ee1dd13fb057afb7ccfb47006c23f6a067185efbc9dd780fc501", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000001 + ], + "", + "0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5", + "P2SH,WITNESS", + "OK", + "Basic P2WPKH" +], +[ + [ + "3044022066e02c19a513049d49349cf5311a1b012b7c4fae023795a18ab1d91c23496c22022025e216342c8e07ce8ef51e8daee88f84306a9de66236cab230bb63067ded1ad301", + "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + 0.00000001 + ], + "0x22 0x0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", + "HASH160 0x14 0xf386c2ba255cc56d20cfa6ea8b062f8b59945518 EQUAL", + "P2SH,WITNESS", + "OK", + "Basic P2SH(P2WSH)" +], +[ + [ + "304402200929d11561cd958460371200f82e9cae64c727a495715a31828e27a7ad57b36d0220361732ced04a6f97351ecca21a56d0b8cd4932c1da1f8f569a2b68e5e48aed7801", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000001 + ], + "0x16 0x001491b24bf9f5288532960ac687abb035127b1d28a5", + "HASH160 0x14 0x17743beb429c55c942d2ec703b98c4d57c2df5c6 EQUAL", + "P2SH,WITNESS", + "OK", + "Basic P2SH(P2WPKH)" +], +[ + [ + "304402202589f0512cb2408fb08ed9bd24f85eb3059744d9e4f2262d0b7f1338cff6e8b902206c0978f449693e0578c71bc543b11079fd0baae700ee5e9a6bee94db490af9fc01", + "41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac", + 0.00000000 + ], + "", + "0 0x20 0xac8ebd9e52c17619a381fa4f71aebb696087c6ef17c960fd0587addad99c0610", + "P2SH,WITNESS", + "EVAL_FALSE", + "Basic P2WSH with the wrong key" +], +[ + [ + "304402206ef7fdb2986325d37c6eb1a8bb24aeb46dede112ed8fc76c7d7500b9b83c0d3d02201edc2322c794fe2d6b0bd73ed319e714aa9b86d8891961530d5c9b7156b60d4e01", + "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf", + 0.00000000 + ], + "", + "0 0x14 0x7cf9c846cd4882efec4bf07e44ebdad495c94f4b", + "P2SH,WITNESS", + "EVAL_FALSE", + "Basic P2WPKH with the wrong key" +], +[ + [ + "30440220069ea3581afaf8187f63feee1fd2bd1f9c0dc71ea7d6e8a8b07ee2ebcf824bf402201a4fdef4c532eae59223be1eda6a397fc835142d4ddc6c74f4aa85b766a5c16f01", + "41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac", + 0.00000000 + ], + "0x22 0x0020ac8ebd9e52c17619a381fa4f71aebb696087c6ef17c960fd0587addad99c0610", + "HASH160 0x14 0x61039a003883787c0d6ebc66d97fdabe8e31449d EQUAL", + "P2SH,WITNESS", + "EVAL_FALSE", + "Basic P2SH(P2WSH) with the wrong key" +], +[ + [ + "304402204209e49457c2358f80d0256bc24535b8754c14d08840fc4be762d6f5a0aed80b02202eaf7d8fc8d62f60c67adcd99295528d0e491ae93c195cec5a67e7a09532a88001", + "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf", + 0.00000000 + ], + "0x16 0x00147cf9c846cd4882efec4bf07e44ebdad495c94f4b", + "HASH160 0x14 0x4e0c2aed91315303fc6a1dc4c7bc21c88f75402e EQUAL", + "P2SH,WITNESS", + "EVAL_FALSE", + "Basic P2SH(P2WPKH) with the wrong key" +], +[ + [ + "304402202589f0512cb2408fb08ed9bd24f85eb3059744d9e4f2262d0b7f1338cff6e8b902206c0978f449693e0578c71bc543b11079fd0baae700ee5e9a6bee94db490af9fc01", + "41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac", + 0.00000000 + ], + "", + "0 0x20 0xac8ebd9e52c17619a381fa4f71aebb696087c6ef17c960fd0587addad99c0610", + "P2SH", + "OK", + "Basic P2WSH with the wrong key but no WITNESS" +], +[ + [ + "304402206ef7fdb2986325d37c6eb1a8bb24aeb46dede112ed8fc76c7d7500b9b83c0d3d02201edc2322c794fe2d6b0bd73ed319e714aa9b86d8891961530d5c9b7156b60d4e01", + "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf", + 0.00000000 + ], + "", + "0 0x14 0x7cf9c846cd4882efec4bf07e44ebdad495c94f4b", + "P2SH", + "OK", + "Basic P2WPKH with the wrong key but no WITNESS" +], +[ + [ + "30440220069ea3581afaf8187f63feee1fd2bd1f9c0dc71ea7d6e8a8b07ee2ebcf824bf402201a4fdef4c532eae59223be1eda6a397fc835142d4ddc6c74f4aa85b766a5c16f01", + "41048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26cafac", + 0.00000000 + ], + "0x22 0x0020ac8ebd9e52c17619a381fa4f71aebb696087c6ef17c960fd0587addad99c0610", + "HASH160 0x14 0x61039a003883787c0d6ebc66d97fdabe8e31449d EQUAL", + "P2SH", + "OK", + "Basic P2SH(P2WSH) with the wrong key but no WITNESS" +], +[ + [ + "304402204209e49457c2358f80d0256bc24535b8754c14d08840fc4be762d6f5a0aed80b02202eaf7d8fc8d62f60c67adcd99295528d0e491ae93c195cec5a67e7a09532a88001", + "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf", + 0.00000000 + ], + "0x16 0x00147cf9c846cd4882efec4bf07e44ebdad495c94f4b", + "HASH160 0x14 0x4e0c2aed91315303fc6a1dc4c7bc21c88f75402e EQUAL", + "P2SH", + "OK", + "Basic P2SH(P2WPKH) with the wrong key but no WITNESS" +], +[ + [ + "3044022066faa86e74e8b30e82691b985b373de4f9e26dc144ec399c4f066aa59308e7c202204712b86f28c32503faa051dbeabff2c238ece861abc36c5e0b40b1139ca222f001", + "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + 0.00000000 + ], + "", + "0 0x20 0xb95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", + "P2SH,WITNESS", + "EVAL_FALSE", + "Basic P2WSH with wrong value" +], +[ + [ + "304402203b3389b87448d7dfdb5e82fb854fcf92d7925f9938ea5444e36abef02c3d6a9602202410bc3265049abb07fd2e252c65ab7034d95c9d5acccabe9fadbdc63a52712601", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000000 + ], + "", + "0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5", + "P2SH,WITNESS", + "EVAL_FALSE", + "Basic P2WPKH with wrong value" +], +[ + [ + "3044022000a30c4cfc10e4387be528613575434826ad3c15587475e0df8ce3b1746aa210022008149265e4f8e9dafe1f3ea50d90cb425e9e40ea7ebdd383069a7cfa2b77004701", + "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + 0.00000000 + ], + "0x22 0x0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", + "HASH160 0x14 0xf386c2ba255cc56d20cfa6ea8b062f8b59945518 EQUAL", + "P2SH,WITNESS", + "EVAL_FALSE", + "Basic P2SH(P2WSH) with wrong value" +], +[ + [ + "304402204fc3a2cd61a47913f2a5f9107d0ad4a504c7b31ee2d6b3b2f38c2b10ee031e940220055d58b7c3c281aaa381d8f486ac0f3e361939acfd568046cb6a311cdfa974cf01", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000000 + ], + "0x16 0x001491b24bf9f5288532960ac687abb035127b1d28a5", + "HASH160 0x14 0x17743beb429c55c942d2ec703b98c4d57c2df5c6 EQUAL", + "P2SH,WITNESS", + "EVAL_FALSE", + "Basic P2SH(P2WPKH) with wrong value" +], +[ + [ + "304402205ae57ae0534c05ca9981c8a6cdf353b505eaacb7375f96681a2d1a4ba6f02f84022056248e68643b7d8ce7c7d128c9f1f348bcab8be15d094ad5cadd24251a28df8001", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000000 + ], + "", + "1 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5", + "DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM,P2SH,WITNESS", + "DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM", + "P2WPKH with future witness version" +], +[ + [ + "3044022064100ca0e2a33332136775a86cd83d0230e58b9aebb889c5ac952abff79a46ef02205f1bf900e022039ad3091bdaf27ac2aef3eae9ed9f190d821d3e508405b9513101", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000000 + ], + "", + "0 0x1f 0xb34b78da162751647974d5cb7410aa428ad339dbf7d1e16e833f68a0cbf1c3", + "P2SH,WITNESS", + "WITNESS_PROGRAM_WRONG_LENGTH", + "P2WPKH with wrong witness program length" +], +[ + "", + "0 0x20 0xb95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", + "P2SH,WITNESS", + "WITNESS_PROGRAM_WITNESS_EMPTY", + "P2WSH with empty witness" +], +[ + [ + "3044022039105b995a5f448639a997a5c90fda06f50b49df30c3bdb6663217bf79323db002206fecd54269dec569fcc517178880eb58bb40f381a282bb75766ff3637d5f4b4301", + "400479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + 0.00000000 + ], + "", + "0 0x20 0xb95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", + "P2SH,WITNESS", + "WITNESS_PROGRAM_MISMATCH", + "P2WSH with witness program mismatch" +], +[ + [ + "304402201a96950593cb0af32d080b0f193517f4559241a8ebd1e95e414533ad64a3f423022047f4f6d3095c23235bdff3aeff480d0529c027a3f093cb265b7cbf148553b85101", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + "", + 0.00000000 + ], + "", + "0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5", + "P2SH,WITNESS", + "WITNESS_PROGRAM_MISMATCH", + "P2WPKH with witness program mismatch" +], +[ + [ + "304402201a96950593cb0af32d080b0f193517f4559241a8ebd1e95e414533ad64a3f423022047f4f6d3095c23235bdff3aeff480d0529c027a3f093cb265b7cbf148553b85101", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000000 + ], + "11", + "0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5", + "P2SH,WITNESS", + "WITNESS_MALLEATED", + "P2WPKH with non-empty scriptSig" +], +[ + [ + "304402204209e49457c2358f80d0256bc24535b8754c14d08840fc4be762d6f5a0aed80b02202eaf7d8fc8d62f60c67adcd99295528d0e491ae93c195cec5a67e7a09532a88001", + "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf", + 0.00000000 + ], + "11 0x16 0x00147cf9c846cd4882efec4bf07e44ebdad495c94f4b", + "HASH160 0x14 0x4e0c2aed91315303fc6a1dc4c7bc21c88f75402e EQUAL", + "P2SH,WITNESS", + "WITNESS_MALLEATED_P2SH", + "P2SH(P2WPKH) with superfluous push in scriptSig" +], +[ + [ + "", + 0.00000000 + ], + "0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", + "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", + "P2SH,WITNESS", + "WITNESS_UNEXPECTED", + "P2PK with witness" +], + +["Testing with compressed keys in witness v0 with WITNESS_PUBKEYTYPE"], +[ + [ + "304402204256146fcf8e73b0fd817ffa2a4e408ff0418ff987dd08a4f485b62546f6c43c02203f3c8c3e2febc051e1222867f5f9d0eaf039d6792911c10940aa3cc74123378e01", + "210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", + 0.00000001 + ], + "", + "0 0x20 0x1863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "Basic P2WSH with compressed key" +], +[ + [ + "304402204edf27486f11432466b744df533e1acac727e0c83e5f912eb289a3df5bf8035f022075809fdd876ede40ad21667eba8b7e96394938f9c9c50f11b6a1280cce2cea8601", + "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + 0.00000001 + ], + "", + "0 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "Basic P2WPKH with compressed key" +], +[ + [ + "304402203a549090cc46bce1e5e95c4922ea2c12747988e0207b04c42f81cdbe87bb1539022050f57a245b875fd5119c419aaf050bcdf41384f0765f04b809e5bced1fe7093d01", + "210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", + 0.00000001 + ], + "0x22 0x00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262", + "HASH160 0x14 0xe4300531190587e3880d4c3004f5355d88ff928d EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "Basic P2SH(P2WSH) with compressed key" +], +[ + [ + "304402201bc0d53046827f4a35a3166e33e3b3366c4085540dc383b95d21ed2ab11e368a0220333e78c6231214f5f8e59621e15d7eeab0d4e4d0796437e00bfbd2680c5f9c1701", + "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + 0.00000001 + ], + "0x16 0x0014751e76e8199196d454941c45d1b3a323f1433bd6", + "HASH160 0x14 0xbcfeb728b584253d5f3f70bcb780e9ef218a68f4 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "Basic P2SH(P2WPKH) with compressed key" +], + +["Testing with uncompressed keys in witness v0 with WITNESS_PUBKEYTYPE"], +[ + [ + "304402200d461c140cfdfcf36b94961db57ae8c18d1cb80e9d95a9e47ac22470c1bf125502201c8dc1cbfef6a3ef90acbbb992ca22fe9466ee6f9d4898eda277a7ac3ab4b25101", + "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + 0.00000001 + ], + "", + "0 0x20 0xb95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "Basic P2WSH" +], +[ + [ + "304402201e7216e5ccb3b61d46946ec6cc7e8c4e0117d13ac2fd4b152197e4805191c74202203e9903e33e84d9ee1dd13fb057afb7ccfb47006c23f6a067185efbc9dd780fc501", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000001 + ], + "", + "0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "Basic P2WPKH" +], +[ + [ + "3044022066e02c19a513049d49349cf5311a1b012b7c4fae023795a18ab1d91c23496c22022025e216342c8e07ce8ef51e8daee88f84306a9de66236cab230bb63067ded1ad301", + "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + 0.00000001 + ], + "0x22 0x0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", + "HASH160 0x14 0xf386c2ba255cc56d20cfa6ea8b062f8b59945518 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "Basic P2SH(P2WSH)" +], +[ + [ + "304402200929d11561cd958460371200f82e9cae64c727a495715a31828e27a7ad57b36d0220361732ced04a6f97351ecca21a56d0b8cd4932c1da1f8f569a2b68e5e48aed7801", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000001 + ], + "0x16 0x001491b24bf9f5288532960ac687abb035127b1d28a5", + "HASH160 0x14 0x17743beb429c55c942d2ec703b98c4d57c2df5c6 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "Basic P2SH(P2WPKH)" +], + +["Testing P2WSH multisig with compressed keys"], +[ + [ + "", + "304402207eb8a59b5c65fc3f6aeef77066556ed5c541948a53a3ba7f7c375b8eed76ee7502201e036a7a9a98ff919ff94dc905d67a1ec006f79ef7cff0708485c8bb79dce38e01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x06c24420938f0fa3c1cb2707d867154220dca365cdbfa0dd2a83854730221460", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2WSH CHECKMULTISIG with compressed keys" +], +[ + [ + "", + "3044022033706aed33b8155d5486df3b9bca8cdd3bd4bdb5436dce46d72cdaba51d22b4002203626e94fe53a178af46624f17315c6931f20a30b103f5e044e1eda0c3fe185c601", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x002006c24420938f0fa3c1cb2707d867154220dca365cdbfa0dd2a83854730221460", + "HASH160 0x14 0x26282aad7c29369d15fed062a778b6100d31a340 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2SH(P2WSH) CHECKMULTISIG with compressed keys" +], +[ + [ + "", + "304402204048b7371ab1c544362efb89af0c80154747d665aa4fcfb2edfd2d161e57b42e02207e043748e96637080ffc3acbd4dcc6fee1e58d30f6d1269535f32188e5ddae7301", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x06c24420938f0fa3c1cb2707d867154220dca365cdbfa0dd2a83854730221460", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2WSH CHECKMULTISIG with compressed keys" +], +[ + [ + "", + "3044022073902ef0b8a554c36c44cc03c1b64df96ce2914ebcf946f5bb36078fd5245cdf02205b148f1ba127065fb8c83a5a9576f2dcd111739788ed4bb3ee08b2bd3860c91c01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x002006c24420938f0fa3c1cb2707d867154220dca365cdbfa0dd2a83854730221460", + "HASH160 0x14 0x26282aad7c29369d15fed062a778b6100d31a340 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2SH(P2WSH) CHECKMULTISIG with compressed keys" +], + +["Testing P2WSH multisig with compressed and uncompressed keys (first key being the key closer to the top of stack)"], +[ + [ + "", + "304402202d092ededd1f060609dbf8cb76950634ff42b3e62cf4adb69ab92397b07d742302204ff886f8d0817491a96d1daccdcc820f6feb122ee6230143303100db37dfa79f01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "", + "0 0x20 0x08a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "P2SH,WITNESS", + "OK", + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key" +], +[ + [ + "", + "304402202dd7e91243f2235481ffb626c3b7baf2c859ae3a5a77fb750ef97b99a8125dc002204960de3d3c3ab9496e218ec57e5240e0e10a6f9546316fe240c216d45116d29301", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "0x22 0x002008a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "HASH160 0x14 0x6f5ecd4b83b77f3c438f5214eff96454934fc5d1 EQUAL", + "P2SH,WITNESS", + "OK", + "P2SH(P2WSH) CHECKMULTISIG first key uncompressed and signing with the first key" +], +[ + [ + "", + "304402202d092ededd1f060609dbf8cb76950634ff42b3e62cf4adb69ab92397b07d742302204ff886f8d0817491a96d1daccdcc820f6feb122ee6230143303100db37dfa79f01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "", + "0 0x20 0x08a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key" +], +[ + [ + "", + "304402202dd7e91243f2235481ffb626c3b7baf2c859ae3a5a77fb750ef97b99a8125dc002204960de3d3c3ab9496e218ec57e5240e0e10a6f9546316fe240c216d45116d29301", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "0x22 0x002008a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "HASH160 0x14 0x6f5ecd4b83b77f3c438f5214eff96454934fc5d1 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the first key" +], +[ + [ + "", + "304402201e9e6f7deef5b2f21d8223c5189b7d5e82d237c10e97165dd08f547c4e5ce6ed02206796372eb1cc6acb52e13ee2d7f45807780bf96b132cb6697f69434be74b1af901", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "", + "0 0x20 0x08a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "P2SH,WITNESS", + "OK", + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key" +], +[ + [ + "", + "3044022045e667f3f0f3147b95597a24babe9afecea1f649fd23637dfa7ed7e9f3ac18440220295748e81005231135289fe3a88338dabba55afa1bdb4478691337009d82b68d01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "0x22 0x002008a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "HASH160 0x14 0x6f5ecd4b83b77f3c438f5214eff96454934fc5d1 EQUAL", + "P2SH,WITNESS", + "OK", + "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key" +], +[ + [ + "", + "304402201e9e6f7deef5b2f21d8223c5189b7d5e82d237c10e97165dd08f547c4e5ce6ed02206796372eb1cc6acb52e13ee2d7f45807780bf96b132cb6697f69434be74b1af901", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "", + "0 0x20 0x08a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key" +], +[ + [ + "", + "3044022045e667f3f0f3147b95597a24babe9afecea1f649fd23637dfa7ed7e9f3ac18440220295748e81005231135289fe3a88338dabba55afa1bdb4478691337009d82b68d01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "0x22 0x002008a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "HASH160 0x14 0x6f5ecd4b83b77f3c438f5214eff96454934fc5d1 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key" +], +[ + [ + "", + "3044022046f5367a261fd8f8d7de6eb390491344f8ec2501638fb9a1095a0599a21d3f4c02205c1b3b51d20091c5f1020841bbca87b44ebe25405c64e4acf758f2eae8665f8401", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "P2SH,WITNESS", + "OK", + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key" +], +[ + [ + "", + "3044022053e210e4fb1881e6092fd75c3efc5163105599e246ded661c0ee2b5682cc2d6c02203a26b7ada8682a095b84c6d1b881637000b47d761fc837c4cee33555296d63f101", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x0020230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "HASH160 0x14 0x3478e7019ce61a68148f87549579b704cbe4c393 EQUAL", + "P2SH,WITNESS", + "OK", + "P2SH(P2WSH) CHECKMULTISIG second key uncompressed and signing with the first key" +], +[ + [ + "", + "3044022046f5367a261fd8f8d7de6eb390491344f8ec2501638fb9a1095a0599a21d3f4c02205c1b3b51d20091c5f1020841bbca87b44ebe25405c64e4acf758f2eae8665f8401", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used" +], +[ + [ + "", + "3044022053e210e4fb1881e6092fd75c3efc5163105599e246ded661c0ee2b5682cc2d6c02203a26b7ada8682a095b84c6d1b881637000b47d761fc837c4cee33555296d63f101", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x0020230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "HASH160 0x14 0x3478e7019ce61a68148f87549579b704cbe4c393 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used" +], +[ + [ + "", + "304402206c6d9f5daf85b54af2a93ec38b15ab27f205dbf5c735365ff12451e43613d1f40220736a44be63423ed5ebf53491618b7cc3d8a5093861908da853739c73717938b701", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "P2SH,WITNESS", + "OK", + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key" +], +[ + [ + "", + "30440220687871bc6144012d75baf585bb26ce13997f7d8c626f4d8825b069c3b2d064470220108936fe1c57327764782253e99090b09c203ec400ed35ce9e026ce2ecf842a001", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x0020230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "HASH160 0x14 0x3478e7019ce61a68148f87549579b704cbe4c393 EQUAL", + "P2SH,WITNESS", + "OK", + "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key" +], +[ + [ + "", + "304402206c6d9f5daf85b54af2a93ec38b15ab27f205dbf5c735365ff12451e43613d1f40220736a44be63423ed5ebf53491618b7cc3d8a5093861908da853739c73717938b701", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key" +], +[ + [ + "", + "30440220687871bc6144012d75baf585bb26ce13997f7d8c626f4d8825b069c3b2d064470220108936fe1c57327764782253e99090b09c203ec400ed35ce9e026ce2ecf842a001", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x0020230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "HASH160 0x14 0x3478e7019ce61a68148f87549579b704cbe4c393 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key" +], + +["CHECKSEQUENCEVERIFY tests"], +["", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on an empty stack"], ["-1", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "NEGATIVE_LOCKTIME", "CSV automatically fails if stack top is negative"], ["0x0100", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY,MINIMALDATA", "UNKNOWN_ERROR", "CSV fails if stack top is not minimally encoded"], ["0", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is set and the tx version < 2"], ["4294967296", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is not set, and tx version < 2"], + +["MINIMALIF tests"], +["MINIMALIF is not applied to non-segwit scripts"], +["1", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"], +["2", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"], +["0x02 0x0100", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"], +["0", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0x01 0x00", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["1", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["2", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0x02 0x0100", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"], +["0x01 0x00", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"], +["Normal P2SH IF 1 ENDIF"], +["1 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +["2 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +["0x02 0x0100 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +["0 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0x01 0x00 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], +["Normal P2SH NOTIF 1 ENDIF"], +["1 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["2 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0x02 0x0100 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +["0x01 0x00 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +["0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], +["P2WSH IF 1 ENDIF"], +[["01", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "OK"], +[["02", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "OK"], +[["0100", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "OK"], +[["", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "EVAL_FALSE"], +[["00", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "EVAL_FALSE"], +[["01", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "OK"], +[["02", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["0100", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +[["00", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"], +[["635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], +["P2WSH NOTIF 1 ENDIF"], +[["01", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "EVAL_FALSE"], +[["02", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "EVAL_FALSE"], +[["0100", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "EVAL_FALSE"], +[["", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "OK"], +[["00", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "OK"], +[["01", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +[["02", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["0100", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "OK"], +[["00", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"], +[["645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], + + + +["P2SH-P2WSH IF 1 ENDIF"], +[["01", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "OK"], +[["02", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "OK"], +[["0100", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "OK"], +[["", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "EVAL_FALSE"], +[["00", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "EVAL_FALSE"], +[["01", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +[["02", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["0100", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +[["00", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"], +[["635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], +["P2SH-P2WSH NOTIF 1 ENDIF"], +[["01", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "EVAL_FALSE"], +[["02", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "EVAL_FALSE"], +[["0100", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "EVAL_FALSE"], +[["", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "OK"], +[["00", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "OK"], +[["01", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +[["02", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["0100", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +[["00", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"], +[["645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], + +["NULLFAIL should cover all signatures and signatures only"], +["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66 and NULLFAIL-compliant"], +["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "OK", "BIP66 and NULLFAIL-compliant"], +["1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "OK", "BIP66 and NULLFAIL-compliant, not NULLDUMMY-compliant"], +["1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL,NULLDUMMY", "SIG_NULLDUMMY", "BIP66 and NULLFAIL-compliant, not NULLDUMMY-compliant"], +["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x09 0x300602010102010101", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66-compliant but not NULLFAIL-compliant"], +["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x09 0x300602010102010101", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "NULLFAIL", "BIP66-compliant but not NULLFAIL-compliant"], +["0 0x09 0x300602010102010101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66-compliant but not NULLFAIL-compliant"], +["0 0x09 0x300602010102010101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "NULLFAIL", "BIP66-compliant but not NULLFAIL-compliant"], + ["The End"] ] diff --git a/test/script.c b/test/script.c index 1e6f1e9c..16b41944 100644 --- a/test/script.c +++ b/test/script.c @@ -1,17 +1,24 @@ +/* Copyright 2012 exMULTI, Inc. + * Distributed under the MIT/X11 software license, see the accompanying + * file COPYING or http://www.opensource.org/licenses/mit-license.php. + */ -#include "picocoin-config.h" +#include "libtest.h" // for parse_script_str, etc +#include // for bp_tx, bp_txin, etc +#include // for cstr_free, cstring +#include // for hex2str +#include // for bp_script_verify, etc -#include -#include -#include -#include -#include #include -#include -#include -#include "libtest.h" -struct bp_tx BuildCreditingTransaction(struct cstring *scriptPubKey) +#include // for assert +#include // for true, bool, false +#include // for fprintf, stderr +#include // for NULL, free +#include // for strcmp, strtok, strlen + + +struct bp_tx BuildCreditingTransaction(struct cstring* scriptPubKey, int64_t nValue) { struct bp_tx txCredit; bp_tx_init(&txCredit); @@ -33,14 +40,16 @@ struct bp_tx BuildCreditingTransaction(struct cstring *scriptPubKey) struct bp_txout *txoutCredit = calloc(1, sizeof(struct bp_txout)); bp_txout_init(txoutCredit); txoutCredit->scriptPubKey = cstr_new_buf(scriptPubKey->str, scriptPubKey->len); - txoutCredit->nValue = (uint64_t) 0; + txoutCredit->nValue = nValue; parr_add(txCredit.vout, txoutCredit); bp_tx_calc_sha256(&txCredit); return txCredit; } -struct bp_tx BuildSpendingTransaction(struct cstring* scriptSig, struct bp_tx* txCredit) +struct bp_tx BuildSpendingTransaction(struct cstring* scriptSig, + parr* scriptWitness, + struct bp_tx* txCredit) { struct bp_tx txSpend; bp_tx_init(&txSpend); @@ -51,116 +60,150 @@ struct bp_tx BuildSpendingTransaction(struct cstring* scriptSig, struct bp_tx* t struct bp_txin* txinSpend = calloc(1, sizeof(struct bp_txin)); bp_txin_init(txinSpend); + txinSpend->scriptWitness = scriptWitness; bu256_copy(&txinSpend->prevout.hash, &txCredit->sha256); txinSpend->prevout.n = 0; txinSpend->scriptSig = cstr_new_buf(scriptSig->str, scriptSig->len); txinSpend->nSequence = SEQUENCE_FINAL; parr_add(txSpend.vin, txinSpend); - struct bp_txout *txoutSpend = calloc(1, sizeof(struct bp_txout)); + struct bp_txout* txoutSpend = calloc(1, sizeof(struct bp_txout)); bp_txout_init(txoutSpend); - txoutSpend->scriptPubKey = cstr_new(NULL); // - txoutSpend->nValue =(uint64_t) 0; + txoutSpend->scriptPubKey = cstr_new(NULL); + struct bp_txout* txoutCredit = parr_idx(txCredit->vout, 0); + txoutSpend->nValue = txoutCredit->nValue; parr_add(txSpend.vout, txoutSpend); bp_tx_free(txCredit); return txSpend; } -static void test_script(bool is_valid, cstring* scriptSig, - cstring* scriptPubKey, unsigned int idx, - const char* scriptSigEnc, const char* scriptPubKeyEnc, - const unsigned int test_flags) +static void test_script(bool is_valid, cstring* scriptSig, cstring* scriptPubKey, + parr* scriptWitness, unsigned int idx, const char* scriptSigString, + const char* scriptPubKeyString, const unsigned int test_flags,int64_t nValue) { - struct bp_tx tx = BuildCreditingTransaction(scriptPubKey); - tx = BuildSpendingTransaction(scriptSig, &tx); + struct bp_tx tx = BuildCreditingTransaction(scriptPubKey, nValue); + tx = BuildSpendingTransaction(scriptSig, scriptWitness, &tx); bool rc; - rc = bp_script_verify(scriptSig, scriptPubKey, &tx, 0, test_flags, SIGHASH_NONE); + rc = bp_script_verify( + scriptSig, scriptPubKey, scriptWitness, &tx, 0, test_flags, SIGHASH_NONE, nValue); if (rc != is_valid) { fprintf(stderr, "script: %sis_valid test %u failed\n" "script: [\"%s\", \"%s\"]\n", - is_valid ? "" : "!", idx, scriptSigEnc, scriptPubKeyEnc); + is_valid ? "" : "!", idx, scriptSigString, scriptPubKeyString); assert(rc == is_valid); } bp_tx_free(&tx); } -static void runtest(const char *basefn) +static void runtest(const char *json_base_fn) { - char *fn = test_filename(basefn); - json_t *tests = read_json(fn); - assert(json_is_array(tests)); - static unsigned int verify_flags; - bool is_valid; - - unsigned int idx; - for (idx = 0; idx < json_array_size(tests); idx++) { - json_t *test = json_array_get(tests, idx); - assert(json_is_array(test)); - unsigned int pos = 0; - if ( json_array_size(test) > 1) { - const char *scriptSigEnc = + char* json_fn = test_filename(json_base_fn); + json_t* tests = read_json(json_fn); + assert(tests != NULL); + assert(json_is_array(tests)); + static unsigned int verify_flags; + bool is_valid; + + unsigned int idx; + for (idx = 0; idx < json_array_size(tests); idx++) { + json_t* test = json_array_get(tests, idx); + assert(json_is_array(test)); + parr* scriptWitness = parr_new(0, buffer_freep); + int64_t nValue = 0; + unsigned int pos = 0; + if ((json_array_size(test) > 0) && + (json_is_array(json_array_get(test, pos)))) { + json_t* witness_data = json_array_get(test, pos); + unsigned int i; + for (i = 0; i < json_array_size(witness_data) - 1; i++) { + cstring* witness = hex2str(json_string_value(json_array_get(witness_data, i))); + if (!witness) + witness = cstr_new_sz(0); + parr_add(scriptWitness, buffer_copy(witness->str, witness->len)); + cstr_free(witness, true); + } + nValue = json_number_value(json_array_get(witness_data, i)) * COIN; + pos++; + } + + // Allow size > 3; extra stuff ignored (useful for comments) + if (json_array_size(test) < 4 + pos) { + if (json_array_size(test) != 1) { + fprintf(stderr, "script: Bad test %u\n", idx); + } + continue; + } + + const char* scriptSigString = json_string_value(json_array_get(test, pos++)); - const char *scriptPubKeyEnc = + assert(scriptSigString != NULL); + cstring* scriptSig = parse_script_str(scriptSigString); + assert(scriptSig != NULL); + + const char *scriptPubKeyString = json_string_value(json_array_get(test, pos++)); - assert(scriptSigEnc != NULL); - assert(scriptPubKeyEnc != NULL); - - cstring *scriptSig = parse_script_str(scriptSigEnc); - - cstring *scriptPubKey = parse_script_str(scriptPubKeyEnc); - assert(scriptSig != NULL); - assert(scriptPubKey != NULL); - - verify_flags = SCRIPT_VERIFY_NONE; - - const char *json_flags = json_string_value(json_array_get(test, pos++)); - - if (strlen(json_flags) > 0) { - const char* json_flag = strtok((char *)json_flags, ","); - - do { - if (strcmp(json_flag, "P2SH") == 0) - verify_flags |= SCRIPT_VERIFY_P2SH; - else if (strcmp(json_flag, "STRICTENC") == 0) - verify_flags |= SCRIPT_VERIFY_STRICTENC; - else if (strcmp(json_flag, "DERSIG") == 0) - verify_flags |= SCRIPT_VERIFY_DERSIG; - else if (strcmp(json_flag, "LOW_S") == 0) - verify_flags |= SCRIPT_VERIFY_LOW_S; - else if (strcmp(json_flag, "NULLDUMMY") == 0) - verify_flags |= SCRIPT_VERIFY_NULLDUMMY; - else if (strcmp(json_flag, "SIGPUSHONLY") == 0) - verify_flags |= SCRIPT_VERIFY_SIGPUSHONLY; - else if (strcmp(json_flag, "MINIMALDATA") == 0) - verify_flags |= SCRIPT_VERIFY_MINIMALDATA; - else if (strcmp(json_flag, "DISCOURAGE_UPGRADABLE_NOPS") == 0) - verify_flags |= SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS; - else if (strcmp(json_flag, "CLEANSTACK") == 0) - verify_flags |= SCRIPT_VERIFY_CLEANSTACK; - else if (strcmp(json_flag, "CHECKSEQUENCEVERIFY") == 0) - verify_flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; - json_flag = strtok(NULL, ","); - } while (json_flag); - } - - const char *scriptError = - json_string_value(json_array_get(test, 3)); - - is_valid = strcmp(scriptError, "OK") == 0 ? true : false; - test_script(is_valid, scriptSig, scriptPubKey, - idx, scriptSigEnc, scriptPubKeyEnc, verify_flags); - - cstr_free(scriptSig, true); - cstr_free(scriptPubKey, true); - } - } - - json_decref(tests); - free(fn); + assert(scriptPubKeyString != NULL); + cstring* scriptPubKey = parse_script_str(scriptPubKeyString); + assert(scriptPubKey != NULL); + + verify_flags = SCRIPT_VERIFY_NONE; + + const char *json_flags = json_string_value(json_array_get(test, pos++)); + if (strlen(json_flags) > 0) { + const char* json_flag = strtok((char*)json_flags, ","); + + do { + if (strcmp(json_flag, "P2SH") == 0) + verify_flags |= SCRIPT_VERIFY_P2SH; + else if (strcmp(json_flag, "STRICTENC") == 0) + verify_flags |= SCRIPT_VERIFY_STRICTENC; + else if (strcmp(json_flag, "DERSIG") == 0) + verify_flags |= SCRIPT_VERIFY_DERSIG; + else if (strcmp(json_flag, "LOW_S") == 0) + verify_flags |= SCRIPT_VERIFY_LOW_S; + else if (strcmp(json_flag, "NULLDUMMY") == 0) + verify_flags |= SCRIPT_VERIFY_NULLDUMMY; + else if (strcmp(json_flag, "SIGPUSHONLY") == 0) + verify_flags |= SCRIPT_VERIFY_SIGPUSHONLY; + else if (strcmp(json_flag, "MINIMALDATA") == 0) + verify_flags |= SCRIPT_VERIFY_MINIMALDATA; + else if (strcmp(json_flag, "DISCOURAGE_UPGRADABLE_NOPS") == 0) + verify_flags |= SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS; + else if (strcmp(json_flag, "CLEANSTACK") == 0) + verify_flags |= SCRIPT_VERIFY_CLEANSTACK; + else if (strcmp(json_flag, "CHECKSEQUENCEVERIFY") == 0) + verify_flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; + else if (strcmp(json_flag, "WITNESS") == 0) + verify_flags |= SCRIPT_VERIFY_WITNESS; + else if (strcmp(json_flag, "DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM") == 0) + verify_flags |= SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM; + else if (strcmp(json_flag, "MINIMALIF") == 0) + verify_flags |= SCRIPT_VERIFY_MINIMALIF; + else if (strcmp(json_flag, "NULLFAIL") == 0) + verify_flags |= SCRIPT_VERIFY_NULLFAIL; + else if (strcmp(json_flag, "WITNESS_PUBKEYTYPE") == 0) + verify_flags |= SCRIPT_VERIFY_WITNESS_PUBKEYTYPE; + json_flag = strtok(NULL, ","); + } while (json_flag); + } + + const char* scriptError = json_string_value(json_array_get(test, pos++)); + + is_valid = strcmp(scriptError, "OK") == 0 ? true : false; + test_script(is_valid, scriptSig, scriptPubKey, scriptWitness, idx, + scriptSigString, scriptPubKeyString, verify_flags, nValue); + + cstr_free(scriptSig, true); + cstr_free(scriptPubKey, true); + parr_free(scriptWitness, true); + } + + json_decref(tests); + free(json_fn); } int main (int argc, char *argv[]) diff --git a/test/sighash.c b/test/sighash.c index 56e49db0..20366dcc 100644 --- a/test/sighash.c +++ b/test/sighash.c @@ -54,14 +54,14 @@ static void runtest(const char* json_base_fn) assert(bp_tx_valid(&txTo) == true); const char *scriptCode_hexser = json_string_value(json_array_get(test, 1)); - assert(scriptCode_hexser != NULL); - cstring *scriptCode = hex2str(scriptCode_hexser); + assert(scriptCode_hexser != NULL); + cstring *scriptCode = hex2str(scriptCode_hexser); - unsigned int nIn = json_integer_value(json_array_get(test, 2)); - int nHashType = json_integer_value(json_array_get(test, 3)); + unsigned int nIn = json_integer_value(json_array_get(test, 2)); + int nHashType = json_integer_value(json_array_get(test, 3)); - bu256_t sighash; - bp_tx_sighash(&sighash, scriptCode, &txTo, nIn, nHashType); + bu256_t sighash; + bp_tx_sighash(&sighash, scriptCode, &txTo, nIn, nHashType, 0, 0); bu256_t sighash_res; hex_bu256(&sighash_res, json_string_value(json_array_get(test, 4))); diff --git a/test/tx-valid.c b/test/tx-valid.c index c8eb67d2..cf4251e3 100644 --- a/test/tx-valid.c +++ b/test/tx-valid.c @@ -94,11 +94,10 @@ static void test_tx_valid(bool is_valid, struct bp_hashtab *input_map, assert(scriptPubKey != NULL); } - bool rc = bp_script_verify(txin->scriptSig, scriptPubKey, - &tx, i, - test_flags, 0); + bool rc = bp_script_verify(txin->scriptSig, scriptPubKey, + NULL, &tx, i, test_flags, 0, 0); - state &= rc; + state &= rc; if (rc != is_valid) { char tx_hexstr[BU256_STRSZ]; From 3038a8c630dfbe25253cbd43394ba8daf9da7884 Mon Sep 17 00:00:00 2001 From: libbitc Date: Fri, 18 Aug 2017 00:45:59 +0000 Subject: [PATCH 2/3] ccoin: Implement SegWit in tx functionality and tests --- include/ccoin/coredefs.h | 15 +++- include/ccoin/script.h | 2 +- include/ccoin/serialize.h | 20 +++-- lib/block.c | 28 ++++-- lib/core.c | 99 +++++++++++++++++---- lib/message.c | 8 +- lib/script_eval.c | 85 ++++++++++-------- lib/serialize.c | 74 ++++++++++++++-- test/data/tx_invalid.json | 67 +++++++++++++- test/data/tx_valid.json | 170 ++++++++++++++++++++++++++++++++++++ test/libtest.c | 2 +- test/script.c | 4 +- test/tx-valid.c | 178 +++++++++++++++++++++----------------- 13 files changed, 580 insertions(+), 172 deletions(-) diff --git a/include/ccoin/coredefs.h b/include/ccoin/coredefs.h index 2ac67561..28675364 100644 --- a/include/ccoin/coredefs.h +++ b/include/ccoin/coredefs.h @@ -10,14 +10,23 @@ extern "C" { #endif enum { + //! BIP 0031, pong message, is enabled for all versions AFTER this one BIP0031_VERSION = 60000, - CADDR_TIME_VERSION = 31402, - MIN_PROTO_VERSION = 209, + //! nTime field added to CAddress, starting with this version; + //! if possible, avoid requesting addresses nodes older than this + CADDR_TIME_VERSION = 31402, - MAX_BLOCK_SIZE = 1000000, + //! initial proto version, to be increased after version/verack negotiation + INIT_PROTO_VERSION = 209, + /** The maximum allowed weight for a block, see BIP 141 (network rule) */ + MAX_BLOCK_WEIGHT = 4000000, + + /** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */ COINBASE_MATURITY = 100, + + WITNESS_SCALE_FACTOR = 4, }; enum { diff --git a/include/ccoin/script.h b/include/ccoin/script.h index ade60c45..7db4ca68 100644 --- a/include/ccoin/script.h +++ b/include/ccoin/script.h @@ -369,7 +369,7 @@ static inline void bsp_start(struct bscript_parser *bp, extern void bp_tx_sighash(bu256_t* hash, const cstring* scriptCode, const struct bp_tx* txTo, unsigned int nIn, int nHashType, int64_t amount, enum SigVersion sigversion); extern bool bp_script_verify(const cstring* scriptSig, const cstring* scriptPubKey, - parr* witness, const struct bp_tx* txTo, unsigned int nIn, + parr** witness, const struct bp_tx* txTo, unsigned int nIn, unsigned int flags, int nHashType, int64_t amount); extern bool bp_verify_sig(const struct bp_utxo* txFrom,const struct bp_tx* txTo, unsigned int nIn, unsigned int flags, int nHashType, int64_t amount); diff --git a/include/ccoin/serialize.h b/include/ccoin/serialize.h index 94a90fb4..c6adf49c 100644 --- a/include/ccoin/serialize.h +++ b/include/ccoin/serialize.h @@ -5,13 +5,17 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php. */ -#include -#include -#include -#include -#include -#include -#include +#include // for const_buffer +#include // for bu256_t +#include // for cstring +#include // for parr + +#include // for mpz_t + +#include // for bool +#include // for size_t +#include // for uint32_t, uint64_t, int64_t, etc + #ifdef __cplusplus extern "C" { @@ -43,6 +47,7 @@ static inline void ser_s64(cstring *s, int64_t v_) } extern void ser_u256_array(cstring *s, parr *arr); +extern void ser_varlen_array(cstring *s, parr *arr); extern bool deser_skip(struct const_buffer *buf, size_t len); extern bool deser_bytes(void *po, struct const_buffer *buf, size_t len); @@ -66,6 +71,7 @@ static inline bool deser_s64(int64_t *vo, struct const_buffer *buf) } extern bool deser_u256_array(parr **ao, struct const_buffer *buf); +extern bool deser_varlen_array(parr **ao, struct const_buffer *buf); extern void u256_from_compact(mpz_t vo, uint32_t c); diff --git a/lib/block.c b/lib/block.c index 2b4ec055..6d792e0c 100644 --- a/lib/block.c +++ b/lib/block.c @@ -4,13 +4,20 @@ */ #include "picocoin-config.h" -#include -#include -#include -#include -#include -#include -#include +#include // for bu256_t, bu256_new, etc +#include // for bitc_block, bitc_tx, etc +#include // for ::MAX_BLOCK_WEIGHT, etc +#include // for cstring +#include // for parr, parr_idx, parr_add, etc +#include // for u256_from_compact +#include // for bu_Hash_, MIN + +#include // for mpz_clear, mpz_init, mpz_t, etc + +#include // for false, bool, true +#include // for int64_t +#include // for NULL, memset +#include // for time, time_t static bool bp_has_dup_inputs(const struct bp_tx *tx) { @@ -46,7 +53,7 @@ bool bp_tx_valid(const struct bp_tx *tx) return false; // Size limits - if (bp_tx_ser_size(tx) > MAX_BLOCK_SIZE) + if (bp_tx_ser_size(tx) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) return false; // Check for negative or overflow output values @@ -215,7 +222,10 @@ bool bp_block_valid(struct bp_block *block) if (!block->vtx || !block->vtx->len) return false; - if (bp_block_ser_size(block) > MAX_BLOCK_SIZE) + if (block->vtx->len * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) + return false; + + if (bp_block_ser_size(block) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) return false; if (!bp_block_valid_target(block)) return false; diff --git a/lib/core.c b/lib/core.c index e447bcf0..830e3884 100644 --- a/lib/core.c +++ b/lib/core.c @@ -166,6 +166,11 @@ void bp_txin_free(struct bp_txin *txin) bp_outpt_free(&txin->prevout); + if (txin->scriptWitness) { + parr_free(txin->scriptWitness, true); + txin->scriptWitness = NULL; + } + if (txin->scriptSig) { cstr_free(txin->scriptSig, true); txin->scriptSig = NULL; @@ -189,6 +194,16 @@ void bp_txin_copy(struct bp_txin *dest, const struct bp_txin *src) bp_outpt_copy(&dest->prevout, &src->prevout); dest->nSequence = src->nSequence; + if (!src->scriptWitness) + dest->scriptWitness = NULL; + else { + dest->scriptWitness = parr_new(src->scriptWitness->len, buffer_freep); + unsigned int i; + for (i = 0; i < src->scriptWitness->len; i++) { + struct buffer *witness_src = parr_idx(src->scriptWitness, i); + parr_add(dest->scriptWitness, buffer_copy(witness_src->p, witness_src->len)); + } + } if (!src->scriptSig) dest->scriptSig = NULL; else { @@ -273,11 +288,13 @@ bool deser_bp_tx(struct bp_tx *tx, struct const_buffer *buf) { bp_tx_free(tx); + if (!deser_u32(&tx->nVersion, buf)) return false; + + unsigned char flags = 0; tx->vin = parr_new(8, bp_txin_freep); tx->vout = parr_new(8, bp_txout_freep); - if (!deser_u32(&tx->nVersion, buf)) return false; - + /* Try to read the vin. In case the dummy is there, this will be read as an empty vector. */ uint32_t vlen; if (!deser_varlen(&vlen, buf)) return false; @@ -294,22 +311,68 @@ bool deser_bp_tx(struct bp_tx *tx, struct const_buffer *buf) parr_add(tx->vin, txin); } - - if (!deser_varlen(&vlen, buf)) return false; - - for (i = 0; i < vlen; i++) { - struct bp_txout *txout; - - txout = calloc(1, sizeof(*txout)); - bp_txout_init(txout); - if (!deser_bp_txout(txout, buf)) { - free(txout); - goto err_out; - } - - parr_add(tx->vout, txout); - } - + if (tx->vin->len == 0) { + /* We read a dummy or an empty vin. */ + deser_bytes(&flags, buf, 1); + if (flags != 0) { + if (!deser_varlen(&vlen, buf)) return false; + for (i = 0; i < vlen; i++) { + struct bp_txin *txin; + + txin = calloc(1, sizeof(*txin)); + bp_txin_init(txin); + if (!deser_bp_txin(txin, buf)) { + free(txin); + goto err_out; + } + + parr_add(tx->vin, txin); + } + + if (!deser_varlen(&vlen, buf)) return false; + + for (i = 0; i < vlen; i++) { + struct bp_txout *txout; + + txout = calloc(1, sizeof(*txout)); + bp_txout_init(txout); + if (!deser_bp_txout(txout, buf)) { + free(txout); + goto err_out; + } + + parr_add(tx->vout, txout); + } + } + } else { + /* We read a non-empty vin. Assume a normal vout follows. */ + if (!deser_varlen(&vlen, buf)) return false; + for (i = 0; i < vlen; i++) { + struct bp_txout *txout; + + txout = calloc(1, sizeof(*txout)); + bp_txout_init(txout); + if (!deser_bp_txout(txout, buf)) { + free(txout); + goto err_out; + } + + parr_add(tx->vout, txout);; + } + } + if (flags & 1) { + /* The witness flag is present, and we support witnesses. */ + flags ^= 1; + for (i = 0; i < tx->vin->len; i++) { + struct bp_txin *txin = parr_idx(tx->vin, i); + if (!deser_varlen_array(&txin->scriptWitness, buf)) + goto err_out; + } + } + if (flags) { + /* Unknown flag in the serialization */ + goto err_out; + } if (!deser_u32(&tx->nLockTime, buf)) return false; return true; diff --git a/lib/message.c b/lib/message.c index 969b9332..35271d78 100644 --- a/lib/message.c +++ b/lib/message.c @@ -248,10 +248,10 @@ bool deser_msg_version(struct msg_version *mv, struct const_buffer *buf) mv->nVersion = 300; if (!deser_u64(&mv->nServices, buf)) return false; if (!deser_s64(&mv->nTime, buf)) return false; - if (!deser_bp_addr(MIN_PROTO_VERSION, &mv->addrTo, buf)) return false; + if (!deser_bp_addr(INIT_PROTO_VERSION, &mv->addrTo, buf)) return false; if (mv->nVersion >= 106) { - if (!deser_bp_addr(MIN_PROTO_VERSION, &mv->addrFrom, buf)) return false; + if (!deser_bp_addr(INIT_PROTO_VERSION, &mv->addrFrom, buf)) return false; if (!deser_u64(&mv->nonce, buf)) return false; if (!deser_str(mv->strSubVer, buf, sizeof(mv->strSubVer))) return false; @@ -275,8 +275,8 @@ cstring *ser_msg_version(const struct msg_version *mv) ser_u64(s, mv->nServices); ser_s64(s, mv->nTime); - ser_bp_addr(s, MIN_PROTO_VERSION, &mv->addrTo); - ser_bp_addr(s, MIN_PROTO_VERSION, &mv->addrFrom); + ser_bp_addr(s, INIT_PROTO_VERSION, &mv->addrTo); + ser_bp_addr(s, INIT_PROTO_VERSION, &mv->addrFrom); ser_u64(s, mv->nonce); ser_str(s, mv->strSubVer, sizeof(mv->strSubVer)); diff --git a/lib/script_eval.c b/lib/script_eval.c index 581ec52b..1b89ce8d 100644 --- a/lib/script_eval.c +++ b/lib/script_eval.c @@ -142,9 +142,9 @@ void bp_tx_sighash(bu256_t* hash, const cstring* scriptCode, const struct bp_tx* cstring* s = cstr_new_sz(512); if (sigversion == SIGVERSION_WITNESS_V0) { - bu256_t hashPrevouts; - bu256_t hashSequence; - bu256_t hashOutputs; + bu256_t* hashPrevouts = bu256_new(NULL); + bu256_t* hashSequence = bu256_new(NULL); + bu256_t* hashOutputs = bu256_new(NULL); if (!(nHashType & SIGHASH_ANYONECANPAY)) { cstring* s_prevout = cstr_new_sz(512); @@ -155,7 +155,7 @@ void bp_tx_sighash(bu256_t* hash, const cstring* scriptCode, const struct bp_tx* // Serialize the prevout ser_bp_outpt(s_prevout, &txin->prevout); } - bu_Hash((unsigned char*)&hashPrevouts, s_prevout->str, s_prevout->len); + bu_Hash((unsigned char*)hashPrevouts, s_prevout->str, s_prevout->len); cstr_free(s_prevout, true); } @@ -169,7 +169,7 @@ void bp_tx_sighash(bu256_t* hash, const cstring* scriptCode, const struct bp_tx* // Serialize the nSequence ser_u32(s_seq, txin->nSequence); } - bu_Hash((unsigned char*)&hashSequence, s_seq->str, s_seq->len); + bu_Hash((unsigned char*)hashSequence, s_seq->str, s_seq->len); cstr_free(s_seq, true); } @@ -181,21 +181,21 @@ void bp_tx_sighash(bu256_t* hash, const cstring* scriptCode, const struct bp_tx* txout = parr_idx(txTo->vout, i); ser_bp_txout(s_out, txout); } - bu_Hash((unsigned char*)&hashOutputs, s_out->str, s_out->len); + bu_Hash((unsigned char*)hashOutputs, s_out->str, s_out->len); cstr_free(s_out, true); } else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo->vout->len) { cstring* s_out = cstr_new_sz(512); struct bp_txout* txout = parr_idx(txTo->vout, nIn); ser_bp_txout(s_out, txout); - bu_Hash((unsigned char*)&hashOutputs, s_out->str, s_out->len); + bu_Hash((unsigned char*)hashOutputs, s_out->str, s_out->len); cstr_free(s_out, true); } // Version ser_u32(s, txTo->nVersion); // Input prevouts/nSequence (none/all, depending on flags) - ser_u256(s, &hashPrevouts); - ser_u256(s, &hashSequence); + ser_u256(s, hashPrevouts); + ser_u256(s, hashSequence); // The input being signed (replacing the scriptSig with scriptCode + amount) // The prevout may already be contained in hashPrevout, and the nSequence // may already be contain in hashSequence. @@ -205,9 +205,13 @@ void bp_tx_sighash(bu256_t* hash, const cstring* scriptCode, const struct bp_tx* ser_s64(s, amount); ser_u32(s, txin->nSequence); // Outputs (none/one/all, depending on flags) - ser_u256(s, &hashOutputs); + ser_u256(s, hashOutputs); // Locktime ser_u32(s, txTo->nLockTime); + + bu256_freep(hashPrevouts); + bu256_freep(hashSequence); + bu256_freep(hashOutputs); } else { if (nIn >= txTo->vin->len) { // nIn out of range @@ -229,6 +233,7 @@ void bp_tx_sighash(bu256_t* hash, const cstring* scriptCode, const struct bp_tx* // Sighash type ser_s32(s, nHashType); + bu_Hash((unsigned char*)hash, s->str, s->len); out: @@ -394,29 +399,29 @@ static bool bp_checksig(const struct buffer* vchSigIn, const struct buffer* vchP const cstring* scriptCode, const struct bp_tx* txTo, unsigned int nIn, int64_t amount, enum SigVersion sigversion) { - if (!vchSigIn || !vchPubKey || !scriptCode || !txTo || - !vchSigIn->len || !vchPubKey->len || !scriptCode->len) - return false; + if (!vchSigIn || !vchPubKey || !scriptCode || !txTo || !vchSigIn->len || !vchPubKey->len || + !scriptCode->len) + return false; - // Hash type is one byte tacked on to the end of the signature - unsigned char *vch_back = vchSigIn->p + (vchSigIn->len - 1); - int nHashType = *vch_back; - struct buffer vchSig = { vchSigIn->p, vchSigIn->len - 1 }; + // Hash type is one byte tacked on to the end of the signature + unsigned char* vch_back = vchSigIn->p + (vchSigIn->len - 1); + int nHashType = *vch_back; + struct buffer vchSig = {vchSigIn->p, vchSigIn->len - 1}; - /* calculate signature hash of transaction */ - bu256_t sighash; + /* calculate signature hash of transaction */ + bu256_t sighash; bp_tx_sighash(&sighash, scriptCode, txTo, nIn, nHashType, amount, sigversion); /* verify signature hash */ struct bp_key pubkey; - bp_key_init(&pubkey); - bool rc = false; - if (!bp_pubkey_set(&pubkey, vchPubKey->p, vchPubKey->len)) - goto out; - if (!bp_verify(&pubkey, &sighash, sizeof(sighash), vchSig.p, vchSig.len)) - goto out; + bp_key_init(&pubkey); + bool rc = false; + if (!bp_pubkey_set(&pubkey, vchPubKey->p, vchPubKey->len)) + goto out; + if (!bp_verify(&pubkey, &sighash, sizeof(sighash), vchSig.p, vchSig.len)) + goto out; - rc = true; + rc = true; out: bp_key_free(&pubkey); @@ -1527,9 +1532,9 @@ static bool bp_script_eval(parr* stack, const cstring* script, // Size limits if (stack->len + altstack->len > MAX_STACK_SIZE) goto out; - } + } - rc = (vfExec->len == 0 && bp.error == false); + rc = (vfExec->len == 0 && bp.error == false); out: mpz_clears(bn, bn_Zero, bn_One, NULL); @@ -1542,11 +1547,12 @@ static bool bp_witnessprogram_verify(parr* witness, int witversion, cstring* program, const struct bp_tx* txTo, + unsigned int nIn, unsigned int flags, int64_t amount) { parr* stack = parr_new(0, buffer_freep); - cstring* scriptPubKey; + cstring* scriptPubKey = NULL; bool rc = false; if (witversion == 0) { @@ -1594,7 +1600,8 @@ static bool bp_witnessprogram_verify(parr* witness, goto out; } - if (!bp_script_eval(stack, scriptPubKey, txTo, 0, flags, 0, amount, SIGVERSION_WITNESS_V0)) { + if (!bp_script_eval( + stack, scriptPubKey, txTo, nIn, flags, nIn, amount, SIGVERSION_WITNESS_V0)) { goto out; } @@ -1609,17 +1616,19 @@ static bool bp_witnessprogram_verify(parr* witness, out: parr_free(stack, true); + cstr_free(scriptPubKey, true); return rc; } bool bp_script_verify(const cstring* scriptSig, const cstring* scriptPubKey, - parr* witness, const struct bp_tx* txTo, unsigned int nIn, + parr** witness, const struct bp_tx* txTo, unsigned int nIn, unsigned int flags, int nHashType, int64_t amount) { cstring* witnessprogram = NULL; - if (witness == NULL) { - witness = parr_new(0, buffer_freep); + if (*witness == NULL) { + *witness = parr_new(0, buffer_freep); } + bool hadWitness = false; cstring* pubkey2 = NULL; @@ -1643,7 +1652,7 @@ bool bp_script_verify(const cstring* scriptSig, const cstring* scriptPubKey, goto out; if (stack->len == 0) goto out; - ; + if (CastToBool(stacktop(stack, -1)) == false) goto out; @@ -1659,7 +1668,7 @@ bool bp_script_verify(const cstring* scriptSig, const cstring* scriptPubKey, goto out; } if (!bp_witnessprogram_verify( - witness, witnessversion, witnessprogram, txTo, flags, amount)) { + *witness, witnessversion, witnessprogram, txTo, nIn, flags, amount)) { goto out; } // Bypass the cleanstack check at the end. The actual stack is obviously not clean @@ -1705,7 +1714,7 @@ bool bp_script_verify(const cstring* scriptSig, const cstring* scriptPubKey, goto out; } if (!bp_witnessprogram_verify( - witness, witnessversion, witnessprogram, txTo, flags, amount)) { + *witness, witnessversion, witnessprogram, txTo, nIn, flags, amount)) { goto out; } // Bypass the cleanstack check at the end. The actual stack is obviously not @@ -1736,7 +1745,7 @@ bool bp_script_verify(const cstring* scriptSig, const cstring* scriptPubKey, // possible, which is not a softfork. if ((flags & SCRIPT_VERIFY_P2SH) == 0) goto out; - if (!hadWitness && (witness->len != 0)) + if (!hadWitness && ((*witness)->len != 0)) goto out; } rc = true; @@ -1771,6 +1780,6 @@ bool bp_verify_sig(const struct bp_utxo* txFrom, const struct bp_tx* txTo, if (!txout) return false; - return bp_script_verify(txin->scriptSig, txout->scriptPubKey, NULL, + return bp_script_verify(txin->scriptSig, txout->scriptPubKey, &txin->scriptWitness, txTo, nIn, flags, nHashType, amount); } diff --git a/lib/serialize.c b/lib/serialize.c index ee79130f..41e68e92 100644 --- a/lib/serialize.c +++ b/lib/serialize.c @@ -2,14 +2,20 @@ * Distributed under the MIT/X11 software license, see the accompanying * file COPYING or http://www.opensource.org/licenses/mit-license.php. */ -#include "picocoin-config.h" -#include -#include -#include -#include -#include -#include +#include // for bu256_t +#include // for cstring, cstr_append_buf, etc +#include // for htole16, htole32, htole64, etc +#include // for parr, parr_idx +#include // for ser_u256 + +#include // for mpz_mul_2exp, mpz_set_ui, etc + +#include // for false, true, bool +#include // for size_t +#include // for uint32_t, uint16_t, etc +#include // for NULL, strnlen + void ser_bytes(cstring *s, const void *p, size_t len) { @@ -97,6 +103,22 @@ void ser_u256_array(cstring *s, parr *arr) } } +void ser_varlen_array(cstring* s, parr* arr) +{ + unsigned int arr_len = arr ? arr->len : 0; + + ser_varlen(s, arr_len); + + unsigned int i; + for (i = 0; i < arr_len; i++) { + struct buffer* buf; + + buf = parr_idx(arr, i); + ser_varlen(s, buf->len); + ser_bytes(s, buf->p, buf->len); + } +} + bool deser_skip(struct const_buffer *buf, size_t len) { if (buf->len < len) @@ -280,6 +302,44 @@ bool deser_u256_array(parr **ao, struct const_buffer *buf) return false; } +bool deser_varlen_array(parr** ao, struct const_buffer* buf) +{ + parr* arr = *ao; + if (arr) { + parr_free(arr, true); + *ao = arr = NULL; + } + + uint32_t vlen; + if (!deser_varlen(&vlen, buf)) + return false; + + if (!vlen) + return true; + + arr = parr_new(vlen, buffer_freep); + if (!arr) + return false; + + unsigned int i; + for (i = 0; i < vlen; i++) { + uint32_t ivlen; + if (!deser_varlen(&ivlen, buf)) + return false; + + parr_add(arr, buffer_copy(buf->p, ivlen)); + buf->p += ivlen; + buf->len -= ivlen; + } + + *ao = arr; + return true; + +err_out: + parr_free(arr, true); + return false; +} + void u256_from_compact(mpz_t vo, uint32_t c) { uint32_t nbytes = (c >> 24) & 0xFF; diff --git a/test/data/tx_invalid.json b/test/data/tx_invalid.json index c73875f1..f8baee05 100644 --- a/test/data/tx_invalid.json +++ b/test/data/tx_invalid.json @@ -30,10 +30,6 @@ "010000000100010000000000000000000000000000000000000000000000000000000000000000000009085768617420697320ffffffff010000000000000000015100000000", "P2SH"], ["Tests for CheckTransaction()"], -["No inputs"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]], -"0100000000010000000000000000015100000000", "P2SH"], - ["No outputs"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x05ab9e14d983742513f0f451e105ffb4198d1dd4 EQUAL"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022100f16703104aab4e4088317c862daec83440242411b039d14280e03dd33b487ab802201318a7be236672c5c56083eb7a5a195bc57a40af7923ff8545016cd3b571e2a601232103c40e5d339df3f30bf753e7e04450ae4ef76c9e45587d1d993bdc4cd06f0651c7acffffffff0000000000", "P2SH"], @@ -255,5 +251,68 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 CHECKSEQUENCEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +["Unknown witness program version (with DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x60 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b00000000000001510002483045022100a3cec69b52cba2d2de623ffffffffff1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"], + +["Unknown length for witness program v0"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x15 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3fff", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff04b60300000000000001519e070000000000000151860b0000000000000100960000000000000001510002473044022022fceb54f62f8feea77faac7083c3b56c4676a78f93745adc8a35800bc36adfa022026927df9abcf0a8777829bcfcce3ff0a385fa54c3f9df577405e3ef24ee56479022103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash Single|AnyoneCanPay (same index output value changed)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e80300000000000001516c070000000000000151b80b0000000000000151000248304502210092f4777a0f17bf5aeb8ae768dec5f2c14feabf9d1fe2c89c78dfed0f13fdb86902206da90a86042e252bcd1e80a168c719e4a1ddcc3cebea24b9812c5453c79107e9832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None|AnyoneCanPay (input sequence changed)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff000100000000000000000000000000000000000000000000000000000000000001000000000100000000010000000000000000000000000000000000000000000000000000000000000200000000ffffffff00000248304502210091b32274295c2a3fa02f5bce92fb2789e3fc6ea947fbe1a76e52ea3f4ef2381a022079ad72aefa3837a2e0c033a8652a59731da05fa4a813f4fc48e87c075037256b822103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash All|AnyoneCanPay (third output value changed)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151540b00000000000001510002483045022100a3cec69b52cba2d2de623eeef89e0ba1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with a push of 521 bytes"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0x33198a9bfef674ebddb9ffaa52928017b8472791e54c609cb95f278ac6b1e349", 1000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015102fd0902000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002755100000000", "P2SH,WITNESS"], + +["Witness with unknown version which push false on the stack should be invalid (even without DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x02 0x0000", 2000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015101010100000000", "P2SH,WITNESS"], + +["Witness program should leave clean stack"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0x2f04a3aa051f1f60d695f6c44c0c3d383973dfd446ace8962664a76bb10e31a8", 2000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01000000000000000001510102515100000000", "P2SH,WITNESS"], + +["Witness v0 with a push of 2 bytes"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x02 0x0001", 2000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015101040002000100000000", "P2SH,WITNESS"], + +["Unknown witness version with non empty scriptSig"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x02 0x0001", 2000]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000000151ffffffff010000000000000000015100000000", "P2SH,WITNESS"], + +["Non witness Single|AnyoneCanPay hash input's position (permutation)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x21 0x03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 CHECKSIG", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x21 0x03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 CHECKSIG", 1001]], +"010000000200010000000000000000000000000000000000000000000000000000000000000100000049483045022100acb96cfdbda6dc94b489fd06f2d720983b5f350e31ba906cdbd800773e80b21c02200d74ea5bdf114212b4bbe9ed82c36d2e369e302dff57cb60d01c428f0bd3daab83ffffffff0001000000000000000000000000000000000000000000000000000000000000000000004847304402202a0b4b1294d70540235ae033d78e64b4897ec859c7b6f1b2b1d8a02e1d46006702201445e756d2254b0f1dfda9ab8e1e1bc26df9668077403204f32d16a49a36eb6983ffffffff02e9030000000000000151e803000000000000015100000000", "P2SH,WITNESS"], + +["P2WSH with a redeem representing a witness scriptPubKey should fail"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0x34b6c399093e06cf9f0f7f660a1abcfe78fcf7b576f43993208edd9518a0ae9b", 1000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0001045102010100000000", "P2SH,WITNESS"], + +["33 bytes push should be considered a witness scriptPubKey"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x21 0xff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3dbff", 1000]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/test/data/tx_valid.json b/test/data/tx_valid.json index 24bde1ef..1ea70135 100644 --- a/test/data/tx_valid.json +++ b/test/data/tx_valid.json @@ -317,5 +317,175 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7c17aff532f22beb54069942f9bf567a66133eaf EQUAL"]], "0200000001000100000000000000000000000000000000000000000000000000000000000000000000030251b2010000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +["Valid P2WPKH (Private key of segwit tests is L5AQtV2HDm4xGsseLokK2VAT2EtYKcTm3c7HwqnJBFt9LdaQULsM)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100cfb07164b36ba64c1b1e8c7720a56ad64d96f6ef332d3d37f9cb3c96477dc44502200a464cd7a9cf94cd70f66ce4f4f0625ef650052c7afcfe29d7d7e01830ff91ed012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000", "P2SH,WITNESS"], + +["Valid P2WSH"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0xff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3db", 1000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb022022dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01232103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ac00000000", "P2SH,WITNESS"], + +["Valid P2SH(P2WPKH)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xfe9c7dacc9fcfbf7e3b7d5ad06aa2b28c5a7b7e3 EQUAL", 1000]], +"01000000000101000100000000000000000000000000000000000000000000000000000000000000000000171600144c9c3dfac4207d5d8cb89df5722cb3d712385e3fffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100cfb07164b36ba64c1b1e8c7720a56ad64d96f6ef332d3d37f9cb3c96477dc44502200a464cd7a9cf94cd70f66ce4f4f0625ef650052c7afcfe29d7d7e01830ff91ed012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000", "P2SH,WITNESS"], + +["Valid P2SH(P2WSH)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x2135ab4f0981830311e35600eebc7376dce3a914 EQUAL", 1000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000023220020ff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3dbffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb022022dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01232103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ac00000000", "P2SH,WITNESS"], + +["Witness with SigHash Single|AnyoneCanPay"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1100], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3100], +["0000000000000000000000000000000000000000000000000000000000000100", 3, "0x51", 4100]], +"0100000000010400010000000000000000000000000000000000000000000000000000000000000200000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000300000000ffffffff05540b0000000000000151d0070000000000000151840300000000000001513c0f00000000000001512c010000000000000151000248304502210092f4777a0f17bf5aeb8ae768dec5f2c14feabf9d1fe2c89c78dfed0f13fdb86902206da90a86042e252bcd1e80a168c719e4a1ddcc3cebea24b9812c5453c79107e9832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71000000000000", "P2SH,WITNESS"], + +["Witness with SigHash Single|AnyoneCanPay (same signature as previous)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b0000000000000151000248304502210092f4777a0f17bf5aeb8ae768dec5f2c14feabf9d1fe2c89c78dfed0f13fdb86902206da90a86042e252bcd1e80a168c719e4a1ddcc3cebea24b9812c5453c79107e9832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash Single"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff0484030000000000000151d0070000000000000151540b0000000000000151c800000000000000015100024730440220699e6b0cfe015b64ca3283e6551440a34f901ba62dd4c72fe1cb815afb2e6761022021cc5e84db498b1479de14efda49093219441adc6c543e5534979605e273d80b032103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash Single (same signature as previous)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b000000000000015100024730440220699e6b0cfe015b64ca3283e6551440a34f901ba62dd4c72fe1cb815afb2e6761022021cc5e84db498b1479de14efda49093219441adc6c543e5534979605e273d80b032103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None|AnyoneCanPay"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1100], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3100], +["0000000000000000000000000000000000000000000000000000000000000100", 3, "0x51", 4100]], +"0100000000010400010000000000000000000000000000000000000000000000000000000000000200000000ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000300000000ffffffff04b60300000000000001519e070000000000000151860b00000000000001009600000000000000015100000248304502210091b32274295c2a3fa02f5bce92fb2789e3fc6ea947fbe1a76e52ea3f4ef2381a022079ad72aefa3837a2e0c033a8652a59731da05fa4a813f4fc48e87c075037256b822103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None|AnyoneCanPay (same signature as previous)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b0000000000000151000248304502210091b32274295c2a3fa02f5bce92fb2789e3fc6ea947fbe1a76e52ea3f4ef2381a022079ad72aefa3837a2e0c033a8652a59731da05fa4a813f4fc48e87c075037256b822103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff04b60300000000000001519e070000000000000151860b0000000000000100960000000000000001510002473044022022fceb54f62f8feea77faac7083c3b56c4676a78f93745adc8a35800bc36adfa022026927df9abcf0a8777829bcfcce3ff0a385fa54c3f9df577405e3ef24ee56479022103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None (same signature as previous)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b00000000000001510002473044022022fceb54f62f8feea77faac7083c3b56c4676a78f93745adc8a35800bc36adfa022026927df9abcf0a8777829bcfcce3ff0a385fa54c3f9df577405e3ef24ee56479022103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None (same signature, only sequences changed)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"01000000000103000100000000000000000000000000000000000000000000000000000000000000000000000200000000010000000000000000000000000000000000000000000000000000000000000100000000ffffffff000100000000000000000000000000000000000000000000000000000000000002000000000200000003e8030000000000000151d0070000000000000151b80b00000000000001510002473044022022fceb54f62f8feea77faac7083c3b56c4676a78f93745adc8a35800bc36adfa022026927df9abcf0a8777829bcfcce3ff0a385fa54c3f9df577405e3ef24ee56479022103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash All|AnyoneCanPay"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1100], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3100], +["0000000000000000000000000000000000000000000000000000000000000100", 3, "0x51", 4100]], +"0100000000010400010000000000000000000000000000000000000000000000000000000000000200000000ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000300000000ffffffff03e8030000000000000151d0070000000000000151b80b0000000000000151000002483045022100a3cec69b52cba2d2de623eeef89e0ba1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash All|AnyoneCanPay (same signature as previous)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b00000000000001510002483045022100a3cec69b52cba2d2de623eeef89e0ba1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Unknown witness program version (without DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x60 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b00000000000001510002483045022100a3cec69b52cba2d2de623ffffffffff1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with a push of 520 bytes"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0x33198a9bfef674ebddb9ffaa52928017b8472791e54c609cb95f278ac6b1e349", 1000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015102fd08020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002755100000000", "P2SH,WITNESS"], + +["Transaction mixing all SigHash, segwit and normal inputs"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1001], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1002], +["0000000000000000000000000000000000000000000000000000000000000100", 3, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1003], +["0000000000000000000000000000000000000000000000000000000000000100", 4, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1004], +["0000000000000000000000000000000000000000000000000000000000000100", 5, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1005], +["0000000000000000000000000000000000000000000000000000000000000100", 6, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1006], +["0000000000000000000000000000000000000000000000000000000000000100", 7, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1007], +["0000000000000000000000000000000000000000000000000000000000000100", 8, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1008], +["0000000000000000000000000000000000000000000000000000000000000100", 9, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1009], +["0000000000000000000000000000000000000000000000000000000000000100", 10, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1010], +["0000000000000000000000000000000000000000000000000000000000000100", 11, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1011]], +"0100000000010c00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff0001000000000000000000000000000000000000000000000000000000000000020000006a473044022026c2e65b33fcd03b2a3b0f25030f0244bd23cc45ae4dec0f48ae62255b1998a00220463aa3982b718d593a6b9e0044513fd67a5009c2fdccc59992cffc2b167889f4012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000030000006a4730440220008bd8382911218dcb4c9f2e75bf5c5c3635f2f2df49b36994fde85b0be21a1a02205a539ef10fb4c778b522c1be852352ea06c67ab74200977c722b0bc68972575a012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000040000006b483045022100d9436c32ff065127d71e1a20e319e4fe0a103ba0272743dbd8580be4659ab5d302203fd62571ee1fe790b182d078ecfd092a509eac112bea558d122974ef9cc012c7012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000050000006a47304402200e2c149b114ec546015c13b2b464bbcb0cdc5872e6775787527af6cbc4830b6c02207e9396c6979fb15a9a2b96ca08a633866eaf20dc0ff3c03e512c1d5a1654f148012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000060000006b483045022100b20e70d897dc15420bccb5e0d3e208d27bdd676af109abbd3f88dbdb7721e6d6022005836e663173fbdfe069f54cde3c2decd3d0ea84378092a5d9d85ec8642e8a41012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff00010000000000000000000000000000000000000000000000000000000000000700000000ffffffff00010000000000000000000000000000000000000000000000000000000000000800000000ffffffff00010000000000000000000000000000000000000000000000000000000000000900000000ffffffff00010000000000000000000000000000000000000000000000000000000000000a00000000ffffffff00010000000000000000000000000000000000000000000000000000000000000b0000006a47304402206639c6e05e3b9d2675a7f3876286bdf7584fe2bbd15e0ce52dd4e02c0092cdc60220757d60b0a61fc95ada79d23746744c72bac1545a75ff6c2c7cdb6ae04e7e9592012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0ce8030000000000000151e9030000000000000151ea030000000000000151eb030000000000000151ec030000000000000151ed030000000000000151ee030000000000000151ef030000000000000151f0030000000000000151f1030000000000000151f2030000000000000151f30300000000000001510248304502210082219a54f61bf126bfc3fa068c6e33831222d1d7138c6faa9d33ca87fd4202d6022063f9902519624254d7c2c8ea7ba2d66ae975e4e229ae38043973ec707d5d4a83012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7102473044022017fb58502475848c1b09f162cb1688d0920ff7f142bed0ef904da2ccc88b168f02201798afa61850c65e77889cbcd648a5703b487895517c88f85cdd18b021ee246a012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000000247304402202830b7926e488da75782c81a54cd281720890d1af064629ebf2e31bf9f5435f30220089afaa8b455bbeb7d9b9c3fe1ed37d07685ade8455c76472cda424d93e4074a012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7102473044022026326fcdae9207b596c2b05921dbac11d81040c4d40378513670f19d9f4af893022034ecd7a282c0163b89aaa62c22ec202cef4736c58cd251649bad0d8139bcbf55012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71024730440220214978daeb2f38cd426ee6e2f44131a33d6b191af1c216247f1dd7d74c16d84a02205fdc05529b0bc0c430b4d5987264d9d075351c4f4484c16e91662e90a72aab24012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710247304402204a6e9f199dc9672cf2ff8094aaa784363be1eb62b679f7ff2df361124f1dca3302205eeb11f70fab5355c9c8ad1a0700ea355d315e334822fa182227e9815308ee8f012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Unknown version witness program with empty witness"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS"], + +["Witness SIGHASH_SINGLE with output out of bound"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x20 0x4d6c2a32c87821d68fc016fca70797abdb80df6cd84651d40a9300c6bad79e62", 1000]], +"0100000000010200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff01d00700000000000001510003483045022100e078de4e96a0e05dcdc0a414124dd8475782b5f3f0ed3f607919e9a5eeeb22bf02201de309b3a3109adb3de8074b3610d4cf454c49b61247a2779a0bcbf31c889333032103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc711976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac00000000", "P2SH,WITNESS"], + +["1 byte push should not be considered a witness scriptPubKey"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x01 0x01", 1000]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"], + +["41 bytes push should not be considered a witness scriptPubKey"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x29 0xff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3dbff0000000000000000", 1000]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"], + +["The witness version must use OP_1 to OP_16 only"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x01 0x10 0x02 0x0001", 1000]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"], + +["The witness program push must be canonical"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x4c02 0x0001", 1000]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"], + +["Witness Single|AnyoneCanPay does not hash input's position"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1001]], +"0100000000010200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff02e8030000000000000151e90300000000000001510247304402206d59682663faab5e4cb733c562e22cdae59294895929ec38d7c016621ff90da0022063ef0af5f970afe8a45ea836e3509b8847ed39463253106ac17d19c437d3d56b832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710248304502210085001a820bfcbc9f9de0298af714493f8a37b3b354bfd21a7097c3e009f2018c022050a8b4dbc8155d4d04da2f5cdd575dcf8dd0108de8bec759bd897ea01ecb3af7832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000", "P2SH,WITNESS"], + +["Witness Single|AnyoneCanPay does not hash input's position (permutation)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1001]], +"0100000000010200010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff02e9030000000000000151e80300000000000001510248304502210085001a820bfcbc9f9de0298af714493f8a37b3b354bfd21a7097c3e009f2018c022050a8b4dbc8155d4d04da2f5cdd575dcf8dd0108de8bec759bd897ea01ecb3af7832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710247304402206d59682663faab5e4cb733c562e22cdae59294895929ec38d7c016621ff90da0022063ef0af5f970afe8a45ea836e3509b8847ed39463253106ac17d19c437d3d56b832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000", "P2SH,WITNESS"], + +["Non witness Single|AnyoneCanPay hash input's position"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x21 0x03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 CHECKSIG", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x21 0x03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 CHECKSIG", 1001]], +"01000000020001000000000000000000000000000000000000000000000000000000000000000000004847304402202a0b4b1294d70540235ae033d78e64b4897ec859c7b6f1b2b1d8a02e1d46006702201445e756d2254b0f1dfda9ab8e1e1bc26df9668077403204f32d16a49a36eb6983ffffffff00010000000000000000000000000000000000000000000000000000000000000100000049483045022100acb96cfdbda6dc94b489fd06f2d720983b5f350e31ba906cdbd800773e80b21c02200d74ea5bdf114212b4bbe9ed82c36d2e369e302dff57cb60d01c428f0bd3daab83ffffffff02e8030000000000000151e903000000000000015100000000", "P2SH,WITNESS"], + +["BIP143 examples: details and private keys are available in BIP143"], +["BIP143 example: P2WSH with OP_CODESEPARATOR and out-of-range SIGHASH_SINGLE."], +[[["6eb316926b1c5d567cd6f5e6a84fec606fc53d7b474526d1fff3948020c93dfe", 0, "0x21 0x036d5c20fa14fb2f635474c1dc4ef5909d4568e5569b79fc94d3448486e14685f8 CHECKSIG", 156250000], +["f825690aee1b3dc247da796cacb12687a5e802429fd291cfd63e010f02cf1508", 0, "0x00 0x20 0x5d1b56b63d714eebe542309525f484b7e9d6f686b3781b6f61ef925d66d6f6a0", 4900000000]], +"01000000000102fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e000000004847304402200af4e47c9b9629dbecc21f73af989bdaa911f7e6f6c2e9394588a3aa68f81e9902204f3fcf6ade7e5abb1295b6774c8e0abd94ae62217367096bc02ee5e435b67da201ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac000347304402200de66acf4527789bfda55fc5459e214fa6083f936b430a762c629656216805ac0220396f550692cd347171cbc1ef1f51e15282e837bb2b30860dc77c8f78bc8501e503473044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e27034721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac00000000", "P2SH,WITNESS"], + +["BIP143 example: P2WSH with unexecuted OP_CODESEPARATOR and SINGLE|ANYONECANPAY"], +[[["01c0cf7fba650638e55eb91261b183251fbb466f90dff17f10086817c542b5e9", 0, "0x00 0x20 0xba468eea561b26301e4cf69fa34bde4ad60c81e70f059f045ca9a79931004a4d", 16777215], +["1b2a9a426ba603ba357ce7773cb5805cb9c7c2b386d100d1fc9263513188e680", 0, "0x00 0x20 0xd9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537", 16777215]], +"01000000000102e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffff0280969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac80969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000", "P2SH,WITNESS"], + +["BIP143 example: Same as the previous example with input-output paris swapped"], +[[["1b2a9a426ba603ba357ce7773cb5805cb9c7c2b386d100d1fc9263513188e680", 0, "0x00 0x20 0xd9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537", 16777215], +["01c0cf7fba650638e55eb91261b183251fbb466f90dff17f10086817c542b5e9", 0, "0x00 0x20 0xba468eea561b26301e4cf69fa34bde4ad60c81e70f059f045ca9a79931004a4d", 16777215]], +"0100000000010280e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffffe9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff0280969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac80969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000", "P2SH,WITNESS"], + +["BIP143 example: P2SH-P2WSH 6-of-6 multisig signed with 6 different SIGHASH types"], +[[["6eb98797a21c6c10aa74edf29d618be109f48a8e94c694f3701e08ca69186436", 1, "HASH160 0x14 0x9993a429037b5d912407a71c252019287b8d27a5 EQUAL", 987654321]], +"0100000000010136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000023220020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac080047304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01473044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502473044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403483045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381483045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a08824730440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae00000000", "P2SH,WITNESS"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/test/libtest.c b/test/libtest.c index 4ccbf103..6c3dc5d5 100644 --- a/test/libtest.c +++ b/test/libtest.c @@ -25,7 +25,7 @@ json_t *read_json(const char *filename) ret = json_load_file(filename, JSON_REJECT_DUPLICATES, &err); - return ret; + return ret; } char *test_filename(const char *basename) diff --git a/test/script.c b/test/script.c index 16b41944..0afe1e40 100644 --- a/test/script.c +++ b/test/script.c @@ -87,7 +87,7 @@ static void test_script(bool is_valid, cstring* scriptSig, cstring* scriptPubKey bool rc; rc = bp_script_verify( - scriptSig, scriptPubKey, scriptWitness, &tx, 0, test_flags, SIGHASH_NONE, nValue); + scriptSig, scriptPubKey, &scriptWitness, &tx, 0, test_flags, SIGHASH_NONE, nValue); if (rc != is_valid) { fprintf(stderr, "script: %sis_valid test %u failed\n" @@ -135,6 +135,7 @@ static void runtest(const char *json_base_fn) if (json_array_size(test) != 1) { fprintf(stderr, "script: Bad test %u\n", idx); } + parr_free(scriptWitness, true); continue; } @@ -199,7 +200,6 @@ static void runtest(const char *json_base_fn) cstr_free(scriptSig, true); cstr_free(scriptPubKey, true); - parr_free(scriptWitness, true); } json_decref(tests); diff --git a/test/tx-valid.c b/test/tx-valid.c index cf4251e3..79f8e21f 100644 --- a/test/tx-valid.c +++ b/test/tx-valid.c @@ -39,8 +39,8 @@ static void dump_comments(void) } } -static void test_tx_valid(bool is_valid, struct bp_hashtab *input_map, - cstring *tx_ser, const unsigned int test_flags) +static void test_tx_valid(bool is_valid, struct bp_hashtab* mapprevOutScriptPubKeys, + struct bp_hashtab* mapprevOutValues, cstring* tx_ser, const unsigned int test_flags) { struct bp_tx tx; @@ -72,14 +72,15 @@ static void test_tx_valid(bool is_valid, struct bp_hashtab *input_map, txin = parr_idx(tx.vin, i); assert(txin != NULL); - cstring *scriptPubKey = bp_hashtab_get(input_map, - &txin->prevout); + cstring* scriptPubKey = bp_hashtab_get(mapprevOutScriptPubKeys, &txin->prevout); + int64_t* amount = bp_hashtab_get(mapprevOutValues, &txin->prevout); + if (scriptPubKey == NULL) { - if (!is_valid) { - /* if testing tx_invalid.json, missing input - * is invalid, and therefore correct - */ - continue; + if (!is_valid) { + /* if testing tx_invalid.json, missing input + * is invalid, and therefore correct + */ + continue; } char tx_hexstr[BU256_STRSZ], hexstr[BU256_STRSZ]; @@ -94,12 +95,12 @@ static void test_tx_valid(bool is_valid, struct bp_hashtab *input_map, assert(scriptPubKey != NULL); } - bool rc = bp_script_verify(txin->scriptSig, scriptPubKey, - NULL, &tx, i, test_flags, 0, 0); + bool rc = bp_script_verify(txin->scriptSig, scriptPubKey, &txin->scriptWitness, + &tx, i, test_flags, SIGHASH_NONE, *amount); state &= rc; - if (rc != is_valid) { + if (rc != is_valid) { char tx_hexstr[BU256_STRSZ]; bu256_hex(tx_hexstr, &tx.sha256); dump_comments(); @@ -115,18 +116,19 @@ static void test_tx_valid(bool is_valid, struct bp_hashtab *input_map, bp_tx_free(&tx); } -static void runtest(bool is_valid, const char *basefn) +static void runtest(bool is_valid, const char *json_base_fn) { - char *fn = test_filename(basefn); - json_t *tests = read_json(fn); + char *json_fn = test_filename(json_base_fn); + json_t *tests = read_json(json_fn); assert(tests != NULL); assert(json_is_array(tests)); - struct bp_hashtab *input_map = bp_hashtab_new_ext( - input_hash, input_equal, - free, input_value_free); + struct bp_hashtab* mapprevOutScriptPubKeys = + bp_hashtab_new_ext(input_hash, input_equal, free, input_value_free); + struct bp_hashtab* mapprevOutValues = + bp_hashtab_new_ext(input_hash, input_equal, free, free); - comments = parr_new(8, free); + comments = parr_new(8, free); unsigned int idx; for (idx = 0; idx < json_array_size(tests); idx++) { @@ -139,101 +141,121 @@ static void runtest(bool is_valid, const char *basefn) if (cmt) parr_add(comments, strdup(cmt)); /* comments */ } else { - assert(json_array_size(test) == 3); - assert(json_is_string(json_array_get(test, 1))); - assert(json_is_string(json_array_get(test, 2))); + assert(json_array_size(test) == 3); + assert(json_is_string(json_array_get(test, 1))); + assert(json_is_string(json_array_get(test, 2))); - json_t *inputs = json_array_get(test, 0); - assert(json_is_array(inputs)); - static unsigned int verify_flags; + json_t *inputs = json_array_get(test, 0); + assert(json_is_array(inputs)); + static unsigned int verify_flags; - bp_hashtab_clear(input_map); + bp_hashtab_clear(mapprevOutScriptPubKeys); + bp_hashtab_clear(mapprevOutValues); - unsigned int i; - for (i = 0; i < json_array_size(inputs); i++) { - json_t *input = json_array_get(inputs, i); - assert(json_is_array(input)); + unsigned int inpIdx; + for (inpIdx = 0; inpIdx < json_array_size(inputs); inpIdx++) { + json_t *input = json_array_get(inputs, inpIdx); + assert(json_is_array(input)); - const char *prev_hashstr = + const char* prev_hashstr = json_string_value(json_array_get(input, 0)); - int prev_n = + int prev_n = json_integer_value(json_array_get(input, 1)); - const char *prev_pubkey_enc = + const char* prev_pubkey_enc = json_string_value(json_array_get(input, 2)); - assert(prev_hashstr != NULL); - assert(json_is_integer(json_array_get(input, 1))); - assert(prev_pubkey_enc != NULL); + assert(prev_hashstr != NULL); + assert(json_is_integer(json_array_get(input, 1))); + assert(prev_pubkey_enc != NULL); + + struct bp_outpt* outpt; + outpt = malloc(sizeof(*outpt)); + hex_bu256(&outpt->hash, prev_hashstr); + outpt->n = prev_n; - struct bp_outpt *outpt; - outpt = malloc(sizeof(*outpt)); - hex_bu256(&outpt->hash, prev_hashstr); - outpt->n = prev_n; + cstring* script = parse_script_str(prev_pubkey_enc); + assert(script != NULL); - cstring *script = parse_script_str(prev_pubkey_enc); - assert(script != NULL); + bp_hashtab_put(mapprevOutScriptPubKeys, outpt, script); - bp_hashtab_put(input_map, outpt, script); - } + struct bp_outpt* outpt_amt; + outpt_amt = malloc(sizeof(*outpt_amt)); + hex_bu256(&outpt_amt->hash, prev_hashstr); + outpt_amt->n = prev_n; - const char *tx_hexser = - json_string_value(json_array_get(test, 1)); - assert(tx_hexser != NULL); + int64_t* amount; + amount = malloc(sizeof(*amount)); + *amount = 0; + if (json_array_size(input) >= 4) { + assert(json_is_number(json_array_get(input, 3))); + *amount = json_number_value(json_array_get(input, 3)); + } + bp_hashtab_put(mapprevOutValues, outpt_amt, amount); + } - verify_flags = SCRIPT_VERIFY_NONE; + const char *tx_hexser = + json_string_value(json_array_get(test, 1)); + assert(tx_hexser != NULL); - const char *json_flags = json_string_value(json_array_get(test, 2)); + verify_flags = SCRIPT_VERIFY_NONE; - if (strlen(json_flags) > 0) { - const char* json_flag = strtok((char *)json_flags, ","); + const char *json_flags = json_string_value(json_array_get(test, 2)); + + if (strlen(json_flags) > 0) { + const char* json_flag = strtok((char *)json_flags, ","); do { if (strcmp(json_flag, "P2SH") == 0) - verify_flags |= SCRIPT_VERIFY_P2SH; + verify_flags |= SCRIPT_VERIFY_P2SH; else if (strcmp(json_flag, "STRICTENC") == 0) - verify_flags |= SCRIPT_VERIFY_STRICTENC; + verify_flags |= SCRIPT_VERIFY_STRICTENC; else if (strcmp(json_flag, "DERSIG") == 0) - verify_flags |= SCRIPT_VERIFY_DERSIG; + verify_flags |= SCRIPT_VERIFY_DERSIG; else if (strcmp(json_flag, "LOW_S") == 0) - verify_flags |= SCRIPT_VERIFY_LOW_S; + verify_flags |= SCRIPT_VERIFY_LOW_S; else if (strcmp(json_flag, "NULLDUMMY") == 0) - verify_flags |= SCRIPT_VERIFY_NULLDUMMY; + verify_flags |= SCRIPT_VERIFY_NULLDUMMY; else if (strcmp(json_flag, "SIGPUSHONLY") == 0) - verify_flags |= SCRIPT_VERIFY_SIGPUSHONLY; + verify_flags |= SCRIPT_VERIFY_SIGPUSHONLY; else if (strcmp(json_flag, "MINIMALDATA") == 0) - verify_flags |= SCRIPT_VERIFY_MINIMALDATA; + verify_flags |= SCRIPT_VERIFY_MINIMALDATA; else if (strcmp(json_flag, "DISCOURAGE_UPGRADABLE_NOPS") == 0) - verify_flags |= SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS; + verify_flags |= SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS; else if (strcmp(json_flag, "CLEANSTACK") == 0) - verify_flags |= SCRIPT_VERIFY_CLEANSTACK; + verify_flags |= SCRIPT_VERIFY_CLEANSTACK; else if (strcmp(json_flag, "CHECKLOCKTIMEVERIFY") == 0) - verify_flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; + verify_flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; else if (strcmp(json_flag, "CHECKSEQUENCEVERIFY") == 0) - verify_flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; - json_flag = strtok(NULL, ","); - } while (json_flag); - } + verify_flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; + else if (strcmp(json_flag, "WITNESS") == 0) + verify_flags |= SCRIPT_VERIFY_WITNESS; + else if (strcmp(json_flag, "DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM") == 0) + verify_flags |= SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM; + json_flag = strtok(NULL, ","); + } while (json_flag); + } - cstring *tx_ser = hex2str(tx_hexser); - assert(tx_ser != NULL); + cstring *tx_ser = hex2str(tx_hexser); + assert(tx_ser != NULL); - test_tx_valid(is_valid, input_map, tx_ser, verify_flags); + test_tx_valid(is_valid, mapprevOutScriptPubKeys, + mapprevOutValues, tx_ser, verify_flags); - cstr_free(tx_ser, true); + cstr_free(tx_ser, true); - if (comments->len > 0) { - parr_free(comments, true); + if (comments->len > 0) { + parr_free(comments, true); comments = parr_new(8, free); - } + } } - } + } parr_free(comments, true); comments = NULL; - - bp_hashtab_unref(input_map); - json_decref(tests); - free(fn); + bp_hashtab_unref(mapprevOutScriptPubKeys); + bp_hashtab_unref(mapprevOutValues); + json_decref(tests); + free(json_fn); } int main (int argc, char *argv[]) @@ -241,6 +263,6 @@ int main (int argc, char *argv[]) runtest(true, "data/tx_valid.json"); runtest(false, "data/tx_invalid.json"); - bp_key_static_shutdown(); + bp_key_static_shutdown(); return 0; } From 8fbaf2c9aa545ac57858ff8fb91ba2cb1b36d00c Mon Sep 17 00:00:00 2001 From: libbitc Date: Mon, 21 Aug 2017 00:50:32 +0000 Subject: [PATCH 3/3] ccoin: Add some checkpoints --- lib/checkpoints.c | 6 ++++++ test/misc.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/checkpoints.c b/lib/checkpoints.c index 9eb674c5..fafa5a89 100644 --- a/lib/checkpoints.c +++ b/lib/checkpoints.c @@ -17,6 +17,12 @@ static const struct bp_checkpoint bp_ck_main[] = { {134444, "0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"}, {168000, "0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"}, {193000, "0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"}, + {210000, "0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"}, + {216116, "0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e"}, + {225430, "0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932"}, + {250000, "0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214"}, + {279000, "0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40"}, + {295000, "0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983"}, }; static const struct bp_checkpoint bp_ck_testnet3[] = { diff --git a/test/misc.c b/test/misc.c index 106642b2..f0006da7 100644 --- a/test/misc.c +++ b/test/misc.c @@ -36,7 +36,7 @@ static void test_checkpoints(void) rc = bp_ckpt_block(CHAIN_BITCOIN, 11111, &tmp); assert(rc == false); - assert(bp_ckpt_last(CHAIN_BITCOIN) == 193000); + assert(bp_ckpt_last(CHAIN_BITCOIN) == 295000); assert(bp_ckpt_last(CHAIN_TESTNET3) == 546); }