aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.test.include2
-rw-r--r--src/bitcoin-cli.cpp21
-rw-r--r--src/httprpc.cpp2
-rw-r--r--src/init.cpp204
-rw-r--r--src/main.cpp74
-rw-r--r--src/miner.cpp207
-rw-r--r--src/miner.h5
-rw-r--r--src/net.cpp12
-rw-r--r--src/net.h1
-rw-r--r--src/qt/forms/debugwindow.ui96
-rw-r--r--src/qt/res/icons/about.pngbin4726 -> 3717 bytes
-rw-r--r--src/qt/res/icons/chevron.pngbin1923 -> 803 bytes
-rw-r--r--src/qt/rpcconsole.cpp31
-rw-r--r--src/qt/rpcconsole.h4
-rw-r--r--src/qt/transactiontablemodel.cpp28
-rw-r--r--src/qt/transactiontablemodel.h2
-rw-r--r--src/qt/transactionview.cpp16
-rw-r--r--src/qt/transactionview.h1
-rw-r--r--src/rpc/blockchain.cpp2
-rw-r--r--src/rpc/client.cpp4
-rw-r--r--src/rpc/mining.cpp94
-rw-r--r--src/rpc/server.cpp13
-rw-r--r--src/rpc/server.h8
-rw-r--r--src/test/alert_tests.cpp2
-rw-r--r--src/test/data/script_invalid.json1055
-rw-r--r--src/test/mempool_tests.cpp22
-rw-r--r--src/test/script_tests.cpp183
-rw-r--r--src/test/test_bitcoin.cpp3
-rw-r--r--src/test/testutil.cpp33
-rw-r--r--src/test/testutil.h15
-rw-r--r--src/test/util_tests.cpp5
-rw-r--r--src/torcontrol.cpp19
-rw-r--r--src/txmempool.cpp6
-rw-r--r--src/txmempool.h8
-rw-r--r--src/util.cpp22
-rw-r--r--src/util.h1
-rw-r--r--src/version.h4
-rw-r--r--src/wallet/db.cpp22
-rw-r--r--src/wallet/rpcwallet.cpp10
-rw-r--r--src/wallet/wallet.cpp215
-rw-r--r--src/wallet/wallet.h8
-rw-r--r--src/wallet/walletdb.cpp18
-rw-r--r--src/wallet/walletdb.h2
-rw-r--r--src/zmq/zmqnotificationinterface.cpp1
-rw-r--r--src/zmq/zmqpublishnotifier.cpp1
45 files changed, 1234 insertions, 1248 deletions
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 6ef6a69a2c..0c4e47a147 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -78,6 +78,8 @@ BITCOIN_TESTS =\
test/streams_tests.cpp \
test/test_bitcoin.cpp \
test/test_bitcoin.h \
+ test/testutil.cpp \
+ test/testutil.h \
test/timedata_tests.cpp \
test/transaction_tests.cpp \
test/txvalidationcache_tests.cpp \
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index 34980d9ca1..49935699fd 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -43,6 +43,7 @@ std::string HelpMessageCli()
strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
strUsage += HelpMessageOpt("-rpcclienttimeout=<n>", strprintf(_("Timeout during HTTP requests (default: %d)"), DEFAULT_HTTP_CLIENT_TIMEOUT));
+ strUsage += HelpMessageOpt("-stdin", _("Read extra arguments from standard input, one per line until EOF/Ctrl-D (recommended for sensitive information such as passphrases)"));
return strUsage;
}
@@ -232,15 +233,17 @@ int CommandLineRPC(int argc, char *argv[])
argc--;
argv++;
}
-
- // Method
- if (argc < 2)
- throw runtime_error("too few parameters");
- string strMethod = argv[1];
-
- // Parameters default to strings
- std::vector<std::string> strParams(&argv[2], &argv[argc]);
- UniValue params = RPCConvertValues(strMethod, strParams);
+ std::vector<std::string> args = std::vector<std::string>(&argv[1], &argv[argc]);
+ if (GetBoolArg("-stdin", false)) {
+ // Read one arg per line from stdin and append
+ std::string line;
+ while (std::getline(std::cin,line))
+ args.push_back(line);
+ }
+ if (args.size() < 1)
+ throw runtime_error("too few parameters (need at least command)");
+ std::string strMethod = args[0];
+ UniValue params = RPCConvertValues(strMethod, std::vector<std::string>(args.begin()+1, args.end()));
// Execute and handle connection failures with -rpcwait
const bool fWait = GetBoolArg("-rpcwait", false);
diff --git a/src/httprpc.cpp b/src/httprpc.cpp
index a447a3eff8..04d3386e9a 100644
--- a/src/httprpc.cpp
+++ b/src/httprpc.cpp
@@ -219,7 +219,7 @@ static bool InitRPCAuthentication()
return false;
}
} else {
- LogPrintf("Config options rpcuser and rpcpassword will soon be deprecated. Locally-run instances may remove rpcuser to use cookie-based auth, or may be replaced with rpcauth. Please see share/rpcuser for rpcauth auth generation.");
+ LogPrintf("Config options rpcuser and rpcpassword will soon be deprecated. Locally-run instances may remove rpcuser to use cookie-based auth, or may be replaced with rpcauth. Please see share/rpcuser for rpcauth auth generation.\n");
strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
}
return true;
diff --git a/src/init.cpp b/src/init.cpp
index 048843a4c1..637b69ab05 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -72,7 +72,6 @@ static const bool DEFAULT_REST_ENABLE = false;
static const bool DEFAULT_DISABLE_SAFEMODE = false;
static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
-static const char * const DEFAULT_WALLET_DAT = "wallet.dat";
#if ENABLE_ZMQ
static CZMQNotificationInterface* pzmqNotificationInterface = NULL;
@@ -196,7 +195,6 @@ void Shutdown()
if (pwalletMain)
pwalletMain->Flush(false);
#endif
- GenerateBitcoins(false, 0, Params());
StopNode();
StopTorControl();
UnregisterNodeSignals(GetNodeSignals());
@@ -395,26 +393,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-maxuploadtarget=<n>", strprintf(_("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)"), DEFAULT_MAX_UPLOAD_TARGET));
#ifdef ENABLE_WALLET
- strUsage += HelpMessageGroup(_("Wallet options:"));
- strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
- strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), DEFAULT_KEYPOOL_SIZE));
- strUsage += HelpMessageOpt("-fallbackfee=<amt>", strprintf(_("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)"),
- CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE)));
- strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"),
- CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE)));
- strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"),
- CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK())));
- strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup"));
- strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat on startup"));
- strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS));
- strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE));
- strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET));
- strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup"));
- strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT));
- strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST));
- strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)"));
- strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") +
- " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)"));
+ strUsage += CWallet::GetWalletHelpString(showDebug);
#endif
#if ENABLE_ZMQ
@@ -432,16 +411,10 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. Also sets -checkmempool (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks()));
strUsage += HelpMessageOpt("-checkmempool=<n>", strprintf("Run checks every <n> transactions (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks()));
strUsage += HelpMessageOpt("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", DEFAULT_CHECKPOINTS_ENABLED));
-#ifdef ENABLE_WALLET
- strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush wallet database activity from memory to disk log every <n> megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE));
-#endif
strUsage += HelpMessageOpt("-disablesafemode", strprintf("Disable safemode, override a real safe mode event (default: %u)", DEFAULT_DISABLE_SAFEMODE));
strUsage += HelpMessageOpt("-testsafemode", strprintf("Force safe mode (default: %u)", DEFAULT_TESTSAFEMODE));
strUsage += HelpMessageOpt("-dropmessagestest=<n>", "Randomly drop 1 of every <n> network messages");
strUsage += HelpMessageOpt("-fuzzmessagestest=<n>", "Randomly fuzz 1 of every <n> network messages");
-#ifdef ENABLE_WALLET
- strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET));
-#endif
strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", DEFAULT_STOPAFTERBLOCKIMPORT));
strUsage += HelpMessageOpt("-limitancestorcount=<n>", strprintf("Do not accept transactions if number of in-mempool ancestors is <n> or more (default: %u)", DEFAULT_ANCESTOR_LIMIT));
strUsage += HelpMessageOpt("-limitancestorsize=<n>", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds <n> kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT));
@@ -455,8 +428,6 @@ std::string HelpMessage(HelpMessageMode mode)
_("If <category> is not supplied or if <category> = 1, output all debugging information.") + _("<category> can be:") + " " + debugCategories + ".");
if (showDebug)
strUsage += HelpMessageOpt("-nodebug", "Turn off debugging messages, same as -debug=0");
- strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), DEFAULT_GENERATE));
- strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), DEFAULT_GENERATE_THREADS));
strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)"));
strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), DEFAULT_LOGIPS));
strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), DEFAULT_LOGTIMESTAMPS));
@@ -477,9 +448,6 @@ std::string HelpMessage(HelpMessageMode mode)
if (showDebug)
{
strUsage += HelpMessageOpt("-printpriority", strprintf("Log transaction priority and fee per kB when mining blocks (default: %u)", DEFAULT_PRINTPRIORITY));
-#ifdef ENABLE_WALLET
- strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB));
-#endif
}
strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)"));
@@ -1091,14 +1059,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (fPrintToDebugLog)
OpenDebugLog();
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
- LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
-#elif defined OPENSSL_VERSION
- LogPrintf("Using OpenSSL version %s\n", OpenSSL_version(OPENSSL_VERSION));
-#elif defined LIBRESSL_VERSION_TEXT
- LogPrintf("Using %s\n", LIBRESSL_VERSION_TEXT);
-#endif
-
#ifdef ENABLE_WALLET
LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
#endif
@@ -1199,6 +1159,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// -proxy sets a proxy for all outgoing network traffic
// -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default
std::string proxyArg = GetArg("-proxy", "");
+ SetLimited(NET_TOR);
if (proxyArg != "" && proxyArg != "0") {
proxyType addrProxy = proxyType(CService(proxyArg, 9050), proxyRandomize);
if (!addrProxy.IsValid())
@@ -1208,7 +1169,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
SetProxy(NET_IPV6, addrProxy);
SetProxy(NET_TOR, addrProxy);
SetNameProxy(addrProxy);
- SetReachable(NET_TOR); // by default, -proxy sets onion as reachable, unless -noonion later
+ SetLimited(NET_TOR, false); // by default, -proxy sets onion as reachable, unless -noonion later
}
// -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses
@@ -1217,13 +1178,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
std::string onionArg = GetArg("-onion", "");
if (onionArg != "") {
if (onionArg == "0") { // Handle -noonion/-onion=0
- SetReachable(NET_TOR, false); // set onions as unreachable
+ SetLimited(NET_TOR); // set onions as unreachable
} else {
proxyType addrOnion = proxyType(CService(onionArg, 9050), proxyRandomize);
if (!addrOnion.IsValid())
return InitError(strprintf(_("Invalid -onion address: '%s'"), onionArg));
SetProxy(NET_TOR, addrOnion);
- SetReachable(NET_TOR);
+ SetLimited(NET_TOR, false);
}
}
@@ -1460,149 +1421,19 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
pwalletMain = NULL;
LogPrintf("Wallet disabled!\n");
} else {
-
- // needed to restore wallet transaction meta data after -zapwallettxes
- std::vector<CWalletTx> vWtx;
-
- if (GetBoolArg("-zapwallettxes", false)) {
- uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
-
- pwalletMain = new CWallet(strWalletFile);
- DBErrors nZapWalletRet = pwalletMain->ZapWalletTx(vWtx);
- if (nZapWalletRet != DB_LOAD_OK) {
- uiInterface.InitMessage(_("Error loading wallet.dat: Wallet corrupted"));
- return false;
- }
-
- delete pwalletMain;
- pwalletMain = NULL;
- }
-
- uiInterface.InitMessage(_("Loading wallet..."));
-
- nStart = GetTimeMillis();
- bool fFirstRun = true;
- pwalletMain = new CWallet(strWalletFile);
- DBErrors nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun);
- if (nLoadWalletRet != DB_LOAD_OK)
- {
- if (nLoadWalletRet == DB_CORRUPT)
- strErrors << _("Error loading wallet.dat: Wallet corrupted") << "\n";
- else if (nLoadWalletRet == DB_NONCRITICAL_ERROR)
- {
- InitWarning(_("Error reading wallet.dat! All keys read correctly, but transaction data"
- " or address book entries might be missing or incorrect."));
- }
- else if (nLoadWalletRet == DB_TOO_NEW)
- strErrors << strprintf(_("Error loading wallet.dat: Wallet requires newer version of %s"), _(PACKAGE_NAME)) << "\n";
- else if (nLoadWalletRet == DB_NEED_REWRITE)
- {
- strErrors << strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)) << "\n";
- LogPrintf("%s", strErrors.str());
- return InitError(strErrors.str());
- }
- else
- strErrors << _("Error loading wallet.dat") << "\n";
- }
-
- if (GetBoolArg("-upgradewallet", fFirstRun))
- {
- int nMaxVersion = GetArg("-upgradewallet", 0);
- if (nMaxVersion == 0) // the -upgradewallet without argument case
- {
- LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
- nMaxVersion = CLIENT_VERSION;
- pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
- }
- else
- LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
- if (nMaxVersion < pwalletMain->GetVersion())
- strErrors << _("Cannot downgrade wallet") << "\n";
- pwalletMain->SetMaxVersion(nMaxVersion);
- }
-
- if (fFirstRun)
- {
- // Create new keyUser and set as default key
- RandAddSeedPerfmon();
-
- CPubKey newDefaultKey;
- if (pwalletMain->GetKeyFromPool(newDefaultKey)) {
- pwalletMain->SetDefaultKey(newDefaultKey);
- if (!pwalletMain->SetAddressBook(pwalletMain->vchDefaultKey.GetID(), "", "receive"))
- strErrors << _("Cannot write default address") << "\n";
- }
-
- pwalletMain->SetBestChain(chainActive.GetLocator());
- }
-
- LogPrintf("%s", strErrors.str());
- LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart);
-
- RegisterValidationInterface(pwalletMain);
-
- CBlockIndex *pindexRescan = chainActive.Tip();
- if (GetBoolArg("-rescan", false))
- pindexRescan = chainActive.Genesis();
- else
- {
- CWalletDB walletdb(strWalletFile);
- CBlockLocator locator;
- if (walletdb.ReadBestBlock(locator))
- pindexRescan = FindForkInGlobalIndex(chainActive, locator);
- else
- pindexRescan = chainActive.Genesis();
- }
- if (chainActive.Tip() && chainActive.Tip() != pindexRescan)
+ std::string warningString;
+ std::string errorString;
+ pwalletMain = CWallet::InitLoadWallet(fDisableWallet, strWalletFile, warningString, errorString);
+ if (!warningString.empty())
+ InitWarning(warningString);
+ if (!errorString.empty())
{
- //We can't rescan beyond non-pruned blocks, stop and throw an error
- //this might happen if a user uses a old wallet within a pruned node
- // or if he ran -disablewallet for a longer time, then decided to re-enable
- if (fPruneMode)
- {
- CBlockIndex *block = chainActive.Tip();
- while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA) && block->pprev->nTx > 0 && pindexRescan != block)
- block = block->pprev;
-
- if (pindexRescan != block)
- return InitError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)"));
- }
-
- uiInterface.InitMessage(_("Rescanning..."));
- LogPrintf("Rescanning last %i blocks (from block %i)...\n", chainActive.Height() - pindexRescan->nHeight, pindexRescan->nHeight);
- nStart = GetTimeMillis();
- pwalletMain->ScanForWalletTransactions(pindexRescan, true);
- LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart);
- pwalletMain->SetBestChain(chainActive.GetLocator());
- nWalletDBUpdated++;
-
- // Restore wallet transaction metadata after -zapwallettxes=1
- if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2")
- {
- CWalletDB walletdb(strWalletFile);
-
- BOOST_FOREACH(const CWalletTx& wtxOld, vWtx)
- {
- uint256 hash = wtxOld.GetHash();
- std::map<uint256, CWalletTx>::iterator mi = pwalletMain->mapWallet.find(hash);
- if (mi != pwalletMain->mapWallet.end())
- {
- const CWalletTx* copyFrom = &wtxOld;
- CWalletTx* copyTo = &mi->second;
- copyTo->mapValue = copyFrom->mapValue;
- copyTo->vOrderForm = copyFrom->vOrderForm;
- copyTo->nTimeReceived = copyFrom->nTimeReceived;
- copyTo->nTimeSmart = copyFrom->nTimeSmart;
- copyTo->fFromMe = copyFrom->fFromMe;
- copyTo->strFromAccount = copyFrom->strFromAccount;
- copyTo->nOrderPos = copyFrom->nOrderPos;
- copyTo->WriteToDisk(&walletdb);
- }
- }
- }
+ LogPrintf("%s", errorString);
+ return InitError(errorString);
}
- pwalletMain->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));
- } // (!fDisableWallet)
+ if (!pwalletMain)
+ return false;
+ }
#else // ENABLE_WALLET
LogPrintf("No wallet support compiled in!\n");
#endif // !ENABLE_WALLET
@@ -1674,9 +1505,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
boost::ref(cs_main), boost::cref(pindexBestHeader), nPowTargetSpacing);
scheduler.scheduleEvery(f, nPowTargetSpacing);
- // Generate coins in the background
- GenerateBitcoins(GetBoolArg("-gen", DEFAULT_GENERATE), GetArg("-genproclimit", DEFAULT_GENERATE_THREADS), chainparams);
-
// ********************************************************* Step 12: finished
SetRPCWarmupFinished();
diff --git a/src/main.cpp b/src/main.cpp
index 525d9902b9..76dc01ea79 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -997,7 +997,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
*pfMissingInputs = false;
if (!CheckTransaction(tx, state))
- return error("%s: CheckTransaction: %s, %s", __func__, hash.ToString(), FormatStateMessage(state));
+ return false; // state filled in by CheckTransaction
// Coinbase is only valid in a block, not as a loose transaction
if (tx.IsCoinBase())
@@ -1211,10 +1211,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
const uint256 &hashAncestor = ancestorIt->GetTx().GetHash();
if (setConflicts.count(hashAncestor))
{
- return state.DoS(10, error("AcceptToMemoryPool: %s spends conflicting transaction %s",
+ return state.DoS(10, false,
+ REJECT_INVALID, "bad-txns-spends-conflicting-tx", false,
+ strprintf("%s spends conflicting transaction %s",
hash.ToString(),
- hashAncestor.ToString()),
- REJECT_INVALID, "bad-txns-spends-conflicting-tx");
+ hashAncestor.ToString()));
}
}
@@ -1251,11 +1252,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
// that we don't spend too much time walking descendants.
// This should be rare.
if (mi->IsDirty()) {
- return state.DoS(0,
- error("AcceptToMemoryPool: rejecting replacement %s; cannot replace tx %s with untracked descendants",
+ return state.DoS(0, false,
+ REJECT_NONSTANDARD, "too many potential replacements", false,
+ strprintf("too many potential replacements: rejecting replacement %s; cannot replace tx %s with untracked descendants",
hash.ToString(),
- mi->GetTx().GetHash().ToString()),
- REJECT_NONSTANDARD, "too many potential replacements");
+ mi->GetTx().GetHash().ToString()));
}
// Don't allow the replacement to reduce the feerate of the
@@ -1277,12 +1278,12 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize());
if (newFeeRate <= oldFeeRate)
{
- return state.DoS(0,
- error("AcceptToMemoryPool: rejecting replacement %s; new feerate %s <= old feerate %s",
+ return state.DoS(0, false,
+ REJECT_INSUFFICIENTFEE, "insufficient fee", false,
+ strprintf("rejecting replacement %s; new feerate %s <= old feerate %s",
hash.ToString(),
newFeeRate.ToString(),
- oldFeeRate.ToString()),
- REJECT_INSUFFICIENTFEE, "insufficient fee");
+ oldFeeRate.ToString()));
}
BOOST_FOREACH(const CTxIn &txin, mi->GetTx().vin)
@@ -1306,12 +1307,12 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
nConflictingSize += it->GetTxSize();
}
} else {
- return state.DoS(0,
- error("AcceptToMemoryPool: rejecting replacement %s; too many potential replacements (%d > %d)\n",
+ return state.DoS(0, false,
+ REJECT_NONSTANDARD, "too many potential replacements", false,
+ strprintf("rejecting replacement %s; too many potential replacements (%d > %d)\n",
hash.ToString(),
nConflictingCount,
- maxDescendantsToVisit),
- REJECT_NONSTANDARD, "too many potential replacements");
+ maxDescendantsToVisit));
}
for (unsigned int j = 0; j < tx.vin.size(); j++)
@@ -1326,9 +1327,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
// it's cheaper to just check if the new input refers to a
// tx that's in the mempool.
if (pool.mapTx.find(tx.vin[j].prevout.hash) != pool.mapTx.end())
- return state.DoS(0, error("AcceptToMemoryPool: replacement %s adds unconfirmed input, idx %d",
- hash.ToString(), j),
- REJECT_NONSTANDARD, "replacement-adds-unconfirmed");
+ return state.DoS(0, false,
+ REJECT_NONSTANDARD, "replacement-adds-unconfirmed", false,
+ strprintf("replacement %s adds unconfirmed input, idx %d",
+ hash.ToString(), j));
}
}
@@ -1337,9 +1339,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
// transactions would not be paid for.
if (nModifiedFees < nConflictingFees)
{
- return state.DoS(0, error("AcceptToMemoryPool: rejecting replacement %s, less fees than conflicting txs; %s < %s",
- hash.ToString(), FormatMoney(nModifiedFees), FormatMoney(nConflictingFees)),
- REJECT_INSUFFICIENTFEE, "insufficient fee");
+ return state.DoS(0, false,
+ REJECT_INSUFFICIENTFEE, "insufficient fee", false,
+ strprintf("rejecting replacement %s, less fees than conflicting txs; %s < %s",
+ hash.ToString(), FormatMoney(nModifiedFees), FormatMoney(nConflictingFees)));
}
// Finally in addition to paying more fees than the conflicts the
@@ -1347,19 +1350,19 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
CAmount nDeltaFees = nModifiedFees - nConflictingFees;
if (nDeltaFees < ::minRelayTxFee.GetFee(nSize))
{
- return state.DoS(0,
- error("AcceptToMemoryPool: rejecting replacement %s, not enough additional fees to relay; %s < %s",
+ return state.DoS(0, false,
+ REJECT_INSUFFICIENTFEE, "insufficient fee", false,
+ strprintf("rejecting replacement %s, not enough additional fees to relay; %s < %s",
hash.ToString(),
FormatMoney(nDeltaFees),
- FormatMoney(::minRelayTxFee.GetFee(nSize))),
- REJECT_INSUFFICIENTFEE, "insufficient fee");
+ FormatMoney(::minRelayTxFee.GetFee(nSize))));
}
}
// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true))
- return error("%s: CheckInputs: %s, %s", __func__, hash.ToString(), FormatStateMessage(state));
+ return false; // state filled in by CheckInputs
// Check again against just the consensus-critical mandatory script
// verification flags, in case of bugs in the standard flags that cause
@@ -5115,13 +5118,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
- // This asymmetric behavior for inbound and outbound connections was introduced
- // to prevent a fingerprinting attack: an attacker can send specific fake addresses
- // to users' AddrMan and later request them by sending getaddr messages.
- // Making nodes which are behind NAT and can only make outgoing connections ignore
- // the getaddr message mitigates the attack.
- else if ((strCommand == NetMsgType::GETADDR) && (pfrom->fInbound))
+ else if (strCommand == NetMsgType::GETADDR)
{
+ // This asymmetric behavior for inbound and outbound connections was introduced
+ // to prevent a fingerprinting attack: an attacker can send specific fake addresses
+ // to users' AddrMan and later request them by sending getaddr messages.
+ // Making nodes which are behind NAT and can only make outgoing connections ignore
+ // the getaddr message mitigates the attack.
+ if (!pfrom->fInbound) {
+ LogPrint("net", "Ignoring \"getaddr\" from outbound connection. peer=%d\n", pfrom->id);
+ return true;
+ }
+
pfrom->vAddrToSend.clear();
vector<CAddress> vAddr = addrman.GetAddr();
BOOST_FOREACH(const CAddress &addr, vAddr)
diff --git a/src/miner.cpp b/src/miner.cpp
index c454c0279c..ec87e84ca7 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -155,10 +155,10 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s
std::make_heap(vecPriority.begin(), vecPriority.end(), pricomparer);
}
- CTxMemPool::indexed_transaction_set::nth_index<3>::type::iterator mi = mempool.mapTx.get<3>().begin();
+ CTxMemPool::indexed_transaction_set::index<mining_score>::type::iterator mi = mempool.mapTx.get<mining_score>().begin();
CTxMemPool::txiter iter;
- while (mi != mempool.mapTx.get<3>().end() || !clearedTxs.empty())
+ while (mi != mempool.mapTx.get<mining_score>().end() || !clearedTxs.empty())
{
bool priorityTx = false;
if (fPriorityBlock && !vecPriority.empty()) { // add a tx from priority queue to fill the blockprioritysize
@@ -315,206 +315,3 @@ void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned
pblock->vtx[0] = txCoinbase;
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// Internal miner
-//
-
-//
-// ScanHash scans nonces looking for a hash with at least some zero bits.
-// The nonce is usually preserved between calls, but periodically or if the
-// nonce is 0xffff0000 or above, the block is rebuilt and nNonce starts over at
-// zero.
-//
-bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phash)
-{
- // Write the first 76 bytes of the block header to a double-SHA256 state.
- CHash256 hasher;
- CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
- ss << *pblock;
- assert(ss.size() == 80);
- hasher.Write((unsigned char*)&ss[0], 76);
-
- while (true) {
- nNonce++;
-
- // Write the last 4 bytes of the block header (the nonce) to a copy of
- // the double-SHA256 state, and compute the result.
- CHash256(hasher).Write((unsigned char*)&nNonce, 4).Finalize((unsigned char*)phash);
-
- // Return the nonce if the hash has at least some zero bits,
- // caller will check if it has enough to reach the target
- if (((uint16_t*)phash)[15] == 0)
- return true;
-
- // If nothing found after trying for a while, return -1
- if ((nNonce & 0xfff) == 0)
- return false;
- }
-}
-
-static bool ProcessBlockFound(const CBlock* pblock, const CChainParams& chainparams)
-{
- LogPrintf("%s\n", pblock->ToString());
- LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));
-
- // Found a solution
- {
- LOCK(cs_main);
- if (pblock->hashPrevBlock != chainActive.Tip()->GetBlockHash())
- return error("BitcoinMiner: generated block is stale");
- }
-
- // Inform about the new block
- GetMainSignals().BlockFound(pblock->GetHash());
-
- // Process this block the same as if we had received it from another node
- CValidationState state;
- if (!ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL))
- return error("BitcoinMiner: ProcessNewBlock, block not accepted");
-
- return true;
-}
-
-void static BitcoinMiner(const CChainParams& chainparams)
-{
- LogPrintf("BitcoinMiner started\n");
- SetThreadPriority(THREAD_PRIORITY_LOWEST);
- RenameThread("bitcoin-miner");
-
- unsigned int nExtraNonce = 0;
-
- boost::shared_ptr<CReserveScript> coinbaseScript;
- GetMainSignals().ScriptForMining(coinbaseScript);
-
- try {
- // Throw an error if no script was provided. This can happen
- // due to some internal error but also if the keypool is empty.
- // In the latter case, already the pointer is NULL.
- if (!coinbaseScript || coinbaseScript->reserveScript.empty())
- throw std::runtime_error("No coinbase script available (mining requires a wallet)");
-
- while (true) {
- if (chainparams.MiningRequiresPeers()) {
- // Busy-wait for the network to come online so we don't waste time mining
- // on an obsolete chain. In regtest mode we expect to fly solo.
- do {
- bool fvNodesEmpty;
- {
- LOCK(cs_vNodes);
- fvNodesEmpty = vNodes.empty();
- }
- if (!fvNodesEmpty && !IsInitialBlockDownload())
- break;
- MilliSleep(1000);
- } while (true);
- }
-
- //
- // Create new block
- //
- unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
- CBlockIndex* pindexPrev = chainActive.Tip();
-
- auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(chainparams, coinbaseScript->reserveScript));
- if (!pblocktemplate.get())
- {
- LogPrintf("Error in BitcoinMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n");
- return;
- }
- CBlock *pblock = &pblocktemplate->block;
- IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
-
- LogPrintf("Running BitcoinMiner with %u transactions in block (%u bytes)\n", pblock->vtx.size(),
- ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
-
- //
- // Search
- //
- int64_t nStart = GetTime();
- arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
- uint256 hash;
- uint32_t nNonce = 0;
- while (true) {
- // Check if something found
- if (ScanHash(pblock, nNonce, &hash))
- {
- if (UintToArith256(hash) <= hashTarget)
- {
- // Found a solution
- pblock->nNonce = nNonce;
- assert(hash == pblock->GetHash());
-
- SetThreadPriority(THREAD_PRIORITY_NORMAL);
- LogPrintf("BitcoinMiner:\n");
- LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex());
- ProcessBlockFound(pblock, chainparams);
- SetThreadPriority(THREAD_PRIORITY_LOWEST);
- coinbaseScript->KeepScript();
-
- // In regression test mode, stop mining after a block is found.
- if (chainparams.MineBlocksOnDemand())
- throw boost::thread_interrupted();
-
- break;
- }
- }
-
- // Check for stop or if block needs to be rebuilt
- boost::this_thread::interruption_point();
- // Regtest mode doesn't require peers
- if (vNodes.empty() && chainparams.MiningRequiresPeers())
- break;
- if (nNonce >= 0xffff0000)
- break;
- if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
- break;
- if (pindexPrev != chainActive.Tip())
- break;
-
- // Update nTime every few seconds
- if (UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev) < 0)
- break; // Recreate the block if the clock has run backwards,
- // so that we can use the correct time.
- if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks)
- {
- // Changing pblock->nTime can change work required on testnet:
- hashTarget.SetCompact(pblock->nBits);
- }
- }
- }
- }
- catch (const boost::thread_interrupted&)
- {
- LogPrintf("BitcoinMiner terminated\n");
- throw;
- }
- catch (const std::runtime_error &e)
- {
- LogPrintf("BitcoinMiner runtime error: %s\n", e.what());
- return;
- }
-}
-
-void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainparams)
-{
- static boost::thread_group* minerThreads = NULL;
-
- if (nThreads < 0)
- nThreads = GetNumCores();
-
- if (minerThreads != NULL)
- {
- minerThreads->interrupt_all();
- delete minerThreads;
- minerThreads = NULL;
- }
-
- if (nThreads == 0 || !fGenerate)
- return;
-
- minerThreads = new boost::thread_group();
- for (int i = 0; i < nThreads; i++)
- minerThreads->create_thread(boost::bind(&BitcoinMiner, boost::cref(chainparams)));
-}
diff --git a/src/miner.h b/src/miner.h
index 512494198b..cd0f136625 100644
--- a/src/miner.h
+++ b/src/miner.h
@@ -17,9 +17,6 @@ class CScript;
class CWallet;
namespace Consensus { struct Params; };
-static const bool DEFAULT_GENERATE = false;
-static const int DEFAULT_GENERATE_THREADS = 1;
-
static const bool DEFAULT_PRINTPRIORITY = false;
struct CBlockTemplate
@@ -29,8 +26,6 @@ struct CBlockTemplate
std::vector<int64_t> vTxSigOps;
};
-/** Run the miner threads */
-void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainparams);
/** Generate a new block, without valid proof-of-work */
CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& scriptPubKeyIn);
/** Modify the extranonce in a block */
diff --git a/src/net.cpp b/src/net.cpp
index e06e5255d6..b589692d1b 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -79,7 +79,6 @@ bool fListen = true;
uint64_t nLocalServices = NODE_NETWORK;
CCriticalSection cs_mapLocalHost;
map<CNetAddr, LocalServiceInfo> mapLocalHost;
-static bool vfReachable[NET_MAX] = {};
static bool vfLimited[NET_MAX] = {};
static CNode* pnodeLocalHost = NULL;
uint64_t nLocalHostNonce = 0;
@@ -226,14 +225,6 @@ void AdvertiseLocal(CNode *pnode)
}
}
-void SetReachable(enum Network net, bool fFlag)
-{
- LOCK(cs_mapLocalHost);
- vfReachable[net] = fFlag;
- if (net == NET_IPV6 && fFlag)
- vfReachable[NET_IPV4] = true;
-}
-
// learn a new local address
bool AddLocal(const CService& addr, int nScore)
{
@@ -256,7 +247,6 @@ bool AddLocal(const CService& addr, int nScore)
info.nScore = nScore + (fAlready ? 1 : 0);
info.nPort = addr.GetPort();
}
- SetReachable(addr.GetNetwork());
}
return true;
@@ -319,7 +309,7 @@ bool IsLocal(const CService& addr)
bool IsReachable(enum Network net)
{
LOCK(cs_mapLocalHost);
- return vfReachable[net] && !vfLimited[net];
+ return !vfLimited[net];
}
/** check whether a given address is in a network we can probably connect to */
diff --git a/src/net.h b/src/net.h
index d939ef55af..ec296e2aba 100644
--- a/src/net.h
+++ b/src/net.h
@@ -146,7 +146,6 @@ bool IsLocal(const CService& addr);
bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
bool IsReachable(enum Network net);
bool IsReachable(const CNetAddr &addr);
-void SetReachable(enum Network net, bool fFlag = true);
CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui
index febbaeda1b..a5ac0a7d26 100644
--- a/src/qt/forms/debugwindow.ui
+++ b/src/qt/forms/debugwindow.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>740</width>
- <height>450</height>
+ <height>430</height>
</rect>
</property>
<property name="windowTitle">
@@ -113,32 +113,6 @@
</widget>
</item>
<item row="4" column="0">
- <widget class="QLabel" name="label_14">
- <property name="text">
- <string>Using OpenSSL version</string>
- </property>
- <property name="indent">
- <number>10</number>
- </property>
- </widget>
- </item>
- <item row="4" column="1" colspan="2">
- <widget class="QLabel" name="openSSLVersion">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="5" column="0">
<widget class="QLabel" name="label_berkeleyDBVersion">
<property name="text">
<string>Using BerkeleyDB version</string>
@@ -148,7 +122,7 @@
</property>
</widget>
</item>
- <item row="5" column="1" colspan="2">
+ <item row="4" column="1" colspan="2">
<widget class="QLabel" name="berkeleyDBVersion">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -164,14 +138,14 @@
</property>
</widget>
</item>
- <item row="6" column="0">
+ <item row="5" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Build date</string>
</property>
</widget>
</item>
- <item row="6" column="1" colspan="2">
+ <item row="5" column="1" colspan="2">
<widget class="QLabel" name="buildDate">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -187,14 +161,14 @@
</property>
</widget>
</item>
- <item row="7" column="0">
+ <item row="6" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Startup time</string>
</property>
</widget>
</item>
- <item row="7" column="1" colspan="2">
+ <item row="6" column="1" colspan="2">
<widget class="QLabel" name="startupTime">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -210,14 +184,27 @@
</property>
</widget>
</item>
- <item row="9" column="0">
+ <item row="7" column="0">
+ <widget class="QLabel" name="labelNetwork">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Network</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
- <item row="9" column="1" colspan="2">
+ <item row="8" column="1" colspan="2">
<widget class="QLabel" name="networkName">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -233,14 +220,14 @@
</property>
</widget>
</item>
- <item row="10" column="0">
+ <item row="9" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Number of connections</string>
</property>
</widget>
</item>
- <item row="10" column="1" colspan="2">
+ <item row="9" column="1" colspan="2">
<widget class="QLabel" name="numberOfConnections">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -256,7 +243,7 @@
</property>
</widget>
</item>
- <item row="11" column="0">
+ <item row="10" column="0">
<widget class="QLabel" name="label_10">
<property name="font">
<font>
@@ -269,14 +256,14 @@
</property>
</widget>
</item>
- <item row="12" column="0">
+ <item row="11" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Current number of blocks</string>
</property>
</widget>
</item>
- <item row="12" column="1" colspan="2">
+ <item row="11" column="1" colspan="2">
<widget class="QLabel" name="numberOfBlocks">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -292,14 +279,14 @@
</property>
</widget>
</item>
- <item row="13" column="0">
+ <item row="12" column="0">
<widget class="QLabel" name="labelLastBlockTime">
<property name="text">
<string>Last block time</string>
</property>
</widget>
</item>
- <item row="13" column="1" colspan="2">
+ <item row="12" column="1" colspan="2">
<widget class="QLabel" name="lastBlockTime">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -315,7 +302,7 @@
</property>
</widget>
</item>
- <item row="14" column="0">
+ <item row="13" column="0">
<widget class="QLabel" name="labelMempoolTitle">
<property name="font">
<font>
@@ -328,14 +315,14 @@
</property>
</widget>
</item>
- <item row="15" column="0">
+ <item row="14" column="0">
<widget class="QLabel" name="labelNumberOfTransactions">
<property name="text">
<string>Current number of transactions</string>
</property>
</widget>
</item>
- <item row="15" column="1">
+ <item row="14" column="1">
<widget class="QLabel" name="mempoolNumberTxs">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -351,27 +338,14 @@
</property>
</widget>
</item>
- <item row="8" column="0">
- <widget class="QLabel" name="labelNetwork">
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string>Network</string>
- </property>
- </widget>
- </item>
- <item row="16" column="0">
+ <item row="15" column="0">
<widget class="QLabel" name="labelMemoryUsage">
<property name="text">
<string>Memory usage</string>
</property>
</widget>
</item>
- <item row="16" column="1">
+ <item row="15" column="1">
<widget class="QLabel" name="mempoolSize">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -387,7 +361,7 @@
</property>
</widget>
</item>
- <item row="14" column="2" rowspan="3">
+ <item row="13" column="2" rowspan="3">
<layout class="QVBoxLayout" name="verticalLayoutDebugButton">
<property name="spacing">
<number>3</number>
@@ -427,7 +401,7 @@
</item>
</layout>
</item>
- <item row="18" column="0">
+ <item row="16" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
diff --git a/src/qt/res/icons/about.png b/src/qt/res/icons/about.png
index 83eb3c07ee..4143be8bac 100644
--- a/src/qt/res/icons/about.png
+++ b/src/qt/res/icons/about.png
Binary files differ
diff --git a/src/qt/res/icons/chevron.png b/src/qt/res/icons/chevron.png
index ac985052c1..2309fb38e2 100644
--- a/src/qt/res/icons/chevron.png
+++ b/src/qt/res/icons/chevron.png
Binary files differ
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index c18c405256..e8ee3042db 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -36,6 +36,7 @@
#include <QThread>
#include <QTime>
#include <QTimer>
+#include <QStringList>
#if QT_VERSION < 0x050000
#include <QUrl>
@@ -275,13 +276,6 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) :
connect(ui->btnClearTrafficGraph, SIGNAL(clicked()), ui->trafficGraph, SLOT(clear()));
// set library version labels
-
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
- ui->openSSLVersion->setText(SSLeay_version(SSLEAY_VERSION));
-#else
- ui->openSSLVersion->setText(OpenSSL_version(OPENSSL_VERSION));
-#endif
-
#ifdef ENABLE_WALLET
ui->berkeleyDBVersion->setText(DbEnv::version(0, 0, 0));
#else
@@ -453,6 +447,18 @@ void RPCConsole::setClientModel(ClientModel *model)
ui->buildDate->setText(model->formatBuildDate());
ui->startupTime->setText(model->formatClientStartupTime());
ui->networkName->setText(QString::fromStdString(Params().NetworkIDString()));
+
+ //Setup autocomplete and attach it
+ QStringList wordList;
+ std::vector<std::string> commandList = tableRPC.listCommands();
+ for (size_t i = 0; i < commandList.size(); ++i)
+ {
+ wordList << commandList[i].c_str();
+ }
+
+ autoCompleter = new QCompleter(wordList, this);
+ ui->lineEdit->setCompleter(autoCompleter);
+
}
}
@@ -497,16 +503,19 @@ void RPCConsole::setFontSize(int newSize)
// clear console (reset icon sizes, default stylesheet) and re-add the content
float oldPosFactor = 1.0 / ui->messagesWidget->verticalScrollBar()->maximum() * ui->messagesWidget->verticalScrollBar()->value();
- clear();
+ clear(false);
ui->messagesWidget->setHtml(str);
ui->messagesWidget->verticalScrollBar()->setValue(oldPosFactor * ui->messagesWidget->verticalScrollBar()->maximum());
}
-void RPCConsole::clear()
+void RPCConsole::clear(bool clearHistory)
{
ui->messagesWidget->clear();
- history.clear();
- historyPtr = 0;
+ if(clearHistory)
+ {
+ history.clear();
+ historyPtr = 0;
+ }
ui->lineEdit->clear();
ui->lineEdit->setFocus();
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index 648e32638f..2923587bc8 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -11,6 +11,7 @@
#include "net.h"
#include <QWidget>
+#include <QCompleter>
class ClientModel;
class PlatformStyle;
@@ -77,7 +78,7 @@ private Q_SLOTS:
void clearSelectedNode();
public Q_SLOTS:
- void clear();
+ void clear(bool clearHistory = true);
void fontBigger();
void fontSmaller();
void setFontSize(int newSize);
@@ -138,6 +139,7 @@ private:
QMenu *peersTableContextMenu;
QMenu *banTableContextMenu;
int consoleFontSize;
+ QCompleter *autoCompleter;
};
#endif // BITCOIN_QT_RPCCONSOLE_H
diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
index 1647b2a6fe..d2a52b3022 100644
--- a/src/qt/transactiontablemodel.cpp
+++ b/src/qt/transactiontablemodel.cpp
@@ -609,6 +609,34 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
return QString::fromStdString(rec->hash.ToString());
case TxHexRole:
return priv->getTxHex(rec);
+ case TxPlainTextRole:
+ {
+ QString details;
+ QDateTime date = QDateTime::fromTime_t(static_cast<uint>(rec->time));
+ QString txLabel = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address));
+
+ details.append(date.toString("M/d/yy HH:mm"));
+ details.append(" ");
+ details.append(formatTxStatus(rec));
+ details.append(". ");
+ if(!formatTxType(rec).isEmpty()) {
+ details.append(formatTxType(rec));
+ details.append(" ");
+ }
+ if(!rec->address.empty()) {
+ if(txLabel.isEmpty())
+ details.append(tr("(no label)") + " ");
+ else {
+ details.append("(");
+ details.append(txLabel);
+ details.append(") ");
+ }
+ details.append(QString::fromStdString(rec->address));
+ details.append(" ");
+ }
+ details.append(formatTxAmount(rec, false, BitcoinUnits::separatorNever));
+ return details;
+ }
case ConfirmedRole:
return rec->status.countsForBalance;
case FormattedAmountRole:
diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h
index fe59a15f6a..6932646e1e 100644
--- a/src/qt/transactiontablemodel.h
+++ b/src/qt/transactiontablemodel.h
@@ -62,6 +62,8 @@ public:
TxHashRole,
/** Transaction data, hex-encoded */
TxHexRole,
+ /** Whole transaction as plain text */
+ TxPlainTextRole,
/** Is transaction confirmed? */
ConfirmedRole,
/** Formatted amount, without brackets when unconfirmed */
diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp
index 4a9a198216..a4d4c7a35f 100644
--- a/src/qt/transactionview.cpp
+++ b/src/qt/transactionview.cpp
@@ -142,6 +142,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa
QAction *copyAmountAction = new QAction(tr("Copy amount"), this);
QAction *copyTxIDAction = new QAction(tr("Copy transaction ID"), this);
QAction *copyTxHexAction = new QAction(tr("Copy raw transaction"), this);
+ QAction *copyTxPlainText = new QAction(tr("Copy full transaction details"), this);
QAction *editLabelAction = new QAction(tr("Edit label"), this);
QAction *showDetailsAction = new QAction(tr("Show transaction details"), this);
@@ -151,6 +152,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa
contextMenu->addAction(copyAmountAction);
contextMenu->addAction(copyTxIDAction);
contextMenu->addAction(copyTxHexAction);
+ contextMenu->addAction(copyTxPlainText);
contextMenu->addAction(editLabelAction);
contextMenu->addAction(showDetailsAction);
@@ -173,6 +175,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa
connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount()));
connect(copyTxIDAction, SIGNAL(triggered()), this, SLOT(copyTxID()));
connect(copyTxHexAction, SIGNAL(triggered()), this, SLOT(copyTxHex()));
+ connect(copyTxPlainText, SIGNAL(triggered()), this, SLOT(copyTxPlainText()));
connect(editLabelAction, SIGNAL(triggered()), this, SLOT(editLabel()));
connect(showDetailsAction, SIGNAL(triggered()), this, SLOT(showDetails()));
}
@@ -388,6 +391,11 @@ void TransactionView::copyTxHex()
GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxHexRole);
}
+void TransactionView::copyTxPlainText()
+{
+ GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxPlainTextRole);
+}
+
void TransactionView::editLabel()
{
if(!transactionView->selectionModel() ||!model)
@@ -526,12 +534,8 @@ bool TransactionView::eventFilter(QObject *obj, QEvent *event)
QKeyEvent *ke = static_cast<QKeyEvent *>(event);
if (ke->key() == Qt::Key_C && ke->modifiers().testFlag(Qt::ControlModifier))
{
- QModelIndex i = this->transactionView->currentIndex();
- if (i.isValid() && i.column() == TransactionTableModel::Amount)
- {
- GUIUtil::setClipboard(i.data(TransactionTableModel::FormattedAmountRole).toString());
- return true;
- }
+ GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxPlainTextRole);
+ return true;
}
}
return QWidget::eventFilter(obj, event);
diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h
index cf2b8fbcd4..2cfbd471b0 100644
--- a/src/qt/transactionview.h
+++ b/src/qt/transactionview.h
@@ -94,6 +94,7 @@ private Q_SLOTS:
void copyAmount();
void copyTxID();
void copyTxHex();
+ void copyTxPlainText();
void openThirdPartyTxUrl(QString url);
void updateWatchOnlyColumn(bool fHaveWatchOnly);
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index de6bda4ea1..da57973dae 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -89,7 +89,7 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex)
UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
{
UniValue result(UniValue::VOBJ);
- result.push_back(Pair("hash", block.GetHash().GetHex()));
+ result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
int confirmations = -1;
// Only report confirmations if the block is on the main chain
if (chainActive.Contains(blockindex))
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index b0e9b6f153..45fb6c1642 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -27,9 +27,8 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "stop", 0 },
{ "setmocktime", 0 },
{ "getaddednodeinfo", 0 },
- { "setgenerate", 0 },
- { "setgenerate", 1 },
{ "generate", 0 },
+ { "generate", 1 },
{ "getnetworkhashps", 0 },
{ "getnetworkhashps", 1 },
{ "sendtoaddress", 1 },
@@ -160,4 +159,3 @@ UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::s
return params;
}
-
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index fec0987a4c..c33082fca0 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -93,34 +93,15 @@ UniValue getnetworkhashps(const UniValue& params, bool fHelp)
return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
}
-UniValue getgenerate(const UniValue& params, bool fHelp)
-{
- if (fHelp || params.size() != 0)
- throw runtime_error(
- "getgenerate\n"
- "\nReturn if the server is set to generate coins or not. The default is false.\n"
- "It is set with the command line argument -gen (or " + std::string(BITCOIN_CONF_FILENAME) + " setting gen)\n"
- "It can also be set with the setgenerate call.\n"
- "\nResult\n"
- "true|false (boolean) If the server is set to generate coins or not\n"
- "\nExamples:\n"
- + HelpExampleCli("getgenerate", "")
- + HelpExampleRpc("getgenerate", "")
- );
-
- LOCK(cs_main);
- return GetBoolArg("-gen", DEFAULT_GENERATE);
-}
-
UniValue generate(const UniValue& params, bool fHelp)
{
- if (fHelp || params.size() < 1 || params.size() > 1)
+ if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
- "generate numblocks\n"
- "\nMine blocks immediately (before the RPC call returns)\n"
- "\nNote: this function can only be used on the regtest network\n"
+ "generate numblocks ( maxtries )\n"
+ "\nMine up to numblocks blocks immediately (before the RPC call returns)\n"
"\nArguments:\n"
"1. numblocks (numeric, required) How many blocks are generated immediately.\n"
+ "2. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n"
"\nResult\n"
"[ blockhashes ] (array) hashes of blocks generated\n"
"\nExamples:\n"
@@ -128,13 +109,15 @@ UniValue generate(const UniValue& params, bool fHelp)
+ HelpExampleCli("generate", "11")
);
- if (!Params().MineBlocksOnDemand())
- throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This method can only be used on regtest");
-
+ static const int nInnerLoopCount = 0x10000;
int nHeightStart = 0;
int nHeightEnd = 0;
int nHeight = 0;
int nGenerate = params[0].get_int();
+ uint64_t nMaxTries = 1000000;
+ if (params.size() > 1) {
+ nMaxTries = params[1].get_int();
+ }
boost::shared_ptr<CReserveScript> coinbaseScript;
GetMainSignals().ScriptForMining(coinbaseScript);
@@ -165,10 +148,15 @@ UniValue generate(const UniValue& params, bool fHelp)
LOCK(cs_main);
IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce);
}
- while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) {
- // Yes, there is a chance every nonce could fail to satisfy the -regtest
- // target -- 1 in 2^(2^32). That ain't gonna happen.
+ while (nMaxTries > 0 && pblock->nNonce < nInnerLoopCount && !CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) {
++pblock->nNonce;
+ --nMaxTries;
+ }
+ if (nMaxTries == 0) {
+ break;
+ }
+ if (pblock->nNonce == nInnerLoopCount) {
+ continue;
}
CValidationState state;
if (!ProcessNewBlock(state, Params(), NULL, pblock, true, NULL))
@@ -182,50 +170,6 @@ UniValue generate(const UniValue& params, bool fHelp)
return blockHashes;
}
-UniValue setgenerate(const UniValue& params, bool fHelp)
-{
- if (fHelp || params.size() < 1 || params.size() > 2)
- throw runtime_error(
- "setgenerate generate ( genproclimit )\n"
- "\nSet 'generate' true or false to turn generation on or off.\n"
- "Generation is limited to 'genproclimit' processors, -1 is unlimited.\n"
- "See the getgenerate call for the current setting.\n"
- "\nArguments:\n"
- "1. generate (boolean, required) Set to true to turn on generation, off to turn off.\n"
- "2. genproclimit (numeric, optional) Set the processor limit for when generation is on. Can be -1 for unlimited.\n"
- "\nExamples:\n"
- "\nSet the generation on with a limit of one processor\n"
- + HelpExampleCli("setgenerate", "true 1") +
- "\nCheck the setting\n"
- + HelpExampleCli("getgenerate", "") +
- "\nTurn off generation\n"
- + HelpExampleCli("setgenerate", "false") +
- "\nUsing json rpc\n"
- + HelpExampleRpc("setgenerate", "true, 1")
- );
-
- if (Params().MineBlocksOnDemand())
- throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Use the generate method instead of setgenerate on this network");
-
- bool fGenerate = true;
- if (params.size() > 0)
- fGenerate = params[0].get_bool();
-
- int nGenProcLimit = GetArg("-genproclimit", DEFAULT_GENERATE_THREADS);
- if (params.size() > 1)
- {
- nGenProcLimit = params[1].get_int();
- if (nGenProcLimit == 0)
- fGenerate = false;
- }
-
- mapArgs["-gen"] = (fGenerate ? "1" : "0");
- mapArgs ["-genproclimit"] = itostr(nGenProcLimit);
- GenerateBitcoins(fGenerate, nGenProcLimit, Params());
-
- return NullUniValue;
-}
-
UniValue getmininginfo(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() != 0)
@@ -239,8 +183,6 @@ UniValue getmininginfo(const UniValue& params, bool fHelp)
" \"currentblocktx\": nnn, (numeric) The last block transaction\n"
" \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n"
" \"errors\": \"...\" (string) Current errors\n"
- " \"generate\": true|false (boolean) If the generation is on or off (see getgenerate or setgenerate calls)\n"
- " \"genproclimit\": n (numeric) The processor limit for generation. -1 if no generation. (see getgenerate or setgenerate calls)\n"
" \"pooledtx\": n (numeric) The size of the mem pool\n"
" \"testnet\": true|false (boolean) If using testnet or not\n"
" \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
@@ -259,12 +201,10 @@ UniValue getmininginfo(const UniValue& params, bool fHelp)
obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx));
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
- obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", DEFAULT_GENERATE_THREADS)));
obj.push_back(Pair("networkhashps", getnetworkhashps(params, false)));
obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
obj.push_back(Pair("chain", Params().NetworkIDString()));
- obj.push_back(Pair("generate", getgenerate(params, false)));
return obj;
}
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index b2d4559ccd..33fa1437e2 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -298,8 +298,6 @@ static const CRPCCommand vRPCCommands[] =
{ "mining", "submitblock", &submitblock, true },
/* Coin generation */
- { "generating", "getgenerate", &getgenerate, true },
- { "generating", "setgenerate", &setgenerate, true },
{ "generating", "generate", &generate, true },
/* Raw transactions */
@@ -499,6 +497,17 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue &params
g_rpcSignals.PostCommand(*pcmd);
}
+std::vector<std::string> CRPCTable::listCommands() const
+{
+ std::vector<std::string> commandList;
+ typedef std::map<std::string, const CRPCCommand*> commandMap;
+
+ std::transform( mapCommands.begin(), mapCommands.end(),
+ std::back_inserter(commandList),
+ boost::bind(&commandMap::value_type::first,_1) );
+ return commandList;
+}
+
std::string HelpExampleCli(const std::string& methodname, const std::string& args)
{
return "> bitcoin-cli " + methodname + " " + args + "\n";
diff --git a/src/rpc/server.h b/src/rpc/server.h
index 99ffad5d40..38cb32e7f2 100644
--- a/src/rpc/server.h
+++ b/src/rpc/server.h
@@ -145,6 +145,12 @@ public:
*/
UniValue execute(const std::string &method, const UniValue &params) const;
+ /**
+ * Returns a list of registered commands
+ * @returns List of registered commands.
+ */
+ std::vector<std::string> listCommands() const;
+
/**
* Appends a CRPCCommand to the dispatch table.
@@ -186,8 +192,6 @@ extern UniValue setban(const UniValue& params, bool fHelp);
extern UniValue listbanned(const UniValue& params, bool fHelp);
extern UniValue clearbanned(const UniValue& params, bool fHelp);
-extern UniValue getgenerate(const UniValue& params, bool fHelp); // in rpc/mining.cpp
-extern UniValue setgenerate(const UniValue& params, bool fHelp);
extern UniValue generate(const UniValue& params, bool fHelp);
extern UniValue getnetworkhashps(const UniValue& params, bool fHelp);
extern UniValue getmininginfo(const UniValue& params, bool fHelp);
diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp
index 0895ef3326..87d35be412 100644
--- a/src/test/alert_tests.cpp
+++ b/src/test/alert_tests.cpp
@@ -12,9 +12,9 @@
#include "main.h" // For PartitionCheck
#include "serialize.h"
#include "streams.h"
-#include "util.h"
#include "utilstrencodings.h"
+#include "test/testutil.h"
#include "test/test_bitcoin.h"
#include <fstream>
diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json
index 7ce7e0879c..9e91132984 100644
--- a/src/test/data/script_invalid.json
+++ b/src/test/data/script_invalid.json
@@ -6,504 +6,519 @@
["correct prevout hash), using the given scriptSig. All nLockTimes are 0, all"],
["nSequences are max."],
-["", "DEPTH", "P2SH,STRICTENC", "Test the test: we should have an empty stack after scriptSig evaluation"],
-[" ", "DEPTH", "P2SH,STRICTENC", "and multiple spaces should not change that."],
-[" ", "DEPTH", "P2SH,STRICTENC"],
-[" ", "DEPTH", "P2SH,STRICTENC"],
-
-["", "", "P2SH,STRICTENC"],
-["", "NOP", "P2SH,STRICTENC"],
-["", "NOP DEPTH", "P2SH,STRICTENC"],
-["NOP", "", "P2SH,STRICTENC"],
-["NOP", "DEPTH", "P2SH,STRICTENC"],
-["NOP","NOP", "P2SH,STRICTENC"],
-["NOP","NOP DEPTH", "P2SH,STRICTENC"],
-
-["DEPTH", "", "P2SH,STRICTENC"],
-
-["0x4c01","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA1 with not enough bytes"],
-["0x4d0200ff","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA2 with not enough bytes"],
-["0x4e03000000ffff","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA4 with not enough bytes"],
-
-["1", "IF 0x50 ENDIF 1", "P2SH,STRICTENC", "0x50 is reserved"],
-["0x52", "0x5f ADD 0x60 EQUAL", "P2SH,STRICTENC", "0x51 through 0x60 push 1 through 16 onto stack"],
-["0","NOP", "P2SH,STRICTENC"],
-["1", "IF VER ELSE 1 ENDIF", "P2SH,STRICTENC", "VER non-functional"],
-["0", "IF VERIF ELSE 1 ENDIF", "P2SH,STRICTENC", "VERIF illegal everywhere"],
-["0", "IF ELSE 1 ELSE VERIF ENDIF", "P2SH,STRICTENC", "VERIF illegal everywhere"],
-["0", "IF VERNOTIF ELSE 1 ENDIF", "P2SH,STRICTENC", "VERNOTIF illegal everywhere"],
-["0", "IF ELSE 1 ELSE VERNOTIF ENDIF", "P2SH,STRICTENC", "VERNOTIF illegal everywhere"],
-
-["1 IF", "1 ENDIF", "P2SH,STRICTENC", "IF/ENDIF can't span scriptSig/scriptPubKey"],
-["1 IF 0 ENDIF", "1 ENDIF", "P2SH,STRICTENC"],
-["1 ELSE 0 ENDIF", "1", "P2SH,STRICTENC"],
-["0 NOTIF", "123", "P2SH,STRICTENC"],
-
-["0", "DUP IF ENDIF", "P2SH,STRICTENC"],
-["0", "IF 1 ENDIF", "P2SH,STRICTENC"],
-["0", "DUP IF ELSE ENDIF", "P2SH,STRICTENC"],
-["0", "IF 1 ELSE ENDIF", "P2SH,STRICTENC"],
-["0", "NOTIF ELSE 1 ENDIF", "P2SH,STRICTENC"],
-
-["0 1", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"],
-["0 0", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"],
-["1 0", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"],
-["0 1", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"],
-
-["0 0", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"],
-["0 1", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"],
-["1 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"],
-["0 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"],
-
-["1", "IF RETURN ELSE ELSE 1 ENDIF", "P2SH,STRICTENC", "Multiple ELSEs"],
-["1", "IF 1 ELSE ELSE RETURN ENDIF", "P2SH,STRICTENC"],
-
-["1", "ENDIF", "P2SH,STRICTENC", "Malformed IF/ELSE/ENDIF sequence"],
-["1", "ELSE ENDIF", "P2SH,STRICTENC"],
-["1", "ENDIF ELSE", "P2SH,STRICTENC"],
-["1", "ENDIF ELSE IF", "P2SH,STRICTENC"],
-["1", "IF ELSE ENDIF ELSE", "P2SH,STRICTENC"],
-["1", "IF ELSE ENDIF ELSE ENDIF", "P2SH,STRICTENC"],
-["1", "IF ENDIF ENDIF", "P2SH,STRICTENC"],
-["1", "IF ELSE ELSE ENDIF ENDIF", "P2SH,STRICTENC"],
-
-["1", "RETURN", "P2SH,STRICTENC"],
-["1", "DUP IF RETURN ENDIF", "P2SH,STRICTENC"],
-
-["1", "RETURN 'data'", "P2SH,STRICTENC", "canonical prunable txout format"],
-["0 IF", "RETURN ENDIF 1", "P2SH,STRICTENC", "still prunable because IF/ENDIF can't span scriptSig/scriptPubKey"],
-
-["0", "VERIFY 1", "P2SH,STRICTENC"],
-["1", "VERIFY", "P2SH,STRICTENC"],
-["1", "VERIFY 0", "P2SH,STRICTENC"],
-
-["1 TOALTSTACK", "FROMALTSTACK 1", "P2SH,STRICTENC", "alt stack not shared between sig/pubkey"],
-
-["IFDUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC"],
-["DROP", "DEPTH 0 EQUAL", "P2SH,STRICTENC"],
-["DUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC"],
-["1", "DUP 1 ADD 2 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC"],
-["NOP", "NIP", "P2SH,STRICTENC"],
-["NOP", "1 NIP", "P2SH,STRICTENC"],
-["NOP", "1 0 NIP", "P2SH,STRICTENC"],
-["NOP", "OVER 1", "P2SH,STRICTENC"],
-["1", "OVER", "P2SH,STRICTENC"],
-["0 1", "OVER DEPTH 3 EQUALVERIFY", "P2SH,STRICTENC"],
-["19 20 21", "PICK 19 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"],
-["NOP", "0 PICK", "P2SH,STRICTENC"],
-["1", "-1 PICK", "P2SH,STRICTENC"],
-["19 20 21", "0 PICK 20 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC"],
-["19 20 21", "1 PICK 21 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC"],
-["19 20 21", "2 PICK 22 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC"],
-["NOP", "0 ROLL", "P2SH,STRICTENC"],
-["1", "-1 ROLL", "P2SH,STRICTENC"],
-["19 20 21", "0 ROLL 20 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"],
-["19 20 21", "1 ROLL 21 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"],
-["19 20 21", "2 ROLL 22 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"],
-["NOP", "ROT 1", "P2SH,STRICTENC"],
-["NOP", "1 ROT 1", "P2SH,STRICTENC"],
-["NOP", "1 2 ROT 1", "P2SH,STRICTENC"],
-["NOP", "0 1 2 ROT", "P2SH,STRICTENC"],
-["NOP", "SWAP 1", "P2SH,STRICTENC"],
-["1", "SWAP 1", "P2SH,STRICTENC"],
-["0 1", "SWAP 1 EQUALVERIFY", "P2SH,STRICTENC"],
-["NOP", "TUCK 1", "P2SH,STRICTENC"],
-["1", "TUCK 1", "P2SH,STRICTENC"],
-["1 0", "TUCK DEPTH 3 EQUALVERIFY SWAP 2DROP", "P2SH,STRICTENC"],
-["NOP", "2DUP 1", "P2SH,STRICTENC"],
-["1", "2DUP 1", "P2SH,STRICTENC"],
-["NOP", "3DUP 1", "P2SH,STRICTENC"],
-["1", "3DUP 1", "P2SH,STRICTENC"],
-["1 2", "3DUP 1", "P2SH,STRICTENC"],
-["NOP", "2OVER 1", "P2SH,STRICTENC"],
-["1", "2 3 2OVER 1", "P2SH,STRICTENC"],
-["NOP", "2SWAP 1", "P2SH,STRICTENC"],
-["1", "2 3 2SWAP 1", "P2SH,STRICTENC"],
-
-["'a' 'b'", "CAT", "P2SH,STRICTENC", "CAT disabled"],
-["'a' 'b' 0", "IF CAT ELSE 1 ENDIF", "P2SH,STRICTENC", "CAT disabled"],
-["'abc' 1 1", "SUBSTR", "P2SH,STRICTENC", "SUBSTR disabled"],
-["'abc' 1 1 0", "IF SUBSTR ELSE 1 ENDIF", "P2SH,STRICTENC", "SUBSTR disabled"],
-["'abc' 2 0", "IF LEFT ELSE 1 ENDIF", "P2SH,STRICTENC", "LEFT disabled"],
-["'abc' 2 0", "IF RIGHT ELSE 1 ENDIF", "P2SH,STRICTENC", "RIGHT disabled"],
-
-["NOP", "SIZE 1", "P2SH,STRICTENC"],
-
-["'abc'", "IF INVERT ELSE 1 ENDIF", "P2SH,STRICTENC", "INVERT disabled"],
-["1 2 0 IF AND ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "AND disabled"],
-["1 2 0 IF OR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "OR disabled"],
-["1 2 0 IF XOR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "XOR disabled"],
-["2 0 IF 2MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "2MUL disabled"],
-["2 0 IF 2DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "2DIV disabled"],
-["2 2 0 IF MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "MUL disabled"],
-["2 2 0 IF DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DIV disabled"],
-["2 2 0 IF MOD ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "MOD disabled"],
-["2 2 0 IF LSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "LSHIFT disabled"],
-["2 2 0 IF RSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "RSHIFT disabled"],
-
-["", "EQUAL NOT", "P2SH,STRICTENC", "EQUAL must error when there are no stack items"],
-["0", "EQUAL NOT", "P2SH,STRICTENC", "EQUAL must error when there are not 2 stack items"],
-["0 1","EQUAL", "P2SH,STRICTENC"],
-["1 1 ADD", "0 EQUAL", "P2SH,STRICTENC"],
-["11 1 ADD 12 SUB", "11 EQUAL", "P2SH,STRICTENC"],
-
-["2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "arithmetic operands must be in range [-2^31...2^31] "],
-["-2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "arithmetic operands must be in range [-2^31...2^31] "],
-["2147483647 DUP ADD", "4294967294 NUMEQUAL", "P2SH,STRICTENC", "NUMEQUAL must be in numeric range"],
-["'abcdef' NOT", "0 EQUAL", "P2SH,STRICTENC", "NOT is an arithmetic operand"],
-
-["2 DUP MUL", "4 EQUAL", "P2SH,STRICTENC", "disabled"],
-["2 DUP DIV", "1 EQUAL", "P2SH,STRICTENC", "disabled"],
-["2 2MUL", "4 EQUAL", "P2SH,STRICTENC", "disabled"],
-["2 2DIV", "1 EQUAL", "P2SH,STRICTENC", "disabled"],
-["7 3 MOD", "1 EQUAL", "P2SH,STRICTENC", "disabled"],
-["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "disabled"],
-["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "disabled"],
-
-["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"],
-["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"],
+["", "DEPTH", "P2SH,STRICTENC", "Test the test: we should have an empty stack after scriptSig evaluation", "EVAL_FALSE"],
+[" ", "DEPTH", "P2SH,STRICTENC", "and multiple spaces should not change that.", "EVAL_FALSE"],
+[" ", "DEPTH", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+[" ", "DEPTH", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+
+["", "", "P2SH,STRICTENC","", "EVAL_FALSE"],
+["", "NOP", "P2SH,STRICTENC","", "EVAL_FALSE"],
+["", "NOP DEPTH", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["NOP", "", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["NOP", "DEPTH", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["NOP","NOP", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["NOP","NOP DEPTH", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+
+["DEPTH", "", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+
+["0x4c01","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA1 with not enough bytes","BAD_OPCODE"],
+["0x4d0200ff","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA2 with not enough bytes","BAD_OPCODE"],
+["0x4e03000000ffff","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA4 with not enough bytes","BAD_OPCODE"],
+
+["1", "IF 0x50 ENDIF 1", "P2SH,STRICTENC", "0x50 is reserved","BAD_OPCODE"],
+["0x52", "0x5f ADD 0x60 EQUAL", "P2SH,STRICTENC", "0x51 through 0x60 push 1 through 16 onto stack","EVAL_FALSE"],
+["0","NOP", "P2SH,STRICTENC","","EVAL_FALSE"],
+["1", "IF VER ELSE 1 ENDIF", "P2SH,STRICTENC", "VER non-functional", "BAD_OPCODE"],
+["0", "IF VERIF ELSE 1 ENDIF", "P2SH,STRICTENC", "VERIF illegal everywhere", "BAD_OPCODE"],
+["0", "IF ELSE 1 ELSE VERIF ENDIF", "P2SH,STRICTENC", "VERIF illegal everywhere", "BAD_OPCODE"],
+["0", "IF VERNOTIF ELSE 1 ENDIF", "P2SH,STRICTENC", "VERNOTIF illegal everywhere", "BAD_OPCODE"],
+["0", "IF ELSE 1 ELSE VERNOTIF ENDIF", "P2SH,STRICTENC", "VERNOTIF illegal everywhere", "BAD_OPCODE"],
+
+["1 IF", "1 ENDIF", "P2SH,STRICTENC", "IF/ENDIF can't span scriptSig/scriptPubKey", "UNBALANCED_CONDITIONAL"],
+["1 IF 0 ENDIF", "1 ENDIF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"],
+["1 ELSE 0 ENDIF", "1", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"],
+["0 NOTIF", "123", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"],
+
+["0", "DUP IF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["0", "IF 1 ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["0", "DUP IF ELSE ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["0", "IF 1 ELSE ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["0", "NOTIF ELSE 1 ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+
+["0 1", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["0 0", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["1 0", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["0 1", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+
+["0 0", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["0 1", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["1 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["0 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+
+["1", "IF RETURN ELSE ELSE 1 ENDIF", "P2SH,STRICTENC", "Multiple ELSEs", "OP_RETURN"],
+["1", "IF 1 ELSE ELSE RETURN ENDIF", "P2SH,STRICTENC", "", "OP_RETURN"],
+
+["1", "ENDIF", "P2SH,STRICTENC", "Malformed IF/ELSE/ENDIF sequence", "UNBALANCED_CONDITIONAL"],
+["1", "ELSE ENDIF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"],
+["1", "ENDIF ELSE", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"],
+["1", "ENDIF ELSE IF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"],
+["1", "IF ELSE ENDIF ELSE", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"],
+["1", "IF ELSE ENDIF ELSE ENDIF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"],
+["1", "IF ENDIF ENDIF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"],
+["1", "IF ELSE ELSE ENDIF ENDIF", "P2SH,STRICTENC", "", "UNBALANCED_CONDITIONAL"],
+
+["1", "RETURN", "P2SH,STRICTENC", "", "OP_RETURN"],
+["1", "DUP IF RETURN ENDIF", "P2SH,STRICTENC", "", "OP_RETURN"],
+
+["1", "RETURN 'data'", "P2SH,STRICTENC", "canonical prunable txout format", "OP_RETURN"],
+["0 IF", "RETURN ENDIF 1", "P2SH,STRICTENC", "still prunable because IF/ENDIF can't span scriptSig/scriptPubKey", "UNBALANCED_CONDITIONAL"],
+
+["0", "VERIFY 1", "P2SH,STRICTENC", "", "VERIFY"],
+["1", "VERIFY", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["1", "VERIFY 0", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+
+["1 TOALTSTACK", "FROMALTSTACK 1", "P2SH,STRICTENC", "alt stack not shared between sig/pubkey", "INVALID_ALTSTACK_OPERATION"],
+
+["IFDUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["DROP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["DUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "DUP 1 ADD 2 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["NOP", "NIP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "1 NIP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "1 0 NIP", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["NOP", "OVER 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "OVER", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["0 1", "OVER DEPTH 3 EQUALVERIFY", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["19 20 21", "PICK 19 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "0 PICK", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "-1 PICK", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["19 20 21", "0 PICK 20 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"],
+["19 20 21", "1 PICK 21 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"],
+["19 20 21", "2 PICK 22 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"],
+["NOP", "0 ROLL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "-1 ROLL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["19 20 21", "0 ROLL 20 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"],
+["19 20 21", "1 ROLL 21 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"],
+["19 20 21", "2 ROLL 22 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC", "", "EQUALVERIFY"],
+["NOP", "ROT 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "1 ROT 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "1 2 ROT 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "0 1 2 ROT", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["NOP", "SWAP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "SWAP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["0 1", "SWAP 1 EQUALVERIFY", "P2SH,STRICTENC", "", "EQUALVERIFY"],
+["NOP", "TUCK 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "TUCK 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1 0", "TUCK DEPTH 3 EQUALVERIFY SWAP 2DROP", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["NOP", "2DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "2DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "3DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "3DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1 2", "3DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "2OVER 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "2 3 2OVER 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "2SWAP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "2 3 2SWAP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+
+["'a' 'b'", "CAT", "P2SH,STRICTENC", "CAT disabled", "DISABLED_OPCODE"],
+["'a' 'b' 0", "IF CAT ELSE 1 ENDIF", "P2SH,STRICTENC", "CAT disabled", "DISABLED_OPCODE"],
+["'abc' 1 1", "SUBSTR", "P2SH,STRICTENC", "SUBSTR disabled", "DISABLED_OPCODE"],
+["'abc' 1 1 0", "IF SUBSTR ELSE 1 ENDIF", "P2SH,STRICTENC", "SUBSTR disabled", "DISABLED_OPCODE"],
+["'abc' 2 0", "IF LEFT ELSE 1 ENDIF", "P2SH,STRICTENC", "LEFT disabled", "DISABLED_OPCODE"],
+["'abc' 2 0", "IF RIGHT ELSE 1 ENDIF", "P2SH,STRICTENC", "RIGHT disabled", "DISABLED_OPCODE"],
+
+["NOP", "SIZE 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+
+["'abc'", "IF INVERT ELSE 1 ENDIF", "P2SH,STRICTENC", "INVERT disabled", "DISABLED_OPCODE"],
+["1 2 0 IF AND ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "AND disabled", "DISABLED_OPCODE"],
+["1 2 0 IF OR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "OR disabled", "DISABLED_OPCODE"],
+["1 2 0 IF XOR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "XOR disabled", "DISABLED_OPCODE"],
+["2 0 IF 2MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "2MUL disabled", "DISABLED_OPCODE"],
+["2 0 IF 2DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "2DIV disabled", "DISABLED_OPCODE"],
+["2 2 0 IF MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "MUL disabled", "DISABLED_OPCODE"],
+["2 2 0 IF DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DIV disabled", "DISABLED_OPCODE"],
+["2 2 0 IF MOD ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "MOD disabled", "DISABLED_OPCODE"],
+["2 2 0 IF LSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "LSHIFT disabled", "DISABLED_OPCODE"],
+["2 2 0 IF RSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "RSHIFT disabled", "DISABLED_OPCODE"],
+
+["", "EQUAL NOT", "P2SH,STRICTENC", "EQUAL must error when there are no stack items", "INVALID_STACK_OPERATION"],
+["0", "EQUAL NOT", "P2SH,STRICTENC", "EQUAL must error when there are not 2 stack items", "INVALID_STACK_OPERATION"],
+["0 1","EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["1 1 ADD", "0 EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["11 1 ADD 12 SUB", "11 EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+
+["2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "arithmetic operands must be in range [-2^31...2^31] ", "UNKNOWN_ERROR"],
+["-2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "arithmetic operands must be in range [-2^31...2^31] ", "UNKNOWN_ERROR"],
+["2147483647 DUP ADD", "4294967294 NUMEQUAL", "P2SH,STRICTENC", "NUMEQUAL must be in numeric range", "UNKNOWN_ERROR"],
+["'abcdef' NOT", "0 EQUAL", "P2SH,STRICTENC", "NOT is an arithmetic operand", "UNKNOWN_ERROR"],
+
+["2 DUP MUL", "4 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"],
+["2 DUP DIV", "1 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"],
+["2 2MUL", "4 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"],
+["2 2DIV", "1 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"],
+["7 3 MOD", "1 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"],
+["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"],
+["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "disabled", "DISABLED_OPCODE"],
+
+["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "", "EVAL_FALSE"],
["Ensure 100% coverage of discouraged NOPS"],
-["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
-["1", "CHECKLOCKTIMEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
-["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
-["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
-["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
-["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
-["1", "NOP7", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
-["1", "NOP8", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
-["1", "NOP9", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
-["1", "NOP10", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
-
-["NOP10", "1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in scriptSig"],
+["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "CHECKLOCKTIMEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP7", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP8", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP9", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP10", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "", "DISCOURAGE_UPGRADABLE_NOPS"],
+
+["NOP10", "1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in scriptSig", "DISCOURAGE_UPGRADABLE_NOPS"],
["1 0x01 0xb9", "HASH160 0x14 0x15727299b05b45fdaf9ac9ecf7565cfe27c3e567 EQUAL",
- "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in redeemScript"],
-
-["0x50","1", "P2SH,STRICTENC", "opcode 0x50 is reserved"],
-["1", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "opcodes above NOP10 invalid if executed"],
-["1", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xc0 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xc1 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xc2 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xc3 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xc4 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xc5 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xc6 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xc7 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xc8 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xc9 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xca ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xcb ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xcc ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xcd ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xce ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xcf ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xd0 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xd1 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xd2 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xd3 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xd4 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xd5 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xd6 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xd7 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xd8 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xd9 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xda ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xdb ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xdc ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xdd ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xde ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xdf ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xe0 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xe1 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xe2 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xe3 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xe4 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xe5 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xe6 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xe7 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xe8 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xe9 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xea ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xeb ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xec ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xed ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xee ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xef ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xf0 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xf1 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xf2 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xf3 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xf4 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xf5 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xf6 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xf7 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xf8 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xf9 ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xfa ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xfb ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xfc ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xfd ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xfe ELSE 1 ENDIF", "P2SH,STRICTENC"],
-["1", "IF 0xff ELSE 1 ENDIF", "P2SH,STRICTENC"],
-
-["1 IF 1 ELSE", "0xff ENDIF", "P2SH,STRICTENC", "invalid because scriptSig and scriptPubKey are processed separately"],
-
-["NOP", "RIPEMD160", "P2SH,STRICTENC"],
-["NOP", "SHA1", "P2SH,STRICTENC"],
-["NOP", "SHA256", "P2SH,STRICTENC"],
-["NOP", "HASH160", "P2SH,STRICTENC"],
-["NOP", "HASH256", "P2SH,STRICTENC"],
+ "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in redeemScript", "DISCOURAGE_UPGRADABLE_NOPS"],
+
+["0x50","1", "P2SH,STRICTENC", "opcode 0x50 is reserved", "BAD_OPCODE"],
+["1", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "opcodes above NOP10 invalid if executed", "BAD_OPCODE"],
+["1", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xc0 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xc1 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xc2 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xc3 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xc4 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xc5 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xc6 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xc7 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xc8 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xc9 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xca ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xcb ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xcc ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xcd ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xce ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xcf ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xd0 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xd1 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xd2 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xd3 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xd4 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xd5 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xd6 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xd7 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xd8 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xd9 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xda ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xdb ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xdc ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xdd ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xde ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xdf ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xe0 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xe1 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xe2 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xe3 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xe4 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xe5 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xe6 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xe7 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xe8 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xe9 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xea ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xeb ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xec ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xed ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xee ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xef ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xf0 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xf1 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xf2 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xf3 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xf4 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xf5 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xf6 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xf7 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xf8 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xf9 ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xfa ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xfb ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xfc ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xfd ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xfe ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+["1", "IF 0xff ELSE 1 ENDIF", "P2SH,STRICTENC", "", "BAD_OPCODE"],
+
+["1 IF 1 ELSE", "0xff ENDIF", "P2SH,STRICTENC", "invalid because scriptSig and scriptPubKey are processed separately", "UNBALANCED_CONDITIONAL"],
+
+["NOP", "RIPEMD160", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "SHA1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "SHA256", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "HASH160", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "HASH256", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
["NOP",
"'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'",
"P2SH,STRICTENC",
-">520 byte push"],
+">520 byte push",
+"PUSH_SIZE"],
["0",
"IF 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' ENDIF 1",
"P2SH,STRICTENC",
-">520 byte push in non-executed IF branch"],
+">520 byte push in non-executed IF branch",
+"PUSH_SIZE"],
["1",
"0x61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161",
"P2SH,STRICTENC",
-">201 opcodes executed. 0x61 is NOP"],
+">201 opcodes executed. 0x61 is NOP",
+"OP_COUNT"],
["0",
"IF 0x6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 ENDIF 1",
"P2SH,STRICTENC",
-">201 opcodes including non-executed IF branch. 0x61 is NOP"],
+">201 opcodes including non-executed IF branch. 0x61 is NOP",
+"OP_COUNT"],
["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f",
"1 2 3 4 5 6 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f",
"P2SH,STRICTENC",
-">1,000 stack size (0x6f is 3DUP)"],
+">1,000 stack size (0x6f is 3DUP)",
+"STACK_SIZE"],
["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f",
"1 TOALTSTACK 2 TOALTSTACK 3 4 5 6 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f",
"P2SH,STRICTENC",
-">1,000 stack+altstack size"],
+">1,000 stack+altstack size",
+"STACK_SIZE"],
["NOP",
"0 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f 2DUP 0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161",
"P2SH,STRICTENC",
-"10,001-byte scriptPubKey"],
-
-["NOP1","NOP10", "P2SH,STRICTENC"],
-
-["1","VER", "P2SH,STRICTENC", "OP_VER is reserved"],
-["1","VERIF", "P2SH,STRICTENC", "OP_VERIF is reserved"],
-["1","VERNOTIF", "P2SH,STRICTENC", "OP_VERNOTIF is reserved"],
-["1","RESERVED", "P2SH,STRICTENC", "OP_RESERVED is reserved"],
-["1","RESERVED1", "P2SH,STRICTENC", "OP_RESERVED1 is reserved"],
-["1","RESERVED2", "P2SH,STRICTENC", "OP_RESERVED2 is reserved"],
-["1","0xba", "P2SH,STRICTENC", "0xba == OP_NOP10 + 1"],
-
-["2147483648", "1ADD 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers"],
-["2147483648", "NEGATE 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers"],
-["-2147483648", "1ADD 1", "P2SH,STRICTENC", "Because we use a sign bit, -2147483648 is also 5 bytes"],
-["2147483647", "1ADD 1SUB 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers, even if the result is 4-bytes"],
-["2147483648", "1SUB 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers, even if the result is 4-bytes"],
-
-["2147483648 1", "BOOLOR 1", "P2SH,STRICTENC", "We cannot do BOOLOR on 5-byte integers (but we can still do IF etc)"],
-["2147483648 1", "BOOLAND 1", "P2SH,STRICTENC", "We cannot do BOOLAND on 5-byte integers"],
-
-["1", "1 ENDIF", "P2SH,STRICTENC", "ENDIF without IF"],
-["1", "IF 1", "P2SH,STRICTENC", "IF without ENDIF"],
-["1 IF 1", "ENDIF", "P2SH,STRICTENC", "IFs don't carry over"],
-
-["NOP", "IF 1 ENDIF", "P2SH,STRICTENC", "The following tests check the if(stack.size() < N) tests in each opcode"],
-["NOP", "NOTIF 1 ENDIF", "P2SH,STRICTENC", "They are here to catch copy-and-paste errors"],
-["NOP", "VERIFY 1", "P2SH,STRICTENC", "Most of them are duplicated elsewhere,"],
-
-["NOP", "TOALTSTACK 1", "P2SH,STRICTENC", "but, hey, more is always better, right?"],
-["1", "FROMALTSTACK", "P2SH,STRICTENC"],
-["1", "2DROP 1", "P2SH,STRICTENC"],
-["1", "2DUP", "P2SH,STRICTENC"],
-["1 1", "3DUP", "P2SH,STRICTENC"],
-["1 1 1", "2OVER", "P2SH,STRICTENC"],
-["1 1 1 1 1", "2ROT", "P2SH,STRICTENC"],
-["1 1 1", "2SWAP", "P2SH,STRICTENC"],
-["NOP", "IFDUP 1", "P2SH,STRICTENC"],
-["NOP", "DROP 1", "P2SH,STRICTENC"],
-["NOP", "DUP 1", "P2SH,STRICTENC"],
-["1", "NIP", "P2SH,STRICTENC"],
-["1", "OVER", "P2SH,STRICTENC"],
-["1 1 1 3", "PICK", "P2SH,STRICTENC"],
-["0", "PICK 1", "P2SH,STRICTENC"],
-["1 1 1 3", "ROLL", "P2SH,STRICTENC"],
-["0", "ROLL 1", "P2SH,STRICTENC"],
-["1 1", "ROT", "P2SH,STRICTENC"],
-["1", "SWAP", "P2SH,STRICTENC"],
-["1", "TUCK", "P2SH,STRICTENC"],
-
-["NOP", "SIZE 1", "P2SH,STRICTENC"],
-
-["1", "EQUAL 1", "P2SH,STRICTENC"],
-["1", "EQUALVERIFY 1", "P2SH,STRICTENC"],
-
-["NOP", "1ADD 1", "P2SH,STRICTENC"],
-["NOP", "1SUB 1", "P2SH,STRICTENC"],
-["NOP", "NEGATE 1", "P2SH,STRICTENC"],
-["NOP", "ABS 1", "P2SH,STRICTENC"],
-["NOP", "NOT 1", "P2SH,STRICTENC"],
-["NOP", "0NOTEQUAL 1", "P2SH,STRICTENC"],
-
-["1", "ADD", "P2SH,STRICTENC"],
-["1", "SUB", "P2SH,STRICTENC"],
-["1", "BOOLAND", "P2SH,STRICTENC"],
-["1", "BOOLOR", "P2SH,STRICTENC"],
-["1", "NUMEQUAL", "P2SH,STRICTENC"],
-["1", "NUMEQUALVERIFY 1", "P2SH,STRICTENC"],
-["1", "NUMNOTEQUAL", "P2SH,STRICTENC"],
-["1", "LESSTHAN", "P2SH,STRICTENC"],
-["1", "GREATERTHAN", "P2SH,STRICTENC"],
-["1", "LESSTHANOREQUAL", "P2SH,STRICTENC"],
-["1", "GREATERTHANOREQUAL", "P2SH,STRICTENC"],
-["1", "MIN", "P2SH,STRICTENC"],
-["1", "MAX", "P2SH,STRICTENC"],
-["1 1", "WITHIN", "P2SH,STRICTENC"],
-
-["NOP", "RIPEMD160 1", "P2SH,STRICTENC"],
-["NOP", "SHA1 1", "P2SH,STRICTENC"],
-["NOP", "SHA256 1", "P2SH,STRICTENC"],
-["NOP", "HASH160 1", "P2SH,STRICTENC"],
-["NOP", "HASH256 1", "P2SH,STRICTENC"],
+"10,001-byte scriptPubKey",
+"SCRIPT_SIZE"],
+
+["NOP1","NOP10", "P2SH,STRICTENC", "", "EVAL_FALSE"],
+
+["1","VER", "P2SH,STRICTENC", "OP_VER is reserved", "BAD_OPCODE"],
+["1","VERIF", "P2SH,STRICTENC", "OP_VERIF is reserved", "BAD_OPCODE"],
+["1","VERNOTIF", "P2SH,STRICTENC", "OP_VERNOTIF is reserved", "BAD_OPCODE"],
+["1","RESERVED", "P2SH,STRICTENC", "OP_RESERVED is reserved", "BAD_OPCODE"],
+["1","RESERVED1", "P2SH,STRICTENC", "OP_RESERVED1 is reserved", "BAD_OPCODE"],
+["1","RESERVED2", "P2SH,STRICTENC", "OP_RESERVED2 is reserved", "BAD_OPCODE"],
+["1","0xba", "P2SH,STRICTENC", "0xba == OP_NOP10 + 1", "BAD_OPCODE"],
+
+["2147483648", "1ADD 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers", "UNKNOWN_ERROR"],
+["2147483648", "NEGATE 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers", "UNKNOWN_ERROR"],
+["-2147483648", "1ADD 1", "P2SH,STRICTENC", "Because we use a sign bit, -2147483648 is also 5 bytes", "UNKNOWN_ERROR"],
+["2147483647", "1ADD 1SUB 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers, even if the result is 4-bytes", "UNKNOWN_ERROR"],
+["2147483648", "1SUB 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers, even if the result is 4-bytes", "UNKNOWN_ERROR"],
+
+["2147483648 1", "BOOLOR 1", "P2SH,STRICTENC", "We cannot do BOOLOR on 5-byte integers (but we can still do IF etc)", "UNKNOWN_ERROR"],
+["2147483648 1", "BOOLAND 1", "P2SH,STRICTENC", "We cannot do BOOLAND on 5-byte integers", "UNKNOWN_ERROR"],
+
+["1", "1 ENDIF", "P2SH,STRICTENC", "ENDIF without IF", "UNBALANCED_CONDITIONAL"],
+["1", "IF 1", "P2SH,STRICTENC", "IF without ENDIF", "UNBALANCED_CONDITIONAL"],
+["1 IF 1", "ENDIF", "P2SH,STRICTENC", "IFs don't carry over", "UNBALANCED_CONDITIONAL"],
+
+["NOP", "IF 1 ENDIF", "P2SH,STRICTENC", "The following tests check the if(stack.size() < N) tests in each opcode", "UNBALANCED_CONDITIONAL"],
+["NOP", "NOTIF 1 ENDIF", "P2SH,STRICTENC", "They are here to catch copy-and-paste errors", "UNBALANCED_CONDITIONAL"],
+["NOP", "VERIFY 1", "P2SH,STRICTENC", "Most of them are duplicated elsewhere,", "INVALID_STACK_OPERATION"],
+
+["NOP", "TOALTSTACK 1", "P2SH,STRICTENC", "but, hey, more is always better, right?", "INVALID_STACK_OPERATION"],
+["1", "FROMALTSTACK", "P2SH,STRICTENC", "", "INVALID_ALTSTACK_OPERATION"],
+["1", "2DROP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "2DUP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1 1", "3DUP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1 1 1", "2OVER", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1 1 1 1 1", "2ROT", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1 1 1", "2SWAP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "IFDUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "DROP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "DUP 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "NIP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "OVER", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1 1 1 3", "PICK", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["0", "PICK 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1 1 1 3", "ROLL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["0", "ROLL 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1 1", "ROT", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "SWAP", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "TUCK", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+
+["NOP", "SIZE 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+
+["1", "EQUAL 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "EQUALVERIFY 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+
+["NOP", "1ADD 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "1SUB 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "NEGATE 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "ABS 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "NOT 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "0NOTEQUAL 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+
+["1", "ADD", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "SUB", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "BOOLAND", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "BOOLOR", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "NUMEQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "NUMEQUALVERIFY 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "NUMNOTEQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "LESSTHAN", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "GREATERTHAN", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "LESSTHANOREQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "GREATERTHANOREQUAL", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "MIN", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1", "MAX", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["1 1", "WITHIN", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+
+["NOP", "RIPEMD160 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "SHA1 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "SHA256 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "HASH160 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
+["NOP", "HASH256 1", "P2SH,STRICTENC", "", "INVALID_STACK_OPERATION"],
["Increase CHECKSIG and CHECKMULTISIG negative test coverage"],
-["", "CHECKSIG NOT", "STRICTENC", "CHECKSIG must error when there are no stack items"],
-["0", "CHECKSIG NOT", "STRICTENC", "CHECKSIG must error when there are not 2 stack items"],
-["", "CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are no stack items"],
-["", "-1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when the specified number of pubkeys is negative"],
-["", "1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are not enough pubkeys on the stack"],
-["", "-1 0 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when the specified number of signatures is negative"],
-["", "1 'pk1' 1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are not enough signatures on the stack"],
-["", "'dummy' 'sig1' 1 'pk1' 1 CHECKMULTISIG IF 1 ENDIF", "", "CHECKMULTISIG must push false to stack when signature is invalid when NOT in strict enc mode"],
+["", "CHECKSIG NOT", "STRICTENC", "CHECKSIG must error when there are no stack items", "INVALID_STACK_OPERATION"],
+["0", "CHECKSIG NOT", "STRICTENC", "CHECKSIG must error when there are not 2 stack items", "INVALID_STACK_OPERATION"],
+["", "CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are no stack items", "INVALID_STACK_OPERATION"],
+["", "-1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when the specified number of pubkeys is negative", "PUBKEY_COUNT"],
+["", "1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are not enough pubkeys on the stack", "INVALID_STACK_OPERATION"],
+["", "-1 0 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when the specified number of signatures is negative", "SIG_COUNT"],
+["", "1 'pk1' 1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are not enough signatures on the stack", "INVALID_STACK_OPERATION"],
+["", "'dummy' 'sig1' 1 'pk1' 1 CHECKMULTISIG IF 1 ENDIF", "", "CHECKMULTISIG must push false to stack when signature is invalid when NOT in strict enc mode","EVAL_FALSE"],
["",
"0 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG",
"P2SH,STRICTENC",
-"202 CHECKMULTISIGS, fails due to 201 op limit"],
+"202 CHECKMULTISIGS, fails due to 201 op limit",
+"OP_COUNT"],
["1",
"0 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY",
-"P2SH,STRICTENC"],
+"P2SH,STRICTENC",
+"",
+"INVALID_STACK_OPERATION"],
["",
"NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG",
"P2SH,STRICTENC",
-"Fails due to 201 sig op limit"],
+"Fails due to 201 sig op limit",
+"OP_COUNT"],
["1",
"NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY",
-"P2SH,STRICTENC"],
+"P2SH,STRICTENC",
+"",
+"OP_COUNT"],
-["0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21", "21 CHECKMULTISIG 1", "P2SH,STRICTENC", "nPubKeys > 20"],
-["0 'sig' 1 0", "CHECKMULTISIG 1", "P2SH,STRICTENC", "nSigs > nPubKeys"],
+["0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21", "21 CHECKMULTISIG 1", "P2SH,STRICTENC", "nPubKeys > 20", "PUBKEY_COUNT"],
+["0 'sig' 1 0", "CHECKMULTISIG 1", "P2SH,STRICTENC", "nSigs > nPubKeys", "SIG_COUNT"],
-["NOP 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "Tests for Script.IsPushOnly()"],
-["NOP1 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC"],
+["NOP 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "Tests for Script.IsPushOnly()", "SIG_PUSHONLY"],
+["NOP1 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "", "SIG_PUSHONLY"],
-["0 0x01 0x50", "HASH160 0x14 0xece424a6bb6ddf4db592c0faed60685047a361b1 EQUAL", "P2SH,STRICTENC", "OP_RESERVED in P2SH should fail"],
-["0 0x01 VER", "HASH160 0x14 0x0f4d7845db968f2a81b530b6f3c1d6246d4c7e01 EQUAL", "P2SH,STRICTENC", "OP_VER in P2SH should fail"],
+["0 0x01 0x50", "HASH160 0x14 0xece424a6bb6ddf4db592c0faed60685047a361b1 EQUAL", "P2SH,STRICTENC", "OP_RESERVED in P2SH should fail", "BAD_OPCODE"],
+["0 0x01 VER", "HASH160 0x14 0x0f4d7845db968f2a81b530b6f3c1d6246d4c7e01 EQUAL", "P2SH,STRICTENC", "OP_VER in P2SH should fail", "BAD_OPCODE"],
-["0x00", "'00' EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"],
+["0x00", "'00' EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution", "EVAL_FALSE"],
["MINIMALDATA enforcement for PUSHDATAs"],
-["0x4c 0x00", "DROP 1", "MINIMALDATA", "Empty vector minimally represented by OP_0"],
-["0x01 0x81", "DROP 1", "MINIMALDATA", "-1 minimally represented by OP_1NEGATE"],
-["0x01 0x01", "DROP 1", "MINIMALDATA", "1 to 16 minimally represented by OP_1 to OP_16"],
-["0x01 0x02", "DROP 1", "MINIMALDATA"],
-["0x01 0x03", "DROP 1", "MINIMALDATA"],
-["0x01 0x04", "DROP 1", "MINIMALDATA"],
-["0x01 0x05", "DROP 1", "MINIMALDATA"],
-["0x01 0x06", "DROP 1", "MINIMALDATA"],
-["0x01 0x07", "DROP 1", "MINIMALDATA"],
-["0x01 0x08", "DROP 1", "MINIMALDATA"],
-["0x01 0x09", "DROP 1", "MINIMALDATA"],
-["0x01 0x0a", "DROP 1", "MINIMALDATA"],
-["0x01 0x0b", "DROP 1", "MINIMALDATA"],
-["0x01 0x0c", "DROP 1", "MINIMALDATA"],
-["0x01 0x0d", "DROP 1", "MINIMALDATA"],
-["0x01 0x0e", "DROP 1", "MINIMALDATA"],
-["0x01 0x0f", "DROP 1", "MINIMALDATA"],
-["0x01 0x10", "DROP 1", "MINIMALDATA"],
+["0x4c 0x00", "DROP 1", "MINIMALDATA", "Empty vector minimally represented by OP_0", "MINIMALDATA"],
+["0x01 0x81", "DROP 1", "MINIMALDATA", "-1 minimally represented by OP_1NEGATE", "MINIMALDATA"],
+["0x01 0x01", "DROP 1", "MINIMALDATA", "1 to 16 minimally represented by OP_1 to OP_16", "MINIMALDATA"],
+["0x01 0x02", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"],
+["0x01 0x03", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"],
+["0x01 0x04", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"],
+["0x01 0x05", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"],
+["0x01 0x06", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"],
+["0x01 0x07", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"],
+["0x01 0x08", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"],
+["0x01 0x09", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"],
+["0x01 0x0a", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"],
+["0x01 0x0b", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"],
+["0x01 0x0c", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"],
+["0x01 0x0d", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"],
+["0x01 0x0e", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"],
+["0x01 0x0f", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"],
+["0x01 0x10", "DROP 1", "MINIMALDATA", "", "MINIMALDATA"],
["0x4c 0x48 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA",
- "PUSHDATA1 of 72 bytes minimally represented by direct push"],
+ "PUSHDATA1 of 72 bytes minimally represented by direct push",
+ "MINIMALDATA"],
["0x4d 0xFF00 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA",
- "PUSHDATA2 of 255 bytes minimally represented by PUSHDATA1"],
+ "PUSHDATA2 of 255 bytes minimally represented by PUSHDATA1",
+ "MINIMALDATA"],
["0x4e 0x00010000 0x11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA",
- "PUSHDATA4 of 256 bytes minimally represented by PUSHDATA2"],
-
+ "PUSHDATA4 of 256 bytes minimally represented by PUSHDATA2",
+ "MINIMALDATA"],
["MINIMALDATA enforcement for numeric arguments"],
-["0x01 0x00", "NOT DROP 1", "MINIMALDATA", "numequals 0"],
-["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "numequals 0"],
-["0x01 0x80", "NOT DROP 1", "MINIMALDATA", "0x80 (negative zero) numequals 0"],
-["0x02 0x0080", "NOT DROP 1", "MINIMALDATA", "numequals 0"],
-["0x02 0x0500", "NOT DROP 1", "MINIMALDATA", "numequals 5"],
-["0x03 0x050000", "NOT DROP 1", "MINIMALDATA", "numequals 5"],
-["0x02 0x0580", "NOT DROP 1", "MINIMALDATA", "numequals -5"],
-["0x03 0x050080", "NOT DROP 1", "MINIMALDATA", "numequals -5"],
-["0x03 0xff7f80", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffff"],
-["0x03 0xff7f00", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xff7f"],
-["0x04 0xffff7f80", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffffff"],
-["0x04 0xffff7f00", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffff7f"],
+["0x01 0x00", "NOT DROP 1", "MINIMALDATA", "numequals 0", "UNKNOWN_ERROR"],
+["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "numequals 0", "UNKNOWN_ERROR"],
+["0x01 0x80", "NOT DROP 1", "MINIMALDATA", "0x80 (negative zero) numequals 0", "UNKNOWN_ERROR"],
+["0x02 0x0080", "NOT DROP 1", "MINIMALDATA", "numequals 0", "UNKNOWN_ERROR"],
+["0x02 0x0500", "NOT DROP 1", "MINIMALDATA", "numequals 5", "UNKNOWN_ERROR"],
+["0x03 0x050000", "NOT DROP 1", "MINIMALDATA", "numequals 5", "UNKNOWN_ERROR"],
+["0x02 0x0580", "NOT DROP 1", "MINIMALDATA", "numequals -5", "UNKNOWN_ERROR"],
+["0x03 0x050080", "NOT DROP 1", "MINIMALDATA", "numequals -5", "UNKNOWN_ERROR"],
+["0x03 0xff7f80", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffff", "UNKNOWN_ERROR"],
+["0x03 0xff7f00", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xff7f", "UNKNOWN_ERROR"],
+["0x04 0xffff7f80", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffffff", "UNKNOWN_ERROR"],
+["0x04 0xffff7f00", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffff7f", "UNKNOWN_ERROR"],
["Test every numeric-accepting opcode for correct handling of the numeric minimal encoding rule"],
-["1 0x02 0x0000", "PICK DROP", "MINIMALDATA"],
-["1 0x02 0x0000", "ROLL DROP 1", "MINIMALDATA"],
-["0x02 0x0000", "1ADD DROP 1", "MINIMALDATA"],
-["0x02 0x0000", "1SUB DROP 1", "MINIMALDATA"],
-["0x02 0x0000", "NEGATE DROP 1", "MINIMALDATA"],
-["0x02 0x0000", "ABS DROP 1", "MINIMALDATA"],
-["0x02 0x0000", "NOT DROP 1", "MINIMALDATA"],
-["0x02 0x0000", "0NOTEQUAL DROP 1", "MINIMALDATA"],
-
-["0 0x02 0x0000", "ADD DROP 1", "MINIMALDATA"],
-["0x02 0x0000 0", "ADD DROP 1", "MINIMALDATA"],
-["0 0x02 0x0000", "SUB DROP 1", "MINIMALDATA"],
-["0x02 0x0000 0", "SUB DROP 1", "MINIMALDATA"],
-["0 0x02 0x0000", "BOOLAND DROP 1", "MINIMALDATA"],
-["0x02 0x0000 0", "BOOLAND DROP 1", "MINIMALDATA"],
-["0 0x02 0x0000", "BOOLOR DROP 1", "MINIMALDATA"],
-["0x02 0x0000 0", "BOOLOR DROP 1", "MINIMALDATA"],
-["0 0x02 0x0000", "NUMEQUAL DROP 1", "MINIMALDATA"],
-["0x02 0x0000 1", "NUMEQUAL DROP 1", "MINIMALDATA"],
-["0 0x02 0x0000", "NUMEQUALVERIFY 1", "MINIMALDATA"],
-["0x02 0x0000 0", "NUMEQUALVERIFY 1", "MINIMALDATA"],
-["0 0x02 0x0000", "NUMNOTEQUAL DROP 1", "MINIMALDATA"],
-["0x02 0x0000 0", "NUMNOTEQUAL DROP 1", "MINIMALDATA"],
-["0 0x02 0x0000", "LESSTHAN DROP 1", "MINIMALDATA"],
-["0x02 0x0000 0", "LESSTHAN DROP 1", "MINIMALDATA"],
-["0 0x02 0x0000", "GREATERTHAN DROP 1", "MINIMALDATA"],
-["0x02 0x0000 0", "GREATERTHAN DROP 1", "MINIMALDATA"],
-["0 0x02 0x0000", "LESSTHANOREQUAL DROP 1", "MINIMALDATA"],
-["0x02 0x0000 0", "LESSTHANOREQUAL DROP 1", "MINIMALDATA"],
-["0 0x02 0x0000", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA"],
-["0x02 0x0000 0", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA"],
-["0 0x02 0x0000", "MIN DROP 1", "MINIMALDATA"],
-["0x02 0x0000 0", "MIN DROP 1", "MINIMALDATA"],
-["0 0x02 0x0000", "MAX DROP 1", "MINIMALDATA"],
-["0x02 0x0000 0", "MAX DROP 1", "MINIMALDATA"],
-
-["0x02 0x0000 0 0", "WITHIN DROP 1", "MINIMALDATA"],
-["0 0x02 0x0000 0", "WITHIN DROP 1", "MINIMALDATA"],
-["0 0 0x02 0x0000", "WITHIN DROP 1", "MINIMALDATA"],
-
-["0 0 0x02 0x0000", "CHECKMULTISIG DROP 1", "MINIMALDATA"],
-["0 0x02 0x0000 0", "CHECKMULTISIG DROP 1", "MINIMALDATA"],
-["0 0x02 0x0000 0 1", "CHECKMULTISIG DROP 1", "MINIMALDATA"],
-["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", "MINIMALDATA"],
-["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", "MINIMALDATA"],
+["1 0x02 0x0000", "PICK DROP", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["1 0x02 0x0000", "ROLL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000", "1ADD DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000", "1SUB DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000", "NEGATE DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000", "ABS DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000", "0NOTEQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+
+["0 0x02 0x0000", "ADD DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000 0", "ADD DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0x02 0x0000", "SUB DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000 0", "SUB DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0x02 0x0000", "BOOLAND DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000 0", "BOOLAND DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0x02 0x0000", "BOOLOR DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000 0", "BOOLOR DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0x02 0x0000", "NUMEQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000 1", "NUMEQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0x02 0x0000", "NUMEQUALVERIFY 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000 0", "NUMEQUALVERIFY 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0x02 0x0000", "NUMNOTEQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000 0", "NUMNOTEQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0x02 0x0000", "LESSTHAN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000 0", "LESSTHAN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0x02 0x0000", "GREATERTHAN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000 0", "GREATERTHAN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0x02 0x0000", "LESSTHANOREQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000 0", "LESSTHANOREQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0x02 0x0000", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000 0", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0x02 0x0000", "MIN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000 0", "MIN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0x02 0x0000", "MAX DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0x02 0x0000 0", "MAX DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+
+["0x02 0x0000 0 0", "WITHIN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0x02 0x0000 0", "WITHIN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0 0x02 0x0000", "WITHIN DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+
+["0 0 0x02 0x0000", "CHECKMULTISIG DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0x02 0x0000 0", "CHECKMULTISIG DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0x02 0x0000 0 1", "CHECKMULTISIG DROP 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
+["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", "MINIMALDATA", "", "UNKNOWN_ERROR"],
["Order of CHECKMULTISIG evaluation tests, inverted by swapping the order of"],
@@ -513,301 +528,349 @@
"0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501",
"2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0 2 CHECKMULTISIG NOT",
"STRICTENC",
- "2-of-2 CHECKMULTISIG NOT with the first pubkey invalid, and both signatures validly encoded."
+ "2-of-2 CHECKMULTISIG NOT with the first pubkey invalid, and both signatures validly encoded.",
+ "PUBKEYTYPE"
],
[
"0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 1",
"2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT",
"STRICTENC",
- "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but first signature invalid."
+ "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but first signature invalid.",
+ "SIG_DER"
+],
+[
+ "0 0x47 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f01 0x46 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f",
+ "2 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 3 CHECKMULTISIG",
+ "P2SH,STRICTENC",
+ "2-of-3 with one valid and one invalid signature due to parse error, nSigs > validSigs",
+ "SIG_DER"
],
["Increase DERSIG test coverage"],
-["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Overly long signature is incorrectly encoded for DERSIG"],
-["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Missing S is incorrectly encoded for DERSIG"],
-["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "S with invalid S length is incorrectly encoded for DERSIG"],
-["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer R is incorrectly encoded for DERSIG"],
-["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer S is incorrectly encoded for DERSIG"],
-["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Zero-length R is incorrectly encoded for DERSIG"],
-["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "Zero-length S is incorrectly encoded for DERSIG"],
-["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Negative S is incorrectly encoded for DERSIG"],
+["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Overly long signature is incorrectly encoded for DERSIG", "SIG_DER"],
+["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Missing S is incorrectly encoded for DERSIG", "SIG_DER"],
+["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "S with invalid S length is incorrectly encoded for DERSIG", "SIG_DER"],
+["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer R is incorrectly encoded for DERSIG", "SIG_DER"],
+["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer S is incorrectly encoded for DERSIG", "SIG_DER"],
+["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Zero-length R is incorrectly encoded for DERSIG", "SIG_DER"],
+["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "Zero-length S is incorrectly encoded for DERSIG", "SIG_DER"],
+["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Negative S is incorrectly encoded for DERSIG", "SIG_DER"],
["Automatically generated test cases"],
[
"0x47 0x304402200a5c6163f07b8c3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001",
"0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
"",
- "P2PK, bad sig"
+ "P2PK, bad sig",
+ "EVAL_FALSE"
],
[
"0x47 0x3044022034bb0494b50b8ef130e2185bb220265b9284ef5b4b8a8da4d8415df489c83b5102206259a26d9cc0a125ac26af6153b17c02956855ebe1467412f066e402f5f05d1201 0x21 0x03363d90d446b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640",
"DUP HASH160 0x14 0xc0834c0c158f53be706d234c38fd52de7eece656 EQUALVERIFY CHECKSIG",
"",
- "P2PKH, bad pubkey"
+ "P2PKH, bad pubkey",
+ "EQUALVERIFY"
],
[
"0x47 0x304402204710a85181663b32d25c70ec2bbd14adff5ddfff6cb50d09e155ef5f541fc86c0220056b0cc949be9386ecc5f6c2ac0493269031dbb185781db90171b54ac127790201",
"0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG",
"",
- "P2PK anyonecanpay marked with normal hashtype"
+ "P2PK anyonecanpay marked with normal hashtype",
+ "EVAL_FALSE"
],
[
"0x47 0x3044022003fef42ed6c7be8917441218f525a60e2431be978e28b7aca4d7a532cc413ae8022067a1f82c74e8d69291b90d148778405c6257bbcfc2353cc38a3e1f22bf44254601 0x23 0x210279be667ef9dcbbac54a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac",
"HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL",
"P2SH",
- "P2SH(P2PK), bad redeemscript"
+ "P2SH(P2PK), bad redeemscript",
+ "EVAL_FALSE"
],
[
"0x47 0x304402204e2eb034be7b089534ac9e798cf6a2c79f38bcb34d1b179efd6f2de0841735db022071461beb056b5a7be1819da6a3e3ce3662831ecc298419ca101eb6887b5dd6a401 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac",
"HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL",
"P2SH",
- "P2SH(P2PKH), bad sig"
+ "P2SH(P2PKH), bad sig",
+ "EQUALVERIFY"
],
[
"0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0",
"3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG",
"",
- "3-of-3, 2 sigs"
+ "3-of-3, 2 sigs",
+ "EVAL_FALSE"
],
[
"0 0x47 0x304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001 0 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae",
"HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL",
"P2SH",
- "P2SH(2-of-3), 1 sig"
+ "P2SH(2-of-3), 1 sig",
+ "EVAL_FALSE"
],
[
"0x47 0x304402200060558477337b9022e70534f1fea71a318caf836812465a2509931c5e7c4987022078ec32bd50ac9e03a349ba953dfd9fe1c8d2dd8bdb1d38ddca844d3d5c78c11801",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
"DERSIG",
- "P2PK with too much R padding"
+ "P2PK with too much R padding",
+ "SIG_DER"
],
[
"0x48 0x304502202de8c03fc525285c9c535631019a5f2af7c6454fa9eb392a3756a4917c420edd02210046130bf2baf7cfc065067c8b9e33a066d9c15edcea9feb0ca2d233e3597925b401",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
"DERSIG",
- "P2PK with too much S padding"
+ "P2PK with too much S padding",
+ "SIG_DER"
],
[
"0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
"DERSIG",
- "P2PK with too little R padding"
+ "P2PK with too little R padding",
+ "SIG_DER"
],
[
"0x47 0x30440220005ece1335e7f757a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT",
"DERSIG",
- "P2PK NOT with bad sig with too much R padding"
+ "P2PK NOT with bad sig with too much R padding",
+ "SIG_DER"
],
[
"0x47 0x30440220005ece1335e7f657a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT",
"",
- "P2PK NOT with too much R padding but no DERSIG"
+ "P2PK NOT with too much R padding but no DERSIG",
+ "EVAL_FALSE"
],
[
"0x47 0x30440220005ece1335e7f657a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT",
"DERSIG",
- "P2PK NOT with too much R padding"
+ "P2PK NOT with too much R padding",
+ "SIG_DER"
],
[
"0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
"DERSIG",
- "BIP66 example 1, with DERSIG"
+ "BIP66 example 1, with DERSIG",
+ "SIG_DER"
],
[
"0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
"",
- "BIP66 example 2, without DERSIG"
+ "BIP66 example 2, without DERSIG",
+ "EVAL_FALSE"
],
[
"0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
"DERSIG",
- "BIP66 example 2, with DERSIG"
+ "BIP66 example 2, with DERSIG",
+ "SIG_DER"
],
[
"0",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
"",
- "BIP66 example 3, without DERSIG"
+ "BIP66 example 3, without DERSIG",
+ "EVAL_FALSE"
],
[
"0",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
"DERSIG",
- "BIP66 example 3, with DERSIG"
+ "BIP66 example 3, with DERSIG",
+ "EVAL_FALSE"
],
[
"1",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
"",
- "BIP66 example 5, without DERSIG"
+ "BIP66 example 5, without DERSIG",
+ "EVAL_FALSE"
],
[
"1",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
"DERSIG",
- "BIP66 example 5, with DERSIG"
+ "BIP66 example 5, with DERSIG",
+ "SIG_DER"
],
[
"1",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
"DERSIG",
- "BIP66 example 6, with DERSIG"
+ "BIP66 example 6, with DERSIG",
+ "SIG_DER"
],
[
"0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x3044022027c2714269ca5aeecc4d70edc88ba5ee0e3da4986e9216028f489ab4f1b8efce022022bd545b4951215267e4c5ceabd4c5350331b2e4a0b6494c56f361fa5a57a1a201",
"2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
"DERSIG",
- "BIP66 example 7, with DERSIG"
+ "BIP66 example 7, with DERSIG",
+ "SIG_DER"
],
[
"0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801",
"2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
"",
- "BIP66 example 8, without DERSIG"
+ "BIP66 example 8, without DERSIG",
+ "EVAL_FALSE"
],
[
"0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801",
"2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
"DERSIG",
- "BIP66 example 8, with DERSIG"
+ "BIP66 example 8, with DERSIG",
+ "SIG_DER"
],
[
"0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01",
"2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
"",
- "BIP66 example 9, without DERSIG"
+ "BIP66 example 9, without DERSIG",
+ "EVAL_FALSE"
],
[
"0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01",
"2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
"DERSIG",
- "BIP66 example 9, with DERSIG"
+ "BIP66 example 9, with DERSIG",
+ "SIG_DER"
],
[
"0 0 0x47 0x30440220da6f441dc3b4b2c84cfa8db0cd5b34ed92c9e01686de5a800d40498b70c0dcac02207c2cf91b0c32b860c4cd4994be36cfb84caf8bb7c3a8e4d96a31b2022c5299c501",
"2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
"DERSIG",
- "BIP66 example 10, with DERSIG"
+ "BIP66 example 10, with DERSIG",
+ "SIG_DER"
],
[
"0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0",
"2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
"",
- "BIP66 example 11, without DERSIG"
+ "BIP66 example 11, without DERSIG",
+ "EVAL_FALSE"
],
[
"0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0",
"2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
"DERSIG",
- "BIP66 example 11, with DERSIG"
+ "BIP66 example 11, with DERSIG",
+ "EVAL_FALSE"
],
[
"0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
"DERSIG",
- "P2PK with multi-byte hashtype, with DERSIG"
+ "P2PK with multi-byte hashtype, with DERSIG",
+ "SIG_DER"
],
[
"0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
"LOW_S",
- "P2PK with high S"
+ "P2PK with high S",
+ "SIG_HIGH_S"
],
[
"0x47 0x3044022057292e2d4dfe775becdd0a9e6547997c728cdf35390f6a017da56d654d374e4902206b643be2fc53763b4e284845bfea2c597d2dc7759941dce937636c9d341b71ed01",
"0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
"STRICTENC",
- "P2PK with hybrid pubkey"
+ "P2PK with hybrid pubkey",
+ "PUBKEYTYPE"
],
[
"0x47 0x30440220035d554e3153c14950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101",
"0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT",
"",
- "P2PK NOT with hybrid pubkey but no STRICTENC"
+ "P2PK NOT with hybrid pubkey but no STRICTENC",
+ "EVAL_FALSE"
],
[
"0x47 0x30440220035d554e3153c14950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101",
"0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT",
"STRICTENC",
- "P2PK NOT with hybrid pubkey"
+ "P2PK NOT with hybrid pubkey",
+ "PUBKEYTYPE"
],
[
"0x47 0x30440220035d554e3153c04950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101",
"0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT",
"STRICTENC",
- "P2PK NOT with invalid hybrid pubkey"
+ "P2PK NOT with invalid hybrid pubkey",
+ "PUBKEYTYPE"
],
[
"0 0x47 0x3044022079c7824d6c868e0e1a273484e28c2654a27d043c8a27f49f52cb72efed0759090220452bbbf7089574fa082095a4fc1b3a16bafcf97a3a34d745fafc922cce66b27201",
"1 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 2 CHECKMULTISIG",
"STRICTENC",
- "1-of-2 with the first 1 hybrid pubkey"
+ "1-of-2 with the first 1 hybrid pubkey",
+ "PUBKEYTYPE"
],
[
"0x47 0x304402206177d513ec2cda444c021a1f4f656fc4c72ba108ae063e157eb86dc3575784940220666fc66702815d0e5413bb9b1df22aed44f5f1efb8b99d41dd5dc9a5be6d205205",
"0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG",
"STRICTENC",
- "P2PK with undefined hashtype"
+ "P2PK with undefined hashtype",
+ "SIG_HASHTYPE"
],
[
"0x47 0x304402207409b5b320296e5e2136a7b281a7f803028ca4ca44e2b83eebd46932677725de02202d4eea1c8d3c98e6f42614f54764e6e5e6542e213eb4d079737e9a8b6e9812ec05",
"0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG NOT",
"STRICTENC",
- "P2PK NOT with invalid sig and undefined hashtype"
+ "P2PK NOT with invalid sig and undefined hashtype",
+ "SIG_HASHTYPE"
],
[
"1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901",
"3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG",
"NULLDUMMY",
- "3-of-3 with nonzero dummy"
+ "3-of-3 with nonzero dummy",
+ "SIG_NULLDUMMY"
],
[
"1 0x47 0x304402201bb2edab700a5d020236df174fefed78087697143731f659bea59642c759c16d022061f42cdbae5bcd3e8790f20bf76687443436e94a634321c16a72aa54cbc7c2ea01 0x47 0x304402204bb4a64f2a6e5c7fb2f07fef85ee56fde5e6da234c6a984262307a20e99842d702206f8303aaba5e625d223897e2ffd3f88ef1bcffef55f38dc3768e5f2e94c923f901 0x47 0x3044022040c2809b71fffb155ec8b82fe7a27f666bd97f941207be4e14ade85a1249dd4d02204d56c85ec525dd18e29a0533d5ddf61b6b1bb32980c2f63edf951aebf7a27bfe01",
"3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT",
"NULLDUMMY",
- "3-of-3 NOT with invalid sig with nonzero dummy"
+ "3-of-3 NOT with invalid sig with nonzero dummy",
+ "SIG_NULLDUMMY"
],
[
"0 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901 DUP",
"2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG",
"SIGPUSHONLY",
- "2-of-2 with two identical keys and sigs pushed using OP_DUP"
+ "2-of-2 with two identical keys and sigs pushed using OP_DUP",
+ "SIG_PUSHONLY"
],
[
"0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
"",
- "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY"
+ "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY",
+ "EVAL_FALSE"
],
[
"0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
"SIGPUSHONLY",
- "P2SH(P2PK) with non-push scriptSig"
-],
-[
- "0 0x47 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f01 0x46 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f",
- "2 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 3 CHECKMULTISIG",
- "P2SH,STRICTENC",
- "2-of-3 with one valid and one invalid signature due to parse error, nSigs > validSigs"
+ "P2SH(P2PK) with non-push scriptSig",
+ "EVAL_FALSE"
],
[
"11 0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001",
"0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
"CLEANSTACK,P2SH",
- "P2PK with unnecessary input"
+ "P2PK with unnecessary input",
+ "CLEANSTACK"
],
[
"11 0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
"HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL",
"CLEANSTACK,P2SH",
- "P2SH with unnecessary input"
+ "P2SH with unnecessary input",
+ "CLEANSTACK"
],
["The End"]
diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp
index 1347d23656..fa352ace8f 100644
--- a/src/test/mempool_tests.cpp
+++ b/src/test/mempool_tests.cpp
@@ -102,13 +102,13 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest)
removed.clear();
}
-template<int index>
+template<typename name>
void CheckSort(CTxMemPool &pool, std::vector<std::string> &sortedOrder)
{
BOOST_CHECK_EQUAL(pool.size(), sortedOrder.size());
- typename CTxMemPool::indexed_transaction_set::nth_index<index>::type::iterator it = pool.mapTx.get<index>().begin();
+ typename CTxMemPool::indexed_transaction_set::index<name>::type::iterator it = pool.mapTx.get<name>().begin();
int count=0;
- for (; it != pool.mapTx.get<index>().end(); ++it, ++count) {
+ for (; it != pool.mapTx.get<name>().end(); ++it, ++count) {
BOOST_CHECK_EQUAL(it->GetTx().GetHash().ToString(), sortedOrder[count]);
}
}
@@ -164,7 +164,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
sortedOrder[2] = tx1.GetHash().ToString(); // 10000
sortedOrder[3] = tx4.GetHash().ToString(); // 15000
sortedOrder[4] = tx2.GetHash().ToString(); // 20000
- CheckSort<1>(pool, sortedOrder);
+ CheckSort<descendant_score>(pool, sortedOrder);
/* low fee but with high fee child */
/* tx6 -> tx7 -> tx8, tx9 -> tx10 */
@@ -176,7 +176,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
BOOST_CHECK_EQUAL(pool.size(), 6);
// Check that at this point, tx6 is sorted low
sortedOrder.insert(sortedOrder.begin(), tx6.GetHash().ToString());
- CheckSort<1>(pool, sortedOrder);
+ CheckSort<descendant_score>(pool, sortedOrder);
CTxMemPool::setEntries setAncestors;
setAncestors.insert(pool.mapTx.find(tx6.GetHash()));
@@ -202,7 +202,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
sortedOrder.erase(sortedOrder.begin());
sortedOrder.push_back(tx6.GetHash().ToString());
sortedOrder.push_back(tx7.GetHash().ToString());
- CheckSort<1>(pool, sortedOrder);
+ CheckSort<descendant_score>(pool, sortedOrder);
/* low fee child of tx7 */
CMutableTransaction tx8 = CMutableTransaction();
@@ -217,7 +217,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
// Now tx8 should be sorted low, but tx6/tx both high
sortedOrder.insert(sortedOrder.begin(), tx8.GetHash().ToString());
- CheckSort<1>(pool, sortedOrder);
+ CheckSort<descendant_score>(pool, sortedOrder);
/* low fee child of tx7 */
CMutableTransaction tx9 = CMutableTransaction();
@@ -232,7 +232,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
// tx9 should be sorted low
BOOST_CHECK_EQUAL(pool.size(), 9);
sortedOrder.insert(sortedOrder.begin(), tx9.GetHash().ToString());
- CheckSort<1>(pool, sortedOrder);
+ CheckSort<descendant_score>(pool, sortedOrder);
std::vector<std::string> snapshotOrder = sortedOrder;
@@ -274,7 +274,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
sortedOrder.insert(sortedOrder.begin()+5, tx9.GetHash().ToString());
sortedOrder.insert(sortedOrder.begin()+6, tx8.GetHash().ToString());
sortedOrder.insert(sortedOrder.begin()+7, tx10.GetHash().ToString()); // tx10 is just before tx6
- CheckSort<1>(pool, sortedOrder);
+ CheckSort<descendant_score>(pool, sortedOrder);
// there should be 10 transactions in the mempool
BOOST_CHECK_EQUAL(pool.size(), 10);
@@ -282,7 +282,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
// Now try removing tx10 and verify the sort order returns to normal
std::list<CTransaction> removed;
pool.remove(pool.mapTx.find(tx10.GetHash())->GetTx(), removed, true);
- CheckSort<1>(pool, snapshotOrder);
+ CheckSort<descendant_score>(pool, snapshotOrder);
pool.remove(pool.mapTx.find(tx9.GetHash())->GetTx(), removed, true);
pool.remove(pool.mapTx.find(tx8.GetHash())->GetTx(), removed, true);
@@ -314,7 +314,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
sortedOrder.push_back(tx3.GetHash().ToString());
sortedOrder.push_back(tx6.GetHash().ToString());
}
- CheckSort<3>(pool, sortedOrder);
+ CheckSort<mining_score>(pool, sortedOrder);
}
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index f370a4aa2a..30e3f37e14 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -52,6 +52,64 @@ read_json(const std::string& jsondata)
return v.get_array();
}
+struct ScriptErrorDesc
+{
+ ScriptError_t err;
+ const char *name;
+};
+
+static ScriptErrorDesc script_errors[]={
+ {SCRIPT_ERR_OK, "OK"},
+ {SCRIPT_ERR_UNKNOWN_ERROR, "UNKNOWN_ERROR"},
+ {SCRIPT_ERR_EVAL_FALSE, "EVAL_FALSE"},
+ {SCRIPT_ERR_OP_RETURN, "OP_RETURN"},
+ {SCRIPT_ERR_SCRIPT_SIZE, "SCRIPT_SIZE"},
+ {SCRIPT_ERR_PUSH_SIZE, "PUSH_SIZE"},
+ {SCRIPT_ERR_OP_COUNT, "OP_COUNT"},
+ {SCRIPT_ERR_STACK_SIZE, "STACK_SIZE"},
+ {SCRIPT_ERR_SIG_COUNT, "SIG_COUNT"},
+ {SCRIPT_ERR_PUBKEY_COUNT, "PUBKEY_COUNT"},
+ {SCRIPT_ERR_VERIFY, "VERIFY"},
+ {SCRIPT_ERR_EQUALVERIFY, "EQUALVERIFY"},
+ {SCRIPT_ERR_CHECKMULTISIGVERIFY, "CHECKMULTISIGVERIFY"},
+ {SCRIPT_ERR_CHECKSIGVERIFY, "CHECKSIGVERIFY"},
+ {SCRIPT_ERR_NUMEQUALVERIFY, "NUMEQUALVERIFY"},
+ {SCRIPT_ERR_BAD_OPCODE, "BAD_OPCODE"},
+ {SCRIPT_ERR_DISABLED_OPCODE, "DISABLED_OPCODE"},
+ {SCRIPT_ERR_INVALID_STACK_OPERATION, "INVALID_STACK_OPERATION"},
+ {SCRIPT_ERR_INVALID_ALTSTACK_OPERATION, "INVALID_ALTSTACK_OPERATION"},
+ {SCRIPT_ERR_UNBALANCED_CONDITIONAL, "UNBALANCED_CONDITIONAL"},
+ {SCRIPT_ERR_NEGATIVE_LOCKTIME, "NEGATIVE_LOCKTIME"},
+ {SCRIPT_ERR_UNSATISFIED_LOCKTIME, "UNSATISFIED_LOCKTIME"},
+ {SCRIPT_ERR_SIG_HASHTYPE, "SIG_HASHTYPE"},
+ {SCRIPT_ERR_SIG_DER, "SIG_DER"},
+ {SCRIPT_ERR_MINIMALDATA, "MINIMALDATA"},
+ {SCRIPT_ERR_SIG_PUSHONLY, "SIG_PUSHONLY"},
+ {SCRIPT_ERR_SIG_HIGH_S, "SIG_HIGH_S"},
+ {SCRIPT_ERR_SIG_NULLDUMMY, "SIG_NULLDUMMY"},
+ {SCRIPT_ERR_PUBKEYTYPE, "PUBKEYTYPE"},
+ {SCRIPT_ERR_CLEANSTACK, "CLEANSTACK"},
+ {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, "DISCOURAGE_UPGRADABLE_NOPS"}
+};
+
+const char *FormatScriptError(ScriptError_t err)
+{
+ for (unsigned int i=0; i<ARRAYLEN(script_errors); ++i)
+ if (script_errors[i].err == err)
+ return script_errors[i].name;
+ BOOST_ERROR("Unknown scripterror enumeration value, update script_errors in script_tests.cpp.");
+ return "";
+}
+
+ScriptError_t ParseScriptError(const std::string &name)
+{
+ for (unsigned int i=0; i<ARRAYLEN(script_errors); ++i)
+ if (script_errors[i].name == name)
+ return script_errors[i].err;
+ BOOST_ERROR("Unknown scripterror \"" << name << "\" in test description");
+ return SCRIPT_ERR_UNKNOWN_ERROR;
+}
+
BOOST_FIXTURE_TEST_SUITE(script_tests, BasicTestingSetup)
CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey)
@@ -87,13 +145,13 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMu
return txSpend;
}
-void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bool expect, const std::string& message)
+void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bool expect, const std::string& message, int scriptError)
{
ScriptError err;
CMutableTransaction tx = BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey));
CMutableTransaction tx2 = tx;
BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, MutableTransactionSignatureChecker(&tx, 0), &err) == expect, message);
- BOOST_CHECK_MESSAGE(expect == (err == SCRIPT_ERR_OK), std::string(ScriptErrorString(err)) + ": " + message);
+ BOOST_CHECK_MESSAGE(scriptError == -1 || 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;
@@ -187,6 +245,7 @@ private:
std::vector<unsigned char> push;
std::string comment;
int flags;
+ int scriptError;
void DoPush()
{
@@ -204,7 +263,7 @@ private:
}
public:
- TestBuilder(const CScript& redeemScript, const std::string& comment_, int flags_, bool P2SH = false) : scriptPubKey(redeemScript), havePush(false), comment(comment_), flags(flags_)
+ TestBuilder(const CScript& redeemScript, const std::string& comment_, int flags_, bool P2SH = false) : scriptPubKey(redeemScript), havePush(false), comment(comment_), flags(flags_), scriptError(-1)
{
if (P2SH) {
creditTx = BuildCreditingTransaction(CScript() << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL);
@@ -214,6 +273,12 @@ public:
spendTx = BuildSpendingTransaction(CScript(), creditTx);
}
+ TestBuilder& ScriptError(ScriptError_t err)
+ {
+ scriptError = err;
+ return *this;
+ }
+
TestBuilder& Add(const CScript& script)
{
DoPush();
@@ -288,7 +353,7 @@ public:
{
TestBuilder copy = *this; // Make a copy so we can rollback the push.
DoPush();
- DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, flags, expect, comment);
+ DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, flags, expect, comment, expect ? SCRIPT_ERR_OK : scriptError);
*this = copy;
return *this;
}
@@ -301,6 +366,8 @@ public:
array.push_back(FormatScript(creditTx.vout[0].scriptPubKey));
array.push_back(FormatScriptFlags(flags));
array.push_back(comment);
+ if (scriptError != -1)
+ array.push_back(FormatScriptError((ScriptError_t)scriptError));
return array;
}
@@ -328,99 +395,99 @@ BOOST_AUTO_TEST_CASE(script_build)
).PushSig(keys.key0));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"P2PK, bad sig", 0
- ).PushSig(keys.key0).DamagePush(10));
+ ).PushSig(keys.key0).DamagePush(10).ScriptError(SCRIPT_ERR_EVAL_FALSE));
good.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1C.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
"P2PKH", 0
).PushSig(keys.key1).Push(keys.pubkey1C));
bad.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey2C.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
"P2PKH, bad pubkey", 0
- ).PushSig(keys.key2).Push(keys.pubkey2C).DamagePush(5));
+ ).PushSig(keys.key2).Push(keys.pubkey2C).DamagePush(5).ScriptError(SCRIPT_ERR_EQUALVERIFY));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
"P2PK anyonecanpay", 0
).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
"P2PK anyonecanpay marked with normal hashtype", 0
- ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY).EditPush(70, "81", "01"));
+ ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY).EditPush(70, "81", "01").ScriptError(SCRIPT_ERR_EVAL_FALSE));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
"P2SH(P2PK)", SCRIPT_VERIFY_P2SH, true
).PushSig(keys.key0).PushRedeem());
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
"P2SH(P2PK), bad redeemscript", SCRIPT_VERIFY_P2SH, true
- ).PushSig(keys.key0).PushRedeem().DamagePush(10));
+ ).PushSig(keys.key0).PushRedeem().DamagePush(10).ScriptError(SCRIPT_ERR_EVAL_FALSE));
good.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
"P2SH(P2PKH), bad sig but no VERIFY_P2SH", 0, true
).PushSig(keys.key0).DamagePush(10).PushRedeem());
bad.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
"P2SH(P2PKH), bad sig", SCRIPT_VERIFY_P2SH, true
- ).PushSig(keys.key0).DamagePush(10).PushRedeem());
+ ).PushSig(keys.key0).DamagePush(10).PushRedeem().ScriptError(SCRIPT_ERR_EQUALVERIFY));
good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
"3-of-3", 0
).Num(0).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
bad.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
"3-of-3, 2 sigs", 0
- ).Num(0).PushSig(keys.key0).PushSig(keys.key1).Num(0));
+ ).Num(0).PushSig(keys.key0).PushSig(keys.key1).Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE));
good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
"P2SH(2-of-3)", SCRIPT_VERIFY_P2SH, true
).Num(0).PushSig(keys.key1).PushSig(keys.key2).PushRedeem());
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
"P2SH(2-of-3), 1 sig", SCRIPT_VERIFY_P2SH, true
- ).Num(0).PushSig(keys.key1).Num(0).PushRedeem());
+ ).Num(0).PushSig(keys.key1).Num(0).PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"P2PK with too much R padding but no DERSIG", 0
).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000"));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"P2PK with too much R padding", SCRIPT_VERIFY_DERSIG
- ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000"));
+ ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").ScriptError(SCRIPT_ERR_SIG_DER));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"P2PK with too much S padding but no DERSIG", 0
).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100"));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"P2PK with too much S padding", SCRIPT_VERIFY_DERSIG
- ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100"));
+ ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100").ScriptError(SCRIPT_ERR_SIG_DER));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"P2PK with too little R padding but no DERSIG", 0
).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"P2PK with too little R padding", SCRIPT_VERIFY_DERSIG
- ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with bad sig with too much R padding but no DERSIG", 0
).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with bad sig with too much R padding", SCRIPT_VERIFY_DERSIG
- ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10));
+ ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10).ScriptError(SCRIPT_ERR_SIG_DER));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with too much R padding but no DERSIG", 0
- ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000"));
+ ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").ScriptError(SCRIPT_ERR_EVAL_FALSE));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with too much R padding", SCRIPT_VERIFY_DERSIG
- ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000"));
+ ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").ScriptError(SCRIPT_ERR_SIG_DER));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"BIP66 example 1, without DERSIG", 0
).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"BIP66 example 1, with DERSIG", SCRIPT_VERIFY_DERSIG
- ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
"BIP66 example 2, without DERSIG", 0
- ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_EVAL_FALSE));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
"BIP66 example 2, with DERSIG", SCRIPT_VERIFY_DERSIG
- ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"BIP66 example 3, without DERSIG", 0
- ).Num(0));
+ ).Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"BIP66 example 3, with DERSIG", SCRIPT_VERIFY_DERSIG
- ).Num(0));
+ ).Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
"BIP66 example 4, without DERSIG", 0
).Num(0));
@@ -429,46 +496,46 @@ BOOST_AUTO_TEST_CASE(script_build)
).Num(0));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"BIP66 example 5, without DERSIG", 0
- ).Num(1));
+ ).Num(1).ScriptError(SCRIPT_ERR_EVAL_FALSE));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"BIP66 example 5, with DERSIG", SCRIPT_VERIFY_DERSIG
- ).Num(1));
+ ).Num(1).ScriptError(SCRIPT_ERR_SIG_DER));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
"BIP66 example 6, without DERSIG", 0
).Num(1));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
"BIP66 example 6, with DERSIG", SCRIPT_VERIFY_DERSIG
- ).Num(1));
+ ).Num(1).ScriptError(SCRIPT_ERR_SIG_DER));
good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
"BIP66 example 7, without DERSIG", 0
).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
"BIP66 example 7, with DERSIG", SCRIPT_VERIFY_DERSIG
- ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2).ScriptError(SCRIPT_ERR_SIG_DER));
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
"BIP66 example 8, without DERSIG", 0
- ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2).ScriptError(SCRIPT_ERR_EVAL_FALSE));
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
"BIP66 example 8, with DERSIG", SCRIPT_VERIFY_DERSIG
- ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2).ScriptError(SCRIPT_ERR_SIG_DER));
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
"BIP66 example 9, without DERSIG", 0
- ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_EVAL_FALSE));
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
"BIP66 example 9, with DERSIG", SCRIPT_VERIFY_DERSIG
- ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER));
good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
"BIP66 example 10, without DERSIG", 0
).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
"BIP66 example 10, with DERSIG", SCRIPT_VERIFY_DERSIG
- ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER));
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
"BIP66 example 11, without DERSIG", 0
- ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE));
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
"BIP66 example 11, with DERSIG", SCRIPT_VERIFY_DERSIG
- ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE));
good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
"BIP66 example 12, without DERSIG", 0
).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
@@ -480,33 +547,33 @@ BOOST_AUTO_TEST_CASE(script_build)
).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101"));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
"P2PK with multi-byte hashtype, with DERSIG", SCRIPT_VERIFY_DERSIG
- ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101"));
+ ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101").ScriptError(SCRIPT_ERR_SIG_DER));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
"P2PK with high S but no LOW_S", 0
).PushSig(keys.key2, SIGHASH_ALL, 32, 33));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
"P2PK with high S", SCRIPT_VERIFY_LOW_S
- ).PushSig(keys.key2, SIGHASH_ALL, 32, 33));
+ ).PushSig(keys.key2, SIGHASH_ALL, 32, 33).ScriptError(SCRIPT_ERR_SIG_HIGH_S));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG,
"P2PK with hybrid pubkey but no STRICTENC", 0
).PushSig(keys.key0, SIGHASH_ALL));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG,
"P2PK with hybrid pubkey", SCRIPT_VERIFY_STRICTENC
- ).PushSig(keys.key0, SIGHASH_ALL));
+ ).PushSig(keys.key0, SIGHASH_ALL).ScriptError(SCRIPT_ERR_PUBKEYTYPE));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with hybrid pubkey but no STRICTENC", 0
- ).PushSig(keys.key0, SIGHASH_ALL));
+ ).PushSig(keys.key0, SIGHASH_ALL).ScriptError(SCRIPT_ERR_EVAL_FALSE));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with hybrid pubkey", SCRIPT_VERIFY_STRICTENC
- ).PushSig(keys.key0, SIGHASH_ALL));
+ ).PushSig(keys.key0, SIGHASH_ALL).ScriptError(SCRIPT_ERR_PUBKEYTYPE));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with invalid hybrid pubkey but no STRICTENC", 0
).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with invalid hybrid pubkey", SCRIPT_VERIFY_STRICTENC
- ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10));
+ ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10).ScriptError(SCRIPT_ERR_PUBKEYTYPE));
good.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
"1-of-2 with the second 1 hybrid pubkey and no STRICTENC", 0
).Num(0).PushSig(keys.key1, SIGHASH_ALL));
@@ -515,62 +582,61 @@ BOOST_AUTO_TEST_CASE(script_build)
).Num(0).PushSig(keys.key1, SIGHASH_ALL));
bad.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0H) << OP_2 << OP_CHECKMULTISIG,
"1-of-2 with the first 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC
- ).Num(0).PushSig(keys.key1, SIGHASH_ALL));
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL).ScriptError(SCRIPT_ERR_PUBKEYTYPE));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
"P2PK with undefined hashtype but no STRICTENC", 0
).PushSig(keys.key1, 5));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
"P2PK with undefined hashtype", SCRIPT_VERIFY_STRICTENC
- ).PushSig(keys.key1, 5));
+ ).PushSig(keys.key1, 5).ScriptError(SCRIPT_ERR_SIG_HASHTYPE));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with invalid sig and undefined hashtype but no STRICTENC", 0
).PushSig(keys.key1, 5).DamagePush(10));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with invalid sig and undefined hashtype", SCRIPT_VERIFY_STRICTENC
- ).PushSig(keys.key1, 5).DamagePush(10));
+ ).PushSig(keys.key1, 5).DamagePush(10).ScriptError(SCRIPT_ERR_SIG_HASHTYPE));
good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
"3-of-3 with nonzero dummy but no NULLDUMMY", 0
).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
bad.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
"3-of-3 with nonzero dummy", SCRIPT_VERIFY_NULLDUMMY
- ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
+ ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).ScriptError(SCRIPT_ERR_SIG_NULLDUMMY));
good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG << OP_NOT,
"3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY", 0
).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10));
bad.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG << OP_NOT,
"3-of-3 NOT with invalid sig with nonzero dummy", SCRIPT_VERIFY_NULLDUMMY
- ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10));
+ ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10).ScriptError(SCRIPT_ERR_SIG_NULLDUMMY));
good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
"2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY", 0
).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP));
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
"2-of-2 with two identical keys and sigs pushed using OP_DUP", SCRIPT_VERIFY_SIGPUSHONLY
- ).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP));
+ ).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP).ScriptError(SCRIPT_ERR_SIG_PUSHONLY));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
"P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY", 0
- ).PushSig(keys.key2).PushRedeem());
+ ).PushSig(keys.key2).PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
"P2SH(P2PK) with non-push scriptSig", SCRIPT_VERIFY_SIGPUSHONLY
- ).PushSig(keys.key2).PushRedeem());
+ ).PushSig(keys.key2).PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
"2-of-2 with two identical keys and sigs pushed", SCRIPT_VERIFY_SIGPUSHONLY
).Num(0).PushSig(keys.key1).PushSig(keys.key1));
-
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"P2PK with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH
).Num(11).PushSig(keys.key0));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"P2PK with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH
- ).Num(11).PushSig(keys.key0));
+ ).Num(11).PushSig(keys.key0).ScriptError(SCRIPT_ERR_CLEANSTACK));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"P2SH with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH, true
).Num(11).PushSig(keys.key0).PushRedeem());
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"P2SH with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true
- ).Num(11).PushSig(keys.key0).PushRedeem());
+ ).Num(11).PushSig(keys.key0).PushRedeem().ScriptError(SCRIPT_ERR_CLEANSTACK));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"P2SH with CLEANSTACK", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true
).PushSig(keys.key0).PushRedeem());
@@ -585,11 +651,11 @@ BOOST_AUTO_TEST_CASE(script_build)
for (unsigned int idx = 0; idx < json_good.size(); idx++) {
const UniValue& tv = json_good[idx];
- tests_good.insert(tv.get_array().write());
+ tests_good.insert(tv.get_array().write(1,4));
}
for (unsigned int idx = 0; idx < json_bad.size(); idx++) {
const UniValue& tv = json_bad[idx];
- tests_bad.insert(tv.get_array().write());
+ tests_bad.insert(tv.get_array().write(1,4));
}
}
@@ -598,7 +664,7 @@ BOOST_AUTO_TEST_CASE(script_build)
BOOST_FOREACH(TestBuilder& test, good) {
test.Test(true);
- std::string str = test.GetJSON().write();
+ std::string str = test.GetJSON().write(1,4);
#ifndef UPDATE_JSON_TESTS
if (tests_good.count(str) == 0) {
BOOST_CHECK_MESSAGE(false, "Missing auto script_valid test: " + test.GetComment());
@@ -608,7 +674,7 @@ BOOST_AUTO_TEST_CASE(script_build)
}
BOOST_FOREACH(TestBuilder& test, bad) {
test.Test(false);
- std::string str = test.GetJSON().write();
+ std::string str = test.GetJSON().write(1,4);
#ifndef UPDATE_JSON_TESTS
if (tests_bad.count(str) == 0) {
BOOST_CHECK_MESSAGE(false, "Missing auto script_invalid test: " + test.GetComment());
@@ -652,7 +718,7 @@ BOOST_AUTO_TEST_CASE(script_valid)
CScript scriptPubKey = ParseScript(scriptPubKeyString);
unsigned int scriptflags = ParseScriptFlags(test[2].get_str());
- DoTest(scriptPubKey, scriptSig, scriptflags, true, strTest);
+ DoTest(scriptPubKey, scriptSig, scriptflags, true, strTest, SCRIPT_ERR_OK);
}
}
@@ -660,7 +726,6 @@ BOOST_AUTO_TEST_CASE(script_invalid)
{
// Scripts that should evaluate as invalid
UniValue tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid)));
-
for (unsigned int idx = 0; idx < tests.size(); idx++) {
UniValue test = tests[idx];
string strTest = test.write();
@@ -676,8 +741,12 @@ BOOST_AUTO_TEST_CASE(script_invalid)
string scriptPubKeyString = test[1].get_str();
CScript scriptPubKey = ParseScript(scriptPubKeyString);
unsigned int scriptflags = ParseScriptFlags(test[2].get_str());
+ int scriptError = -1; // Expected script error is optional, and follows comment
+ if (test.size() >= 5 && test[4].get_str() != "") {
+ scriptError = ParseScriptError(test[4].get_str());
+ }
- DoTest(scriptPubKey, scriptSig, scriptflags, false, strTest);
+ DoTest(scriptPubKey, scriptSig, scriptflags, false, strTest, scriptError);
}
}
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index a272018cf1..dadc8b948f 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -17,12 +17,13 @@
#include "txdb.h"
#include "txmempool.h"
#include "ui_interface.h"
-#include "util.h"
#ifdef ENABLE_WALLET
#include "wallet/db.h"
#include "wallet/wallet.h"
#endif
+#include "test/testutil.h"
+
#include <boost/filesystem.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/thread.hpp>
diff --git a/src/test/testutil.cpp b/src/test/testutil.cpp
new file mode 100644
index 0000000000..304cffb798
--- /dev/null
+++ b/src/test/testutil.cpp
@@ -0,0 +1,33 @@
+// Copyright (c) 2009-2016 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 "testutil.h"
+
+#ifdef WIN32
+#include <shlobj.h>
+#endif
+
+#include <boost/filesystem.hpp>
+
+boost::filesystem::path GetTempPath() {
+#if BOOST_FILESYSTEM_VERSION == 3
+ return boost::filesystem::temp_directory_path();
+#else
+ // TODO: remove when we don't support filesystem v2 anymore
+ boost::filesystem::path path;
+#ifdef WIN32
+ char pszPath[MAX_PATH] = "";
+
+ if (GetTempPathA(MAX_PATH, pszPath))
+ path = boost::filesystem::path(pszPath);
+#else
+ path = boost::filesystem::path("/tmp");
+#endif
+ if (path.empty() || !boost::filesystem::is_directory(path)) {
+ LogPrintf("GetTempPath(): failed to find temp path\n");
+ return boost::filesystem::path("");
+ }
+ return path;
+#endif
+}
diff --git a/src/test/testutil.h b/src/test/testutil.h
new file mode 100644
index 0000000000..5875dc50e6
--- /dev/null
+++ b/src/test/testutil.h
@@ -0,0 +1,15 @@
+// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+/**
+ * Utility functions shared by unit tests
+ */
+#ifndef BITCOIN_TEST_TESTUTIL_H
+#define BITCOIN_TEST_TESTUTIL_H
+
+#include <boost/filesystem/path.hpp>
+
+boost::filesystem::path GetTempPath();
+
+#endif // BITCOIN_TEST_TESTUTIL_H
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index 43e8ae9b36..b99f952a0d 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -200,6 +200,8 @@ BOOST_AUTO_TEST_CASE(util_ParseMoney)
BOOST_CHECK_EQUAL(ret, COIN*10);
BOOST_CHECK(ParseMoney("1.00", ret));
BOOST_CHECK_EQUAL(ret, COIN);
+ BOOST_CHECK(ParseMoney("1", ret));
+ BOOST_CHECK_EQUAL(ret, COIN);
BOOST_CHECK(ParseMoney("0.1", ret));
BOOST_CHECK_EQUAL(ret, COIN/10);
BOOST_CHECK(ParseMoney("0.01", ret));
@@ -219,6 +221,9 @@ BOOST_AUTO_TEST_CASE(util_ParseMoney)
// Attempted 63 bit overflow should fail
BOOST_CHECK(!ParseMoney("92233720368.54775808", ret));
+
+ // Parsing negative amounts must fail
+ BOOST_CHECK(!ParseMoney("-1", ret));
}
BOOST_AUTO_TEST_CASE(util_IsHex)
diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp
index 10170dbcea..1c7bc2dbee 100644
--- a/src/torcontrol.cpp
+++ b/src/torcontrol.cpp
@@ -393,11 +393,14 @@ private:
static void reconnect_cb(evutil_socket_t fd, short what, void *arg);
};
-TorController::TorController(struct event_base* base, const std::string& target):
- base(base),
+TorController::TorController(struct event_base* baseIn, const std::string& target):
+ base(baseIn),
target(target), conn(base), reconnect(true), reconnect_ev(0),
reconnect_timeout(RECONNECT_TIMEOUT_START)
{
+ reconnect_ev = event_new(base, -1, 0, reconnect_cb, this);
+ if (!reconnect_ev)
+ LogPrintf("tor: Failed to create event for reconnection: out of memory?\n");
// Start connection attempts immediately
if (!conn.Connect(target, boost::bind(&TorController::connected_cb, this, _1),
boost::bind(&TorController::disconnected_cb, this, _1) )) {
@@ -413,8 +416,10 @@ TorController::TorController(struct event_base* base, const std::string& target)
TorController::~TorController()
{
- if (reconnect_ev)
- event_del(reconnect_ev);
+ if (reconnect_ev) {
+ event_free(reconnect_ev);
+ reconnect_ev = 0;
+ }
if (service.IsValid()) {
RemoveLocal(service);
}
@@ -459,7 +464,7 @@ void TorController::auth_cb(TorControlConnection& conn, const TorControlReply& r
if (GetArg("-onion", "") == "") {
proxyType addrOnion = proxyType(CService("127.0.0.1", 9050), true);
SetProxy(NET_TOR, addrOnion);
- SetReachable(NET_TOR);
+ SetLimited(NET_TOR, false);
}
// Finally - now create the service
@@ -626,8 +631,8 @@ void TorController::disconnected_cb(TorControlConnection& conn)
// Single-shot timer for reconnect. Use exponential backoff.
struct timeval time = MillisToTimeval(int64_t(reconnect_timeout * 1000.0));
- reconnect_ev = event_new(base, -1, 0, reconnect_cb, this);
- event_add(reconnect_ev, &time);
+ if (reconnect_ev)
+ event_add(reconnect_ev, &time);
reconnect_timeout *= RECONNECT_TIMEOUT_EXP;
}
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 5f814749b7..29c559d227 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -871,9 +871,9 @@ void CTxMemPool::RemoveStaged(setEntries &stage) {
int CTxMemPool::Expire(int64_t time) {
LOCK(cs);
- indexed_transaction_set::nth_index<2>::type::iterator it = mapTx.get<2>().begin();
+ indexed_transaction_set::index<entry_time>::type::iterator it = mapTx.get<entry_time>().begin();
setEntries toremove;
- while (it != mapTx.get<2>().end() && it->GetTime() < time) {
+ while (it != mapTx.get<entry_time>().end() && it->GetTime() < time) {
toremove.insert(mapTx.project<0>(it));
it++;
}
@@ -969,7 +969,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<uint256>* pvNoSpendsRe
unsigned nTxnRemoved = 0;
CFeeRate maxFeeRateRemoved(0);
while (DynamicMemoryUsage() > sizelimit) {
- indexed_transaction_set::nth_index<1>::type::iterator it = mapTx.get<1>().begin();
+ indexed_transaction_set::index<descendant_score>::type::iterator it = mapTx.get<descendant_score>().begin();
// We set the new mempool min fee to the feerate of the removed set, plus the
// "minimum reasonable fee rate" (ie some value under which we consider txn
diff --git a/src/txmempool.h b/src/txmempool.h
index 5997346b02..81bca2d963 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -258,6 +258,11 @@ public:
}
};
+// Multi_index tag names
+struct descendant_score {};
+struct entry_time {};
+struct mining_score {};
+
class CBlockPolicyEstimator;
/** An inpoint - a combination of a transaction and an index n into its vin */
@@ -380,16 +385,19 @@ public:
boost::multi_index::ordered_unique<mempoolentry_txid>,
// sorted by fee rate
boost::multi_index::ordered_non_unique<
+ boost::multi_index::tag<descendant_score>,
boost::multi_index::identity<CTxMemPoolEntry>,
CompareTxMemPoolEntryByDescendantScore
>,
// sorted by entry time
boost::multi_index::ordered_non_unique<
+ boost::multi_index::tag<entry_time>,
boost::multi_index::identity<CTxMemPoolEntry>,
CompareTxMemPoolEntryByEntryTime
>,
// sorted by score (for mining prioritization)
boost::multi_index::ordered_unique<
+ boost::multi_index::tag<mining_score>,
boost::multi_index::identity<CTxMemPoolEntry>,
CompareTxMemPoolEntryByScore
>
diff --git a/src/util.cpp b/src/util.cpp
index 492697e12f..59f58f2c55 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -738,28 +738,6 @@ boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate)
}
#endif
-boost::filesystem::path GetTempPath() {
-#if BOOST_FILESYSTEM_VERSION == 3
- return boost::filesystem::temp_directory_path();
-#else
- // TODO: remove when we don't support filesystem v2 anymore
- boost::filesystem::path path;
-#ifdef WIN32
- char pszPath[MAX_PATH] = "";
-
- if (GetTempPathA(MAX_PATH, pszPath))
- path = boost::filesystem::path(pszPath);
-#else
- path = boost::filesystem::path("/tmp");
-#endif
- if (path.empty() || !boost::filesystem::is_directory(path)) {
- LogPrintf("GetTempPath(): failed to find temp path\n");
- return boost::filesystem::path("");
- }
- return path;
-#endif
-}
-
void runCommand(const std::string& strCommand)
{
int nErr = ::system(strCommand.c_str());
diff --git a/src/util.h b/src/util.h
index 9da8fdf87a..ac099f1184 100644
--- a/src/util.h
+++ b/src/util.h
@@ -133,7 +133,6 @@ void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map
#ifdef WIN32
boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
#endif
-boost::filesystem::path GetTempPath();
void OpenDebugLog();
void ShrinkDebugFile();
void runCommand(const std::string& strCommand);
diff --git a/src/version.h b/src/version.h
index f7cf18d0b6..af2eb8eab6 100644
--- a/src/version.h
+++ b/src/version.h
@@ -24,10 +24,6 @@ static const int MIN_PEER_PROTO_VERSION = GETHEADERS_VERSION;
//! if possible, avoid requesting addresses nodes older than this
static const int CADDR_TIME_VERSION = 31402;
-//! only request blocks from nodes outside this range of versions
-static const int NOBLKS_VERSION_START = 32000;
-static const int NOBLKS_VERSION_END = 32400;
-
//! BIP 0031, pong message, is enabled for all versions AFTER this one
static const int BIP0031_VERSION = 60000;
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index 6af5413a9e..c906785e9e 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -165,6 +165,11 @@ CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, bool (*recoverFu
return (fRecovered ? RECOVER_OK : RECOVER_FAIL);
}
+/* End of headers, beginning of key/value data */
+static const char *HEADER_END = "HEADER=END";
+/* End of key/value data */
+static const char *DATA_END = "DATA=END";
+
bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<CDBEnv::KeyValPair>& vResult)
{
LOCK(cs_db);
@@ -199,18 +204,29 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<C
// DATA=END
string strLine;
- while (!strDump.eof() && strLine != "HEADER=END")
+ while (!strDump.eof() && strLine != HEADER_END)
getline(strDump, strLine); // Skip past header
std::string keyHex, valueHex;
- while (!strDump.eof() && keyHex != "DATA=END") {
+ while (!strDump.eof() && keyHex != DATA_END) {
getline(strDump, keyHex);
- if (keyHex != "DATA=END") {
+ if (keyHex != DATA_END) {
+ if (strDump.eof())
+ break;
getline(strDump, valueHex);
+ if (valueHex == DATA_END) {
+ LogPrintf("CDBEnv::Salvage: WARNING: Number of keys in data does not match number of values.\n");
+ break;
+ }
vResult.push_back(make_pair(ParseHex(keyHex), ParseHex(valueHex)));
}
}
+ if (keyHex != DATA_END) {
+ LogPrintf("CDBEnv::Salvage: WARNING: Unexpected end of file while reading salvage output.\n");
+ return false;
+ }
+
return (result == 0);
}
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 34ad5a46f7..759f894ccb 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -394,7 +394,7 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr
throw JSONRPCError(RPC_WALLET_ERROR, strError);
}
if (!pwalletMain->CommitTransaction(wtxNew, reservekey))
- throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
+ throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of the wallet and coins were spent in the copy but not marked as spent here.");
}
UniValue sendtoaddress(const UniValue& params, bool fHelp)
@@ -1444,7 +1444,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp)
" \"trusted\": xxx (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n"
" \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n"
" category of transactions.\n"
- " \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive'\n"
+ " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive'\n"
" category of transactions.\n"
" \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
" \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
@@ -1637,7 +1637,7 @@ UniValue listsinceblock(const UniValue& params, bool fHelp)
" \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the 'send' category of transactions.\n"
" \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n"
" \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
- " \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
+ " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive' category of transactions.\n"
" \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
" \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
" \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n"
@@ -1721,7 +1721,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp)
" \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n"
" \"confirmations\" : n, (numeric) The number of confirmations\n"
" \"blockhash\" : \"hash\", (string) The block hash\n"
- " \"blockindex\" : xx, (numeric) The block index\n"
+ " \"blockindex\" : xx, (numeric) The index of the transaction in the block that includes it\n"
" \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n"
" \"txid\" : \"transactionid\", (string) The transaction id.\n"
" \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n"
@@ -1827,7 +1827,7 @@ UniValue backupwallet(const UniValue& params, bool fHelp)
if (fHelp || params.size() != 1)
throw runtime_error(
"backupwallet \"destination\"\n"
- "\nSafely copies wallet.dat to destination, which can be a directory or a path with filename.\n"
+ "\nSafely copies current wallet file to destination, which can be a directory or a path with filename.\n"
"\nArguments:\n"
"1. \"destination\" (string) The destination directory or file\n"
"\nExamples:\n"
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 65defc30aa..bcfefa27ff 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -33,14 +33,14 @@
using namespace std;
-/**
- * Settings
- */
+/** Transaction fee set by the user */
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE;
bool fSendFreeTransactions = DEFAULT_SEND_FREE_TRANSACTIONS;
+const char * DEFAULT_WALLET_DAT = "wallet.dat";
+
/**
* Fees smaller than this (in satoshi) are considered zero fee (for transaction creation)
* Override with -mintxfee
@@ -399,13 +399,14 @@ bool CWallet::Verify(const string& walletFile, string& warningString, string& er
CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover);
if (r == CDBEnv::RECOVER_OK)
{
- warningString += strprintf(_("Warning: wallet.dat corrupt, data salvaged!"
- " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if"
- " your balance or transactions are incorrect you should"
- " restore from a backup."), GetDataDir());
+ warningString += strprintf(_("Warning: Wallet file corrupt, data salvaged!"
+ " Original %s saved as %s in %s; if"
+ " your balance or transactions are incorrect you should"
+ " restore from a backup."),
+ walletFile, "wallet.{timestamp}.bak", GetDataDir());
}
if (r == CDBEnv::RECOVER_FAIL)
- errorString += _("wallet.dat corrupt, salvage failed");
+ errorString += strprintf(_("%s corrupt, salvage failed"), walletFile);
}
return true;
@@ -1265,7 +1266,7 @@ bool CWalletTx::RelayWalletTransaction()
assert(pwallet->GetBroadcastTransactions());
if (!IsCoinBase())
{
- if (GetDepthInMainChain() == 0 && !isAbandoned()) {
+ if (GetDepthInMainChain() == 0 && !isAbandoned() && InMempool()) {
LogPrintf("Relaying wtx %s\n", GetHash().ToString());
RelayTransaction((CTransaction)*this);
return true;
@@ -2956,6 +2957,202 @@ bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, st
return false;
}
+std::string CWallet::GetWalletHelpString(bool showDebug)
+{
+ std::string strUsage = HelpMessageGroup(_("Wallet options:"));
+ strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
+ strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), DEFAULT_KEYPOOL_SIZE));
+ strUsage += HelpMessageOpt("-fallbackfee=<amt>", strprintf(_("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)"),
+ CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE)));
+ strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"),
+ CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE)));
+ strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"),
+ CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK())));
+ strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup"));
+ strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet on startup"));
+ strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS));
+ strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE));
+ strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET));
+ strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup"));
+ strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT));
+ strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST));
+ strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)"));
+ strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") +
+ " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)"));
+
+ if (showDebug)
+ {
+ strUsage += HelpMessageGroup(_("Wallet debugging/testing options:"));
+
+ strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush wallet database activity from memory to disk log every <n> megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE));
+ strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET));
+ strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB));
+ }
+
+ return strUsage;
+}
+
+CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWalletFile, std::string& warningString, std::string& errorString)
+{
+ // needed to restore wallet transaction meta data after -zapwallettxes
+ std::vector<CWalletTx> vWtx;
+
+ if (GetBoolArg("-zapwallettxes", false)) {
+ uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
+
+ CWallet *tempWallet = new CWallet(strWalletFile);
+ DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
+ if (nZapWalletRet != DB_LOAD_OK) {
+ errorString = strprintf(_("Error loading %s: Wallet corrupted"), strWalletFile);
+ uiInterface.InitMessage(strprintf(_("Error loading %s: Wallet corrupted"), strWalletFile));
+ return NULL;
+ }
+
+ delete tempWallet;
+ tempWallet = NULL;
+ }
+
+ uiInterface.InitMessage(_("Loading wallet..."));
+
+ int64_t nStart = GetTimeMillis();
+ bool fFirstRun = true;
+ CWallet *walletInstance = new CWallet(strWalletFile);
+ DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
+ if (nLoadWalletRet != DB_LOAD_OK)
+ {
+ if (nLoadWalletRet == DB_CORRUPT)
+ errorString += strprintf(_("Error loading %s: Wallet corrupted"), strWalletFile) + "\n";
+ else if (nLoadWalletRet == DB_NONCRITICAL_ERROR)
+ {
+ warningString += strprintf(_("Error reading %s! All keys read correctly, but transaction data"
+ " or address book entries might be missing or incorrect."),
+ strWalletFile);
+ }
+ else if (nLoadWalletRet == DB_TOO_NEW)
+ errorString += strprintf(_("Error loading %s: Wallet requires newer version of %s"),
+ strWalletFile, _(PACKAGE_NAME)) +
+ "\n";
+ else if (nLoadWalletRet == DB_NEED_REWRITE)
+ {
+ errorString += strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)) + "\n";
+ LogPrintf("%s", errorString);
+ }
+ else
+ errorString += strprintf(_("Error loading %s"), strWalletFile) + "\n";
+
+ if (!errorString.empty())
+ return NULL;
+ }
+
+ if (GetBoolArg("-upgradewallet", fFirstRun))
+ {
+ int nMaxVersion = GetArg("-upgradewallet", 0);
+ if (nMaxVersion == 0) // the -upgradewallet without argument case
+ {
+ LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
+ nMaxVersion = CLIENT_VERSION;
+ walletInstance->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
+ }
+ else
+ LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
+ if (nMaxVersion < walletInstance->GetVersion())
+ {
+ errorString += _("Cannot downgrade wallet") + "\n";
+ return NULL;
+ }
+ walletInstance->SetMaxVersion(nMaxVersion);
+ }
+
+ if (fFirstRun)
+ {
+ // Create new keyUser and set as default key
+ RandAddSeedPerfmon();
+
+ CPubKey newDefaultKey;
+ if (walletInstance->GetKeyFromPool(newDefaultKey)) {
+ walletInstance->SetDefaultKey(newDefaultKey);
+ if (!walletInstance->SetAddressBook(walletInstance->vchDefaultKey.GetID(), "", "receive"))
+ {
+ errorString += _("Cannot write default address") += "\n";
+ return NULL;
+ }
+ }
+
+ walletInstance->SetBestChain(chainActive.GetLocator());
+ }
+
+ LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart);
+
+ RegisterValidationInterface(walletInstance);
+
+ CBlockIndex *pindexRescan = chainActive.Tip();
+ if (GetBoolArg("-rescan", false))
+ pindexRescan = chainActive.Genesis();
+ else
+ {
+ CWalletDB walletdb(strWalletFile);
+ CBlockLocator locator;
+ if (walletdb.ReadBestBlock(locator))
+ pindexRescan = FindForkInGlobalIndex(chainActive, locator);
+ else
+ pindexRescan = chainActive.Genesis();
+ }
+ if (chainActive.Tip() && chainActive.Tip() != pindexRescan)
+ {
+ //We can't rescan beyond non-pruned blocks, stop and throw an error
+ //this might happen if a user uses a old wallet within a pruned node
+ // or if he ran -disablewallet for a longer time, then decided to re-enable
+ if (fPruneMode)
+ {
+ CBlockIndex *block = chainActive.Tip();
+ while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA) && block->pprev->nTx > 0 && pindexRescan != block)
+ block = block->pprev;
+
+ if (pindexRescan != block)
+ {
+ errorString = _("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)");
+ return NULL;
+ }
+ }
+
+ uiInterface.InitMessage(_("Rescanning..."));
+ LogPrintf("Rescanning last %i blocks (from block %i)...\n", chainActive.Height() - pindexRescan->nHeight, pindexRescan->nHeight);
+ nStart = GetTimeMillis();
+ walletInstance->ScanForWalletTransactions(pindexRescan, true);
+ LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart);
+ walletInstance->SetBestChain(chainActive.GetLocator());
+ nWalletDBUpdated++;
+
+ // Restore wallet transaction metadata after -zapwallettxes=1
+ if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2")
+ {
+ CWalletDB walletdb(strWalletFile);
+
+ BOOST_FOREACH(const CWalletTx& wtxOld, vWtx)
+ {
+ uint256 hash = wtxOld.GetHash();
+ std::map<uint256, CWalletTx>::iterator mi = walletInstance->mapWallet.find(hash);
+ if (mi != walletInstance->mapWallet.end())
+ {
+ const CWalletTx* copyFrom = &wtxOld;
+ CWalletTx* copyTo = &mi->second;
+ copyTo->mapValue = copyFrom->mapValue;
+ copyTo->vOrderForm = copyFrom->vOrderForm;
+ copyTo->nTimeReceived = copyFrom->nTimeReceived;
+ copyTo->nTimeSmart = copyFrom->nTimeSmart;
+ copyTo->fFromMe = copyFrom->fFromMe;
+ copyTo->strFromAccount = copyFrom->strFromAccount;
+ copyTo->nOrderPos = copyFrom->nOrderPos;
+ copyTo->WriteToDisk(&walletdb);
+ }
+ }
+ }
+ }
+ walletInstance->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));
+
+ return walletInstance;
+}
+
CKeyPool::CKeyPool()
{
nTime = GetTime();
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 990b27c7ce..d009211a92 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -55,6 +55,8 @@ static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2;
static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000;
static const bool DEFAULT_WALLETBROADCAST = true;
+extern const char * DEFAULT_WALLET_DAT;
+
class CBlockIndex;
class CCoinControl;
class COutput;
@@ -869,6 +871,12 @@ public:
/* Mark a transaction (and it in-wallet descendants) as abandoned so its inputs may be respent. */
bool AbandonTransaction(const uint256& hashTx);
+
+ /* Returns the wallets help message */
+ static std::string GetWalletHelpString(bool showDebug);
+
+ /* initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */
+ static CWallet* InitLoadWallet(bool fDisableWallet, const std::string& strWalletFile, std::string& warningString, std::string& errorString);
};
/** A key allocated from the key pool. */
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 67511976df..0a4a1dae2f 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -847,16 +847,16 @@ void ThreadFlushWalletDB(const string& strFile)
map<string, int>::iterator mi = bitdb.mapFileUseCount.find(strFile);
if (mi != bitdb.mapFileUseCount.end())
{
- LogPrint("db", "Flushing wallet.dat\n");
+ LogPrint("db", "Flushing %s\n", strFile);
nLastFlushed = nWalletDBUpdated;
int64_t nStart = GetTimeMillis();
- // Flush wallet.dat so it's self contained
+ // Flush wallet file so it's self contained
bitdb.CloseDb(strFile);
bitdb.CheckpointLSN(strFile);
bitdb.mapFileUseCount.erase(mi++);
- LogPrint("db", "Flushed wallet.dat %dms\n", GetTimeMillis() - nStart);
+ LogPrint("db", "Flushed %s %dms\n", strFile, GetTimeMillis() - nStart);
}
}
}
@@ -879,7 +879,7 @@ bool BackupWallet(const CWallet& wallet, const string& strDest)
bitdb.CheckpointLSN(wallet.strWalletFile);
bitdb.mapFileUseCount.erase(wallet.strWalletFile);
- // Copy wallet.dat
+ // Copy wallet file
boost::filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile;
boost::filesystem::path pathDest(strDest);
if (boost::filesystem::is_directory(pathDest))
@@ -891,10 +891,10 @@ bool BackupWallet(const CWallet& wallet, const string& strDest)
#else
boost::filesystem::copy_file(pathSrc, pathDest);
#endif
- LogPrintf("copied wallet.dat to %s\n", pathDest.string());
+ LogPrintf("copied %s to %s\n", wallet.strWalletFile, pathDest.string());
return true;
} catch (const boost::filesystem::filesystem_error& e) {
- LogPrintf("error copying wallet.dat to %s - %s\n", pathDest.string(), e.what());
+ LogPrintf("error copying %s to %s - %s\n", wallet.strWalletFile, pathDest.string(), e.what());
return false;
}
}
@@ -905,15 +905,15 @@ bool BackupWallet(const CWallet& wallet, const string& strDest)
}
//
-// Try to (very carefully!) recover wallet.dat if there is a problem.
+// Try to (very carefully!) recover wallet file if there is a problem.
//
bool CWalletDB::Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKeys)
{
// Recovery procedure:
- // move wallet.dat to wallet.timestamp.bak
+ // move wallet file to wallet.timestamp.bak
// Call Salvage with fAggressive=true to
// get as much data as possible.
- // Rewrite salvaged data to wallet.dat
+ // Rewrite salvaged data to fresh wallet file
// Set -rescan so any missing transactions will be
// found.
int64_t now = GetTime();
diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h
index 8da33dead2..7e8cc4084e 100644
--- a/src/wallet/walletdb.h
+++ b/src/wallet/walletdb.h
@@ -73,7 +73,7 @@ public:
}
};
-/** Access to the wallet database (wallet.dat) */
+/** Access to the wallet database */
class CWalletDB : public CDB
{
public:
diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp
index c8adcf8462..8705532429 100644
--- a/src/zmq/zmqnotificationinterface.cpp
+++ b/src/zmq/zmqnotificationinterface.cpp
@@ -100,7 +100,6 @@ bool CZMQNotificationInterface::Initialize()
if (i!=notifiers.end())
{
- Shutdown();
return false;
}
diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp
index ddc8fe93e9..f5839620ff 100644
--- a/src/zmq/zmqpublishnotifier.cpp
+++ b/src/zmq/zmqpublishnotifier.cpp
@@ -69,6 +69,7 @@ bool CZMQAbstractPublishNotifier::Initialize(void *pcontext)
if (rc!=0)
{
zmqError("Failed to bind address");
+ zmq_close(psocket);
return false;
}