diff --git a/src/test/script_p2sh_tests.cpp b/src/test/script_p2sh_tests.cpp
index 3821a6341..6ecbe127a 100644
--- a/src/test/script_p2sh_tests.cpp
+++ b/src/test/script_p2sh_tests.cpp
@@ -1,353 +1,350 @@
 // Copyright (c) 2012-2019 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 <consensus/tx_verify.h>
 #include <key.h>
 #include <policy/policy.h>
 #include <policy/settings.h>
 #include <script/script.h>
 #include <script/script_error.h>
 #include <script/sign.h>
 #include <script/signingprovider.h>
 #include <tinyformat.h>
 #include <validation.h>
 
 #include <test/util/setup_common.h>
 
 #include <boost/test/unit_test.hpp>
 
 #include <vector>
 
 // Helpers:
 static std::vector<uint8_t> Serialize(const CScript &s) {
     std::vector<uint8_t> sSerialized(s.begin(), s.end());
     return sSerialized;
 }
 
 static bool Verify(const CScript &scriptSig, const CScript &scriptPubKey,
                    bool fStrict, ScriptError &err) {
     // Create dummy to/from transactions:
     CMutableTransaction txFrom;
     txFrom.vout.resize(1);
     txFrom.vout[0].scriptPubKey = scriptPubKey;
 
     CMutableTransaction txTo;
     txTo.vin.resize(1);
     txTo.vout.resize(1);
     txTo.vin[0].prevout = COutPoint(txFrom.GetId(), 0);
     txTo.vin[0].scriptSig = scriptSig;
     txTo.vout[0].nValue = SATOSHI;
 
     return VerifyScript(
         scriptSig, scriptPubKey,
         (fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE) |
             SCRIPT_ENABLE_SIGHASH_FORKID,
         MutableTransactionSignatureChecker(&txTo, 0, txFrom.vout[0].nValue),
         &err);
 }
 
 BOOST_FIXTURE_TEST_SUITE(script_p2sh_tests, BasicTestingSetup)
 
 BOOST_AUTO_TEST_CASE(sign) {
-    LOCK(cs_main);
     // Pay-to-script-hash looks like this:
     // scriptSig:    <sig> <sig...> <serialized_script>
     // scriptPubKey: HASH160 <hash> EQUAL
 
     // Test SignSignature() (and therefore the version of Solver() that signs
     // transactions)
     FillableSigningProvider keystore;
     CKey key[4];
     for (int i = 0; i < 4; i++) {
         key[i].MakeNewKey(true);
         BOOST_CHECK(keystore.AddKey(key[i]));
     }
 
     // 8 Scripts: checking all combinations of
     // different keys, straight/P2SH, pubkey/pubkeyhash
     CScript standardScripts[4];
     standardScripts[0] << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG;
     standardScripts[1] = GetScriptForDestination(PKHash(key[1].GetPubKey()));
     standardScripts[2] << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG;
     standardScripts[3] = GetScriptForDestination(PKHash(key[2].GetPubKey()));
     CScript evalScripts[4];
     for (int i = 0; i < 4; i++) {
         BOOST_CHECK(keystore.AddCScript(standardScripts[i]));
         evalScripts[i] =
             GetScriptForDestination(ScriptHash(standardScripts[i]));
     }
 
     // Funding transaction:
     CMutableTransaction txFrom;
     std::string reason;
     txFrom.vout.resize(8);
     for (int i = 0; i < 4; i++) {
         txFrom.vout[i].scriptPubKey = evalScripts[i];
         txFrom.vout[i].nValue = COIN;
         txFrom.vout[i + 4].scriptPubKey = standardScripts[i];
         txFrom.vout[i + 4].nValue = COIN;
     }
     BOOST_CHECK(IsStandardTx(CTransaction(txFrom), reason));
 
     // Spending transactions
     CMutableTransaction txTo[8];
     for (int i = 0; i < 8; i++) {
         txTo[i].vin.resize(1);
         txTo[i].vout.resize(1);
         txTo[i].vin[0].prevout = COutPoint(txFrom.GetId(), i);
         txTo[i].vout[0].nValue = SATOSHI;
     }
 
     for (int i = 0; i < 8; i++) {
         BOOST_CHECK_MESSAGE(SignSignature(keystore, CTransaction(txFrom),
                                           txTo[i], 0,
                                           SigHashType().withForkId()),
                             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:
     for (int i = 0; i < 8; i++) {
         CTransaction tx(txTo[i]);
         PrecomputedTransactionData txdata(tx);
         for (int j = 0; j < 8; j++) {
             CScript sigSave = txTo[i].vin[0].scriptSig;
             txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig;
             bool sigOK =
                 CScriptCheck(txFrom.vout[txTo[i].vin[0].prevout.GetN()],
                              CTransaction(txTo[i]), 0,
                              SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC |
                                  SCRIPT_ENABLE_SIGHASH_FORKID,
                              false, txdata)();
             if (i == j) {
                 BOOST_CHECK_MESSAGE(sigOK,
                                     strprintf("VerifySignature %d %d", i, j));
             } else {
                 BOOST_CHECK_MESSAGE(!sigOK,
                                     strprintf("VerifySignature %d %d", i, j));
             }
             txTo[i].vin[0].scriptSig = sigSave;
         }
     }
 }
 
 BOOST_AUTO_TEST_CASE(norecurse) {
     ScriptError err;
     // Make sure only the outer pay-to-script-hash does the
     // extra-validation thing:
     CScript invalidAsScript;
     invalidAsScript << OP_INVALIDOPCODE << OP_INVALIDOPCODE;
 
     CScript p2sh = GetScriptForDestination(ScriptHash(invalidAsScript));
 
     CScript scriptSig;
     scriptSig << Serialize(invalidAsScript);
 
     // Should not verify, because it will try to execute OP_INVALIDOPCODE
     BOOST_CHECK(!Verify(scriptSig, p2sh, true, err));
     BOOST_CHECK_MESSAGE(err == ScriptError::BAD_OPCODE, ScriptErrorString(err));
 
     // Try to recur, and verification should succeed because
     // the inner HASH160 <> EQUAL should only check the hash:
     CScript p2sh2 = GetScriptForDestination(ScriptHash(p2sh));
     CScript scriptSig2;
     scriptSig2 << Serialize(invalidAsScript) << Serialize(p2sh);
 
     BOOST_CHECK(Verify(scriptSig2, p2sh2, true, err));
     BOOST_CHECK_MESSAGE(err == ScriptError::OK, ScriptErrorString(err));
 }
 
 BOOST_AUTO_TEST_CASE(set) {
-    LOCK(cs_main);
     // Test the CScript::Set* methods
     FillableSigningProvider keystore;
     CKey key[4];
     std::vector<CPubKey> keys;
     for (int i = 0; i < 4; i++) {
         key[i].MakeNewKey(true);
         BOOST_CHECK(keystore.AddKey(key[i]));
         keys.push_back(key[i].GetPubKey());
     }
 
     CScript inner[4];
     inner[0] = GetScriptForDestination(PKHash(key[0].GetPubKey()));
     inner[1] = GetScriptForMultisig(
         2, std::vector<CPubKey>(keys.begin(), keys.begin() + 2));
     inner[2] = GetScriptForMultisig(
         1, std::vector<CPubKey>(keys.begin(), keys.begin() + 2));
     inner[3] = GetScriptForMultisig(
         2, std::vector<CPubKey>(keys.begin(), keys.begin() + 3));
 
     CScript outer[4];
     for (int i = 0; i < 4; i++) {
         outer[i] = GetScriptForDestination(ScriptHash(inner[i]));
         BOOST_CHECK(keystore.AddCScript(inner[i]));
     }
 
     // Funding transaction:
     CMutableTransaction txFrom;
     std::string reason;
     txFrom.vout.resize(4);
     for (int i = 0; i < 4; i++) {
         txFrom.vout[i].scriptPubKey = outer[i];
         txFrom.vout[i].nValue = CENT;
     }
     BOOST_CHECK(IsStandardTx(CTransaction(txFrom), reason));
 
     // Spending transactions
     CMutableTransaction txTo[4];
     for (int i = 0; i < 4; i++) {
         txTo[i].vin.resize(1);
         txTo[i].vout.resize(1);
         txTo[i].vin[0].prevout = COutPoint(txFrom.GetId(), i);
         txTo[i].vout[0].nValue = 1 * CENT;
         txTo[i].vout[0].scriptPubKey = inner[i];
     }
     for (int i = 0; i < 4; i++) {
         BOOST_CHECK_MESSAGE(SignSignature(keystore, CTransaction(txFrom),
                                           txTo[i], 0,
                                           SigHashType().withForkId()),
                             strprintf("SignSignature %d", i));
         BOOST_CHECK_MESSAGE(IsStandardTx(CTransaction(txTo[i]), reason),
                             strprintf("txTo[%d].IsStandard", i));
     }
 }
 
 BOOST_AUTO_TEST_CASE(is) {
     // Test CScript::IsPayToScriptHash()
     uint160 dummy;
     CScript p2sh;
     p2sh << OP_HASH160 << ToByteVector(dummy) << OP_EQUAL;
     BOOST_CHECK(p2sh.IsPayToScriptHash());
 
     std::vector<uint8_t> direct = {OP_HASH160, 20};
     direct.insert(direct.end(), 20, 0);
     direct.push_back(OP_EQUAL);
     BOOST_CHECK(CScript(direct.begin(), direct.end()).IsPayToScriptHash());
 
     // Not considered pay-to-script-hash if using one of the OP_PUSHDATA
     // opcodes:
     std::vector<uint8_t> pushdata1 = {OP_HASH160, OP_PUSHDATA1, 20};
     pushdata1.insert(pushdata1.end(), 20, 0);
     pushdata1.push_back(OP_EQUAL);
     BOOST_CHECK(
         !CScript(pushdata1.begin(), pushdata1.end()).IsPayToScriptHash());
     std::vector<uint8_t> pushdata2 = {OP_HASH160, OP_PUSHDATA2, 20, 0};
     pushdata2.insert(pushdata2.end(), 20, 0);
     pushdata2.push_back(OP_EQUAL);
     BOOST_CHECK(
         !CScript(pushdata2.begin(), pushdata2.end()).IsPayToScriptHash());
     std::vector<uint8_t> pushdata4 = {OP_HASH160, OP_PUSHDATA4, 20, 0, 0, 0};
     pushdata4.insert(pushdata4.end(), 20, 0);
     pushdata4.push_back(OP_EQUAL);
     BOOST_CHECK(
         !CScript(pushdata4.begin(), pushdata4.end()).IsPayToScriptHash());
 
     CScript not_p2sh;
     BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
 
     not_p2sh.clear();
     not_p2sh << OP_HASH160 << ToByteVector(dummy) << ToByteVector(dummy)
              << OP_EQUAL;
     BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
 
     not_p2sh.clear();
     not_p2sh << OP_NOP << ToByteVector(dummy) << OP_EQUAL;
     BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
 
     not_p2sh.clear();
     not_p2sh << OP_HASH160 << ToByteVector(dummy) << OP_CHECKSIG;
     BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
 }
 
 BOOST_AUTO_TEST_CASE(switchover) {
     // Test switch over code
     CScript notValid;
     ScriptError err;
     notValid << OP_11 << OP_12 << OP_EQUALVERIFY;
     CScript scriptSig;
     scriptSig << Serialize(notValid);
 
     CScript fund = GetScriptForDestination(ScriptHash(notValid));
 
     // Validation should succeed under old rules (hash is correct):
     BOOST_CHECK(Verify(scriptSig, fund, false, err));
     BOOST_CHECK_MESSAGE(err == ScriptError::OK, ScriptErrorString(err));
     // Fail under new:
     BOOST_CHECK(!Verify(scriptSig, fund, true, err));
     BOOST_CHECK_MESSAGE(err == ScriptError::EQUALVERIFY,
                         ScriptErrorString(err));
 }
 
 BOOST_AUTO_TEST_CASE(AreInputsStandard) {
-    LOCK(cs_main);
     CCoinsView coinsDummy;
     CCoinsViewCache coins(&coinsDummy);
     FillableSigningProvider keystore;
     CKey key[6];
     std::vector<CPubKey> keys;
     for (int i = 0; i < 6; i++) {
         key[i].MakeNewKey(true);
         BOOST_CHECK(keystore.AddKey(key[i]));
     }
     for (int i = 0; i < 3; i++) {
         keys.push_back(key[i].GetPubKey());
     }
 
     CMutableTransaction txFrom;
     txFrom.vout.resize(4);
 
     // First three are standard:
     CScript pay1 = GetScriptForDestination(PKHash(key[0].GetPubKey()));
     BOOST_CHECK(keystore.AddCScript(pay1));
     CScript pay1of3 = GetScriptForMultisig(1, keys);
 
     // P2SH (OP_CHECKSIG)
     txFrom.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(pay1));
     txFrom.vout[0].nValue = 1000 * SATOSHI;
     // ordinary OP_CHECKSIG
     txFrom.vout[1].scriptPubKey = pay1;
     txFrom.vout[1].nValue = 2000 * SATOSHI;
     // ordinary OP_CHECKMULTISIG
     txFrom.vout[2].scriptPubKey = pay1of3;
     txFrom.vout[2].nValue = 3000 * SATOSHI;
 
     // vout[3] is complicated 1-of-3 AND 2-of-3
     // ... that is OK if wrapped in P2SH:
     CScript oneAndTwo;
     oneAndTwo << OP_1 << ToByteVector(key[0].GetPubKey())
               << ToByteVector(key[1].GetPubKey())
               << ToByteVector(key[2].GetPubKey());
     oneAndTwo << OP_3 << OP_CHECKMULTISIGVERIFY;
     oneAndTwo << OP_2 << ToByteVector(key[3].GetPubKey())
               << ToByteVector(key[4].GetPubKey())
               << ToByteVector(key[5].GetPubKey());
     oneAndTwo << OP_3 << OP_CHECKMULTISIG;
     BOOST_CHECK(keystore.AddCScript(oneAndTwo));
     txFrom.vout[3].scriptPubKey =
         GetScriptForDestination(ScriptHash(oneAndTwo));
     txFrom.vout[3].nValue = 4000 * SATOSHI;
 
     AddCoins(coins, CTransaction(txFrom), 0);
 
     CMutableTransaction txTo;
     txTo.vout.resize(1);
     txTo.vout[0].scriptPubKey =
         GetScriptForDestination(PKHash(key[1].GetPubKey()));
 
     txTo.vin.resize(3);
     for (int i = 0; i < 3; i++) {
         txTo.vin[i].prevout = COutPoint(txFrom.GetId(), i);
     }
 
     BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0,
                               SigHashType().withForkId()));
     BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 1,
                               SigHashType().withForkId()));
     BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 2,
                               SigHashType().withForkId()));
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 1dc7c0cf5..6ae9e375a 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -1,934 +1,933 @@
 // Copyright (c) 2011-2019 The Bitcoin Core developers
 // Copyright (c) 2017-2020 The Bitcoin developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include <chainparams.h> // For CChainParams
 #include <checkqueue.h>
 #include <clientversion.h>
 #include <config.h>
 #include <consensus/amount.h>
 #include <consensus/tx_check.h>
 #include <consensus/tx_verify.h>
 #include <consensus/validation.h>
 #include <core_io.h>
 #include <key.h>
 #include <policy/policy.h>
 #include <policy/settings.h>
 #include <script/script.h>
 #include <script/script_error.h>
 #include <script/sign.h>
 #include <script/signingprovider.h>
 #include <script/standard.h>
 #include <streams.h>
 #include <util/strencodings.h>
 #include <util/string.h>
 #include <util/system.h>
 #include <validation.h>
 
 #include <test/data/tx_invalid.json.h>
 #include <test/data/tx_valid.json.h>
 #include <test/jsonutil.h>
 #include <test/scriptflags.h>
 #include <test/util/setup_common.h>
 #include <test/util/transaction_utils.h>
 
 #include <boost/test/unit_test.hpp>
 
 #include <univalue.h>
 
 #include <map>
 #include <string>
 
 typedef std::vector<uint8_t> valtype;
 
 BOOST_FIXTURE_TEST_SUITE(transaction_tests, BasicTestingSetup)
 
 static COutPoint buildOutPoint(const UniValue &vinput) {
     TxId txid;
     txid.SetHex(vinput[0].get_str());
     return COutPoint(txid, vinput[1].get_int());
 }
 
 BOOST_AUTO_TEST_CASE(tx_valid) {
     // Read tests from test/data/tx_valid.json
     // Format is an array of arrays
     // Inner arrays are either [ "comment" ]
     // or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2],
     // ...],"], serializedTransaction, verifyFlags
     // ... where all scripts are stringified scripts.
     //
     // verifyFlags is a comma separated list of script verification flags to
     // apply, or "NONE"
     UniValue tests = read_json(
         std::string(json_tests::tx_valid,
                     json_tests::tx_valid + sizeof(json_tests::tx_valid)));
 
     ScriptError err;
     for (size_t idx = 0; idx < tests.size(); idx++) {
         UniValue test = tests[idx];
         std::string strTest = test.write();
         if (test[0].isArray()) {
             if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) {
                 BOOST_ERROR("Bad test: " << strTest);
                 continue;
             }
 
             std::map<COutPoint, CScript> mapprevOutScriptPubKeys;
             std::map<COutPoint, Amount> mapprevOutValues;
             UniValue inputs = test[0].get_array();
             bool fValid = true;
             for (size_t inpIdx = 0; inpIdx < inputs.size(); inpIdx++) {
                 const UniValue &input = inputs[inpIdx];
                 if (!input.isArray()) {
                     fValid = false;
                     break;
                 }
                 UniValue vinput = input.get_array();
                 if (vinput.size() < 3 || vinput.size() > 4) {
                     fValid = false;
                     break;
                 }
                 COutPoint outpoint = buildOutPoint(vinput);
                 mapprevOutScriptPubKeys[outpoint] =
                     ParseScript(vinput[2].get_str());
                 if (vinput.size() >= 4) {
                     mapprevOutValues[outpoint] =
                         vinput[3].get_int64() * SATOSHI;
                 }
             }
             if (!fValid) {
                 BOOST_ERROR("Bad test: " << strTest);
                 continue;
             }
 
             std::string transaction = test[1].get_str();
             CDataStream stream(ParseHex(transaction), SER_NETWORK,
                                PROTOCOL_VERSION);
             CTransaction tx(deserialize, stream);
 
             TxValidationState state;
             BOOST_CHECK_MESSAGE(tx.IsCoinBase()
                                     ? CheckCoinbase(tx, state)
                                     : CheckRegularTransaction(tx, state),
                                 strTest);
             BOOST_CHECK(state.IsValid());
 
             // Check that CheckCoinbase reject non-coinbase transactions and
             // vice versa.
             BOOST_CHECK_MESSAGE(!(tx.IsCoinBase()
                                       ? CheckRegularTransaction(tx, state)
                                       : CheckCoinbase(tx, state)),
                                 strTest);
             BOOST_CHECK(state.IsInvalid());
 
             PrecomputedTransactionData txdata(tx);
             for (size_t i = 0; i < tx.vin.size(); i++) {
                 if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout)) {
                     BOOST_ERROR("Bad test: " << strTest);
                     break;
                 }
 
                 Amount amount = Amount::zero();
                 if (mapprevOutValues.count(tx.vin[i].prevout)) {
                     amount = mapprevOutValues[tx.vin[i].prevout];
                 }
 
                 uint32_t verify_flags = ParseScriptFlags(test[2].get_str());
                 BOOST_CHECK_MESSAGE(
                     VerifyScript(
                         tx.vin[i].scriptSig,
                         mapprevOutScriptPubKeys[tx.vin[i].prevout],
                         verify_flags,
                         TransactionSignatureChecker(&tx, i, amount, txdata),
                         &err),
                     strTest);
                 BOOST_CHECK_MESSAGE(err == ScriptError::OK,
                                     ScriptErrorString(err));
             }
         }
     }
 }
 
 BOOST_AUTO_TEST_CASE(tx_invalid) {
     // Read tests from test/data/tx_invalid.json
     // Format is an array of arrays
     // Inner arrays are either [ "comment" ]
     // or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2],
     // ...],"], serializedTransaction, verifyFlags
     // ... where all scripts are stringified scripts.
     //
     // verifyFlags is a comma separated list of script verification flags to
     // apply, or "NONE"
     UniValue tests = read_json(
         std::string(json_tests::tx_invalid,
                     json_tests::tx_invalid + sizeof(json_tests::tx_invalid)));
 
     // Initialize to ScriptError::OK. The tests expect err to be changed to a
     // value other than ScriptError::OK.
     ScriptError err = ScriptError::OK;
     for (size_t idx = 0; idx < tests.size(); idx++) {
         UniValue test = tests[idx];
         std::string strTest = test.write();
         if (test[0].isArray()) {
             if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) {
                 BOOST_ERROR("Bad test: " << strTest);
                 continue;
             }
 
             std::map<COutPoint, CScript> mapprevOutScriptPubKeys;
             std::map<COutPoint, Amount> mapprevOutValues;
             UniValue inputs = test[0].get_array();
             bool fValid = true;
             for (size_t inpIdx = 0; inpIdx < inputs.size(); inpIdx++) {
                 const UniValue &input = inputs[inpIdx];
                 if (!input.isArray()) {
                     fValid = false;
                     break;
                 }
                 UniValue vinput = input.get_array();
                 if (vinput.size() < 3 || vinput.size() > 4) {
                     fValid = false;
                     break;
                 }
                 COutPoint outpoint = buildOutPoint(vinput);
                 mapprevOutScriptPubKeys[outpoint] =
                     ParseScript(vinput[2].get_str());
                 if (vinput.size() >= 4) {
                     mapprevOutValues[outpoint] =
                         vinput[3].get_int64() * SATOSHI;
                 }
             }
             if (!fValid) {
                 BOOST_ERROR("Bad test: " << strTest);
                 continue;
             }
 
             std::string transaction = test[1].get_str();
             CDataStream stream(ParseHex(transaction), SER_NETWORK,
                                PROTOCOL_VERSION);
             CTransaction tx(deserialize, stream);
 
             TxValidationState state;
             fValid = CheckRegularTransaction(tx, state) && state.IsValid();
 
             PrecomputedTransactionData txdata(tx);
             for (size_t i = 0; i < tx.vin.size() && fValid; i++) {
                 if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout)) {
                     BOOST_ERROR("Bad test: " << strTest);
                     break;
                 }
 
                 Amount amount = Amount::zero();
                 if (0 != mapprevOutValues.count(tx.vin[i].prevout)) {
                     amount = mapprevOutValues[tx.vin[i].prevout];
                 }
 
                 uint32_t verify_flags = ParseScriptFlags(test[2].get_str());
                 fValid = VerifyScript(
                     tx.vin[i].scriptSig,
                     mapprevOutScriptPubKeys[tx.vin[i].prevout], verify_flags,
                     TransactionSignatureChecker(&tx, i, amount, txdata), &err);
             }
             BOOST_CHECK_MESSAGE(!fValid, strTest);
             BOOST_CHECK_MESSAGE(err != ScriptError::OK, ScriptErrorString(err));
         }
     }
 }
 
 BOOST_AUTO_TEST_CASE(basic_transaction_tests) {
     // Random real transaction
     // (e2769b09e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436)
     uint8_t ch[] = {
         0x01, 0x00, 0x00, 0x00, 0x01, 0x6b, 0xff, 0x7f, 0xcd, 0x4f, 0x85, 0x65,
         0xef, 0x40, 0x6d, 0xd5, 0xd6, 0x3d, 0x4f, 0xf9, 0x4f, 0x31, 0x8f, 0xe8,
         0x20, 0x27, 0xfd, 0x4d, 0xc4, 0x51, 0xb0, 0x44, 0x74, 0x01, 0x9f, 0x74,
         0xb4, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x49, 0x30, 0x46, 0x02, 0x21, 0x00,
         0xda, 0x0d, 0xc6, 0xae, 0xce, 0xfe, 0x1e, 0x06, 0xef, 0xdf, 0x05, 0x77,
         0x37, 0x57, 0xde, 0xb1, 0x68, 0x82, 0x09, 0x30, 0xe3, 0xb0, 0xd0, 0x3f,
         0x46, 0xf5, 0xfc, 0xf1, 0x50, 0xbf, 0x99, 0x0c, 0x02, 0x21, 0x00, 0xd2,
         0x5b, 0x5c, 0x87, 0x04, 0x00, 0x76, 0xe4, 0xf2, 0x53, 0xf8, 0x26, 0x2e,
         0x76, 0x3e, 0x2d, 0xd5, 0x1e, 0x7f, 0xf0, 0xbe, 0x15, 0x77, 0x27, 0xc4,
         0xbc, 0x42, 0x80, 0x7f, 0x17, 0xbd, 0x39, 0x01, 0x41, 0x04, 0xe6, 0xc2,
         0x6e, 0xf6, 0x7d, 0xc6, 0x10, 0xd2, 0xcd, 0x19, 0x24, 0x84, 0x78, 0x9a,
         0x6c, 0xf9, 0xae, 0xa9, 0x93, 0x0b, 0x94, 0x4b, 0x7e, 0x2d, 0xb5, 0x34,
         0x2b, 0x9d, 0x9e, 0x5b, 0x9f, 0xf7, 0x9a, 0xff, 0x9a, 0x2e, 0xe1, 0x97,
         0x8d, 0xd7, 0xfd, 0x01, 0xdf, 0xc5, 0x22, 0xee, 0x02, 0x28, 0x3d, 0x3b,
         0x06, 0xa9, 0xd0, 0x3a, 0xcf, 0x80, 0x96, 0x96, 0x8d, 0x7d, 0xbb, 0x0f,
         0x91, 0x78, 0xff, 0xff, 0xff, 0xff, 0x02, 0x8b, 0xa7, 0x94, 0x0e, 0x00,
         0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xba, 0xde, 0xec, 0xfd, 0xef,
         0x05, 0x07, 0x24, 0x7f, 0xc8, 0xf7, 0x42, 0x41, 0xd7, 0x3b, 0xc0, 0x39,
         0x97, 0x2d, 0x7b, 0x88, 0xac, 0x40, 0x94, 0xa8, 0x02, 0x00, 0x00, 0x00,
         0x00, 0x19, 0x76, 0xa9, 0x14, 0xc1, 0x09, 0x32, 0x48, 0x3f, 0xec, 0x93,
         0xed, 0x51, 0xf5, 0xfe, 0x95, 0xe7, 0x25, 0x59, 0xf2, 0xcc, 0x70, 0x43,
         0xf9, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00};
     std::vector<uint8_t> vch(ch, ch + sizeof(ch) - 1);
     CDataStream stream(vch, SER_DISK, CLIENT_VERSION);
     CMutableTransaction tx;
     stream >> tx;
     TxValidationState state;
     BOOST_CHECK_MESSAGE(CheckRegularTransaction(CTransaction(tx), state) &&
                             state.IsValid(),
                         "Simple deserialized transaction should be valid.");
 
     // Check that duplicate txins fail
     tx.vin.push_back(tx.vin[0]);
     BOOST_CHECK_MESSAGE(!CheckRegularTransaction(CTransaction(tx), state) ||
                             !state.IsValid(),
                         "Transaction with duplicate txins should be invalid.");
 }
 
 BOOST_AUTO_TEST_CASE(test_Get) {
     FillableSigningProvider keystore;
     CCoinsView coinsDummy;
     CCoinsViewCache coins(&coinsDummy);
     std::vector<CMutableTransaction> dummyTransactions = SetupDummyInputs(
         keystore, coins, {{11 * CENT, 50 * CENT, 21 * CENT, 22 * CENT}});
 
     CMutableTransaction t1;
     t1.vin.resize(3);
     t1.vin[0].prevout = COutPoint(dummyTransactions[0].GetId(), 1);
     t1.vin[0].scriptSig << std::vector<uint8_t>(65, 0);
     t1.vin[1].prevout = COutPoint(dummyTransactions[1].GetId(), 0);
     t1.vin[1].scriptSig << std::vector<uint8_t>(65, 0)
                         << std::vector<uint8_t>(33, 4);
     t1.vin[2].prevout = COutPoint(dummyTransactions[1].GetId(), 1);
     t1.vin[2].scriptSig << std::vector<uint8_t>(65, 0)
                         << std::vector<uint8_t>(33, 4);
     t1.vout.resize(2);
     t1.vout[0].nValue = 90 * CENT;
     t1.vout[0].scriptPubKey << OP_1;
 
     BOOST_CHECK(AreInputsStandard(CTransaction(t1), coins,
                                   STANDARD_SCRIPT_VERIFY_FLAGS));
 }
 
 static void CreateCreditAndSpend(const FillableSigningProvider &keystore,
                                  const CScript &outscript,
                                  CTransactionRef &output,
                                  CMutableTransaction &input,
                                  bool success = true) {
     CMutableTransaction outputm;
     outputm.nVersion = 1;
     outputm.vin.resize(1);
     outputm.vin[0].prevout = COutPoint();
     outputm.vin[0].scriptSig = CScript();
     outputm.vout.resize(1);
     outputm.vout[0].nValue = SATOSHI;
     outputm.vout[0].scriptPubKey = outscript;
     CDataStream ssout(SER_NETWORK, PROTOCOL_VERSION);
     ssout << outputm;
     ssout >> output;
     BOOST_CHECK_EQUAL(output->vin.size(), 1UL);
     BOOST_CHECK(output->vin[0] == outputm.vin[0]);
     BOOST_CHECK_EQUAL(output->vout.size(), 1UL);
     BOOST_CHECK(output->vout[0] == outputm.vout[0]);
 
     CMutableTransaction inputm;
     inputm.nVersion = 1;
     inputm.vin.resize(1);
     inputm.vin[0].prevout = COutPoint(output->GetId(), 0);
     inputm.vout.resize(1);
     inputm.vout[0].nValue = SATOSHI;
     inputm.vout[0].scriptPubKey = CScript();
     bool ret =
         SignSignature(keystore, *output, inputm, 0, SigHashType().withForkId());
     BOOST_CHECK_EQUAL(ret, success);
     CDataStream ssin(SER_NETWORK, PROTOCOL_VERSION);
     ssin << inputm;
     ssin >> input;
     BOOST_CHECK_EQUAL(input.vin.size(), 1UL);
     BOOST_CHECK(input.vin[0] == inputm.vin[0]);
     BOOST_CHECK_EQUAL(input.vout.size(), 1UL);
     BOOST_CHECK(input.vout[0] == inputm.vout[0]);
 }
 
 static void CheckWithFlag(const CTransactionRef &output,
                           const CMutableTransaction &input, int flags,
                           bool success) {
     ScriptError error;
     CTransaction inputi(input);
     bool ret = VerifyScript(
         inputi.vin[0].scriptSig, output->vout[0].scriptPubKey,
         flags | SCRIPT_ENABLE_SIGHASH_FORKID,
         TransactionSignatureChecker(&inputi, 0, output->vout[0].nValue),
         &error);
     BOOST_CHECK_EQUAL(ret, success);
 }
 
 static CScript PushAll(const std::vector<valtype> &values) {
     CScript result;
     for (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;
 }
 
 static void ReplaceRedeemScript(CScript &script, const CScript &redeemScript) {
     std::vector<valtype> stack;
     EvalScript(stack, script, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker());
     BOOST_CHECK(stack.size() > 0);
     stack.back() =
         std::vector<uint8_t>(redeemScript.begin(), redeemScript.end());
     script = PushAll(stack);
 }
 
 BOOST_AUTO_TEST_CASE(test_big_transaction) {
     CKey key;
     key.MakeNewKey(false);
     FillableSigningProvider keystore;
     BOOST_CHECK(keystore.AddKeyPubKey(key, key.GetPubKey()));
     CScript scriptPubKey = CScript()
                            << ToByteVector(key.GetPubKey()) << OP_CHECKSIG;
 
     std::vector<SigHashType> sigHashes;
     sigHashes.emplace_back(SIGHASH_NONE | SIGHASH_FORKID);
     sigHashes.emplace_back(SIGHASH_SINGLE | SIGHASH_FORKID);
     sigHashes.emplace_back(SIGHASH_ALL | SIGHASH_FORKID);
     sigHashes.emplace_back(SIGHASH_NONE | SIGHASH_FORKID |
                            SIGHASH_ANYONECANPAY);
     sigHashes.emplace_back(SIGHASH_SINGLE | SIGHASH_FORKID |
                            SIGHASH_ANYONECANPAY);
     sigHashes.emplace_back(SIGHASH_ALL | SIGHASH_FORKID | SIGHASH_ANYONECANPAY);
 
     CMutableTransaction mtx;
     mtx.nVersion = 1;
 
     // create a big transaction of 4500 inputs signed by the same key.
     const static size_t OUTPUT_COUNT = 4500;
     mtx.vout.reserve(OUTPUT_COUNT);
 
     for (size_t ij = 0; ij < OUTPUT_COUNT; ij++) {
         size_t i = mtx.vin.size();
         TxId prevId(uint256S("0000000000000000000000000000000000000000000000000"
                              "000000000000100"));
         COutPoint outpoint(prevId, i);
 
         mtx.vin.resize(mtx.vin.size() + 1);
         mtx.vin[i].prevout = outpoint;
         mtx.vin[i].scriptSig = CScript();
 
         mtx.vout.emplace_back(1000 * SATOSHI, CScript() << OP_1);
     }
 
     // sign all inputs
     for (size_t i = 0; i < mtx.vin.size(); i++) {
         bool hashSigned =
             SignSignature(keystore, scriptPubKey, mtx, i, 1000 * SATOSHI,
                           sigHashes.at(i % sigHashes.size()));
         BOOST_CHECK_MESSAGE(hashSigned, "Failed to sign test transaction");
     }
 
     CTransaction tx(mtx);
 
     // check all inputs concurrently, with the cache
     PrecomputedTransactionData txdata(tx);
     CCheckQueue<CScriptCheck> scriptcheckqueue(128);
     CCheckQueueControl<CScriptCheck> control(&scriptcheckqueue);
 
     scriptcheckqueue.StartWorkerThreads(20);
 
     std::vector<Coin> coins;
     for (size_t i = 0; i < mtx.vin.size(); i++) {
         CTxOut out;
         out.nValue = 1000 * SATOSHI;
         out.scriptPubKey = scriptPubKey;
         coins.emplace_back(std::move(out), 1, false);
     }
 
     for (size_t i = 0; i < mtx.vin.size(); i++) {
         std::vector<CScriptCheck> vChecks;
         CScriptCheck check(coins[tx.vin[i].prevout.GetN()].GetTxOut(), tx, i,
                            STANDARD_SCRIPT_VERIFY_FLAGS, false, txdata);
         vChecks.push_back(CScriptCheck());
         check.swap(vChecks.back());
         control.Add(vChecks);
     }
 
     bool controlCheck = control.Wait();
     BOOST_CHECK(controlCheck);
     scriptcheckqueue.StopWorkerThreads();
 }
 
 SignatureData CombineSignatures(const CMutableTransaction &input1,
                                 const CMutableTransaction &input2,
                                 const CTransactionRef tx) {
     SignatureData sigdata;
     sigdata = DataFromTransaction(input1, 0, tx->vout[0]);
     sigdata.MergeSignatureData(DataFromTransaction(input2, 0, tx->vout[0]));
     ProduceSignature(
         DUMMY_SIGNING_PROVIDER,
         MutableTransactionSignatureCreator(&input1, 0, tx->vout[0].nValue),
         tx->vout[0].scriptPubKey, sigdata);
     return sigdata;
 }
 
 BOOST_AUTO_TEST_CASE(test_witness) {
     FillableSigningProvider 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();
     BOOST_CHECK(keystore.AddKeyPubKey(key1, pubkey1));
     BOOST_CHECK(keystore.AddKeyPubKey(key2, pubkey2));
     BOOST_CHECK(keystore.AddKeyPubKey(key1L, pubkey1L));
     BOOST_CHECK(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);
     BOOST_CHECK(keystore.AddCScript(scriptPubkey1));
     BOOST_CHECK(keystore.AddCScript(scriptPubkey2));
     BOOST_CHECK(keystore.AddCScript(scriptPubkey1L));
     BOOST_CHECK(keystore.AddCScript(scriptPubkey2L));
     BOOST_CHECK(keystore.AddCScript(scriptMulti));
     BOOST_CHECK(keystore2.AddCScript(scriptMulti));
     BOOST_CHECK(keystore2.AddKeyPubKey(key3, pubkey3));
 
     CTransactionRef output1, output2;
     CMutableTransaction input1, input2;
 
     // 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, STANDARD_SCRIPT_VERIFY_FLAGS, true);
     CheckWithFlag(output1, input2, 0, false);
     CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);
     CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
 
     // P2SH pay-to-compressed-pubkey.
     CreateCreditAndSpend(keystore,
                          GetScriptForDestination(ScriptHash(scriptPubkey1)),
                          output1, input1);
     CreateCreditAndSpend(keystore,
                          GetScriptForDestination(ScriptHash(scriptPubkey2)),
                          output2, input2);
     ReplaceRedeemScript(input2.vin[0].scriptSig, scriptPubkey1);
     CheckWithFlag(output1, input1, 0, true);
     CheckWithFlag(output1, input1, 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, 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, STANDARD_SCRIPT_VERIFY_FLAGS, true);
     CheckWithFlag(output1, input2, 0, false);
     CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);
     CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
 
     // P2SH pay-to-uncompressed-pubkey.
     CreateCreditAndSpend(keystore,
                          GetScriptForDestination(ScriptHash(scriptPubkey1L)),
                          output1, input1);
     CreateCreditAndSpend(keystore,
                          GetScriptForDestination(ScriptHash(scriptPubkey2L)),
                          output2, input2);
     ReplaceRedeemScript(input2.vin[0].scriptSig, scriptPubkey1L);
     CheckWithFlag(output1, input1, 0, true);
     CheckWithFlag(output1, input1, 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, 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);
     UpdateInput(input1.vin[0], CombineSignatures(input1, input2, output1));
     CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
 
     // P2SH 2-of-2 multisig
     CreateCreditAndSpend(keystore,
                          GetScriptForDestination(ScriptHash(scriptMulti)),
                          output1, input1, false);
     CheckWithFlag(output1, input1, 0, true);
     CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, false);
     CreateCreditAndSpend(keystore2,
                          GetScriptForDestination(ScriptHash(scriptMulti)),
                          output2, input2, false);
     CheckWithFlag(output2, input2, 0, true);
     CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH, false);
     BOOST_CHECK(*output1 == *output2);
     UpdateInput(input1.vin[0], CombineSignatures(input1, input2, output1));
     CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
     CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
 }
 
 BOOST_AUTO_TEST_CASE(test_IsStandard) {
-    LOCK(cs_main);
     FillableSigningProvider keystore;
     CCoinsView coinsDummy;
     CCoinsViewCache coins(&coinsDummy);
     std::vector<CMutableTransaction> dummyTransactions = SetupDummyInputs(
         keystore, coins, {{11 * CENT, 50 * CENT, 21 * CENT, 22 * CENT}});
 
     CMutableTransaction t;
     t.vin.resize(1);
     t.vin[0].prevout = COutPoint(dummyTransactions[0].GetId(), 1);
     t.vin[0].scriptSig << std::vector<uint8_t>(65, 0);
     t.vout.resize(1);
     t.vout[0].nValue = 90 * CENT;
     CKey key;
     key.MakeNewKey(true);
     t.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
 
     std::string reason;
     BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
 
     // Check dust with default relay fee:
     Amount nDustThreshold = 3 * 182 * dustRelayFee.GetFeePerK() / 1000;
     BOOST_CHECK_EQUAL(nDustThreshold, 546 * SATOSHI);
     // dust:
     t.vout[0].nValue = nDustThreshold - SATOSHI;
     reason.clear();
     BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
     BOOST_CHECK_EQUAL(reason, "dust");
     // not dust:
     t.vout[0].nValue = nDustThreshold;
     BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
 
     // Disallowed nVersion
     t.nVersion = -1;
     reason.clear();
     BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
     BOOST_CHECK_EQUAL(reason, "version");
 
     t.nVersion = 0;
     reason.clear();
     BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
     BOOST_CHECK_EQUAL(reason, "version");
 
     t.nVersion = 3;
     reason.clear();
     BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
     BOOST_CHECK_EQUAL(reason, "version");
 
     // Allowed nVersion
     t.nVersion = 1;
     BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
 
     t.nVersion = 2;
     BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
 
     // Check dust with odd relay fee to verify rounding:
     // nDustThreshold = 182 * 1234 / 1000 * 3
     dustRelayFee = CFeeRate(1234 * SATOSHI);
     // dust:
     t.vout[0].nValue = (672 - 1) * SATOSHI;
     reason.clear();
     BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
     BOOST_CHECK_EQUAL(reason, "dust");
     // not dust:
     t.vout[0].nValue = 672 * SATOSHI;
     BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
     dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE);
 
     t.vout[0].scriptPubKey = CScript() << OP_1;
     reason.clear();
     BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
     BOOST_CHECK_EQUAL(reason, "scriptpubkey");
 
     // MAX_OP_RETURN_RELAY-byte TxoutType::NULL_DATA (standard)
     t.vout[0].scriptPubKey =
         CScript() << OP_RETURN
                   << ParseHex("646578784062697477617463682e636f2092c558ed52c56d"
                               "8dd14ca76226bc936a84820d898443873eb03d8854b21fa3"
                               "952b99a2981873e74509281730d78a21786d34a38bd1ebab"
                               "822fad42278f7f4420db6ab1fd2b6826148d4f73bb41ec2d"
                               "40a6d5793d66e17074a0c56a8a7df21062308f483dd6e38d"
                               "53609d350038df0a1b2a9ac8332016e0b904f66880dd0108"
                               "81c4e8074cce8e4ad6c77cb3460e01bf0e7e811b5f945f83"
                               "732ba6677520a893d75d9a966cb8f85dc301656b1635c631"
                               "f5d00d4adf73f2dd112ca75cf19754651909becfbe65aed1"
                               "3afb2ab8");
     BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY, t.vout[0].scriptPubKey.size());
     BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
 
     // MAX_OP_RETURN_RELAY+1-byte TxoutType::NULL_DATA (non-standard)
     t.vout[0].scriptPubKey =
         CScript() << OP_RETURN
                   << ParseHex("646578784062697477617463682e636f2092c558ed52c56d"
                               "8dd14ca76226bc936a84820d898443873eb03d8854b21fa3"
                               "952b99a2981873e74509281730d78a21786d34a38bd1ebab"
                               "822fad42278f7f4420db6ab1fd2b6826148d4f73bb41ec2d"
                               "40a6d5793d66e17074a0c56a8a7df21062308f483dd6e38d"
                               "53609d350038df0a1b2a9ac8332016e0b904f66880dd0108"
                               "81c4e8074cce8e4ad6c77cb3460e01bf0e7e811b5f945f83"
                               "732ba6677520a893d75d9a966cb8f85dc301656b1635c631"
                               "f5d00d4adf73f2dd112ca75cf19754651909becfbe65aed1"
                               "3afb2ab800");
     BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY + 1, t.vout[0].scriptPubKey.size());
     reason.clear();
     BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
     BOOST_CHECK_EQUAL(reason, "scriptpubkey");
 
     /**
      * Check when a custom value is used for -datacarriersize .
      */
     unsigned newMaxSize = 90;
     gArgs.ForceSetArg("-datacarriersize", ToString(newMaxSize));
 
     // Max user provided payload size is standard
     t.vout[0].scriptPubKey =
         CScript() << OP_RETURN
                   << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909"
                               "a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548"
                               "271967f1a67130b7105cd6a828e03909a67962e0ea1f61de"
                               "b649f6bc3f4cef3877696e64657878");
     BOOST_CHECK_EQUAL(t.vout[0].scriptPubKey.size(), newMaxSize);
     BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
 
     // Max user provided payload size + 1 is non-standard
     t.vout[0].scriptPubKey =
         CScript() << OP_RETURN
                   << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909"
                               "a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548"
                               "271967f1a67130b7105cd6a828e03909a67962e0ea1f61de"
                               "b649f6bc3f4cef3877696e6465787800");
     BOOST_CHECK_EQUAL(t.vout[0].scriptPubKey.size(), newMaxSize + 1);
     BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
 
     // Clear custom confirguration.
     gArgs.ClearForcedArg("-datacarriersize");
 
     // Data payload can be encoded in any way...
     t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("");
     BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
     t.vout[0].scriptPubKey = CScript()
                              << OP_RETURN << ParseHex("00") << ParseHex("01");
     BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
     // OP_RESERVED *is* considered to be a PUSHDATA type opcode by IsPushOnly()!
     t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_RESERVED << -1 << 0
                                        << ParseHex("01") << 2 << 3 << 4 << 5
                                        << 6 << 7 << 8 << 9 << 10 << 11 << 12
                                        << 13 << 14 << 15 << 16;
     BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
     t.vout[0].scriptPubKey = CScript()
                              << OP_RETURN << 0 << ParseHex("01") << 2
                              << ParseHex("fffffffffffffffffffffffffffffffffffff"
                                          "fffffffffffffffffffffffffffffffffff");
     BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
 
     // ...so long as it only contains PUSHDATA's
     t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_RETURN;
     reason.clear();
     BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
     BOOST_CHECK_EQUAL(reason, "scriptpubkey");
 
     // TxoutType::NULL_DATA w/o PUSHDATA
     t.vout.resize(1);
     t.vout[0].scriptPubKey = CScript() << OP_RETURN;
     BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
 
     // Only one TxoutType::NULL_DATA permitted in all cases
     t.vout.resize(2);
     t.vout[0].scriptPubKey =
         CScript() << OP_RETURN
                   << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909"
                               "a67962e0ea1f61deb649f6bc3f4cef38");
     t.vout[1].scriptPubKey =
         CScript() << OP_RETURN
                   << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909"
                               "a67962e0ea1f61deb649f6bc3f4cef38");
     reason.clear();
     BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
     BOOST_CHECK_EQUAL(reason, "multi-op-return");
 
     t.vout[0].scriptPubKey =
         CScript() << OP_RETURN
                   << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909"
                               "a67962e0ea1f61deb649f6bc3f4cef38");
     t.vout[1].scriptPubKey = CScript() << OP_RETURN;
     reason.clear();
     BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
     BOOST_CHECK_EQUAL(reason, "multi-op-return");
 
     t.vout[0].scriptPubKey = CScript() << OP_RETURN;
     t.vout[1].scriptPubKey = CScript() << OP_RETURN;
     reason.clear();
     BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
     BOOST_CHECK_EQUAL(reason, "multi-op-return");
 
     // Check large scriptSig (non-standard if size is >1650 bytes)
     t.vout.resize(1);
     t.vout[0].nValue = MAX_MONEY;
     t.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
     // OP_PUSHDATA2 with len (3 bytes) + data (1647 bytes) = 1650 bytes
     t.vin[0].scriptSig = CScript() << std::vector<uint8_t>(1647, 0); // 1650
     BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
 
     t.vin[0].scriptSig = CScript() << std::vector<uint8_t>(1648, 0); // 1651
     reason.clear();
     BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
     BOOST_CHECK_EQUAL(reason, "scriptsig-size");
 
     // Check scriptSig format (non-standard if there are any other ops than just
     // PUSHs)
     t.vin[0].scriptSig = CScript()
                          // OP_n (single byte pushes: n = 1, 0, -1, 16)
                          << OP_TRUE << OP_0 << OP_1NEGATE
                          << OP_16
                          // OP_PUSHx [...x bytes...]
                          << std::vector<uint8_t>(75, 0)
                          // OP_PUSHDATA1 x [...x bytes...]
                          << std::vector<uint8_t>(235, 0)
                          // OP_PUSHDATA2 x [...x bytes...]
                          << std::vector<uint8_t>(1234, 0) << OP_9;
     BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
 
     const std::vector<uint8_t> non_push_ops = {
         // arbitrary set of non-push operations
         OP_NOP,
         OP_VERIFY,
         OP_IF,
         OP_ROT,
         OP_3DUP,
         OP_SIZE,
         OP_EQUAL,
         OP_ADD,
         OP_SUB,
         OP_HASH256,
         OP_CODESEPARATOR,
         OP_CHECKSIG,
         OP_CHECKLOCKTIMEVERIFY};
 
     CScript::const_iterator pc = t.vin[0].scriptSig.begin();
     while (pc < t.vin[0].scriptSig.end()) {
         opcodetype opcode;
         CScript::const_iterator prev_pc = pc;
         // advance to next op
         t.vin[0].scriptSig.GetOp(pc, opcode);
         // for the sake of simplicity, we only replace single-byte push
         // operations
         if (opcode >= 1 && opcode <= OP_PUSHDATA4) {
             continue;
         }
 
         int index = prev_pc - t.vin[0].scriptSig.begin();
         // save op
         uint8_t orig_op = *prev_pc;
         // replace current push-op with each non-push-op
         for (auto op : non_push_ops) {
             t.vin[0].scriptSig[index] = op;
             BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
             BOOST_CHECK_EQUAL(reason, "scriptsig-not-pushonly");
         }
         // restore op
         t.vin[0].scriptSig[index] = orig_op;
         BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
     }
 
     // Check bare multisig (standard if policy flag fIsBareMultisigStd is set)
     fIsBareMultisigStd = true;
     // simple 1-of-1
     t.vout[0].scriptPubKey = GetScriptForMultisig(1, {key.GetPubKey()});
     t.vin[0].scriptSig = CScript() << std::vector<uint8_t>(65, 0);
     BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
 
     fIsBareMultisigStd = false;
     reason.clear();
     BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
     BOOST_CHECK_EQUAL(reason, "bare-multisig");
     fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG;
 }
 
 BOOST_AUTO_TEST_CASE(txsize_activation_test) {
     const Config &config = GetConfig();
     const Consensus::Params &params = config.GetChainParams().GetConsensus();
     const int32_t magneticAnomalyActivationHeight =
         params.magneticAnomalyHeight;
 
     // A minimaly sized transction.
     CTransaction minTx;
     TxValidationState state;
 
     BOOST_CHECK(ContextualCheckTransaction(
         params, minTx, state, magneticAnomalyActivationHeight - 1, 5678));
     BOOST_CHECK(!ContextualCheckTransaction(
         params, minTx, state, magneticAnomalyActivationHeight, 5678));
     BOOST_CHECK_EQUAL(state.GetRejectReason(), "bad-txns-undersize");
 }
 
 BOOST_AUTO_TEST_CASE(tx_getvalueout) {
     CMutableTransaction mtx;
 
     // Negative output value
     mtx.vout.resize(1);
     mtx.vout[0].nValue = -1 * SATOSHI;
     CTransaction negative_tx{mtx};
     BOOST_CHECK_THROW(negative_tx.GetValueOut(), std::runtime_error);
 
     // Good output
     mtx.vout[0].nValue = 10000 * SATOSHI;
     CTransaction valid_one_output_tx{mtx};
     BOOST_CHECK_EQUAL(valid_one_output_tx.GetValueOut(), 10000 * SATOSHI);
 
     // Maximum output
     mtx.vout[0].nValue = MAX_MONEY;
     CTransaction max_one_output_tx{mtx};
     BOOST_CHECK_EQUAL(max_one_output_tx.GetValueOut(), MAX_MONEY);
 
     // Too high output
     mtx.vout[0].nValue = MAX_MONEY + 1 * SATOSHI;
     CTransaction too_high_tx{mtx};
     BOOST_CHECK_THROW(too_high_tx.GetValueOut(), std::runtime_error);
 
     // Valid sum
     mtx.vout.resize(2);
     mtx.vout[0].nValue = 42 * SATOSHI;
     mtx.vout[1].nValue = 1337 * SATOSHI;
     CTransaction valid_tx{mtx};
     BOOST_CHECK_EQUAL(valid_tx.GetValueOut(), 1379 * SATOSHI);
 
     // Maximum sum
     mtx.vout[0].nValue = MAX_MONEY - 1 * SATOSHI;
     mtx.vout[1].nValue = 1 * SATOSHI;
     CTransaction max_two_outputs_tx{mtx};
     BOOST_CHECK_EQUAL(max_two_outputs_tx.GetValueOut(), MAX_MONEY);
 
     // Too high sum
     mtx.vout[0].nValue = MAX_MONEY - 1 * SATOSHI;
     mtx.vout[1].nValue = 2 * SATOSHI;
     CTransaction too_high_sum_tx{mtx};
     BOOST_CHECK_THROW(too_high_sum_tx.GetValueOut(), std::runtime_error);
 
     // First output valid, but the second output would cause an int64 overflow.
     // This issue was encountered while fuzzing:
     // https://github.com/bitcoin/bitcoin/issues/18046
     mtx.vout[0].nValue = 2 * SATOSHI;
     mtx.vout[1].nValue = (std::numeric_limits<int64_t>::max() - 1) * SATOSHI;
     CTransaction overflow_sum_tx{mtx};
     BOOST_CHECK_THROW(overflow_sum_tx.GetValueOut(), std::runtime_error);
 }
 
 BOOST_AUTO_TEST_SUITE_END()