aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/DoS_tests.cpp6
-rw-r--r--src/test/blockencodings_tests.cpp315
-rw-r--r--src/test/data/script_tests.json291
-rw-r--r--src/test/data/tx_invalid.json67
-rw-r--r--src/test/data/tx_valid.json170
-rw-r--r--src/test/mempool_tests.cpp11
-rw-r--r--src/test/miner_tests.cpp114
-rw-r--r--src/test/multisig_tests.cpp21
-rw-r--r--src/test/policyestimator_tests.cpp3
-rw-r--r--src/test/script_P2SH_tests.cpp13
-rw-r--r--src/test/script_tests.cpp370
-rw-r--r--src/test/sighash_tests.cpp6
-rw-r--r--src/test/sigopcount_tests.cpp177
-rw-r--r--src/test/test_bitcoin.cpp9
-rw-r--r--src/test/test_bitcoin.h7
-rw-r--r--src/test/transaction_tests.cpp318
-rw-r--r--src/test/txvalidationcache_tests.cpp2
17 files changed, 1753 insertions, 147 deletions
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp
index 4a373fc60b..a8c5f95ace 100644
--- a/src/test/DoS_tests.cpp
+++ b/src/test/DoS_tests.cpp
@@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
- SignSignature(keystore, txPrev, tx, 0);
+ SignSignature(keystore, txPrev, tx, 0, SIGHASH_ALL);
AddOrphanTx(tx, i);
}
@@ -162,13 +162,13 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
- tx.vin.resize(500);
+ tx.vin.resize(2777);
for (unsigned int j = 0; j < tx.vin.size(); j++)
{
tx.vin[j].prevout.n = j;
tx.vin[j].prevout.hash = txPrev.GetHash();
}
- SignSignature(keystore, txPrev, tx, 0);
+ SignSignature(keystore, txPrev, tx, 0, SIGHASH_ALL);
// Re-use same signature for other inputs
// (they don't have to be valid for this test)
for (unsigned int j = 1; j < tx.vin.size(); j++)
diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp
new file mode 100644
index 0000000000..3884bf3fe3
--- /dev/null
+++ b/src/test/blockencodings_tests.cpp
@@ -0,0 +1,315 @@
+// Copyright (c) 2011-2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "blockencodings.h"
+#include "consensus/merkle.h"
+#include "chainparams.h"
+#include "random.h"
+
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+struct RegtestingSetup : public TestingSetup {
+ RegtestingSetup() : TestingSetup(CBaseChainParams::REGTEST) {}
+};
+
+BOOST_FIXTURE_TEST_SUITE(blockencodings_tests, RegtestingSetup)
+
+static CBlock BuildBlockTestCase() {
+ CBlock block;
+ CMutableTransaction tx;
+ tx.vin.resize(1);
+ tx.vin[0].scriptSig.resize(10);
+ tx.vout.resize(1);
+ tx.vout[0].nValue = 42;
+
+ block.vtx.resize(3);
+ block.vtx[0] = tx;
+ block.nVersion = 42;
+ block.hashPrevBlock = GetRandHash();
+ block.nBits = 0x207fffff;
+
+ tx.vin[0].prevout.hash = GetRandHash();
+ tx.vin[0].prevout.n = 0;
+ block.vtx[1] = tx;
+
+ tx.vin.resize(10);
+ for (size_t i = 0; i < tx.vin.size(); i++) {
+ tx.vin[i].prevout.hash = GetRandHash();
+ tx.vin[i].prevout.n = 0;
+ }
+ block.vtx[2] = tx;
+
+ bool mutated;
+ block.hashMerkleRoot = BlockMerkleRoot(block, &mutated);
+ assert(!mutated);
+ while (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) ++block.nNonce;
+ return block;
+}
+
+// Number of shared use_counts we expect for a tx we havent touched
+// == 2 (mempool + our copy from the GetSharedTx call)
+#define SHARED_TX_OFFSET 2
+
+BOOST_AUTO_TEST_CASE(SimpleRoundTripTest)
+{
+ CTxMemPool pool(CFeeRate(0));
+ TestMemPoolEntryHelper entry;
+ CBlock block(BuildBlockTestCase());
+
+ pool.addUnchecked(block.vtx[2].GetHash(), entry.FromTx(block.vtx[2]));
+ BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0);
+
+ // Do a simple ShortTxIDs RT
+ {
+ CBlockHeaderAndShortTxIDs shortIDs(block);
+
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ stream << shortIDs;
+
+ CBlockHeaderAndShortTxIDs shortIDs2;
+ stream >> shortIDs2;
+
+ PartiallyDownloadedBlock partialBlock(&pool);
+ BOOST_CHECK(partialBlock.InitData(shortIDs2) == READ_STATUS_OK);
+ BOOST_CHECK( partialBlock.IsTxAvailable(0));
+ BOOST_CHECK(!partialBlock.IsTxAvailable(1));
+ BOOST_CHECK( partialBlock.IsTxAvailable(2));
+
+ BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1);
+
+ std::list<CTransaction> removed;
+ pool.removeRecursive(block.vtx[2], removed);
+ BOOST_CHECK_EQUAL(removed.size(), 1);
+
+ CBlock block2;
+ std::vector<CTransaction> vtx_missing;
+ BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_INVALID); // No transactions
+
+ vtx_missing.push_back(block.vtx[2]); // Wrong transaction
+ partialBlock.FillBlock(block2, vtx_missing); // Current implementation doesn't check txn here, but don't require that
+ bool mutated;
+ BOOST_CHECK(block.hashMerkleRoot != BlockMerkleRoot(block2, &mutated));
+
+ vtx_missing[0] = block.vtx[1];
+ CBlock block3;
+ BOOST_CHECK(partialBlock.FillBlock(block3, vtx_missing) == READ_STATUS_OK);
+ BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString());
+ BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block3, &mutated).ToString());
+ BOOST_CHECK(!mutated);
+ }
+}
+
+class TestHeaderAndShortIDs {
+ // Utility to encode custom CBlockHeaderAndShortTxIDs
+public:
+ CBlockHeader header;
+ uint64_t nonce;
+ std::vector<uint64_t> shorttxids;
+ std::vector<PrefilledTransaction> prefilledtxn;
+
+ TestHeaderAndShortIDs(const CBlockHeaderAndShortTxIDs& orig) {
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ stream << orig;
+ stream >> *this;
+ }
+ TestHeaderAndShortIDs(const CBlock& block) :
+ TestHeaderAndShortIDs(CBlockHeaderAndShortTxIDs(block)) {}
+
+ uint64_t GetShortID(const uint256& txhash) const {
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ stream << *this;
+ CBlockHeaderAndShortTxIDs base;
+ stream >> base;
+ return base.GetShortID(txhash);
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(header);
+ READWRITE(nonce);
+ size_t shorttxids_size = shorttxids.size();
+ READWRITE(VARINT(shorttxids_size));
+ shorttxids.resize(shorttxids_size);
+ for (size_t i = 0; i < shorttxids.size(); i++) {
+ uint32_t lsb = shorttxids[i] & 0xffffffff;
+ uint16_t msb = (shorttxids[i] >> 32) & 0xffff;
+ READWRITE(lsb);
+ READWRITE(msb);
+ shorttxids[i] = (uint64_t(msb) << 32) | uint64_t(lsb);
+ }
+ READWRITE(prefilledtxn);
+ }
+};
+
+BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
+{
+ CTxMemPool pool(CFeeRate(0));
+ TestMemPoolEntryHelper entry;
+ CBlock block(BuildBlockTestCase());
+
+ pool.addUnchecked(block.vtx[2].GetHash(), entry.FromTx(block.vtx[2]));
+ BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0);
+
+ // Test with pre-forwarding tx 1, but not coinbase
+ {
+ TestHeaderAndShortIDs shortIDs(block);
+ shortIDs.prefilledtxn.resize(1);
+ shortIDs.prefilledtxn[0] = {1, block.vtx[1]};
+ shortIDs.shorttxids.resize(2);
+ shortIDs.shorttxids[0] = shortIDs.GetShortID(block.vtx[0].GetHash());
+ shortIDs.shorttxids[1] = shortIDs.GetShortID(block.vtx[2].GetHash());
+
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ stream << shortIDs;
+
+ CBlockHeaderAndShortTxIDs shortIDs2;
+ stream >> shortIDs2;
+
+ PartiallyDownloadedBlock partialBlock(&pool);
+ BOOST_CHECK(partialBlock.InitData(shortIDs2) == READ_STATUS_OK);
+ BOOST_CHECK(!partialBlock.IsTxAvailable(0));
+ BOOST_CHECK( partialBlock.IsTxAvailable(1));
+ BOOST_CHECK( partialBlock.IsTxAvailable(2));
+
+ BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1);
+
+ CBlock block2;
+ std::vector<CTransaction> vtx_missing;
+ BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_INVALID); // No transactions
+
+ vtx_missing.push_back(block.vtx[1]); // Wrong transaction
+ partialBlock.FillBlock(block2, vtx_missing); // Current implementation doesn't check txn here, but don't require that
+ bool mutated;
+ BOOST_CHECK(block.hashMerkleRoot != BlockMerkleRoot(block2, &mutated));
+
+ vtx_missing[0] = block.vtx[0];
+ CBlock block3;
+ BOOST_CHECK(partialBlock.FillBlock(block3, vtx_missing) == READ_STATUS_OK);
+ BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString());
+ BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block3, &mutated).ToString());
+ BOOST_CHECK(!mutated);
+
+ BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1);
+ }
+ BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0);
+}
+
+BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
+{
+ CTxMemPool pool(CFeeRate(0));
+ TestMemPoolEntryHelper entry;
+ CBlock block(BuildBlockTestCase());
+
+ pool.addUnchecked(block.vtx[1].GetHash(), entry.FromTx(block.vtx[1]));
+ BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0);
+
+ // Test with pre-forwarding coinbase + tx 2 with tx 1 in mempool
+ {
+ TestHeaderAndShortIDs shortIDs(block);
+ shortIDs.prefilledtxn.resize(2);
+ shortIDs.prefilledtxn[0] = {0, block.vtx[0]};
+ shortIDs.prefilledtxn[1] = {1, block.vtx[2]}; // id == 1 as it is 1 after index 1
+ shortIDs.shorttxids.resize(1);
+ shortIDs.shorttxids[0] = shortIDs.GetShortID(block.vtx[1].GetHash());
+
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ stream << shortIDs;
+
+ CBlockHeaderAndShortTxIDs shortIDs2;
+ stream >> shortIDs2;
+
+ PartiallyDownloadedBlock partialBlock(&pool);
+ BOOST_CHECK(partialBlock.InitData(shortIDs2) == READ_STATUS_OK);
+ BOOST_CHECK( partialBlock.IsTxAvailable(0));
+ BOOST_CHECK( partialBlock.IsTxAvailable(1));
+ BOOST_CHECK( partialBlock.IsTxAvailable(2));
+
+ BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1);
+
+ CBlock block2;
+ std::vector<CTransaction> vtx_missing;
+ BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_OK);
+ BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString());
+ bool mutated;
+ BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block2, &mutated).ToString());
+ BOOST_CHECK(!mutated);
+
+ BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1);
+ }
+ BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1].GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0);
+}
+
+BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest)
+{
+ CTxMemPool pool(CFeeRate(0));
+ CMutableTransaction coinbase;
+ coinbase.vin.resize(1);
+ coinbase.vin[0].scriptSig.resize(10);
+ coinbase.vout.resize(1);
+ coinbase.vout[0].nValue = 42;
+
+ CBlock block;
+ block.vtx.resize(1);
+ block.vtx[0] = coinbase;
+ block.nVersion = 42;
+ block.hashPrevBlock = GetRandHash();
+ block.nBits = 0x207fffff;
+
+ bool mutated;
+ block.hashMerkleRoot = BlockMerkleRoot(block, &mutated);
+ assert(!mutated);
+ while (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) ++block.nNonce;
+
+ // Test simple header round-trip with only coinbase
+ {
+ CBlockHeaderAndShortTxIDs shortIDs(block);
+
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ stream << shortIDs;
+
+ CBlockHeaderAndShortTxIDs shortIDs2;
+ stream >> shortIDs2;
+
+ PartiallyDownloadedBlock partialBlock(&pool);
+ BOOST_CHECK(partialBlock.InitData(shortIDs2) == READ_STATUS_OK);
+ BOOST_CHECK(partialBlock.IsTxAvailable(0));
+
+ CBlock block2;
+ std::vector<CTransaction> vtx_missing;
+ BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_OK);
+ BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString());
+ bool mutated;
+ BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block2, &mutated).ToString());
+ BOOST_CHECK(!mutated);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(TransactionsRequestSerializationTest) {
+ BlockTransactionsRequest req1;
+ req1.blockhash = GetRandHash();
+ req1.indexes.resize(4);
+ req1.indexes[0] = 0;
+ req1.indexes[1] = 1;
+ req1.indexes[2] = 3;
+ req1.indexes[3] = 4;
+
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ stream << req1;
+
+ BlockTransactionsRequest req2;
+ stream >> req2;
+
+ BOOST_CHECK_EQUAL(req1.blockhash.ToString(), req2.blockhash.ToString());
+ BOOST_CHECK_EQUAL(req1.indexes.size(), req2.indexes.size());
+ BOOST_CHECK_EQUAL(req1.indexes[0], req2.indexes[0]);
+ BOOST_CHECK_EQUAL(req1.indexes[1], req2.indexes[1]);
+ BOOST_CHECK_EQUAL(req1.indexes[2], req2.indexes[2]);
+ BOOST_CHECK_EQUAL(req1.indexes[3], req2.indexes[3]);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json
index 0bdac182e0..9b81e0c77d 100644
--- a/src/test/data/script_tests.json
+++ b/src/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"],
@@ -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",
@@ -1828,6 +1834,289 @@
"OK",
"P2SH with CLEANSTACK"
],
+[
+ [
+ "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"
+],
["CHECKSEQUENCEVERIFY tests"],
["", "NOP3", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on a empty stack"],
diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json
index 2d7d9b9585..05502a83f7 100644
--- a/src/test/data/tx_invalid.json
+++ b/src/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 NOP3 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/src/test/data/tx_valid.json b/src/test/data/tx_valid.json
index 717ad19549..c9fe4e313a 100644
--- a/src/test/data/tx_valid.json
+++ b/src/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/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp
index c8b43df26c..033a50f94f 100644
--- a/src/test/mempool_tests.cpp
+++ b/src/test/mempool_tests.cpp
@@ -2,6 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include "policy/policy.h"
#include "txmempool.h"
#include "util.h"
@@ -336,7 +337,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest)
tx2.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
tx2.vout[0].nValue = 2 * COIN;
pool.addUnchecked(tx2.GetHash(), entry.Fee(20000LL).Priority(9.0).FromTx(tx2));
- uint64_t tx2Size = ::GetSerializeSize(tx2, SER_NETWORK, PROTOCOL_VERSION);
+ uint64_t tx2Size = GetVirtualTransactionSize(tx2);
/* lowest fee */
CMutableTransaction tx3 = CMutableTransaction();
@@ -384,7 +385,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest)
tx6.vout.resize(1);
tx6.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
tx6.vout[0].nValue = 20 * COIN;
- uint64_t tx6Size = ::GetSerializeSize(tx6, SER_NETWORK, PROTOCOL_VERSION);
+ uint64_t tx6Size = GetVirtualTransactionSize(tx6);
pool.addUnchecked(tx6.GetHash(), entry.Fee(0LL).FromTx(tx6));
BOOST_CHECK_EQUAL(pool.size(), 6);
@@ -398,7 +399,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest)
tx7.vout.resize(1);
tx7.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
tx7.vout[0].nValue = 10 * COIN;
- uint64_t tx7Size = ::GetSerializeSize(tx7, SER_NETWORK, PROTOCOL_VERSION);
+ uint64_t tx7Size = GetVirtualTransactionSize(tx7);
/* set the fee to just below tx2's feerate when including ancestor */
CAmount fee = (20000/tx2Size)*(tx7Size + tx6Size) - 1;
@@ -467,12 +468,12 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
BOOST_CHECK(pool.exists(tx2.GetHash()));
BOOST_CHECK(pool.exists(tx3.GetHash()));
- pool.TrimToSize(::GetSerializeSize(CTransaction(tx1), SER_NETWORK, PROTOCOL_VERSION)); // mempool is limited to tx1's size in memory usage, so nothing fits
+ pool.TrimToSize(GetVirtualTransactionSize(tx1)); // mempool is limited to tx1's size in memory usage, so nothing fits
BOOST_CHECK(!pool.exists(tx1.GetHash()));
BOOST_CHECK(!pool.exists(tx2.GetHash()));
BOOST_CHECK(!pool.exists(tx3.GetHash()));
- CFeeRate maxFeeRateRemoved(25000, ::GetSerializeSize(CTransaction(tx3), SER_NETWORK, PROTOCOL_VERSION) + ::GetSerializeSize(CTransaction(tx2), SER_NETWORK, PROTOCOL_VERSION));
+ CFeeRate maxFeeRateRemoved(25000, GetVirtualTransactionSize(tx3) + GetVirtualTransactionSize(tx2));
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), maxFeeRateRemoved.GetFeePerK() + 1000);
CMutableTransaction tx4 = CMutableTransaction();
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index 3fb7967881..fd581db52e 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -71,9 +71,119 @@ bool TestSequenceLocks(const CTransaction &tx, int flags)
return CheckSequenceLocks(tx, flags);
}
+// Test suite for ancestor feerate transaction selection.
+// Implemented as an additional function, rather than a separate test case,
+// to allow reusing the blockchain created in CreateNewBlock_validity.
+// Note that this test assumes blockprioritysize is 0.
+void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, std::vector<CTransaction *>& txFirst)
+{
+ // Test the ancestor feerate transaction selection.
+ TestMemPoolEntryHelper entry;
+
+ // Test that a medium fee transaction will be selected after a higher fee
+ // rate package with a low fee rate parent.
+ CMutableTransaction tx;
+ tx.vin.resize(1);
+ tx.vin[0].scriptSig = CScript() << OP_1;
+ tx.vin[0].prevout.hash = txFirst[0]->GetHash();
+ tx.vin[0].prevout.n = 0;
+ tx.vout.resize(1);
+ tx.vout[0].nValue = 5000000000LL - 1000;
+ // This tx has a low fee: 1000 satoshis
+ uint256 hashParentTx = tx.GetHash(); // save this txid for later use
+ mempool.addUnchecked(hashParentTx, entry.Fee(1000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
+
+ // This tx has a medium fee: 10000 satoshis
+ tx.vin[0].prevout.hash = txFirst[1]->GetHash();
+ tx.vout[0].nValue = 5000000000LL - 10000;
+ uint256 hashMediumFeeTx = tx.GetHash();
+ mempool.addUnchecked(hashMediumFeeTx, entry.Fee(10000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
+
+ // This tx has a high fee, but depends on the first transaction
+ tx.vin[0].prevout.hash = hashParentTx;
+ tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 50k satoshi fee
+ uint256 hashHighFeeTx = tx.GetHash();
+ mempool.addUnchecked(hashHighFeeTx, entry.Fee(50000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
+
+ CBlockTemplate *pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey);
+ BOOST_CHECK(pblocktemplate->block.vtx[1].GetHash() == hashParentTx);
+ BOOST_CHECK(pblocktemplate->block.vtx[2].GetHash() == hashHighFeeTx);
+ BOOST_CHECK(pblocktemplate->block.vtx[3].GetHash() == hashMediumFeeTx);
+
+ // Test that a package below the min relay fee doesn't get included
+ tx.vin[0].prevout.hash = hashHighFeeTx;
+ tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 0 fee
+ uint256 hashFreeTx = tx.GetHash();
+ mempool.addUnchecked(hashFreeTx, entry.Fee(0).FromTx(tx));
+ size_t freeTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
+
+ // Calculate a fee on child transaction that will put the package just
+ // below the min relay fee (assuming 1 child tx of the same size).
+ CAmount feeToUse = minRelayTxFee.GetFee(2*freeTxSize) - 1;
+
+ tx.vin[0].prevout.hash = hashFreeTx;
+ tx.vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse;
+ uint256 hashLowFeeTx = tx.GetHash();
+ mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse).FromTx(tx));
+ pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey);
+ // Verify that the free tx and the low fee tx didn't get selected
+ for (size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
+ BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashFreeTx);
+ BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashLowFeeTx);
+ }
+
+ // Test that packages above the min relay fee do get included, even if one
+ // of the transactions is below the min relay fee
+ // Remove the low fee transaction and replace with a higher fee transaction
+ std::list<CTransaction> dummy;
+ mempool.removeRecursive(tx, dummy);
+ tx.vout[0].nValue -= 2; // Now we should be just over the min relay fee
+ hashLowFeeTx = tx.GetHash();
+ mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse+2).FromTx(tx));
+ pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey);
+ BOOST_CHECK(pblocktemplate->block.vtx[4].GetHash() == hashFreeTx);
+ BOOST_CHECK(pblocktemplate->block.vtx[5].GetHash() == hashLowFeeTx);
+
+ // Test that transaction selection properly updates ancestor fee
+ // calculations as ancestor transactions get included in a block.
+ // Add a 0-fee transaction that has 2 outputs.
+ tx.vin[0].prevout.hash = txFirst[2]->GetHash();
+ tx.vout.resize(2);
+ tx.vout[0].nValue = 5000000000LL - 100000000;
+ tx.vout[1].nValue = 100000000; // 1BTC output
+ uint256 hashFreeTx2 = tx.GetHash();
+ mempool.addUnchecked(hashFreeTx2, entry.Fee(0).SpendsCoinbase(true).FromTx(tx));
+
+ // This tx can't be mined by itself
+ tx.vin[0].prevout.hash = hashFreeTx2;
+ tx.vout.resize(1);
+ feeToUse = minRelayTxFee.GetFee(freeTxSize);
+ tx.vout[0].nValue = 5000000000LL - 100000000 - feeToUse;
+ uint256 hashLowFeeTx2 = tx.GetHash();
+ mempool.addUnchecked(hashLowFeeTx2, entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx));
+ pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey);
+
+ // Verify that this tx isn't selected.
+ for (size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
+ BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashFreeTx2);
+ BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashLowFeeTx2);
+ }
+
+ // This tx will be mineable, and should cause hashLowFeeTx2 to be selected
+ // as well.
+ tx.vin[0].prevout.n = 1;
+ tx.vout[0].nValue = 100000000 - 10000; // 10k satoshi fee
+ mempool.addUnchecked(tx.GetHash(), entry.Fee(10000).FromTx(tx));
+ pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey);
+ BOOST_CHECK(pblocktemplate->block.vtx[8].GetHash() == hashLowFeeTx2);
+}
+
// NOTE: These tests rely on CreateNewBlock doing its own self-validation!
BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
{
+ // Disable size accounting (CPFP does not support it)
+ mapArgs["-blockmaxsize"] = strprintf("%u", MAX_BLOCK_SERIALIZED_SIZE);
+
const CChainParams& chainparams = Params(CBaseChainParams::MAIN);
CScript scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
CBlockTemplate *pblocktemplate;
@@ -157,7 +267,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
hash = tx.GetHash();
bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase
// If we do set the # of sig ops in the CTxMemPoolEntry, template creation passes
- mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOps(20).FromTx(tx));
+ mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOpsCost(80).FromTx(tx));
tx.vin[0].prevout.hash = hash;
}
BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey));
@@ -385,6 +495,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
SetMockTime(0);
mempool.clear();
+ TestPackageSelection(chainparams, scriptPubKey, txFirst);
+
BOOST_FOREACH(CTransaction *_tx, txFirst)
delete _tx;
diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp
index d48a68ba54..581b0cee1e 100644
--- a/src/test/multisig_tests.cpp
+++ b/src/test/multisig_tests.cpp
@@ -26,7 +26,7 @@ BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup)
CScript
sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction, int whichIn)
{
- uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL);
+ uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL, 0, SIGVERSION_BASE);
CScript result;
result << OP_0; // CHECKMULTISIG bug workaround
@@ -46,6 +46,7 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
ScriptError err;
CKey key[4];
+ CAmount amount = 0;
for (int i = 0; i < 4; i++)
key[i].MakeNewKey(true);
@@ -81,20 +82,20 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
keys.assign(1,key[0]);
keys.push_back(key[1]);
s = sign_multisig(a_and_b, keys, txTo[0], 0);
- BOOST_CHECK(VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err));
+ BOOST_CHECK(VerifyScript(s, a_and_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
for (int i = 0; i < 4; i++)
{
keys.assign(1,key[i]);
s = sign_multisig(a_and_b, keys, txTo[0], 0);
- BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 1: %d", i));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 1: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
keys.assign(1,key[1]);
keys.push_back(key[i]);
s = sign_multisig(a_and_b, keys, txTo[0], 0);
- BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 2: %d", i));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 2: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
@@ -105,18 +106,18 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
s = sign_multisig(a_or_b, keys, txTo[1], 0);
if (i == 0 || i == 1)
{
- BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i));
+ BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
else
{
- BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
}
s.clear();
s << OP_0 << OP_1;
- BOOST_CHECK(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err));
+ BOOST_CHECK(!VerifyScript(s, a_or_b, NULL, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
@@ -128,12 +129,12 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
s = sign_multisig(escrow, keys, txTo[2], 0);
if (i < j && i < 3 && j < 3)
{
- BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j));
+ BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, NULL, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 1: %d %d", i, j));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
else
{
- BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, NULL, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 2: %d %d", i, j));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
}
@@ -302,7 +303,7 @@ BOOST_AUTO_TEST_CASE(multisig_Sign)
for (int i = 0; i < 3; i++)
{
- BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i));
+ BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL), strprintf("SignSignature %d", i));
}
}
diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp
index 2b00e6f567..5c902387f1 100644
--- a/src/test/policyestimator_tests.cpp
+++ b/src/test/policyestimator_tests.cpp
@@ -2,6 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include "policy/policy.h"
#include "policy/fees.h"
#include "txmempool.h"
#include "uint256.h"
@@ -50,7 +51,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
tx.vin[0].scriptSig = garbage;
tx.vout.resize(1);
tx.vout[0].nValue=0LL;
- CFeeRate baseRate(basefee, ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION));
+ CFeeRate baseRate(basefee, GetVirtualTransactionSize(tx));
// Create a fake block
std::vector<CTransaction> block;
diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp
index d10284fe94..5224b57ca4 100644
--- a/src/test/script_P2SH_tests.cpp
+++ b/src/test/script_P2SH_tests.cpp
@@ -2,6 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include "core_io.h"
#include "key.h"
#include "keystore.h"
#include "main.h"
@@ -42,7 +43,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, Scri
txTo.vin[0].scriptSig = scriptSig;
txTo.vout[0].nValue = 1;
- return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0), &err);
+ return VerifyScript(scriptSig, scriptPubKey, NULL, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0, txFrom.vout[0].nValue), &err);
}
@@ -102,7 +103,7 @@ BOOST_AUTO_TEST_CASE(sign)
}
for (int i = 0; i < 8; i++)
{
- BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i));
+ BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL), strprintf("SignSignature %d", i));
}
// All of the above should be OK, and the txTos have valid signatures
// Check to make sure signature verification fails if we use the wrong ScriptSig:
@@ -197,7 +198,7 @@ BOOST_AUTO_TEST_CASE(set)
}
for (int i = 0; i < 4; i++)
{
- BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i));
+ BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL), strprintf("SignSignature %d", i));
BOOST_CHECK_MESSAGE(IsStandardTx(txTo[i], reason), strprintf("txTo[%d].IsStandard", i));
}
}
@@ -326,9 +327,9 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txTo.vin[i].prevout.n = i;
txTo.vin[i].prevout.hash = txFrom.GetHash();
}
- BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 0));
- BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 1));
- BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 2));
+ BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL));
+ BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 1, SIGHASH_ALL));
+ BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 2, SIGHASH_ALL));
// SignSignature doesn't know how to sign these. We're
// not testing validating signatures, so just create
// dummy signatures that DO include the correct P2SH scripts:
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 39089f103d..5a9aaf9bc0 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -13,6 +13,7 @@
#include "util.h"
#include "utilstrencodings.h"
#include "test/test_bitcoin.h"
+#include "rpc/server.h"
#if defined(HAVE_CONSENSUS_LIB)
#include "script/bitcoinconsensus.h"
@@ -88,7 +89,14 @@ static ScriptErrorDesc script_errors[]={
{SCRIPT_ERR_SIG_NULLDUMMY, "SIG_NULLDUMMY"},
{SCRIPT_ERR_PUBKEYTYPE, "PUBKEYTYPE"},
{SCRIPT_ERR_CLEANSTACK, "CLEANSTACK"},
- {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, "DISCOURAGE_UPGRADABLE_NOPS"}
+ {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, "DISCOURAGE_UPGRADABLE_NOPS"},
+ {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM, "DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"},
+ {SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH, "WITNESS_PROGRAM_WRONG_LENGTH"},
+ {SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY, "WITNESS_PROGRAM_WITNESS_EMPTY"},
+ {SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH, "WITNESS_PROGRAM_MISMATCH"},
+ {SCRIPT_ERR_WITNESS_MALLEATED, "WITNESS_MALLEATED"},
+ {SCRIPT_ERR_WITNESS_MALLEATED_P2SH, "WITNESS_MALLEATED_P2SH"},
+ {SCRIPT_ERR_WITNESS_UNEXPECTED, "WITNESS_UNEXPECTED"},
};
const char *FormatScriptError(ScriptError_t err)
@@ -111,7 +119,7 @@ ScriptError_t ParseScriptError(const std::string &name)
BOOST_FIXTURE_TEST_SUITE(script_tests, BasicTestingSetup)
-CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey)
+CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey, int nValue = 0)
{
CMutableTransaction txCredit;
txCredit.nVersion = 1;
@@ -122,40 +130,52 @@ CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey)
txCredit.vin[0].scriptSig = CScript() << CScriptNum(0) << CScriptNum(0);
txCredit.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
txCredit.vout[0].scriptPubKey = scriptPubKey;
- txCredit.vout[0].nValue = 0;
+ txCredit.vout[0].nValue = nValue;
return txCredit;
}
-CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMutableTransaction& txCredit)
+CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScriptWitness& scriptWitness, const CMutableTransaction& txCredit)
{
CMutableTransaction txSpend;
txSpend.nVersion = 1;
txSpend.nLockTime = 0;
txSpend.vin.resize(1);
txSpend.vout.resize(1);
+ txSpend.wit.vtxinwit.resize(1);
+ txSpend.wit.vtxinwit[0].scriptWitness = scriptWitness;
txSpend.vin[0].prevout.hash = txCredit.GetHash();
txSpend.vin[0].prevout.n = 0;
txSpend.vin[0].scriptSig = scriptSig;
txSpend.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
txSpend.vout[0].scriptPubKey = CScript();
- txSpend.vout[0].nValue = 0;
+ txSpend.vout[0].nValue = txCredit.vout[0].nValue;
return txSpend;
}
-void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, const std::string& message, int scriptError)
+void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScriptWitness& scriptWitness, int flags, const std::string& message, int scriptError, CAmount nValue = 0)
{
bool expect = (scriptError == SCRIPT_ERR_OK);
+ if (flags & SCRIPT_VERIFY_CLEANSTACK) {
+ flags |= SCRIPT_VERIFY_P2SH;
+ flags |= SCRIPT_VERIFY_WITNESS;
+ }
ScriptError err;
- CMutableTransaction tx = BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey));
+ CMutableTransaction txCredit = BuildCreditingTransaction(scriptPubKey, nValue);
+ CMutableTransaction tx = BuildSpendingTransaction(scriptSig, scriptWitness, txCredit);
CMutableTransaction tx2 = tx;
- BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, MutableTransactionSignatureChecker(&tx, 0), &err) == expect, message);
+ BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue), &err) == expect, message);
BOOST_CHECK_MESSAGE(err == scriptError, std::string(FormatScriptError(err)) + " where " + std::string(FormatScriptError((ScriptError_t)scriptError)) + " expected: " + message);
#if defined(HAVE_CONSENSUS_LIB)
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
stream << tx2;
- BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(begin_ptr(scriptPubKey), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect,message);
+ if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) {
+ BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(begin_ptr(scriptPubKey), scriptPubKey.size(), txCredit.vout[0].nValue, (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect, message);
+ } else {
+ BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(begin_ptr(scriptPubKey), scriptPubKey.size(), 0, (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect, message);
+ BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(begin_ptr(scriptPubKey), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect,message);
+ }
#endif
}
@@ -234,11 +254,22 @@ struct KeyData
}
};
+enum WitnessMode {
+ WITNESS_NONE,
+ WITNESS_PKH,
+ WITNESS_SH
+};
class TestBuilder
{
private:
- CScript scriptPubKey;
+ //! Actually executed script
+ CScript script;
+ //! The P2SH redeemscript
+ CScript redeemscript;
+ //! The Witness embedded script
+ CScript witscript;
+ CScriptWitness scriptWitness;
CTransaction creditTx;
CMutableTransaction spendTx;
bool havePush;
@@ -246,6 +277,7 @@ private:
std::string comment;
int flags;
int scriptError;
+ CAmount nValue;
void DoPush()
{
@@ -263,14 +295,26 @@ private:
}
public:
- TestBuilder(const CScript& redeemScript, const std::string& comment_, int flags_, bool P2SH = false) : scriptPubKey(redeemScript), havePush(false), comment(comment_), flags(flags_), scriptError(SCRIPT_ERR_OK)
+ TestBuilder(const CScript& script_, const std::string& comment_, int flags_, bool P2SH = false, WitnessMode wm = WITNESS_NONE, int witnessversion = 0, CAmount nValue_ = 0) : script(script_), havePush(false), comment(comment_), flags(flags_), scriptError(SCRIPT_ERR_OK), nValue(nValue_)
{
+ CScript scriptPubKey = script;
+ if (wm == WITNESS_PKH) {
+ uint160 hash;
+ CHash160().Write(&script[1], script.size() - 1).Finalize(hash.begin());
+ script = CScript() << OP_DUP << OP_HASH160 << ToByteVector(hash) << OP_EQUALVERIFY << OP_CHECKSIG;
+ scriptPubKey = CScript() << witnessversion << ToByteVector(hash);
+ } else if (wm == WITNESS_SH) {
+ witscript = scriptPubKey;
+ uint256 hash;
+ CSHA256().Write(&witscript[0], witscript.size()).Finalize(hash.begin());
+ scriptPubKey = CScript() << witnessversion << ToByteVector(hash);
+ }
if (P2SH) {
- creditTx = BuildCreditingTransaction(CScript() << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL);
- } else {
- creditTx = BuildCreditingTransaction(redeemScript);
+ redeemscript = scriptPubKey;
+ scriptPubKey = CScript() << OP_HASH160 << ToByteVector(CScriptID(redeemscript)) << OP_EQUAL;
}
- spendTx = BuildSpendingTransaction(CScript(), creditTx);
+ creditTx = BuildCreditingTransaction(scriptPubKey, nValue);
+ spendTx = BuildSpendingTransaction(CScript(), CScriptWitness(), creditTx);
}
TestBuilder& ScriptError(ScriptError_t err)
@@ -299,9 +343,14 @@ public:
return *this;
}
- TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32)
+ TestBuilder& Push(const CScript& script) {
+ DoPush(std::vector<unsigned char>(script.begin(), script.end()));
+ return *this;
+ }
+
+ TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SIGVERSION_BASE, CAmount amount = 0)
{
- uint256 hash = SignatureHash(scriptPubKey, spendTx, 0, nHashType);
+ uint256 hash = SignatureHash(script, spendTx, 0, nHashType, amount, sigversion);
std::vector<unsigned char> vchSig, r, s;
uint32_t iter = 0;
do {
@@ -317,6 +366,13 @@ public:
return *this;
}
+ TestBuilder& PushWitSig(const CKey& key, CAmount amount = -1, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SIGVERSION_WITNESS_V0)
+ {
+ if (amount == -1)
+ amount = nValue;
+ return PushSig(key, nHashType, lenR, lenS, sigversion, amount).AsWit();
+ }
+
TestBuilder& Push(const CPubKey& pubkey)
{
DoPush(std::vector<unsigned char>(pubkey.begin(), pubkey.end()));
@@ -325,10 +381,16 @@ public:
TestBuilder& PushRedeem()
{
- DoPush(std::vector<unsigned char>(scriptPubKey.begin(), scriptPubKey.end()));
+ DoPush(std::vector<unsigned char>(redeemscript.begin(), redeemscript.end()));
return *this;
}
+ TestBuilder& PushWitRedeem()
+ {
+ DoPush(std::vector<unsigned char>(witscript.begin(), witscript.end()));
+ return AsWit();
+ }
+
TestBuilder& EditPush(unsigned int pos, const std::string& hexin, const std::string& hexout)
{
assert(havePush);
@@ -353,15 +415,31 @@ public:
{
TestBuilder copy = *this; // Make a copy so we can rollback the push.
DoPush();
- DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, flags, comment, scriptError);
+ DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, scriptWitness, flags, comment, scriptError, nValue);
*this = copy;
return *this;
}
+ TestBuilder& AsWit()
+ {
+ assert(havePush);
+ scriptWitness.stack.push_back(push);
+ havePush = false;
+ return *this;
+ }
+
UniValue GetJSON()
{
DoPush();
UniValue array(UniValue::VARR);
+ if (!scriptWitness.stack.empty()) {
+ UniValue wit(UniValue::VARR);
+ for (unsigned i = 0; i < scriptWitness.stack.size(); i++) {
+ wit.push_back(HexStr(scriptWitness.stack[i]));
+ }
+ wit.push_back(ValueFromAmount(nValue));
+ array.push_back(wit);
+ }
array.push_back(FormatScript(spendTx.vin[0].scriptSig));
array.push_back(FormatScript(creditTx.vout[0].scriptPubKey));
array.push_back(FormatScriptFlags(flags));
@@ -660,6 +738,90 @@ BOOST_AUTO_TEST_CASE(script_build)
"P2SH with CLEANSTACK", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true
).PushSig(keys.key0).PushRedeem());
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "Basic P2WSH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH,
+ 0, 1).PushWitSig(keys.key0).PushWitRedeem());
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
+ "Basic P2WPKH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH,
+ 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit());
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "Basic P2SH(P2WSH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH,
+ 0, 1).PushWitSig(keys.key0).PushWitRedeem().PushRedeem());
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
+ "Basic P2SH(P2WPKH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_PKH,
+ 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().PushRedeem());
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
+ "Basic P2WSH with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH
+ ).PushWitSig(keys.key0).PushWitRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1),
+ "Basic P2WPKH with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH
+ ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().ScriptError(SCRIPT_ERR_EVAL_FALSE));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
+ "Basic P2SH(P2WSH) with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH
+ ).PushWitSig(keys.key0).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1),
+ "Basic P2SH(P2WPKH) with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_PKH
+ ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
+ "Basic P2WSH with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, false, WITNESS_SH
+ ).PushWitSig(keys.key0).PushWitRedeem());
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1),
+ "Basic P2WPKH with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, false, WITNESS_PKH
+ ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit());
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
+ "Basic P2SH(P2WSH) with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, true, WITNESS_SH
+ ).PushWitSig(keys.key0).PushWitRedeem().PushRedeem());
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1),
+ "Basic P2SH(P2WPKH) with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, true, WITNESS_PKH
+ ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().PushRedeem());
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "Basic P2WSH with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH,
+ 0, 0).PushWitSig(keys.key0, 1).PushWitRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
+ "Basic P2WPKH with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH,
+ 0, 0).PushWitSig(keys.key0, 1).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_EVAL_FALSE));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "Basic P2SH(P2WSH) with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH,
+ 0, 0).PushWitSig(keys.key0, 1).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
+ "Basic P2SH(P2WPKH) with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_PKH,
+ 0, 0).PushWitSig(keys.key0, 1).Push(keys.pubkey0).AsWit().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
+
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
+ "P2WPKH with future witness version", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH |
+ SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM, false, WITNESS_PKH, 1
+ ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM));
+ {
+ CScript witscript = CScript() << ToByteVector(keys.pubkey0);
+ uint256 hash;
+ CSHA256().Write(&witscript[0], witscript.size()).Finalize(hash.begin());
+ vector<unsigned char> hashBytes = ToByteVector(hash);
+ hashBytes.pop_back();
+ tests.push_back(TestBuilder(CScript() << OP_0 << hashBytes,
+ "P2WPKH with wrong witness program length", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false
+ ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH));
+ }
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2WSH with empty witness", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH
+ ).ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY));
+ {
+ CScript witscript = CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG;
+ tests.push_back(TestBuilder(witscript,
+ "P2WSH with witness program mismatch", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH
+ ).PushWitSig(keys.key0).Push(witscript).DamagePush(0).AsWit().ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH));
+ }
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
+ "P2WPKH with witness program mismatch", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH
+ ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().Push("0").AsWit().ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
+ "P2WPKH with non-empty scriptSig", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH
+ ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().Num(11).ScriptError(SCRIPT_ERR_WITNESS_MALLEATED));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1),
+ "P2SH(P2WPKH) with superfluous push in scriptSig", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_PKH
+ ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().Num(11).PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_MALLEATED_P2SH));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2PK with witness", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH
+ ).PushSig(keys.key0).Push("0").AsWit().ScriptError(SCRIPT_ERR_WITNESS_UNEXPECTED));
std::set<std::string> tests_set;
@@ -696,29 +858,42 @@ BOOST_AUTO_TEST_CASE(script_json_test)
{
// Read tests from test/data/script_tests.json
// Format is an array of arrays
- // Inner arrays are [ "scriptSig", "scriptPubKey", "flags", "expected_scripterror" ]
+ // Inner arrays are [ ["wit"..., nValue]?, "scriptSig", "scriptPubKey", "flags", "expected_scripterror" ]
// ... where scriptSig and scriptPubKey are stringified
// scripts.
+ // If a witness is given, then the last value in the array should be the
+ // amount (nValue) to use in the crediting tx
UniValue tests = read_json(std::string(json_tests::script_tests, json_tests::script_tests + sizeof(json_tests::script_tests)));
for (unsigned int idx = 0; idx < tests.size(); idx++) {
UniValue test = tests[idx];
string strTest = test.write();
- if (test.size() < 4) // Allow size > 3; extra stuff ignored (useful for comments)
+ CScriptWitness witness;
+ CAmount nValue = 0;
+ unsigned int pos = 0;
+ if (test.size() > 0 && test[pos].isArray()) {
+ unsigned int i=0;
+ for (i = 0; i < test[pos].size()-1; i++) {
+ witness.stack.push_back(ParseHex(test[pos][i].get_str()));
+ }
+ nValue = AmountFromValue(test[pos][i]);
+ pos++;
+ }
+ if (test.size() < 4 + pos) // Allow size > 3; extra stuff ignored (useful for comments)
{
if (test.size() != 1) {
BOOST_ERROR("Bad test: " << strTest);
}
continue;
}
- string scriptSigString = test[0].get_str();
+ string scriptSigString = test[pos++].get_str();
CScript scriptSig = ParseScript(scriptSigString);
- string scriptPubKeyString = test[1].get_str();
+ string scriptPubKeyString = test[pos++].get_str();
CScript scriptPubKey = ParseScript(scriptPubKeyString);
- unsigned int scriptflags = ParseScriptFlags(test[2].get_str());
- int scriptError = ParseScriptError(test[3].get_str());
+ unsigned int scriptflags = ParseScriptFlags(test[pos++].get_str());
+ int scriptError = ParseScriptError(test[pos++].get_str());
- DoTest(scriptPubKey, scriptSig, scriptflags, strTest, scriptError);
+ DoTest(scriptPubKey, scriptSig, witness, scriptflags, strTest, scriptError, nValue);
}
}
@@ -733,21 +908,21 @@ BOOST_AUTO_TEST_CASE(script_PushData)
ScriptError err;
vector<vector<unsigned char> > directStack;
- BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
+ BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SIGVERSION_BASE, &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
vector<vector<unsigned char> > pushdata1Stack;
- BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
+ BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SIGVERSION_BASE, &err));
BOOST_CHECK(pushdata1Stack == directStack);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
vector<vector<unsigned char> > pushdata2Stack;
- BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
+ BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SIGVERSION_BASE, &err));
BOOST_CHECK(pushdata2Stack == directStack);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
vector<vector<unsigned char> > pushdata4Stack;
- BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
+ BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SIGVERSION_BASE, &err));
BOOST_CHECK(pushdata4Stack == directStack);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
@@ -755,7 +930,7 @@ BOOST_AUTO_TEST_CASE(script_PushData)
CScript
sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transaction)
{
- uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL);
+ uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL, 0, SIGVERSION_BASE);
CScript result;
//
@@ -796,21 +971,21 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12)
scriptPubKey12 << OP_1 << ToByteVector(key1.GetPubKey()) << ToByteVector(key2.GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
CMutableTransaction txFrom12 = BuildCreditingTransaction(scriptPubKey12);
- CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12);
+ CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom12);
CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12);
- BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
+ BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
txTo12.vout[0].nValue = 2;
- BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
+ BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12);
- BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
+ BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12);
- BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
@@ -827,65 +1002,66 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
scriptPubKey23 << OP_2 << ToByteVector(key1.GetPubKey()) << ToByteVector(key2.GetPubKey()) << ToByteVector(key3.GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
CMutableTransaction txFrom23 = BuildCreditingTransaction(scriptPubKey23);
- CMutableTransaction txTo23 = BuildSpendingTransaction(CScript(), txFrom23);
+ CMutableTransaction txTo23 = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom23);
std::vector<CKey> keys;
keys.push_back(key1); keys.push_back(key2);
CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear();
keys.push_back(key1); keys.push_back(key3);
CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear();
keys.push_back(key2); keys.push_back(key3);
CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear();
keys.push_back(key2); keys.push_back(key2); // Can't re-use sig
CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order
CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order
CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys
CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys
CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear(); // Must have signatures
CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
}
BOOST_AUTO_TEST_CASE(script_combineSigs)
{
// Test the CombineSignatures function
+ CAmount amount = 0;
CBasicKeyStore keystore;
vector<CKey> keys;
vector<CPubKey> pubkeys;
@@ -899,66 +1075,66 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
}
CMutableTransaction txFrom = BuildCreditingTransaction(GetScriptForDestination(keys[0].GetPubKey().GetID()));
- CMutableTransaction txTo = BuildSpendingTransaction(CScript(), txFrom);
+ CMutableTransaction txTo = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom);
CScript& scriptPubKey = txFrom.vout[0].scriptPubKey;
CScript& scriptSig = txTo.vin[0].scriptSig;
- CScript empty;
- CScript combined = CombineSignatures(scriptPubKey, txTo, 0, empty, empty);
- BOOST_CHECK(combined.empty());
+ SignatureData empty;
+ SignatureData combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), empty, empty);
+ BOOST_CHECK(combined.scriptSig.empty());
// Single signature case:
- SignSignature(keystore, txFrom, txTo, 0); // changes scriptSig
- combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty);
- BOOST_CHECK(combined == scriptSig);
- combined = CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig);
- BOOST_CHECK(combined == scriptSig);
+ SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL); // changes scriptSig
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), empty);
+ BOOST_CHECK(combined.scriptSig == scriptSig);
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), empty, SignatureData(scriptSig));
+ BOOST_CHECK(combined.scriptSig == scriptSig);
CScript scriptSigCopy = scriptSig;
// Signing again will give a different, valid signature:
- SignSignature(keystore, txFrom, txTo, 0);
- combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig);
- BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig);
+ SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL);
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig));
+ BOOST_CHECK(combined.scriptSig == scriptSigCopy || combined.scriptSig == scriptSig);
// P2SH, single-signature case:
CScript pkSingle; pkSingle << ToByteVector(keys[0].GetPubKey()) << OP_CHECKSIG;
keystore.AddCScript(pkSingle);
scriptPubKey = GetScriptForDestination(CScriptID(pkSingle));
- SignSignature(keystore, txFrom, txTo, 0);
- combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty);
- BOOST_CHECK(combined == scriptSig);
- combined = CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig);
- BOOST_CHECK(combined == scriptSig);
+ SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL);
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), empty);
+ BOOST_CHECK(combined.scriptSig == scriptSig);
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), empty, SignatureData(scriptSig));
+ BOOST_CHECK(combined.scriptSig == scriptSig);
scriptSigCopy = scriptSig;
- SignSignature(keystore, txFrom, txTo, 0);
- combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig);
- BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig);
+ SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL);
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig));
+ BOOST_CHECK(combined.scriptSig == scriptSigCopy || combined.scriptSig == scriptSig);
// dummy scriptSigCopy with placeholder, should always choose non-placeholder:
- scriptSigCopy = CScript() << OP_0 << vector<unsigned char>(pkSingle.begin(), pkSingle.end());
- combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig);
- BOOST_CHECK(combined == scriptSig);
- combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, scriptSigCopy);
- BOOST_CHECK(combined == scriptSig);
+ scriptSigCopy = CScript() << OP_0 << std::vector<unsigned char>(pkSingle.begin(), pkSingle.end());
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig));
+ BOOST_CHECK(combined.scriptSig == scriptSig);
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), SignatureData(scriptSigCopy));
+ BOOST_CHECK(combined.scriptSig == scriptSig);
// Hardest case: Multisig 2-of-3
scriptPubKey = GetScriptForMultisig(2, pubkeys);
keystore.AddCScript(scriptPubKey);
- SignSignature(keystore, txFrom, txTo, 0);
- combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty);
- BOOST_CHECK(combined == scriptSig);
- combined = CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig);
- BOOST_CHECK(combined == scriptSig);
+ SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL);
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), empty);
+ BOOST_CHECK(combined.scriptSig == scriptSig);
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), empty, SignatureData(scriptSig));
+ BOOST_CHECK(combined.scriptSig == scriptSig);
// A couple of partially-signed versions:
vector<unsigned char> sig1;
- uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL);
+ uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL, 0, SIGVERSION_BASE);
BOOST_CHECK(keys[0].Sign(hash1, sig1));
sig1.push_back(SIGHASH_ALL);
vector<unsigned char> sig2;
- uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE);
+ uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE, 0, SIGVERSION_BASE);
BOOST_CHECK(keys[1].Sign(hash2, sig2));
sig2.push_back(SIGHASH_NONE);
vector<unsigned char> sig3;
- uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE);
+ uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE, 0, SIGVERSION_BASE);
BOOST_CHECK(keys[2].Sign(hash3, sig3));
sig3.push_back(SIGHASH_SINGLE);
@@ -974,22 +1150,22 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
CScript complete13 = CScript() << OP_0 << sig1 << sig3;
CScript complete23 = CScript() << OP_0 << sig2 << sig3;
- combined = CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial1b);
- BOOST_CHECK(combined == partial1a);
- combined = CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial2a);
- BOOST_CHECK(combined == complete12);
- combined = CombineSignatures(scriptPubKey, txTo, 0, partial2a, partial1a);
- BOOST_CHECK(combined == complete12);
- combined = CombineSignatures(scriptPubKey, txTo, 0, partial1b, partial2b);
- BOOST_CHECK(combined == complete12);
- combined = CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial1b);
- BOOST_CHECK(combined == complete13);
- combined = CombineSignatures(scriptPubKey, txTo, 0, partial2a, partial3a);
- BOOST_CHECK(combined == complete23);
- combined = CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial2b);
- BOOST_CHECK(combined == complete23);
- combined = CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial3a);
- BOOST_CHECK(combined == partial3c);
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial1a), SignatureData(partial1b));
+ BOOST_CHECK(combined.scriptSig == partial1a);
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial1a), SignatureData(partial2a));
+ BOOST_CHECK(combined.scriptSig == complete12);
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial2a), SignatureData(partial1a));
+ BOOST_CHECK(combined.scriptSig == complete12);
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial1b), SignatureData(partial2b));
+ BOOST_CHECK(combined.scriptSig == complete12);
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial3b), SignatureData(partial1b));
+ BOOST_CHECK(combined.scriptSig == complete13);
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial2a), SignatureData(partial3a));
+ BOOST_CHECK(combined.scriptSig == complete23);
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial3b), SignatureData(partial2b));
+ BOOST_CHECK(combined.scriptSig == complete23);
+ combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial3b), SignatureData(partial3a));
+ BOOST_CHECK(combined.scriptSig == partial3c);
}
BOOST_AUTO_TEST_CASE(script_standard_push)
@@ -999,7 +1175,7 @@ BOOST_AUTO_TEST_CASE(script_standard_push)
CScript script;
script << i;
BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Number " << i << " is not pure push.");
- BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Number " << i << " push is not minimal data.");
+ BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, NULL, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Number " << i << " push is not minimal data.");
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
@@ -1008,7 +1184,7 @@ BOOST_AUTO_TEST_CASE(script_standard_push)
CScript script;
script << data;
BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Length " << i << " is not pure push.");
- BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Length " << i << " push is not minimal data.");
+ BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, NULL, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Length " << i << " push is not minimal data.");
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
}
diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp
index e43b2ff6c4..4a48347b70 100644
--- a/src/test/sighash_tests.cpp
+++ b/src/test/sighash_tests.cpp
@@ -82,7 +82,7 @@ uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, un
}
// Serialize and hash
- CHashWriter ss(SER_GETHASH, 0);
+ CHashWriter ss(SER_GETHASH, SERIALIZE_TRANSACTION_NO_WITNESS);
ss << txTmp << nHashType;
return ss.GetHash();
}
@@ -143,7 +143,7 @@ BOOST_AUTO_TEST_CASE(sighash_test)
uint256 sh, sho;
sho = SignatureHashOld(scriptCode, txTo, nIn, nHashType);
- sh = SignatureHash(scriptCode, txTo, nIn, nHashType);
+ sh = SignatureHash(scriptCode, txTo, nIn, nHashType, 0, SIGVERSION_BASE);
#if defined(PRINT_SIGHASH_JSON)
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << txTo;
@@ -209,7 +209,7 @@ BOOST_AUTO_TEST_CASE(sighash_from_data)
continue;
}
- sh = SignatureHash(scriptCode, tx, nIn, nHashType);
+ sh = SignatureHash(scriptCode, tx, nIn, nHashType, 0, SIGVERSION_BASE);
BOOST_CHECK_MESSAGE(sh.GetHex() == sigHashHex, strTest);
}
}
diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp
index a207fd9216..8dea388332 100644
--- a/src/test/sigopcount_tests.cpp
+++ b/src/test/sigopcount_tests.cpp
@@ -2,6 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include "main.h"
#include "pubkey.h"
#include "key.h"
#include "script/script.h"
@@ -64,4 +65,180 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount)
BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig2), 3U);
}
+/**
+ * Verifies script execution of the zeroth scriptPubKey of tx output and
+ * zeroth scriptSig and witness of tx input.
+ */
+ScriptError VerifyWithFlag(const CTransaction& output, const CMutableTransaction& input, int flags)
+{
+ ScriptError error;
+ CTransaction inputi(input);
+ bool ret = VerifyScript(inputi.vin[0].scriptSig, output.vout[0].scriptPubKey, inputi.wit.vtxinwit.size() > 0 ? &inputi.wit.vtxinwit[0].scriptWitness : NULL, flags, TransactionSignatureChecker(&inputi, 0, output.vout[0].nValue), &error);
+ BOOST_CHECK((ret == true) == (error == SCRIPT_ERR_OK));
+
+ return error;
+}
+
+/**
+ * Builds a creationTx from scriptPubKey and a spendingTx from scriptSig
+ * and witness such that spendingTx spends output zero of creationTx.
+ * Also inserts creationTx's output into the coins view.
+ */
+void BuildTxs(CMutableTransaction& spendingTx, CCoinsViewCache& coins, CMutableTransaction& creationTx, const CScript& scriptPubKey, const CScript& scriptSig, const CTxinWitness& witness)
+{
+ creationTx.nVersion = 1;
+ creationTx.vin.resize(1);
+ creationTx.vin[0].prevout.SetNull();
+ creationTx.vin[0].scriptSig = CScript();
+ creationTx.wit.vtxinwit.resize(1);
+ creationTx.vout.resize(1);
+ creationTx.vout[0].nValue = 1;
+ creationTx.vout[0].scriptPubKey = scriptPubKey;
+
+ spendingTx.nVersion = 1;
+ spendingTx.vin.resize(1);
+ spendingTx.vin[0].prevout.hash = creationTx.GetHash();
+ spendingTx.vin[0].prevout.n = 0;
+ spendingTx.vin[0].scriptSig = scriptSig;
+ spendingTx.wit.vtxinwit.resize(1);
+ spendingTx.wit.vtxinwit[0] = witness;
+ spendingTx.vout.resize(1);
+ spendingTx.vout[0].nValue = 1;
+ spendingTx.vout[0].scriptPubKey = CScript();
+
+ coins.ModifyCoins(creationTx.GetHash())->FromTx(creationTx, 0);
+}
+
+BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
+{
+ // Transaction creates outputs
+ CMutableTransaction creationTx;
+ // Transaction that spends outputs and whose
+ // sig op cost is going to be tested
+ CMutableTransaction spendingTx;
+
+ // Create utxo set
+ CCoinsView coinsDummy;
+ CCoinsViewCache coins(&coinsDummy);
+ // Create key
+ CKey key;
+ key.MakeNewKey(true);
+ CPubKey pubkey = key.GetPubKey();
+ // Default flags
+ int flags = SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH;
+
+ // Multisig script (legacy counting)
+ {
+ CScript scriptPubKey = CScript() << 1 << ToByteVector(pubkey) << ToByteVector(pubkey) << 2 << OP_CHECKMULTISIGVERIFY;
+ // Do not use a valid signature to avoid using wallet operations.
+ CScript scriptSig = CScript() << OP_0 << OP_0;
+
+ BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, CTxinWitness());
+ // Legacy counting only includes signature operations in scriptSigs and scriptPubKeys
+ // of a transaction and does not take the actual executed sig operations into account.
+ // spendingTx in itself does not contain a signature operation.
+ assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 0);
+ // creationTx contains two signature operations in its scriptPubKey, but legacy counting
+ // is not accurate.
+ assert(GetTransactionSigOpCost(CTransaction(creationTx), coins, flags) == MAX_PUBKEYS_PER_MULTISIG * WITNESS_SCALE_FACTOR);
+ // Sanity check: script verification fails because of an invalid signature.
+ assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY);
+ }
+
+ // Multisig nested in P2SH
+ {
+ CScript redeemScript = CScript() << 1 << ToByteVector(pubkey) << ToByteVector(pubkey) << 2 << OP_CHECKMULTISIGVERIFY;
+ CScript scriptPubKey = GetScriptForDestination(CScriptID(redeemScript));
+ CScript scriptSig = CScript() << OP_0 << OP_0 << ToByteVector(redeemScript);
+
+ BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, CTxinWitness());
+ assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 2 * WITNESS_SCALE_FACTOR);
+ assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY);
+ }
+
+ // P2WPKH witness program
+ {
+ CScript p2pk = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
+ CScript scriptPubKey = GetScriptForWitness(p2pk);
+ CScript scriptSig = CScript();
+ CTxinWitness witness;
+ CScriptWitness scriptWitness;
+ scriptWitness.stack.push_back(vector<unsigned char>(0));
+ scriptWitness.stack.push_back(vector<unsigned char>(0));
+ witness.scriptWitness = scriptWitness;
+
+
+ BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness);
+ assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 1);
+ // No signature operations if we don't verify the witness.
+ assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags & ~SCRIPT_VERIFY_WITNESS) == 0);
+ assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_EQUALVERIFY);
+
+ // The sig op cost for witness version != 0 is zero.
+ assert(scriptPubKey[0] == 0x00);
+ scriptPubKey[0] = 0x51;
+ BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness);
+ assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 0);
+ scriptPubKey[0] = 0x00;
+ BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness);
+
+ // The witness of a coinbase transaction is not taken into account.
+ spendingTx.vin[0].prevout.SetNull();
+ assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 0);
+ }
+
+ // P2WPKH nested in P2SH
+ {
+ CScript p2pk = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
+ CScript scriptSig = GetScriptForWitness(p2pk);
+ CScript scriptPubKey = GetScriptForDestination(CScriptID(scriptSig));
+ scriptSig = CScript() << ToByteVector(scriptSig);
+ CTxinWitness witness;
+ CScriptWitness scriptWitness;
+ scriptWitness.stack.push_back(vector<unsigned char>(0));
+ scriptWitness.stack.push_back(vector<unsigned char>(0));
+ witness.scriptWitness = scriptWitness;
+
+ BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness);
+ assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 1);
+ assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_EQUALVERIFY);
+ }
+
+ // P2WSH witness program
+ {
+ CScript witnessScript = CScript() << 1 << ToByteVector(pubkey) << ToByteVector(pubkey) << 2 << OP_CHECKMULTISIGVERIFY;
+ CScript scriptPubKey = GetScriptForWitness(witnessScript);
+ CScript scriptSig = CScript();
+ CTxinWitness witness;
+ CScriptWitness scriptWitness;
+ scriptWitness.stack.push_back(vector<unsigned char>(0));
+ scriptWitness.stack.push_back(vector<unsigned char>(0));
+ scriptWitness.stack.push_back(vector<unsigned char>(witnessScript.begin(), witnessScript.end()));
+ witness.scriptWitness = scriptWitness;
+
+ BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness);
+ assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 2);
+ assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags & ~SCRIPT_VERIFY_WITNESS) == 0);
+ assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY);
+ }
+
+ // P2WSH nested in P2SH
+ {
+ CScript witnessScript = CScript() << 1 << ToByteVector(pubkey) << ToByteVector(pubkey) << 2 << OP_CHECKMULTISIGVERIFY;
+ CScript redeemScript = GetScriptForWitness(witnessScript);
+ CScript scriptPubKey = GetScriptForDestination(CScriptID(redeemScript));
+ CScript scriptSig = CScript() << ToByteVector(redeemScript);
+ CTxinWitness witness;
+ CScriptWitness scriptWitness;
+ scriptWitness.stack.push_back(vector<unsigned char>(0));
+ scriptWitness.stack.push_back(vector<unsigned char>(0));
+ scriptWitness.stack.push_back(vector<unsigned char>(witnessScript.begin(), witnessScript.end()));
+ witness.scriptWitness = scriptWitness;
+
+ BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness);
+ assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 2);
+ assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY);
+ }
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index c68320ba8b..856f9b8423 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -55,6 +55,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000)));
boost::filesystem::create_directories(pathTemp);
mapArgs["-datadir"] = pathTemp.string();
+ mempool.setSanityCheck(1.0);
pblocktree = new CBlockTreeDB(1 << 20, true);
pcoinsdbview = new CCoinsViewDB(1 << 23, true);
pcoinsTip = new CCoinsViewCache(pcoinsdbview);
@@ -126,12 +127,16 @@ TestChain100Setup::~TestChain100Setup()
CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CMutableTransaction &tx, CTxMemPool *pool) {
CTransaction txn(tx);
- bool hasNoDependencies = pool ? pool->HasNoInputsOf(tx) : hadNoDependencies;
+ return FromTx(txn, pool);
+}
+
+CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CTransaction &txn, CTxMemPool *pool) {
+ bool hasNoDependencies = pool ? pool->HasNoInputsOf(txn) : hadNoDependencies;
// Hack to assume either its completely dependent on other mempool txs or not at all
CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0;
return CTxMemPoolEntry(txn, nFee, nTime, dPriority, nHeight,
- hasNoDependencies, inChainValue, spendsCoinbase, sigOpCount, lp);
+ hasNoDependencies, inChainValue, spendsCoinbase, sigOpCost, lp);
}
void Shutdown(void* parg)
diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h
index 57f66f6c6d..bc0d2fe316 100644
--- a/src/test/test_bitcoin.h
+++ b/src/test/test_bitcoin.h
@@ -70,14 +70,15 @@ struct TestMemPoolEntryHelper
unsigned int nHeight;
bool hadNoDependencies;
bool spendsCoinbase;
- unsigned int sigOpCount;
+ unsigned int sigOpCost;
LockPoints lp;
TestMemPoolEntryHelper() :
nFee(0), nTime(0), dPriority(0.0), nHeight(1),
- hadNoDependencies(false), spendsCoinbase(false), sigOpCount(1) { }
+ hadNoDependencies(false), spendsCoinbase(false), sigOpCost(4) { }
CTxMemPoolEntry FromTx(CMutableTransaction &tx, CTxMemPool *pool = NULL);
+ CTxMemPoolEntry FromTx(CTransaction &tx, CTxMemPool *pool = NULL);
// Change the default value
TestMemPoolEntryHelper &Fee(CAmount _fee) { nFee = _fee; return *this; }
@@ -86,6 +87,6 @@ struct TestMemPoolEntryHelper
TestMemPoolEntryHelper &Height(unsigned int _height) { nHeight = _height; return *this; }
TestMemPoolEntryHelper &HadNoDependencies(bool _hnd) { hadNoDependencies = _hnd; return *this; }
TestMemPoolEntryHelper &SpendsCoinbase(bool _flag) { spendsCoinbase = _flag; return *this; }
- TestMemPoolEntryHelper &SigOps(unsigned int _sigops) { sigOpCount = _sigops; return *this; }
+ TestMemPoolEntryHelper &SigOpsCost(unsigned int _sigopsCost) { sigOpCost = _sigopsCost; return *this; }
};
#endif
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index d9195bf345..fd4f174b40 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -14,7 +14,9 @@
#include "main.h" // For CheckTransaction
#include "policy/policy.h"
#include "script/script.h"
+#include "script/sign.h"
#include "script/script_error.h"
+#include "script/standard.h"
#include "utilstrencodings.h"
#include <map>
@@ -25,11 +27,14 @@
#include <boost/assign/list_of.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign/list_of.hpp>
+#include <boost/foreach.hpp>
#include <univalue.h>
using namespace std;
+typedef vector<unsigned char> valtype;
+
// In script_tests.cpp
extern UniValue read_json(const std::string& jsondata);
@@ -45,7 +50,9 @@ static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of
(string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
(string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK)
(string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)
- (string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY);
+ (string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)
+ (string("WITNESS"), (unsigned int)SCRIPT_VERIFY_WITNESS)
+ (string("DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM);
unsigned int ParseScriptFlags(string strFlags)
{
@@ -108,6 +115,7 @@ BOOST_AUTO_TEST_CASE(tx_valid)
}
map<COutPoint, CScript> mapprevOutScriptPubKeys;
+ map<COutPoint, int64_t> mapprevOutValues;
UniValue inputs = test[0].get_array();
bool fValid = true;
for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) {
@@ -118,13 +126,17 @@ BOOST_AUTO_TEST_CASE(tx_valid)
break;
}
UniValue vinput = input.get_array();
- if (vinput.size() != 3)
+ if (vinput.size() < 3 || vinput.size() > 4)
{
fValid = false;
break;
}
-
- mapprevOutScriptPubKeys[COutPoint(uint256S(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str());
+ COutPoint outpoint(uint256S(vinput[0].get_str()), vinput[1].get_int());
+ mapprevOutScriptPubKeys[outpoint] = ParseScript(vinput[2].get_str());
+ if (vinput.size() >= 4)
+ {
+ mapprevOutValues[outpoint] = vinput[3].get_int64();
+ }
}
if (!fValid)
{
@@ -149,9 +161,14 @@ BOOST_AUTO_TEST_CASE(tx_valid)
break;
}
+ CAmount amount = 0;
+ if (mapprevOutValues.count(tx.vin[i].prevout)) {
+ amount = mapprevOutValues[tx.vin[i].prevout];
+ }
unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
+ const CScriptWitness *witness = (i < tx.wit.vtxinwit.size()) ? &tx.wit.vtxinwit[i].scriptWitness : NULL;
BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
- verify_flags, TransactionSignatureChecker(&tx, i), &err),
+ witness, verify_flags, TransactionSignatureChecker(&tx, i, amount), &err),
strTest);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
@@ -183,6 +200,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
}
map<COutPoint, CScript> mapprevOutScriptPubKeys;
+ map<COutPoint, int64_t> mapprevOutValues;
UniValue inputs = test[0].get_array();
bool fValid = true;
for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) {
@@ -193,13 +211,17 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
break;
}
UniValue vinput = input.get_array();
- if (vinput.size() != 3)
+ if (vinput.size() < 3 || vinput.size() > 4)
{
fValid = false;
break;
}
-
- mapprevOutScriptPubKeys[COutPoint(uint256S(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str());
+ COutPoint outpoint(uint256S(vinput[0].get_str()), vinput[1].get_int());
+ mapprevOutScriptPubKeys[outpoint] = ParseScript(vinput[2].get_str());
+ if (vinput.size() >= 4)
+ {
+ mapprevOutValues[outpoint] = vinput[3].get_int64();
+ }
}
if (!fValid)
{
@@ -208,7 +230,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
}
string transaction = test[1].get_str();
- CDataStream stream(ParseHex(transaction), SER_NETWORK, PROTOCOL_VERSION);
+ CDataStream stream(ParseHex(transaction), SER_NETWORK, PROTOCOL_VERSION );
CTransaction tx;
stream >> tx;
@@ -224,8 +246,13 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
}
unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
+ CAmount amount = 0;
+ if (mapprevOutValues.count(tx.vin[i].prevout)) {
+ amount = mapprevOutValues[tx.vin[i].prevout];
+ }
+ const CScriptWitness *witness = (i < tx.wit.vtxinwit.size()) ? &tx.wit.vtxinwit[i].scriptWitness : NULL;
fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
- verify_flags, TransactionSignatureChecker(&tx, i), &err);
+ witness, verify_flags, TransactionSignatureChecker(&tx, i, amount), &err);
}
BOOST_CHECK_MESSAGE(!fValid, strTest);
BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err));
@@ -313,6 +340,277 @@ BOOST_AUTO_TEST_CASE(test_Get)
BOOST_CHECK_EQUAL(coins.GetValueIn(t1), (50+21+22)*CENT);
}
+void CreateCreditAndSpend(const CKeyStore& keystore, const CScript& outscript, CTransaction& output, CMutableTransaction& input, bool success = true)
+{
+ CMutableTransaction outputm;
+ outputm.nVersion = 1;
+ outputm.vin.resize(1);
+ outputm.vin[0].prevout.SetNull();
+ outputm.vin[0].scriptSig = CScript();
+ outputm.wit.vtxinwit.resize(1);
+ outputm.vout.resize(1);
+ outputm.vout[0].nValue = 1;
+ outputm.vout[0].scriptPubKey = outscript;
+ CDataStream ssout(SER_NETWORK, PROTOCOL_VERSION);
+ ssout << outputm;
+ ssout >> output;
+ assert(output.vin.size() == 1);
+ assert(output.vin[0] == outputm.vin[0]);
+ assert(output.vout.size() == 1);
+ assert(output.vout[0] == outputm.vout[0]);
+ assert(output.wit.vtxinwit.size() == 0);
+
+ CMutableTransaction inputm;
+ inputm.nVersion = 1;
+ inputm.vin.resize(1);
+ inputm.vin[0].prevout.hash = output.GetHash();
+ inputm.vin[0].prevout.n = 0;
+ inputm.wit.vtxinwit.resize(1);
+ inputm.vout.resize(1);
+ inputm.vout[0].nValue = 1;
+ inputm.vout[0].scriptPubKey = CScript();
+ bool ret = SignSignature(keystore, output, inputm, 0, SIGHASH_ALL);
+ assert(ret == success);
+ CDataStream ssin(SER_NETWORK, PROTOCOL_VERSION);
+ ssin << inputm;
+ ssin >> input;
+ assert(input.vin.size() == 1);
+ assert(input.vin[0] == inputm.vin[0]);
+ assert(input.vout.size() == 1);
+ assert(input.vout[0] == inputm.vout[0]);
+ if (inputm.wit.IsNull()) {
+ assert(input.wit.IsNull());
+ } else {
+ assert(!input.wit.IsNull());
+ assert(input.wit.vtxinwit.size() == 1);
+ assert(input.wit.vtxinwit[0].scriptWitness.stack == inputm.wit.vtxinwit[0].scriptWitness.stack);
+ }
+}
+
+void CheckWithFlag(const CTransaction& output, const CMutableTransaction& input, int flags, bool success)
+{
+ ScriptError error;
+ CTransaction inputi(input);
+ bool ret = VerifyScript(inputi.vin[0].scriptSig, output.vout[0].scriptPubKey, inputi.wit.vtxinwit.size() > 0 ? &inputi.wit.vtxinwit[0].scriptWitness : NULL, flags, TransactionSignatureChecker(&inputi, 0, output.vout[0].nValue), &error);
+ assert(ret == success);
+}
+
+static CScript PushAll(const vector<valtype>& values)
+{
+ CScript result;
+ BOOST_FOREACH(const valtype& v, values) {
+ if (v.size() == 0) {
+ result << OP_0;
+ } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) {
+ result << CScript::EncodeOP_N(v[0]);
+ } else {
+ result << v;
+ }
+ }
+ return result;
+}
+
+void ReplaceRedeemScript(CScript& script, const CScript& redeemScript)
+{
+ vector<valtype> stack;
+ EvalScript(stack, script, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), SIGVERSION_BASE);
+ assert(stack.size() > 0);
+ stack.back() = std::vector<unsigned char>(redeemScript.begin(), redeemScript.end());
+ script = PushAll(stack);
+}
+
+BOOST_AUTO_TEST_CASE(test_witness)
+{
+ CBasicKeyStore keystore, keystore2;
+ CKey key1, key2, key3, key1L, key2L;
+ CPubKey pubkey1, pubkey2, pubkey3, pubkey1L, pubkey2L;
+ key1.MakeNewKey(true);
+ key2.MakeNewKey(true);
+ key3.MakeNewKey(true);
+ key1L.MakeNewKey(false);
+ key2L.MakeNewKey(false);
+ pubkey1 = key1.GetPubKey();
+ pubkey2 = key2.GetPubKey();
+ pubkey3 = key3.GetPubKey();
+ pubkey1L = key1L.GetPubKey();
+ pubkey2L = key2L.GetPubKey();
+ keystore.AddKeyPubKey(key1, pubkey1);
+ keystore.AddKeyPubKey(key2, pubkey2);
+ keystore.AddKeyPubKey(key1L, pubkey1L);
+ keystore.AddKeyPubKey(key2L, pubkey2L);
+ CScript scriptPubkey1, scriptPubkey2, scriptPubkey1L, scriptPubkey2L, scriptMulti;
+ scriptPubkey1 << ToByteVector(pubkey1) << OP_CHECKSIG;
+ scriptPubkey2 << ToByteVector(pubkey2) << OP_CHECKSIG;
+ scriptPubkey1L << ToByteVector(pubkey1L) << OP_CHECKSIG;
+ scriptPubkey2L << ToByteVector(pubkey2L) << OP_CHECKSIG;
+ std::vector<CPubKey> oneandthree;
+ oneandthree.push_back(pubkey1);
+ oneandthree.push_back(pubkey3);
+ scriptMulti = GetScriptForMultisig(2, oneandthree);
+ keystore.AddCScript(scriptPubkey1);
+ keystore.AddCScript(scriptPubkey2);
+ keystore.AddCScript(scriptPubkey1L);
+ keystore.AddCScript(scriptPubkey2L);
+ keystore.AddCScript(scriptMulti);
+ keystore.AddCScript(GetScriptForWitness(scriptPubkey1));
+ keystore.AddCScript(GetScriptForWitness(scriptPubkey2));
+ keystore.AddCScript(GetScriptForWitness(scriptPubkey1L));
+ keystore.AddCScript(GetScriptForWitness(scriptPubkey2L));
+ keystore.AddCScript(GetScriptForWitness(scriptMulti));
+ keystore2.AddCScript(scriptMulti);
+ keystore2.AddCScript(GetScriptForWitness(scriptMulti));
+ keystore2.AddKeyPubKey(key3, pubkey3);
+
+ CTransaction output1, output2;
+ CMutableTransaction input1, input2;
+ SignatureData sigdata;
+
+ // Normal pay-to-compressed-pubkey.
+ CreateCreditAndSpend(keystore, scriptPubkey1, output1, input1);
+ CreateCreditAndSpend(keystore, scriptPubkey2, output2, input2);
+ CheckWithFlag(output1, input1, 0, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
+ CheckWithFlag(output1, input2, 0, false);
+ CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);
+ CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);
+ CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
+
+ // P2SH pay-to-compressed-pubkey.
+ CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(scriptPubkey1)), output1, input1);
+ CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(scriptPubkey2)), output2, input2);
+ ReplaceRedeemScript(input2.vin[0].scriptSig, scriptPubkey1);
+ CheckWithFlag(output1, input1, 0, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
+ CheckWithFlag(output1, input2, 0, true);
+ CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);
+ CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);
+ CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
+
+ // Witness pay-to-compressed-pubkey (v0).
+ CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey1), output1, input1);
+ CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey2), output2, input2);
+ CheckWithFlag(output1, input1, 0, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
+ CheckWithFlag(output1, input2, 0, true);
+ CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);
+ CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
+
+ // P2SH witness pay-to-compressed-pubkey (v0).
+ CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptPubkey1))), output1, input1);
+ CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptPubkey2))), output2, input2);
+ ReplaceRedeemScript(input2.vin[0].scriptSig, GetScriptForWitness(scriptPubkey1));
+ CheckWithFlag(output1, input1, 0, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
+ CheckWithFlag(output1, input2, 0, true);
+ CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);
+ CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
+
+ // Normal pay-to-uncompressed-pubkey.
+ CreateCreditAndSpend(keystore, scriptPubkey1L, output1, input1);
+ CreateCreditAndSpend(keystore, scriptPubkey2L, output2, input2);
+ CheckWithFlag(output1, input1, 0, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
+ CheckWithFlag(output1, input2, 0, false);
+ CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);
+ CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);
+ CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
+
+ // P2SH pay-to-uncompressed-pubkey.
+ CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(scriptPubkey1L)), output1, input1);
+ CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(scriptPubkey2L)), output2, input2);
+ ReplaceRedeemScript(input2.vin[0].scriptSig, scriptPubkey1L);
+ CheckWithFlag(output1, input1, 0, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
+ CheckWithFlag(output1, input2, 0, true);
+ CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);
+ CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);
+ CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
+
+ // Witness pay-to-uncompressed-pubkey (v1).
+ CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey1L), output1, input1);
+ CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey2L), output2, input2);
+ CheckWithFlag(output1, input1, 0, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
+ CheckWithFlag(output1, input2, 0, true);
+ CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);
+ CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
+
+ // P2SH witness pay-to-uncompressed-pubkey (v1).
+ CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptPubkey1L))), output1, input1);
+ CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptPubkey2L))), output2, input2);
+ ReplaceRedeemScript(input2.vin[0].scriptSig, GetScriptForWitness(scriptPubkey1L));
+ CheckWithFlag(output1, input1, 0, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
+ CheckWithFlag(output1, input2, 0, true);
+ CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);
+ CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
+
+ // Normal 2-of-2 multisig
+ CreateCreditAndSpend(keystore, scriptMulti, output1, input1, false);
+ CheckWithFlag(output1, input1, 0, false);
+ CreateCreditAndSpend(keystore2, scriptMulti, output2, input2, false);
+ CheckWithFlag(output2, input2, 0, false);
+ BOOST_CHECK(output1 == output2);
+ UpdateTransaction(input1, 0, CombineSignatures(output1.vout[0].scriptPubKey, MutableTransactionSignatureChecker(&input1, 0, output1.vout[0].nValue), DataFromTransaction(input1, 0), DataFromTransaction(input2, 0)));
+ CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
+
+ // P2SH 2-of-2 multisig
+ CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(scriptMulti)), output1, input1, false);
+ CheckWithFlag(output1, input1, 0, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, false);
+ CreateCreditAndSpend(keystore2, GetScriptForDestination(CScriptID(scriptMulti)), output2, input2, false);
+ CheckWithFlag(output2, input2, 0, true);
+ CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH, false);
+ BOOST_CHECK(output1 == output2);
+ UpdateTransaction(input1, 0, CombineSignatures(output1.vout[0].scriptPubKey, MutableTransactionSignatureChecker(&input1, 0, output1.vout[0].nValue), DataFromTransaction(input1, 0), DataFromTransaction(input2, 0)));
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
+
+ // Witness 2-of-2 multisig
+ CreateCreditAndSpend(keystore, GetScriptForWitness(scriptMulti), output1, input1, false);
+ CheckWithFlag(output1, input1, 0, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);
+ CreateCreditAndSpend(keystore2, GetScriptForWitness(scriptMulti), output2, input2, false);
+ CheckWithFlag(output2, input2, 0, true);
+ CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);
+ BOOST_CHECK(output1 == output2);
+ UpdateTransaction(input1, 0, CombineSignatures(output1.vout[0].scriptPubKey, MutableTransactionSignatureChecker(&input1, 0, output1.vout[0].nValue), DataFromTransaction(input1, 0), DataFromTransaction(input2, 0)));
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true);
+ CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
+
+ // P2SH witness 2-of-2 multisig
+ CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptMulti))), output1, input1, false);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);
+ CreateCreditAndSpend(keystore2, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptMulti))), output2, input2, false);
+ CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH, true);
+ CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);
+ BOOST_CHECK(output1 == output2);
+ UpdateTransaction(input1, 0, CombineSignatures(output1.vout[0].scriptPubKey, MutableTransactionSignatureChecker(&input1, 0, output1.vout[0].nValue), DataFromTransaction(input1, 0), DataFromTransaction(input2, 0)));
+ CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true);
+ CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
+}
+
BOOST_AUTO_TEST_CASE(test_IsStandard)
{
LOCK(cs_main);
diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp
index c29e30792a..76e4e7a4be 100644
--- a/src/test/txvalidationcache_tests.cpp
+++ b/src/test/txvalidationcache_tests.cpp
@@ -48,7 +48,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
// Sign:
std::vector<unsigned char> vchSig;
- uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, SIGHASH_ALL);
+ uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, SIGHASH_ALL, 0, SIGVERSION_BASE);
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
vchSig.push_back((unsigned char)SIGHASH_ALL);
spends[i].vin[0].scriptSig << vchSig;