Merge #10742: scripted-diff: Use scoped enumerations (C++11, "enum class")

1f45e21 scripted-diff: Convert 11 enums into scoped enums (C++11) (practicalswift)

Pull request description:

  Rationale (from Bjarne Stroustrup's ["C++11 FAQ"](http://www.stroustrup.com/C++11FAQ.html#enum)):

  >
  > The enum classes ("new enums", "strong enums") address three problems with traditional C++ enumerations:
  >
  > * conventional enums implicitly convert to int, causing errors when someone does not want an enumeration to act as an integer.
  > * conventional enums export their enumerators to the surrounding scope, causing name clashes.
  > * the underlying type of an enum cannot be specified, causing confusion, compatibility problems, and makes forward declaration impossible.
  >
  > The new enums are "enum class" because they combine aspects of traditional enumerations (names values) with aspects of classes (scoped members and absence of conversions).

Tree-SHA512: 9656e1cf4c3cabd4378c7a38d0c2eaf79e4a54d204a3c5762330840e55ee7e141e188a3efb2b4daf0ef3110bbaff80d8b9253abf2a9b015cdc4d60b49ac2b914
This commit is contained in:
Wladimir J. van der Laan 2018-03-27 16:28:27 +02:00
commit 3de01268b7
No known key found for this signature in database
GPG key ID: 1E4AED62986CD25D
38 changed files with 295 additions and 295 deletions

View file

@ -75,7 +75,7 @@ static void VerifyScriptBench(benchmark::State& state)
CMutableTransaction txSpend = BuildSpendingTransaction(scriptSig, txCredit); CMutableTransaction txSpend = BuildSpendingTransaction(scriptSig, txCredit);
CScriptWitness& witness = txSpend.vin[0].scriptWitness; CScriptWitness& witness = txSpend.vin[0].scriptWitness;
witness.stack.emplace_back(); witness.stack.emplace_back();
key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, txCredit.vout[0].nValue, SIGVERSION_WITNESS_V0), witness.stack.back(), 0); key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, txCredit.vout[0].nValue, SigVersion::WITNESS_V0), witness.stack.back(), 0);
witness.stack.back().push_back(static_cast<unsigned char>(SIGHASH_ALL)); witness.stack.back().push_back(static_cast<unsigned char>(SIGHASH_ALL));
witness.stack.push_back(ToByteVector(pubkey)); witness.stack.push_back(ToByteVector(pubkey));

View file

@ -79,7 +79,7 @@ bool AppInit(int argc, char* argv[])
strUsage += "\n" + _("Usage:") + "\n" + strUsage += "\n" + _("Usage:") + "\n" +
" bitcoind [options] " + strprintf(_("Start %s Daemon"), _(PACKAGE_NAME)) + "\n"; " bitcoind [options] " + strprintf(_("Start %s Daemon"), _(PACKAGE_NAME)) + "\n";
strUsage += "\n" + HelpMessage(HMM_BITCOIND); strUsage += "\n" + HelpMessage(HelpMessageMode::BITCOIND);
} }
fprintf(stdout, "%s", strUsage.c_str()); fprintf(stdout, "%s", strUsage.c_str());

View file

@ -338,7 +338,7 @@ std::string HelpMessage(HelpMessageMode mode)
if (showDebug) if (showDebug)
strUsage += HelpMessageOpt("-blocksonly", strprintf(_("Whether to operate in a blocks only mode (default: %u)"), DEFAULT_BLOCKSONLY)); strUsage += HelpMessageOpt("-blocksonly", strprintf(_("Whether to operate in a blocks only mode (default: %u)"), DEFAULT_BLOCKSONLY));
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file. Relative paths will be prefixed by datadir location. (default: %s)"), BITCOIN_CONF_FILENAME)); strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file. Relative paths will be prefixed by datadir location. (default: %s)"), BITCOIN_CONF_FILENAME));
if (mode == HMM_BITCOIND) if (mode == HelpMessageMode::BITCOIND)
{ {
#if HAVE_DECL_DAEMON #if HAVE_DECL_DAEMON
strUsage += HelpMessageOpt("-daemon", _("Run in the background as a daemon and accept commands")); strUsage += HelpMessageOpt("-daemon", _("Run in the background as a daemon and accept commands"));

View file

@ -57,9 +57,9 @@ bool AppInitLockDataDirectory();
bool AppInitMain(); bool AppInitMain();
/** The help message mode determines what help message to show */ /** The help message mode determines what help message to show */
enum HelpMessageMode { enum class HelpMessageMode {
HMM_BITCOIND, BITCOIND,
HMM_BITCOIN_QT BITCOIN_QT
}; };
/** Help for options shared between UI and daemon (for -help) */ /** Help for options shared between UI and daemon (for -help) */

View file

@ -68,7 +68,7 @@ class TxConfirmStats;
/* Identifier for each of the 3 different TxConfirmStats which will track /* Identifier for each of the 3 different TxConfirmStats which will track
* history over different time horizons. */ * history over different time horizons. */
enum FeeEstimateHorizon { enum class FeeEstimateHorizon {
SHORT_HALFLIFE = 0, SHORT_HALFLIFE = 0,
MED_HALFLIFE = 1, MED_HALFLIFE = 1,
LONG_HALFLIFE = 2 LONG_HALFLIFE = 2

View file

@ -179,7 +179,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
{ {
std::vector<std::vector<unsigned char> > stack; std::vector<std::vector<unsigned char> > stack;
// convert the scriptSig into a stack, so we can inspect the redeemScript // convert the scriptSig into a stack, so we can inspect the redeemScript
if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SIGVERSION_BASE)) if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE))
return false; return false;
if (stack.empty()) if (stack.empty())
return false; return false;
@ -215,7 +215,7 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
// If the scriptPubKey is P2SH, we try to extract the redeemScript casually by converting the scriptSig // If the scriptPubKey is P2SH, we try to extract the redeemScript casually by converting the scriptSig
// into a stack. We do not check IsPushOnly nor compare the hash as these will be done later anyway. // into a stack. We do not check IsPushOnly nor compare the hash as these will be done later anyway.
// If the check fails at this stage, we know that this txid must be a bad one. // If the check fails at this stage, we know that this txid must be a bad one.
if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SIGVERSION_BASE)) if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE))
return false; return false;
if (stack.empty()) if (stack.empty())
return false; return false;

View file

@ -22,13 +22,13 @@ RBFTransactionState IsRBFOptIn(const CTransaction &tx, CTxMemPool &pool)
// First check the transaction itself. // First check the transaction itself.
if (SignalsOptInRBF(tx)) { if (SignalsOptInRBF(tx)) {
return RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125; return RBFTransactionState::REPLACEABLE_BIP125;
} }
// If this transaction is not in our mempool, then we can't be sure // If this transaction is not in our mempool, then we can't be sure
// we will know about all its inputs. // we will know about all its inputs.
if (!pool.exists(tx.GetHash())) { if (!pool.exists(tx.GetHash())) {
return RBF_TRANSACTIONSTATE_UNKNOWN; return RBFTransactionState::UNKNOWN;
} }
// If all the inputs have nSequence >= maxint-1, it still might be // If all the inputs have nSequence >= maxint-1, it still might be
@ -40,8 +40,8 @@ RBFTransactionState IsRBFOptIn(const CTransaction &tx, CTxMemPool &pool)
for (CTxMemPool::txiter it : setAncestors) { for (CTxMemPool::txiter it : setAncestors) {
if (SignalsOptInRBF(it->GetTx())) { if (SignalsOptInRBF(it->GetTx())) {
return RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125; return RBFTransactionState::REPLACEABLE_BIP125;
} }
} }
return RBF_TRANSACTIONSTATE_FINAL; return RBFTransactionState::FINAL;
} }

View file

@ -9,10 +9,10 @@
static const uint32_t MAX_BIP125_RBF_SEQUENCE = 0xfffffffd; static const uint32_t MAX_BIP125_RBF_SEQUENCE = 0xfffffffd;
enum RBFTransactionState { enum class RBFTransactionState {
RBF_TRANSACTIONSTATE_UNKNOWN, UNKNOWN,
RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125, REPLACEABLE_BIP125,
RBF_TRANSACTIONSTATE_FINAL FINAL
}; };
// Check whether the sequence numbers on this transaction are signaling // Check whether the sequence numbers on this transaction are signaling

View file

@ -799,7 +799,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer
// Acquire current block source // Acquire current block source
enum BlockSource blockSource = clientModel->getBlockSource(); enum BlockSource blockSource = clientModel->getBlockSource();
switch (blockSource) { switch (blockSource) {
case BLOCK_SOURCE_NETWORK: case BlockSource::NETWORK:
if (header) { if (header) {
updateHeadersSyncProgressLabel(); updateHeadersSyncProgressLabel();
return; return;
@ -807,17 +807,17 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer
progressBarLabel->setText(tr("Synchronizing with network...")); progressBarLabel->setText(tr("Synchronizing with network..."));
updateHeadersSyncProgressLabel(); updateHeadersSyncProgressLabel();
break; break;
case BLOCK_SOURCE_DISK: case BlockSource::DISK:
if (header) { if (header) {
progressBarLabel->setText(tr("Indexing blocks on disk...")); progressBarLabel->setText(tr("Indexing blocks on disk..."));
} else { } else {
progressBarLabel->setText(tr("Processing blocks on disk...")); progressBarLabel->setText(tr("Processing blocks on disk..."));
} }
break; break;
case BLOCK_SOURCE_REINDEX: case BlockSource::REINDEX:
progressBarLabel->setText(tr("Reindexing blocks on disk...")); progressBarLabel->setText(tr("Reindexing blocks on disk..."));
break; break;
case BLOCK_SOURCE_NONE: case BlockSource::NONE:
if (header) { if (header) {
return; return;
} }

View file

@ -177,13 +177,13 @@ bool ClientModel::inInitialBlockDownload() const
enum BlockSource ClientModel::getBlockSource() const enum BlockSource ClientModel::getBlockSource() const
{ {
if (fReindex) if (fReindex)
return BLOCK_SOURCE_REINDEX; return BlockSource::REINDEX;
else if (fImporting) else if (fImporting)
return BLOCK_SOURCE_DISK; return BlockSource::DISK;
else if (getNumConnections() > 0) else if (getNumConnections() > 0)
return BLOCK_SOURCE_NETWORK; return BlockSource::NETWORK;
return BLOCK_SOURCE_NONE; return BlockSource::NONE;
} }
void ClientModel::setNetworkActive(bool active) void ClientModel::setNetworkActive(bool active)

View file

@ -20,11 +20,11 @@ QT_BEGIN_NAMESPACE
class QTimer; class QTimer;
QT_END_NAMESPACE QT_END_NAMESPACE
enum BlockSource { enum class BlockSource {
BLOCK_SOURCE_NONE, NONE,
BLOCK_SOURCE_REINDEX, REINDEX,
BLOCK_SOURCE_DISK, DISK,
BLOCK_SOURCE_NETWORK NETWORK
}; };
enum NumConnections { enum NumConnections {

View file

@ -77,7 +77,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
cursor.insertText(header); cursor.insertText(header);
cursor.insertBlock(); cursor.insertBlock();
std::string strUsage = HelpMessage(HMM_BITCOIN_QT); std::string strUsage = HelpMessage(HelpMessageMode::BITCOIN_QT);
const bool showDebug = gArgs.GetBoolArg("-help-debug", false); const bool showDebug = gArgs.GetBoolArg("-help-debug", false);
strUsage += HelpMessageGroup(tr("UI Options:").toStdString()); strUsage += HelpMessageGroup(tr("UI Options:").toStdString());
if (showDebug) { if (showDebug) {

View file

@ -24,21 +24,21 @@
static const size_t MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once static const size_t MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once
enum RetFormat { enum class RetFormat {
RF_UNDEF, UNDEF,
RF_BINARY, BINARY,
RF_HEX, HEX,
RF_JSON, JSON,
}; };
static const struct { static const struct {
enum RetFormat rf; enum RetFormat rf;
const char* name; const char* name;
} rf_names[] = { } rf_names[] = {
{RF_UNDEF, ""}, {RetFormat::UNDEF, ""},
{RF_BINARY, "bin"}, {RetFormat::BINARY, "bin"},
{RF_HEX, "hex"}, {RetFormat::HEX, "hex"},
{RF_JSON, "json"}, {RetFormat::JSON, "json"},
}; };
struct CCoin { struct CCoin {
@ -162,20 +162,20 @@ static bool rest_headers(HTTPRequest* req,
} }
switch (rf) { switch (rf) {
case RF_BINARY: { case RetFormat::BINARY: {
std::string binaryHeader = ssHeader.str(); std::string binaryHeader = ssHeader.str();
req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteHeader("Content-Type", "application/octet-stream");
req->WriteReply(HTTP_OK, binaryHeader); req->WriteReply(HTTP_OK, binaryHeader);
return true; return true;
} }
case RF_HEX: { case RetFormat::HEX: {
std::string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n"; std::string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n";
req->WriteHeader("Content-Type", "text/plain"); req->WriteHeader("Content-Type", "text/plain");
req->WriteReply(HTTP_OK, strHex); req->WriteReply(HTTP_OK, strHex);
return true; return true;
} }
case RF_JSON: { case RetFormat::JSON: {
UniValue jsonHeaders(UniValue::VARR); UniValue jsonHeaders(UniValue::VARR);
{ {
LOCK(cs_main); LOCK(cs_main);
@ -227,21 +227,21 @@ static bool rest_block(HTTPRequest* req,
ssBlock << block; ssBlock << block;
switch (rf) { switch (rf) {
case RF_BINARY: { case RetFormat::BINARY: {
std::string binaryBlock = ssBlock.str(); std::string binaryBlock = ssBlock.str();
req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteHeader("Content-Type", "application/octet-stream");
req->WriteReply(HTTP_OK, binaryBlock); req->WriteReply(HTTP_OK, binaryBlock);
return true; return true;
} }
case RF_HEX: { case RetFormat::HEX: {
std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n"; std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n";
req->WriteHeader("Content-Type", "text/plain"); req->WriteHeader("Content-Type", "text/plain");
req->WriteReply(HTTP_OK, strHex); req->WriteReply(HTTP_OK, strHex);
return true; return true;
} }
case RF_JSON: { case RetFormat::JSON: {
UniValue objBlock; UniValue objBlock;
{ {
LOCK(cs_main); LOCK(cs_main);
@ -280,7 +280,7 @@ static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart)
const RetFormat rf = ParseDataFormat(param, strURIPart); const RetFormat rf = ParseDataFormat(param, strURIPart);
switch (rf) { switch (rf) {
case RF_JSON: { case RetFormat::JSON: {
JSONRPCRequest jsonRequest; JSONRPCRequest jsonRequest;
jsonRequest.params = UniValue(UniValue::VARR); jsonRequest.params = UniValue(UniValue::VARR);
UniValue chainInfoObject = getblockchaininfo(jsonRequest); UniValue chainInfoObject = getblockchaininfo(jsonRequest);
@ -303,7 +303,7 @@ static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart)
const RetFormat rf = ParseDataFormat(param, strURIPart); const RetFormat rf = ParseDataFormat(param, strURIPart);
switch (rf) { switch (rf) {
case RF_JSON: { case RetFormat::JSON: {
UniValue mempoolInfoObject = mempoolInfoToJSON(); UniValue mempoolInfoObject = mempoolInfoToJSON();
std::string strJSON = mempoolInfoObject.write() + "\n"; std::string strJSON = mempoolInfoObject.write() + "\n";
@ -325,7 +325,7 @@ static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPar
const RetFormat rf = ParseDataFormat(param, strURIPart); const RetFormat rf = ParseDataFormat(param, strURIPart);
switch (rf) { switch (rf) {
case RF_JSON: { case RetFormat::JSON: {
UniValue mempoolObject = mempoolToJSON(true); UniValue mempoolObject = mempoolToJSON(true);
std::string strJSON = mempoolObject.write() + "\n"; std::string strJSON = mempoolObject.write() + "\n";
@ -359,21 +359,21 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart)
ssTx << tx; ssTx << tx;
switch (rf) { switch (rf) {
case RF_BINARY: { case RetFormat::BINARY: {
std::string binaryTx = ssTx.str(); std::string binaryTx = ssTx.str();
req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteHeader("Content-Type", "application/octet-stream");
req->WriteReply(HTTP_OK, binaryTx); req->WriteReply(HTTP_OK, binaryTx);
return true; return true;
} }
case RF_HEX: { case RetFormat::HEX: {
std::string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n"; std::string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n";
req->WriteHeader("Content-Type", "text/plain"); req->WriteHeader("Content-Type", "text/plain");
req->WriteReply(HTTP_OK, strHex); req->WriteReply(HTTP_OK, strHex);
return true; return true;
} }
case RF_JSON: { case RetFormat::JSON: {
UniValue objTx(UniValue::VOBJ); UniValue objTx(UniValue::VOBJ);
TxToUniv(*tx, hashBlock, objTx); TxToUniv(*tx, hashBlock, objTx);
std::string strJSON = objTx.write() + "\n"; std::string strJSON = objTx.write() + "\n";
@ -440,13 +440,13 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
} }
switch (rf) { switch (rf) {
case RF_HEX: { case RetFormat::HEX: {
// convert hex to bin, continue then with bin part // convert hex to bin, continue then with bin part
std::vector<unsigned char> strRequestV = ParseHex(strRequestMutable); std::vector<unsigned char> strRequestV = ParseHex(strRequestMutable);
strRequestMutable.assign(strRequestV.begin(), strRequestV.end()); strRequestMutable.assign(strRequestV.begin(), strRequestV.end());
} }
case RF_BINARY: { case RetFormat::BINARY: {
try { try {
//deserialize only if user sent a request //deserialize only if user sent a request
if (strRequestMutable.size() > 0) if (strRequestMutable.size() > 0)
@ -466,7 +466,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
break; break;
} }
case RF_JSON: { case RetFormat::JSON: {
if (!fInputParsed) if (!fInputParsed)
return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request"); return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request");
break; break;
@ -513,7 +513,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
} }
switch (rf) { switch (rf) {
case RF_BINARY: { case RetFormat::BINARY: {
// serialize data // serialize data
// use exact same output as mentioned in Bip64 // use exact same output as mentioned in Bip64
CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION); CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION);
@ -525,7 +525,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
return true; return true;
} }
case RF_HEX: { case RetFormat::HEX: {
CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION); CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION);
ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs; ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs;
std::string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n"; std::string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n";
@ -535,7 +535,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
return true; return true;
} }
case RF_JSON: { case RetFormat::JSON: {
UniValue objGetUTXOResponse(UniValue::VOBJ); UniValue objGetUTXOResponse(UniValue::VOBJ);
// pack in some essentials // pack in some essentials

View file

@ -1120,20 +1120,20 @@ static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Conse
UniValue rv(UniValue::VOBJ); UniValue rv(UniValue::VOBJ);
const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id); const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id);
switch (thresholdState) { switch (thresholdState) {
case THRESHOLD_DEFINED: rv.pushKV("status", "defined"); break; case ThresholdState::DEFINED: rv.pushKV("status", "defined"); break;
case THRESHOLD_STARTED: rv.pushKV("status", "started"); break; case ThresholdState::STARTED: rv.pushKV("status", "started"); break;
case THRESHOLD_LOCKED_IN: rv.pushKV("status", "locked_in"); break; case ThresholdState::LOCKED_IN: rv.pushKV("status", "locked_in"); break;
case THRESHOLD_ACTIVE: rv.pushKV("status", "active"); break; case ThresholdState::ACTIVE: rv.pushKV("status", "active"); break;
case THRESHOLD_FAILED: rv.pushKV("status", "failed"); break; case ThresholdState::FAILED: rv.pushKV("status", "failed"); break;
} }
if (THRESHOLD_STARTED == thresholdState) if (ThresholdState::STARTED == thresholdState)
{ {
rv.pushKV("bit", consensusParams.vDeployments[id].bit); rv.pushKV("bit", consensusParams.vDeployments[id].bit);
} }
rv.pushKV("startTime", consensusParams.vDeployments[id].nStartTime); rv.pushKV("startTime", consensusParams.vDeployments[id].nStartTime);
rv.pushKV("timeout", consensusParams.vDeployments[id].nTimeout); rv.pushKV("timeout", consensusParams.vDeployments[id].nTimeout);
rv.pushKV("since", VersionBitsTipStateSinceHeight(consensusParams, id)); rv.pushKV("since", VersionBitsTipStateSinceHeight(consensusParams, id));
if (THRESHOLD_STARTED == thresholdState) if (ThresholdState::STARTED == thresholdState)
{ {
UniValue statsUV(UniValue::VOBJ); UniValue statsUV(UniValue::VOBJ);
BIP9Stats statsStruct = VersionBitsTipStatistics(consensusParams, id); BIP9Stats statsStruct = VersionBitsTipStatistics(consensusParams, id);

View file

@ -532,7 +532,7 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
pblock->nNonce = 0; pblock->nNonce = 0;
// NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration // NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration
const bool fPreSegWit = (THRESHOLD_ACTIVE != VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache)); const bool fPreSegWit = (ThresholdState::ACTIVE != VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache));
UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal"); UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
@ -593,15 +593,15 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
Consensus::DeploymentPos pos = Consensus::DeploymentPos(j); Consensus::DeploymentPos pos = Consensus::DeploymentPos(j);
ThresholdState state = VersionBitsState(pindexPrev, consensusParams, pos, versionbitscache); ThresholdState state = VersionBitsState(pindexPrev, consensusParams, pos, versionbitscache);
switch (state) { switch (state) {
case THRESHOLD_DEFINED: case ThresholdState::DEFINED:
case THRESHOLD_FAILED: case ThresholdState::FAILED:
// Not exposed to GBT at all // Not exposed to GBT at all
break; break;
case THRESHOLD_LOCKED_IN: case ThresholdState::LOCKED_IN:
// Ensure bit is set in block version // Ensure bit is set in block version
pblock->nVersion |= VersionBitsMask(consensusParams, pos); pblock->nVersion |= VersionBitsMask(consensusParams, pos);
// FALL THROUGH to get vbavailable set... // FALL THROUGH to get vbavailable set...
case THRESHOLD_STARTED: case ThresholdState::STARTED:
{ {
const struct VBDeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos]; const struct VBDeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos];
vbavailable.pushKV(gbt_vb_name(pos), consensusParams.vDeployments[pos].bit); vbavailable.pushKV(gbt_vb_name(pos), consensusParams.vDeployments[pos].bit);
@ -613,7 +613,7 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
} }
break; break;
} }
case THRESHOLD_ACTIVE: case ThresholdState::ACTIVE:
{ {
// Add to rules only // Add to rules only
const struct VBDeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos]; const struct VBDeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos];

View file

@ -219,7 +219,7 @@ bool static CheckPubKeyEncoding(const valtype &vchPubKey, unsigned int flags, co
return set_error(serror, SCRIPT_ERR_PUBKEYTYPE); return set_error(serror, SCRIPT_ERR_PUBKEYTYPE);
} }
// Only compressed keys are accepted in segwit // Only compressed keys are accepted in segwit
if ((flags & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE) != 0 && sigversion == SIGVERSION_WITNESS_V0 && !IsCompressedPubKey(vchPubKey)) { if ((flags & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE) != 0 && sigversion == SigVersion::WITNESS_V0 && !IsCompressedPubKey(vchPubKey)) {
return set_error(serror, SCRIPT_ERR_WITNESS_PUBKEYTYPE); return set_error(serror, SCRIPT_ERR_WITNESS_PUBKEYTYPE);
} }
return true; return true;
@ -443,7 +443,7 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
if (stack.size() < 1) if (stack.size() < 1)
return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);
valtype& vch = stacktop(-1); valtype& vch = stacktop(-1);
if (sigversion == SIGVERSION_WITNESS_V0 && (flags & SCRIPT_VERIFY_MINIMALIF)) { if (sigversion == SigVersion::WITNESS_V0 && (flags & SCRIPT_VERIFY_MINIMALIF)) {
if (vch.size() > 1) if (vch.size() > 1)
return set_error(serror, SCRIPT_ERR_MINIMALIF); return set_error(serror, SCRIPT_ERR_MINIMALIF);
if (vch.size() == 1 && vch[0] != 1) if (vch.size() == 1 && vch[0] != 1)
@ -890,7 +890,7 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
CScript scriptCode(pbegincodehash, pend); CScript scriptCode(pbegincodehash, pend);
// Drop the signature in pre-segwit scripts but not segwit scripts // Drop the signature in pre-segwit scripts but not segwit scripts
if (sigversion == SIGVERSION_BASE) { if (sigversion == SigVersion::BASE) {
scriptCode.FindAndDelete(CScript(vchSig)); scriptCode.FindAndDelete(CScript(vchSig));
} }
@ -954,7 +954,7 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
for (int k = 0; k < nSigsCount; k++) for (int k = 0; k < nSigsCount; k++)
{ {
valtype& vchSig = stacktop(-isig-k); valtype& vchSig = stacktop(-isig-k);
if (sigversion == SIGVERSION_BASE) { if (sigversion == SigVersion::BASE) {
scriptCode.FindAndDelete(CScript(vchSig)); scriptCode.FindAndDelete(CScript(vchSig));
} }
} }
@ -1182,7 +1182,7 @@ uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsig
{ {
assert(nIn < txTo.vin.size()); assert(nIn < txTo.vin.size());
if (sigversion == SIGVERSION_WITNESS_V0) { if (sigversion == SigVersion::WITNESS_V0) {
uint256 hashPrevouts; uint256 hashPrevouts;
uint256 hashSequence; uint256 hashSequence;
uint256 hashOutputs; uint256 hashOutputs;
@ -1396,7 +1396,7 @@ static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion,
return set_error(serror, SCRIPT_ERR_PUSH_SIZE); return set_error(serror, SCRIPT_ERR_PUSH_SIZE);
} }
if (!EvalScript(stack, scriptPubKey, flags, checker, SIGVERSION_WITNESS_V0, serror)) { if (!EvalScript(stack, scriptPubKey, flags, checker, SigVersion::WITNESS_V0, serror)) {
return false; return false;
} }
@ -1423,12 +1423,12 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C
} }
std::vector<std::vector<unsigned char> > stack, stackCopy; std::vector<std::vector<unsigned char> > stack, stackCopy;
if (!EvalScript(stack, scriptSig, flags, checker, SIGVERSION_BASE, serror)) if (!EvalScript(stack, scriptSig, flags, checker, SigVersion::BASE, serror))
// serror is set // serror is set
return false; return false;
if (flags & SCRIPT_VERIFY_P2SH) if (flags & SCRIPT_VERIFY_P2SH)
stackCopy = stack; stackCopy = stack;
if (!EvalScript(stack, scriptPubKey, flags, checker, SIGVERSION_BASE, serror)) if (!EvalScript(stack, scriptPubKey, flags, checker, SigVersion::BASE, serror))
// serror is set // serror is set
return false; return false;
if (stack.empty()) if (stack.empty())
@ -1474,7 +1474,7 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C
CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end());
popstack(stack); popstack(stack);
if (!EvalScript(stack, pubKey2, flags, checker, SIGVERSION_BASE, serror)) if (!EvalScript(stack, pubKey2, flags, checker, SigVersion::BASE, serror))
// serror is set // serror is set
return false; return false;
if (stack.empty()) if (stack.empty())

View file

@ -123,10 +123,10 @@ struct PrecomputedTransactionData
explicit PrecomputedTransactionData(const CTransaction& tx); explicit PrecomputedTransactionData(const CTransaction& tx);
}; };
enum SigVersion enum class SigVersion
{ {
SIGVERSION_BASE = 0, BASE = 0,
SIGVERSION_WITNESS_V0 = 1, WITNESS_V0 = 1,
}; };
uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache = nullptr); uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache = nullptr);

View file

@ -61,7 +61,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey, bool&
break; break;
case TX_PUBKEY: case TX_PUBKEY:
keyID = CPubKey(vSolutions[0]).GetID(); keyID = CPubKey(vSolutions[0]).GetID();
if (sigversion != SIGVERSION_BASE && vSolutions[0].size() != 33) { if (sigversion != SigVersion::BASE && vSolutions[0].size() != 33) {
isInvalid = true; isInvalid = true;
return ISMINE_NO; return ISMINE_NO;
} }
@ -76,14 +76,14 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey, bool&
// This also applies to the P2WSH case. // This also applies to the P2WSH case.
break; break;
} }
isminetype ret = ::IsMine(keystore, GetScriptForDestination(CKeyID(uint160(vSolutions[0]))), isInvalid, SIGVERSION_WITNESS_V0); isminetype ret = ::IsMine(keystore, GetScriptForDestination(CKeyID(uint160(vSolutions[0]))), isInvalid, SigVersion::WITNESS_V0);
if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid)) if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid))
return ret; return ret;
break; break;
} }
case TX_PUBKEYHASH: case TX_PUBKEYHASH:
keyID = CKeyID(uint160(vSolutions[0])); keyID = CKeyID(uint160(vSolutions[0]));
if (sigversion != SIGVERSION_BASE) { if (sigversion != SigVersion::BASE) {
CPubKey pubkey; CPubKey pubkey;
if (keystore.GetPubKey(keyID, pubkey) && !pubkey.IsCompressed()) { if (keystore.GetPubKey(keyID, pubkey) && !pubkey.IsCompressed()) {
isInvalid = true; isInvalid = true;
@ -114,7 +114,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey, bool&
CScriptID scriptID = CScriptID(hash); CScriptID scriptID = CScriptID(hash);
CScript subscript; CScript subscript;
if (keystore.GetCScript(scriptID, subscript)) { if (keystore.GetCScript(scriptID, subscript)) {
isminetype ret = IsMine(keystore, subscript, isInvalid, SIGVERSION_WITNESS_V0); isminetype ret = IsMine(keystore, subscript, isInvalid, SigVersion::WITNESS_V0);
if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid)) if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid))
return ret; return ret;
} }
@ -129,7 +129,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey, bool&
// them) enable spend-out-from-under-you attacks, especially // them) enable spend-out-from-under-you attacks, especially
// in shared-wallet situations. // in shared-wallet situations.
std::vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1); std::vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
if (sigversion != SIGVERSION_BASE) { if (sigversion != SigVersion::BASE) {
for (size_t i = 0; i < keys.size(); i++) { for (size_t i = 0; i < keys.size(); i++) {
if (keys[i].size() != 33) { if (keys[i].size() != 33) {
isInvalid = true; isInvalid = true;

View file

@ -31,11 +31,11 @@ typedef uint8_t isminefilter;
/* isInvalid becomes true when the script is found invalid by consensus or policy. This will terminate the recursion /* isInvalid becomes true when the script is found invalid by consensus or policy. This will terminate the recursion
* and return ISMINE_NO immediately, as an invalid script should never be considered as "mine". This is needed as * and return ISMINE_NO immediately, as an invalid script should never be considered as "mine". This is needed as
* different SIGVERSION may have different network rules. Currently the only use of isInvalid is indicate uncompressed * different SIGVERSION may have different network rules. Currently the only use of isInvalid is indicate uncompressed
* keys in SIGVERSION_WITNESS_V0 script, but could also be used in similar cases in the future * keys in SigVersion::WITNESS_V0 script, but could also be used in similar cases in the future
*/ */
isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey, bool& isInvalid, SigVersion = SIGVERSION_BASE); isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey, bool& isInvalid, SigVersion = SigVersion::BASE);
isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey, SigVersion = SIGVERSION_BASE); isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey, SigVersion = SigVersion::BASE);
isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest, bool& isInvalid, SigVersion = SIGVERSION_BASE); isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest, bool& isInvalid, SigVersion = SigVersion::BASE);
isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest, SigVersion = SIGVERSION_BASE); isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest, SigVersion = SigVersion::BASE);
#endif // BITCOIN_SCRIPT_ISMINE_H #endif // BITCOIN_SCRIPT_ISMINE_H

View file

@ -24,7 +24,7 @@ bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig,
return false; return false;
// Signing with uncompressed keys is disabled in witness scripts // Signing with uncompressed keys is disabled in witness scripts
if (sigversion == SIGVERSION_WITNESS_V0 && !key.IsCompressed()) if (sigversion == SigVersion::WITNESS_V0 && !key.IsCompressed())
return false; return false;
uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion); uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion);
@ -142,7 +142,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
{ {
std::vector<valtype> result; std::vector<valtype> result;
txnouttype whichType; txnouttype whichType;
bool solved = SignStep(creator, fromPubKey, result, whichType, SIGVERSION_BASE); bool solved = SignStep(creator, fromPubKey, result, whichType, SigVersion::BASE);
bool P2SH = false; bool P2SH = false;
CScript subscript; CScript subscript;
sigdata.scriptWitness.stack.clear(); sigdata.scriptWitness.stack.clear();
@ -153,7 +153,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
// the final scriptSig is the signatures from that // the final scriptSig is the signatures from that
// and then the serialized subscript: // and then the serialized subscript:
subscript = CScript(result[0].begin(), result[0].end()); subscript = CScript(result[0].begin(), result[0].end());
solved = solved && SignStep(creator, subscript, result, whichType, SIGVERSION_BASE) && whichType != TX_SCRIPTHASH; solved = solved && SignStep(creator, subscript, result, whichType, SigVersion::BASE) && whichType != TX_SCRIPTHASH;
P2SH = true; P2SH = true;
} }
@ -162,7 +162,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
CScript witnessscript; CScript witnessscript;
witnessscript << OP_DUP << OP_HASH160 << ToByteVector(result[0]) << OP_EQUALVERIFY << OP_CHECKSIG; witnessscript << OP_DUP << OP_HASH160 << ToByteVector(result[0]) << OP_EQUALVERIFY << OP_CHECKSIG;
txnouttype subType; txnouttype subType;
solved = solved && SignStep(creator, witnessscript, result, subType, SIGVERSION_WITNESS_V0); solved = solved && SignStep(creator, witnessscript, result, subType, SigVersion::WITNESS_V0);
sigdata.scriptWitness.stack = result; sigdata.scriptWitness.stack = result;
result.clear(); result.clear();
} }
@ -170,7 +170,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
{ {
CScript witnessscript(result[0].begin(), result[0].end()); CScript witnessscript(result[0].begin(), result[0].end());
txnouttype subType; txnouttype subType;
solved = solved && SignStep(creator, witnessscript, result, subType, SIGVERSION_WITNESS_V0) && subType != TX_SCRIPTHASH && subType != TX_WITNESS_V0_SCRIPTHASH && subType != TX_WITNESS_V0_KEYHASH; solved = solved && SignStep(creator, witnessscript, result, subType, SigVersion::WITNESS_V0) && subType != TX_SCRIPTHASH && subType != TX_WITNESS_V0_SCRIPTHASH && subType != TX_WITNESS_V0_KEYHASH;
result.push_back(std::vector<unsigned char>(witnessscript.begin(), witnessscript.end())); result.push_back(std::vector<unsigned char>(witnessscript.begin(), witnessscript.end()));
sigdata.scriptWitness.stack = result; sigdata.scriptWitness.stack = result;
result.clear(); result.clear();
@ -294,7 +294,7 @@ struct Stacks
Stacks() {} Stacks() {}
explicit Stacks(const std::vector<valtype>& scriptSigStack_) : script(scriptSigStack_), witness() {} explicit Stacks(const std::vector<valtype>& scriptSigStack_) : script(scriptSigStack_), witness() {}
explicit Stacks(const SignatureData& data) : witness(data.scriptWitness.stack) { explicit Stacks(const SignatureData& data) : witness(data.scriptWitness.stack) {
EvalScript(script, data.scriptSig, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), SIGVERSION_BASE); EvalScript(script, data.scriptSig, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), SigVersion::BASE);
} }
SignatureData Output() const { SignatureData Output() const {
@ -370,7 +370,7 @@ static Stacks CombineSignatures(const CScript& scriptPubKey, const BaseSignature
sigs2.witness.pop_back(); sigs2.witness.pop_back();
sigs2.script = sigs2.witness; sigs2.script = sigs2.witness;
sigs2.witness.clear(); sigs2.witness.clear();
Stacks result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2, SIGVERSION_WITNESS_V0); Stacks result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2, SigVersion::WITNESS_V0);
result.witness = result.script; result.witness = result.script;
result.script.clear(); result.script.clear();
result.witness.push_back(valtype(pubKey2.begin(), pubKey2.end())); result.witness.push_back(valtype(pubKey2.begin(), pubKey2.end()));
@ -388,7 +388,7 @@ SignatureData CombineSignatures(const CScript& scriptPubKey, const BaseSignature
std::vector<std::vector<unsigned char> > vSolutions; std::vector<std::vector<unsigned char> > vSolutions;
Solver(scriptPubKey, txType, vSolutions); Solver(scriptPubKey, txType, vSolutions);
return CombineSignatures(scriptPubKey, checker, txType, vSolutions, Stacks(scriptSig1), Stacks(scriptSig2), SIGVERSION_BASE).Output(); return CombineSignatures(scriptPubKey, checker, txType, vSolutions, Stacks(scriptSig1), Stacks(scriptSig2), SigVersion::BASE).Output();
} }
namespace { namespace {

View file

@ -321,7 +321,7 @@
["where the pubkey is obtained through key recovery with sig and the wrong sighash."], ["where the pubkey is obtained through key recovery with sig and the wrong sighash."],
["This is to show that FindAndDelete is applied only to non-segwit scripts"], ["This is to show that FindAndDelete is applied only to non-segwit scripts"],
["To show that the tests are 'correctly wrong', they should pass by modifying OP_CHECKSIG under interpreter.cpp"], ["To show that the tests are 'correctly wrong', they should pass by modifying OP_CHECKSIG under interpreter.cpp"],
["by replacing (sigversion == SIGVERSION_BASE) with (sigversion != SIGVERSION_BASE)"], ["by replacing (sigversion == SigVersion::BASE) with (sigversion != SigVersion::BASE)"],
["Non-segwit: wrong sighash (without FindAndDelete) = 1ba1fe3bc90c5d1265460e684ce6774e324f0fabdf67619eda729e64e8b6bc08"], ["Non-segwit: wrong sighash (without FindAndDelete) = 1ba1fe3bc90c5d1265460e684ce6774e324f0fabdf67619eda729e64e8b6bc08"],
[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7000, "HASH160 0x14 0x0c746489e2d83cdbb5b90b432773342ba809c134 EQUAL", 200000]], [[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7000, "HASH160 0x14 0x0c746489e2d83cdbb5b90b432773342ba809c134 EQUAL", 200000]],
"010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f1581b0000b64830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012103b12a1ec8428fc74166926318c15e17408fea82dbb157575e16a8c365f546248f4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01ffffffff0101000000000000000000000000", "P2SH,WITNESS"], "010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f1581b0000b64830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012103b12a1ec8428fc74166926318c15e17408fea82dbb157575e16a8c365f546248f4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01ffffffff0101000000000000000000000000", "P2SH,WITNESS"],
@ -332,7 +332,7 @@
["Script is 2 CHECKMULTISIGVERIFY <sig1> <sig2> DROP"], ["Script is 2 CHECKMULTISIGVERIFY <sig1> <sig2> DROP"],
["52af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175"], ["52af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175"],
["Signature is 0 <sig1> <sig2> 2 <key1> <key2>"], ["Signature is 0 <sig1> <sig2> 2 <key1> <key2>"],
["Should pass by replacing (sigversion == SIGVERSION_BASE) with (sigversion != SIGVERSION_BASE) under OP_CHECKMULTISIG"], ["Should pass by replacing (sigversion == SigVersion::BASE) with (sigversion != SigVersion::BASE) under OP_CHECKMULTISIG"],
["Non-segwit: wrong sighash (without FindAndDelete) = 4bc6a53e8e16ef508c19e38bba08831daba85228b0211f323d4cb0999cf2a5e8"], ["Non-segwit: wrong sighash (without FindAndDelete) = 4bc6a53e8e16ef508c19e38bba08831daba85228b0211f323d4cb0999cf2a5e8"],
[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7000, "HASH160 0x14 0x5748407f5ca5cdca53ba30b79040260770c9ee1b EQUAL", 200000]], [[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7000, "HASH160 0x14 0x5748407f5ca5cdca53ba30b79040260770c9ee1b EQUAL", 200000]],
"01000000019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a662896581b0000fd6f01004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596015221023fd5dd42b44769c5653cbc5947ff30ab8871f240ad0c0e7432aefe84b5b4ff3421039d52178dbde360b83f19cf348deb04fa8360e1bf5634577be8e50fafc2b0e4ef4c9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175ffffffff0101000000000000000000000000", "P2SH,WITNESS"], "01000000019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a662896581b0000fd6f01004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596015221023fd5dd42b44769c5653cbc5947ff30ab8871f240ad0c0e7432aefe84b5b4ff3421039d52178dbde360b83f19cf348deb04fa8360e1bf5634577be8e50fafc2b0e4ef4c9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175ffffffff0101000000000000000000000000", "P2SH,WITNESS"],

View file

@ -21,7 +21,7 @@ BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup)
CScript CScript
sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transaction, int whichIn) sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transaction, int whichIn)
{ {
uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL, 0, SIGVERSION_BASE); uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL, 0, SigVersion::BASE);
CScript result; CScript result;
result << OP_0; // CHECKMULTISIG bug workaround result << OP_0; // CHECKMULTISIG bug workaround

View file

@ -267,10 +267,10 @@ struct KeyData
} }
}; };
enum WitnessMode { enum class WitnessMode {
WITNESS_NONE, NONE,
WITNESS_PKH, PKH,
WITNESS_SH SH
}; };
class TestBuilder class TestBuilder
@ -308,15 +308,15 @@ private:
} }
public: public:
TestBuilder(const CScript& script_, const std::string& comment_, int flags_, bool P2SH = false, WitnessMode wm = WITNESS_NONE, int witnessversion = 0, CAmount nValue_ = 0) : script(script_), havePush(false), comment(comment_), flags(flags_), scriptError(SCRIPT_ERR_OK), nValue(nValue_) TestBuilder(const CScript& script_, const std::string& comment_, int flags_, bool P2SH = false, WitnessMode wm = WitnessMode::NONE, int witnessversion = 0, CAmount nValue_ = 0) : script(script_), havePush(false), comment(comment_), flags(flags_), scriptError(SCRIPT_ERR_OK), nValue(nValue_)
{ {
CScript scriptPubKey = script; CScript scriptPubKey = script;
if (wm == WITNESS_PKH) { if (wm == WitnessMode::PKH) {
uint160 hash; uint160 hash;
CHash160().Write(&script[1], script.size() - 1).Finalize(hash.begin()); CHash160().Write(&script[1], script.size() - 1).Finalize(hash.begin());
script = CScript() << OP_DUP << OP_HASH160 << ToByteVector(hash) << OP_EQUALVERIFY << OP_CHECKSIG; script = CScript() << OP_DUP << OP_HASH160 << ToByteVector(hash) << OP_EQUALVERIFY << OP_CHECKSIG;
scriptPubKey = CScript() << witnessversion << ToByteVector(hash); scriptPubKey = CScript() << witnessversion << ToByteVector(hash);
} else if (wm == WITNESS_SH) { } else if (wm == WitnessMode::SH) {
witscript = scriptPubKey; witscript = scriptPubKey;
uint256 hash; uint256 hash;
CSHA256().Write(&witscript[0], witscript.size()).Finalize(hash.begin()); CSHA256().Write(&witscript[0], witscript.size()).Finalize(hash.begin());
@ -361,7 +361,7 @@ public:
return *this; return *this;
} }
TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SIGVERSION_BASE, CAmount amount = 0) TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SigVersion::BASE, CAmount amount = 0)
{ {
uint256 hash = SignatureHash(script, spendTx, 0, nHashType, amount, sigversion); uint256 hash = SignatureHash(script, spendTx, 0, nHashType, amount, sigversion);
std::vector<unsigned char> vchSig, r, s; std::vector<unsigned char> vchSig, r, s;
@ -379,7 +379,7 @@ public:
return *this; return *this;
} }
TestBuilder& PushWitSig(const CKey& key, CAmount amount = -1, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SIGVERSION_WITNESS_V0) TestBuilder& PushWitSig(const CKey& key, CAmount amount = -1, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SigVersion::WITNESS_V0)
{ {
if (amount == -1) if (amount == -1)
amount = nValue; amount = nValue;
@ -747,57 +747,57 @@ BOOST_AUTO_TEST_CASE(script_build)
).PushSig(keys.key0).PushRedeem()); ).PushSig(keys.key0).PushRedeem());
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"Basic P2WSH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH, "Basic P2WSH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH,
0, 1).PushWitSig(keys.key0).PushWitRedeem()); 0, 1).PushWitSig(keys.key0).PushWitRedeem());
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
"Basic P2WPKH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH, "Basic P2WPKH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::PKH,
0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit()); 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit());
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"Basic P2SH(P2WSH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH, "Basic P2SH(P2WSH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::SH,
0, 1).PushWitSig(keys.key0).PushWitRedeem().PushRedeem()); 0, 1).PushWitSig(keys.key0).PushWitRedeem().PushRedeem());
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
"Basic P2SH(P2WPKH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_PKH, "Basic P2SH(P2WPKH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::PKH,
0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().PushRedeem()); 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().PushRedeem());
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
"Basic P2WSH with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH "Basic P2WSH with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH
).PushWitSig(keys.key0).PushWitRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); ).PushWitSig(keys.key0).PushWitRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1), tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1),
"Basic P2WPKH with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH "Basic P2WPKH with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::PKH
).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().ScriptError(SCRIPT_ERR_EVAL_FALSE)); ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().ScriptError(SCRIPT_ERR_EVAL_FALSE));
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
"Basic P2SH(P2WSH) with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH "Basic P2SH(P2WSH) with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::SH
).PushWitSig(keys.key0).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); ).PushWitSig(keys.key0).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1), tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1),
"Basic P2SH(P2WPKH) with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_PKH "Basic P2SH(P2WPKH) with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::PKH
).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
"Basic P2WSH with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, false, WITNESS_SH "Basic P2WSH with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, false, WitnessMode::SH
).PushWitSig(keys.key0).PushWitRedeem()); ).PushWitSig(keys.key0).PushWitRedeem());
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1), tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1),
"Basic P2WPKH with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, false, WITNESS_PKH "Basic P2WPKH with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, false, WitnessMode::PKH
).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit()); ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit());
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
"Basic P2SH(P2WSH) with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, true, WITNESS_SH "Basic P2SH(P2WSH) with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, true, WitnessMode::SH
).PushWitSig(keys.key0).PushWitRedeem().PushRedeem()); ).PushWitSig(keys.key0).PushWitRedeem().PushRedeem());
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1), tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1),
"Basic P2SH(P2WPKH) with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, true, WITNESS_PKH "Basic P2SH(P2WPKH) with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, true, WitnessMode::PKH
).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().PushRedeem()); ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().PushRedeem());
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"Basic P2WSH with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH, "Basic P2WSH with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH,
0, 0).PushWitSig(keys.key0, 1).PushWitRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); 0, 0).PushWitSig(keys.key0, 1).PushWitRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
"Basic P2WPKH with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH, "Basic P2WPKH with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::PKH,
0, 0).PushWitSig(keys.key0, 1).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_EVAL_FALSE)); 0, 0).PushWitSig(keys.key0, 1).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_EVAL_FALSE));
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"Basic P2SH(P2WSH) with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH, "Basic P2SH(P2WSH) with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::SH,
0, 0).PushWitSig(keys.key0, 1).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); 0, 0).PushWitSig(keys.key0, 1).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
"Basic P2SH(P2WPKH) with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_PKH, "Basic P2SH(P2WPKH) with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::PKH,
0, 0).PushWitSig(keys.key0, 1).Push(keys.pubkey0).AsWit().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE)); 0, 0).PushWitSig(keys.key0, 1).Push(keys.pubkey0).AsWit().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
"P2WPKH with future witness version", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | "P2WPKH with future witness version", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH |
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM, false, WITNESS_PKH, 1 SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM, false, WitnessMode::PKH, 1
).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)); ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM));
{ {
CScript witscript = CScript() << ToByteVector(keys.pubkey0); CScript witscript = CScript() << ToByteVector(keys.pubkey0);
@ -810,22 +810,22 @@ BOOST_AUTO_TEST_CASE(script_build)
).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH)); ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH));
} }
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"P2WSH with empty witness", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH "P2WSH with empty witness", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH
).ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY)); ).ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY));
{ {
CScript witscript = CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG; CScript witscript = CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG;
tests.push_back(TestBuilder(witscript, tests.push_back(TestBuilder(witscript,
"P2WSH with witness program mismatch", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH "P2WSH with witness program mismatch", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH
).PushWitSig(keys.key0).Push(witscript).DamagePush(0).AsWit().ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH)); ).PushWitSig(keys.key0).Push(witscript).DamagePush(0).AsWit().ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH));
} }
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
"P2WPKH with witness program mismatch", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH "P2WPKH with witness program mismatch", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::PKH
).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().Push("0").AsWit().ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH)); ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().Push("0").AsWit().ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH));
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
"P2WPKH with non-empty scriptSig", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_PKH "P2WPKH with non-empty scriptSig", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::PKH
).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().Num(11).ScriptError(SCRIPT_ERR_WITNESS_MALLEATED)); ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().Num(11).ScriptError(SCRIPT_ERR_WITNESS_MALLEATED));
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1), tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1),
"P2SH(P2WPKH) with superfluous push in scriptSig", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_PKH "P2SH(P2WPKH) with superfluous push in scriptSig", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::PKH
).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().Num(11).PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_MALLEATED_P2SH)); ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().Num(11).PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_MALLEATED_P2SH));
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"P2PK with witness", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH "P2PK with witness", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH
@ -833,95 +833,95 @@ BOOST_AUTO_TEST_CASE(script_build)
// Compressed keys should pass SCRIPT_VERIFY_WITNESS_PUBKEYTYPE // Compressed keys should pass SCRIPT_VERIFY_WITNESS_PUBKEYTYPE
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
"Basic P2WSH with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, "Basic P2WSH with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::SH,
0, 1).PushWitSig(keys.key0C).PushWitRedeem()); 0, 1).PushWitSig(keys.key0C).PushWitRedeem());
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C), tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C),
"Basic P2WPKH with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_PKH, "Basic P2WPKH with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::PKH,
0, 1).PushWitSig(keys.key0C).Push(keys.pubkey0C).AsWit()); 0, 1).PushWitSig(keys.key0C).Push(keys.pubkey0C).AsWit());
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
"Basic P2SH(P2WSH) with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, "Basic P2SH(P2WSH) with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::SH,
0, 1).PushWitSig(keys.key0C).PushWitRedeem().PushRedeem()); 0, 1).PushWitSig(keys.key0C).PushWitRedeem().PushRedeem());
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C), tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C),
"Basic P2SH(P2WPKH) with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_PKH, "Basic P2SH(P2WPKH) with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::PKH,
0, 1).PushWitSig(keys.key0C).Push(keys.pubkey0C).AsWit().PushRedeem()); 0, 1).PushWitSig(keys.key0C).Push(keys.pubkey0C).AsWit().PushRedeem());
// Testing uncompressed key in witness with SCRIPT_VERIFY_WITNESS_PUBKEYTYPE // Testing uncompressed key in witness with SCRIPT_VERIFY_WITNESS_PUBKEYTYPE
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"Basic P2WSH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, "Basic P2WSH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::SH,
0, 1).PushWitSig(keys.key0).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); 0, 1).PushWitSig(keys.key0).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
"Basic P2WPKH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_PKH, "Basic P2WPKH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::PKH,
0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"Basic P2SH(P2WSH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, "Basic P2SH(P2WSH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::SH,
0, 1).PushWitSig(keys.key0).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); 0, 1).PushWitSig(keys.key0).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
"Basic P2SH(P2WPKH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_PKH, "Basic P2SH(P2WPKH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::PKH,
0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
// P2WSH 1-of-2 multisig with compressed keys // P2WSH 1-of-2 multisig with compressed keys
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
"P2WSH CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, "P2WSH CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem()); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem());
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
"P2SH(P2WSH) CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, "P2SH(P2WSH) CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem()); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem());
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
"P2WSH CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, "P2WSH CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem()); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem());
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
"P2SH(P2WSH) CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, "P2SH(P2WSH) CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem()); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem());
// P2WSH 1-of-2 multisig with first key uncompressed // P2WSH 1-of-2 multisig with first key uncompressed
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG,
"P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH, "P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem()); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem());
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG,
"P2SH(P2WSH) CHECKMULTISIG first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH, "P2SH(P2WSH) CHECKMULTISIG first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().PushRedeem()); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().PushRedeem());
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG,
"P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, "P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG,
"P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG,
"P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH, "P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem()); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem());
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG,
"P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH, "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem()); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem());
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG,
"P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, "P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG,
"P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
// P2WSH 1-of-2 multisig with second key uncompressed // P2WSH 1-of-2 multisig with second key uncompressed
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
"P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH, "P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem()); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem());
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
"P2SH(P2WSH) CHECKMULTISIG second key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH, "P2SH(P2WSH) CHECKMULTISIG second key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem()); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem());
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
"P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, "P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem()); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem());
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
"P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem()); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem());
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
"P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH, "P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem()); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem());
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
"P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH, "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().PushRedeem()); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().PushRedeem());
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
"P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, "P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
"P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::SH,
0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
std::set<std::string> tests_set; std::set<std::string> tests_set;
@ -1009,21 +1009,21 @@ BOOST_AUTO_TEST_CASE(script_PushData)
ScriptError err; ScriptError err;
std::vector<std::vector<unsigned char> > directStack; std::vector<std::vector<unsigned char> > directStack;
BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SIGVERSION_BASE, &err)); BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
std::vector<std::vector<unsigned char> > pushdata1Stack; std::vector<std::vector<unsigned char> > pushdata1Stack;
BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SIGVERSION_BASE, &err)); BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
BOOST_CHECK(pushdata1Stack == directStack); BOOST_CHECK(pushdata1Stack == directStack);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
std::vector<std::vector<unsigned char> > pushdata2Stack; std::vector<std::vector<unsigned char> > pushdata2Stack;
BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SIGVERSION_BASE, &err)); BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
BOOST_CHECK(pushdata2Stack == directStack); BOOST_CHECK(pushdata2Stack == directStack);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
std::vector<std::vector<unsigned char> > pushdata4Stack; std::vector<std::vector<unsigned char> > pushdata4Stack;
BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SIGVERSION_BASE, &err)); BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
BOOST_CHECK(pushdata4Stack == directStack); BOOST_CHECK(pushdata4Stack == directStack);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
} }
@ -1031,7 +1031,7 @@ BOOST_AUTO_TEST_CASE(script_PushData)
CScript CScript
sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transaction) sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transaction)
{ {
uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL, 0, SIGVERSION_BASE); uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL, 0, SigVersion::BASE);
CScript result; CScript result;
// //
@ -1227,15 +1227,15 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
// A couple of partially-signed versions: // A couple of partially-signed versions:
std::vector<unsigned char> sig1; std::vector<unsigned char> sig1;
uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL, 0, SIGVERSION_BASE); uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL, 0, SigVersion::BASE);
BOOST_CHECK(keys[0].Sign(hash1, sig1)); BOOST_CHECK(keys[0].Sign(hash1, sig1));
sig1.push_back(SIGHASH_ALL); sig1.push_back(SIGHASH_ALL);
std::vector<unsigned char> sig2; std::vector<unsigned char> sig2;
uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE, 0, SIGVERSION_BASE); uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE, 0, SigVersion::BASE);
BOOST_CHECK(keys[1].Sign(hash2, sig2)); BOOST_CHECK(keys[1].Sign(hash2, sig2));
sig2.push_back(SIGHASH_NONE); sig2.push_back(SIGHASH_NONE);
std::vector<unsigned char> sig3; std::vector<unsigned char> sig3;
uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE, 0, SIGVERSION_BASE); uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE, 0, SigVersion::BASE);
BOOST_CHECK(keys[2].Sign(hash3, sig3)); BOOST_CHECK(keys[2].Sign(hash3, sig3));
sig3.push_back(SIGHASH_SINGLE); sig3.push_back(SIGHASH_SINGLE);

View file

@ -138,7 +138,7 @@ BOOST_AUTO_TEST_CASE(sighash_test)
uint256 sh, sho; uint256 sh, sho;
sho = SignatureHashOld(scriptCode, txTo, nIn, nHashType); sho = SignatureHashOld(scriptCode, txTo, nIn, nHashType);
sh = SignatureHash(scriptCode, txTo, nIn, nHashType, 0, SIGVERSION_BASE); sh = SignatureHash(scriptCode, txTo, nIn, nHashType, 0, SigVersion::BASE);
#if defined(PRINT_SIGHASH_JSON) #if defined(PRINT_SIGHASH_JSON)
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << txTo; ss << txTo;
@ -204,7 +204,7 @@ BOOST_AUTO_TEST_CASE(sighash_from_data)
continue; continue;
} }
sh = SignatureHash(scriptCode, *tx, nIn, nHashType, 0, SIGVERSION_BASE); sh = SignatureHash(scriptCode, *tx, nIn, nHashType, 0, SigVersion::BASE);
BOOST_CHECK_MESSAGE(sh.GetHex() == sigHashHex, strTest); BOOST_CHECK_MESSAGE(sh.GetHex() == sigHashHex, strTest);
} }
} }

View file

@ -407,7 +407,7 @@ static CScript PushAll(const std::vector<valtype>& values)
void ReplaceRedeemScript(CScript& script, const CScript& redeemScript) void ReplaceRedeemScript(CScript& script, const CScript& redeemScript)
{ {
std::vector<valtype> stack; std::vector<valtype> stack;
EvalScript(stack, script, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), SIGVERSION_BASE); EvalScript(stack, script, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), SigVersion::BASE);
assert(stack.size() > 0); assert(stack.size() > 0);
stack.back() = std::vector<unsigned char>(redeemScript.begin(), redeemScript.end()); stack.back() = std::vector<unsigned char>(redeemScript.begin(), redeemScript.end());
script = PushAll(stack); script = PushAll(stack);

View file

@ -56,7 +56,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
// Sign: // Sign:
std::vector<unsigned char> vchSig; std::vector<unsigned char> vchSig;
uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, SIGHASH_ALL, 0, SIGVERSION_BASE); uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, SIGHASH_ALL, 0, SigVersion::BASE);
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
vchSig.push_back((unsigned char)SIGHASH_ALL); vchSig.push_back((unsigned char)SIGHASH_ALL);
spends[i].vin[0].scriptSig << vchSig; spends[i].vin[0].scriptSig << vchSig;
@ -182,7 +182,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
// Sign, with a non-DER signature // Sign, with a non-DER signature
{ {
std::vector<unsigned char> vchSig; std::vector<unsigned char> vchSig;
uint256 hash = SignatureHash(p2pk_scriptPubKey, spend_tx, 0, SIGHASH_ALL, 0, SIGVERSION_BASE); uint256 hash = SignatureHash(p2pk_scriptPubKey, spend_tx, 0, SIGHASH_ALL, 0, SigVersion::BASE);
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
vchSig.push_back((unsigned char) 0); // padding byte makes this non-DER vchSig.push_back((unsigned char) 0); // padding byte makes this non-DER
vchSig.push_back((unsigned char)SIGHASH_ALL); vchSig.push_back((unsigned char)SIGHASH_ALL);
@ -256,7 +256,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
// Sign // Sign
std::vector<unsigned char> vchSig; std::vector<unsigned char> vchSig;
uint256 hash = SignatureHash(spend_tx.vout[2].scriptPubKey, invalid_with_cltv_tx, 0, SIGHASH_ALL, 0, SIGVERSION_BASE); uint256 hash = SignatureHash(spend_tx.vout[2].scriptPubKey, invalid_with_cltv_tx, 0, SIGHASH_ALL, 0, SigVersion::BASE);
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
vchSig.push_back((unsigned char)SIGHASH_ALL); vchSig.push_back((unsigned char)SIGHASH_ALL);
invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 101; invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 101;
@ -284,7 +284,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
// Sign // Sign
std::vector<unsigned char> vchSig; std::vector<unsigned char> vchSig;
uint256 hash = SignatureHash(spend_tx.vout[3].scriptPubKey, invalid_with_csv_tx, 0, SIGHASH_ALL, 0, SIGVERSION_BASE); uint256 hash = SignatureHash(spend_tx.vout[3].scriptPubKey, invalid_with_csv_tx, 0, SIGHASH_ALL, 0, SigVersion::BASE);
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
vchSig.push_back((unsigned char)SIGHASH_ALL); vchSig.push_back((unsigned char)SIGHASH_ALL);
invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 101; invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 101;

View file

@ -101,8 +101,8 @@ public:
VersionBitsTester& TestDefined() { VersionBitsTester& TestDefined() {
for (int i = 0; i < CHECKERS; i++) { for (int i = 0; i < CHECKERS; i++) {
if (InsecureRandBits(i) == 0) { if (InsecureRandBits(i) == 0) {
BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_DEFINED, strprintf("Test %i for DEFINED", num)); BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::DEFINED, strprintf("Test %i for DEFINED", num));
BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE (always active)", num)); BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE (always active)", num));
} }
} }
num++; num++;
@ -112,8 +112,8 @@ public:
VersionBitsTester& TestStarted() { VersionBitsTester& TestStarted() {
for (int i = 0; i < CHECKERS; i++) { for (int i = 0; i < CHECKERS; i++) {
if (InsecureRandBits(i) == 0) { if (InsecureRandBits(i) == 0) {
BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_STARTED, strprintf("Test %i for STARTED", num)); BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::STARTED, strprintf("Test %i for STARTED", num));
BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE (always active)", num)); BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE (always active)", num));
} }
} }
num++; num++;
@ -123,8 +123,8 @@ public:
VersionBitsTester& TestLockedIn() { VersionBitsTester& TestLockedIn() {
for (int i = 0; i < CHECKERS; i++) { for (int i = 0; i < CHECKERS; i++) {
if (InsecureRandBits(i) == 0) { if (InsecureRandBits(i) == 0) {
BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_LOCKED_IN, strprintf("Test %i for LOCKED_IN", num)); BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::LOCKED_IN, strprintf("Test %i for LOCKED_IN", num));
BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE (always active)", num)); BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE (always active)", num));
} }
} }
num++; num++;
@ -134,8 +134,8 @@ public:
VersionBitsTester& TestActive() { VersionBitsTester& TestActive() {
for (int i = 0; i < CHECKERS; i++) { for (int i = 0; i < CHECKERS; i++) {
if (InsecureRandBits(i) == 0) { if (InsecureRandBits(i) == 0) {
BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE", num)); BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE", num));
BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE (always active)", num)); BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE (always active)", num));
} }
} }
num++; num++;
@ -145,8 +145,8 @@ public:
VersionBitsTester& TestFailed() { VersionBitsTester& TestFailed() {
for (int i = 0; i < CHECKERS; i++) { for (int i = 0; i < CHECKERS; i++) {
if (InsecureRandBits(i) == 0) { if (InsecureRandBits(i) == 0) {
BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_FAILED, strprintf("Test %i for FAILED", num)); BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::FAILED, strprintf("Test %i for FAILED", num));
BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE (always active)", num)); BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE (always active)", num));
} }
} }
num++; num++;

View file

@ -280,11 +280,11 @@ std::unique_ptr<CCoinsViewDB> pcoinsdbview;
std::unique_ptr<CCoinsViewCache> pcoinsTip; std::unique_ptr<CCoinsViewCache> pcoinsTip;
std::unique_ptr<CBlockTreeDB> pblocktree; std::unique_ptr<CBlockTreeDB> pblocktree;
enum FlushStateMode { enum class FlushStateMode {
FLUSH_STATE_NONE, NONE,
FLUSH_STATE_IF_NEEDED, IF_NEEDED,
FLUSH_STATE_PERIODIC, PERIODIC,
FLUSH_STATE_ALWAYS ALWAYS
}; };
// See definition for documentation // See definition for documentation
@ -983,7 +983,7 @@ static bool AcceptToMemoryPoolWithTime(const CChainParams& chainparams, CTxMemPo
} }
// After we've (potentially) uncached entries, ensure our coins cache is still within its size limits // After we've (potentially) uncached entries, ensure our coins cache is still within its size limits
CValidationState stateDummy; CValidationState stateDummy;
FlushStateToDisk(chainparams, stateDummy, FLUSH_STATE_PERIODIC); FlushStateToDisk(chainparams, stateDummy, FlushStateMode::PERIODIC);
return res; return res;
} }
@ -1684,7 +1684,7 @@ int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Para
for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) { for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
ThresholdState state = VersionBitsState(pindexPrev, params, static_cast<Consensus::DeploymentPos>(i), versionbitscache); ThresholdState state = VersionBitsState(pindexPrev, params, static_cast<Consensus::DeploymentPos>(i), versionbitscache);
if (state == THRESHOLD_LOCKED_IN || state == THRESHOLD_STARTED) { if (state == ThresholdState::LOCKED_IN || state == ThresholdState::STARTED) {
nVersion |= VersionBitsMask(params, static_cast<Consensus::DeploymentPos>(i)); nVersion |= VersionBitsMask(params, static_cast<Consensus::DeploymentPos>(i));
} }
} }
@ -1740,7 +1740,7 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consens
} }
// Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY) using versionbits logic. // Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY) using versionbits logic.
if (VersionBitsState(pindex->pprev, consensusparams, Consensus::DEPLOYMENT_CSV, versionbitscache) == THRESHOLD_ACTIVE) { if (VersionBitsState(pindex->pprev, consensusparams, Consensus::DEPLOYMENT_CSV, versionbitscache) == ThresholdState::ACTIVE) {
flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
} }
@ -1926,7 +1926,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
// Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY) using versionbits logic. // Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY) using versionbits logic.
int nLockTimeFlags = 0; int nLockTimeFlags = 0;
if (VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_CSV, versionbitscache) == THRESHOLD_ACTIVE) { if (VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_CSV, versionbitscache) == ThresholdState::ACTIVE) {
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE; nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
} }
@ -2096,15 +2096,15 @@ bool static FlushStateToDisk(const CChainParams& chainparams, CValidationState &
int64_t cacheSize = pcoinsTip->DynamicMemoryUsage(); int64_t cacheSize = pcoinsTip->DynamicMemoryUsage();
int64_t nTotalSpace = nCoinCacheUsage + std::max<int64_t>(nMempoolSizeMax - nMempoolUsage, 0); int64_t nTotalSpace = nCoinCacheUsage + std::max<int64_t>(nMempoolSizeMax - nMempoolUsage, 0);
// The cache is large and we're within 10% and 10 MiB of the limit, but we have time now (not in the middle of a block processing). // The cache is large and we're within 10% and 10 MiB of the limit, but we have time now (not in the middle of a block processing).
bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize > std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE * 1024 * 1024); bool fCacheLarge = mode == FlushStateMode::PERIODIC && cacheSize > std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE * 1024 * 1024);
// The cache is over the limit, we have to write now. // The cache is over the limit, we have to write now.
bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && cacheSize > nTotalSpace; bool fCacheCritical = mode == FlushStateMode::IF_NEEDED && cacheSize > nTotalSpace;
// It's been a while since we wrote the block index to disk. Do this frequently, so we don't need to redownload after a crash. // It's been a while since we wrote the block index to disk. Do this frequently, so we don't need to redownload after a crash.
bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000; bool fPeriodicWrite = mode == FlushStateMode::PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000;
// It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage. // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000; bool fPeriodicFlush = mode == FlushStateMode::PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000;
// Combine all conditions that result in a full cache flush. // Combine all conditions that result in a full cache flush.
fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune; fDoFullFlush = (mode == FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
// Write blocks and block index to disk. // Write blocks and block index to disk.
if (fDoFullFlush || fPeriodicWrite) { if (fDoFullFlush || fPeriodicWrite) {
// Depend on nMinDiskSpace to ensure we can write block index // Depend on nMinDiskSpace to ensure we can write block index
@ -2150,7 +2150,7 @@ bool static FlushStateToDisk(const CChainParams& chainparams, CValidationState &
nLastFlush = nNow; nLastFlush = nNow;
} }
} }
if (fDoFullFlush || ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000)) { if (fDoFullFlush || ((mode == FlushStateMode::ALWAYS || mode == FlushStateMode::PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000)) {
// Update best block in wallet (so we can detect restored wallets). // Update best block in wallet (so we can detect restored wallets).
GetMainSignals().SetBestChain(chainActive.GetLocator()); GetMainSignals().SetBestChain(chainActive.GetLocator());
nLastSetChain = nNow; nLastSetChain = nNow;
@ -2164,14 +2164,14 @@ bool static FlushStateToDisk(const CChainParams& chainparams, CValidationState &
void FlushStateToDisk() { void FlushStateToDisk() {
CValidationState state; CValidationState state;
const CChainParams& chainparams = Params(); const CChainParams& chainparams = Params();
FlushStateToDisk(chainparams, state, FLUSH_STATE_ALWAYS); FlushStateToDisk(chainparams, state, FlushStateMode::ALWAYS);
} }
void PruneAndFlush() { void PruneAndFlush() {
CValidationState state; CValidationState state;
fCheckForPruning = true; fCheckForPruning = true;
const CChainParams& chainparams = Params(); const CChainParams& chainparams = Params();
FlushStateToDisk(chainparams, state, FLUSH_STATE_NONE); FlushStateToDisk(chainparams, state, FlushStateMode::NONE);
} }
static void DoWarning(const std::string& strWarning) static void DoWarning(const std::string& strWarning)
@ -2199,9 +2199,9 @@ void static UpdateTip(const CBlockIndex *pindexNew, const CChainParams& chainPar
for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) { for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) {
WarningBitsConditionChecker checker(bit); WarningBitsConditionChecker checker(bit);
ThresholdState state = checker.GetStateFor(pindex, chainParams.GetConsensus(), warningcache[bit]); ThresholdState state = checker.GetStateFor(pindex, chainParams.GetConsensus(), warningcache[bit]);
if (state == THRESHOLD_ACTIVE || state == THRESHOLD_LOCKED_IN) { if (state == ThresholdState::ACTIVE || state == ThresholdState::LOCKED_IN) {
const std::string strWarning = strprintf(_("Warning: unknown new rules activated (versionbit %i)"), bit); const std::string strWarning = strprintf(_("Warning: unknown new rules activated (versionbit %i)"), bit);
if (state == THRESHOLD_ACTIVE) { if (state == ThresholdState::ACTIVE) {
DoWarning(strWarning); DoWarning(strWarning);
} else { } else {
warningMessages.push_back(strWarning); warningMessages.push_back(strWarning);
@ -2267,7 +2267,7 @@ bool CChainState::DisconnectTip(CValidationState& state, const CChainParams& cha
} }
LogPrint(BCLog::BENCH, "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * MILLI); LogPrint(BCLog::BENCH, "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * MILLI);
// Write the chain state to disk, if necessary. // Write the chain state to disk, if necessary.
if (!FlushStateToDisk(chainparams, state, FLUSH_STATE_IF_NEEDED)) if (!FlushStateToDisk(chainparams, state, FlushStateMode::IF_NEEDED))
return false; return false;
if (disconnectpool) { if (disconnectpool) {
@ -2405,7 +2405,7 @@ bool CChainState::ConnectTip(CValidationState& state, const CChainParams& chainp
int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3; int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
LogPrint(BCLog::BENCH, " - Flush: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime4 - nTime3) * MILLI, nTimeFlush * MICRO, nTimeFlush * MILLI / nBlocksTotal); LogPrint(BCLog::BENCH, " - Flush: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime4 - nTime3) * MILLI, nTimeFlush * MICRO, nTimeFlush * MILLI / nBlocksTotal);
// Write the chain state to disk, if necessary. // Write the chain state to disk, if necessary.
if (!FlushStateToDisk(chainparams, state, FLUSH_STATE_IF_NEEDED)) if (!FlushStateToDisk(chainparams, state, FlushStateMode::IF_NEEDED))
return false; return false;
int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4; int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
LogPrint(BCLog::BENCH, " - Writing chainstate: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime5 - nTime4) * MILLI, nTimeChainState * MICRO, nTimeChainState * MILLI / nBlocksTotal); LogPrint(BCLog::BENCH, " - Writing chainstate: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime5 - nTime4) * MILLI, nTimeChainState * MICRO, nTimeChainState * MILLI / nBlocksTotal);
@ -2682,7 +2682,7 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
CheckBlockIndex(chainparams.GetConsensus()); CheckBlockIndex(chainparams.GetConsensus());
// Write changes periodically to disk, after relay. // Write changes periodically to disk, after relay.
if (!FlushStateToDisk(chainparams, state, FLUSH_STATE_PERIODIC)) { if (!FlushStateToDisk(chainparams, state, FlushStateMode::PERIODIC)) {
return false; return false;
} }
@ -3076,7 +3076,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params) bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params)
{ {
LOCK(cs_main); LOCK(cs_main);
return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == THRESHOLD_ACTIVE); return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == ThresholdState::ACTIVE);
} }
// Compute at which vout of the block's coinbase transaction the witness // Compute at which vout of the block's coinbase transaction the witness
@ -3195,7 +3195,7 @@ static bool ContextualCheckBlock(const CBlock& block, CValidationState& state, c
// Start enforcing BIP113 (Median Time Past) using versionbits logic. // Start enforcing BIP113 (Median Time Past) using versionbits logic.
int nLockTimeFlags = 0; int nLockTimeFlags = 0;
if (VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CSV, versionbitscache) == THRESHOLD_ACTIVE) { if (VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CSV, versionbitscache) == ThresholdState::ACTIVE) {
nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST; nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST;
} }
@ -3229,7 +3229,7 @@ static bool ContextualCheckBlock(const CBlock& block, CValidationState& state, c
// {0xaa, 0x21, 0xa9, 0xed}, and the following 32 bytes are SHA256^2(witness root, witness nonce). In case there are // {0xaa, 0x21, 0xa9, 0xed}, and the following 32 bytes are SHA256^2(witness root, witness nonce). In case there are
// multiple, the last one is used. // multiple, the last one is used.
bool fHaveWitness = false; bool fHaveWitness = false;
if (VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == THRESHOLD_ACTIVE) { if (VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == ThresholdState::ACTIVE) {
int commitpos = GetWitnessCommitmentIndex(block); int commitpos = GetWitnessCommitmentIndex(block);
if (commitpos != -1) { if (commitpos != -1) {
bool malleated = false; bool malleated = false;
@ -3443,7 +3443,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CVali
} }
if (fCheckForPruning) if (fCheckForPruning)
FlushStateToDisk(chainparams, state, FLUSH_STATE_NONE); // we just allocated more disk space for block files FlushStateToDisk(chainparams, state, FlushStateMode::NONE); // we just allocated more disk space for block files
CheckBlockIndex(chainparams.GetConsensus()); CheckBlockIndex(chainparams.GetConsensus());
@ -3596,7 +3596,7 @@ void PruneBlockFilesManual(int nManualPruneHeight)
{ {
CValidationState state; CValidationState state;
const CChainParams& chainparams = Params(); const CChainParams& chainparams = Params();
FlushStateToDisk(chainparams, state, FLUSH_STATE_NONE, nManualPruneHeight); FlushStateToDisk(chainparams, state, FlushStateMode::NONE, nManualPruneHeight);
} }
/** /**
@ -4094,7 +4094,7 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
return error("RewindBlockIndex: unable to disconnect block at height %i", pindex->nHeight); return error("RewindBlockIndex: unable to disconnect block at height %i", pindex->nHeight);
} }
// Occasionally flush state to disk. // Occasionally flush state to disk.
if (!FlushStateToDisk(params, state, FLUSH_STATE_PERIODIC)) if (!FlushStateToDisk(params, state, FlushStateMode::PERIODIC))
return false; return false;
} }
@ -4160,7 +4160,7 @@ bool RewindBlockIndex(const CChainParams& params) {
// and skip it here, we're about to -reindex-chainstate anyway, so // and skip it here, we're about to -reindex-chainstate anyway, so
// it'll get called a bunch real soon. // it'll get called a bunch real soon.
CValidationState state; CValidationState state;
if (!FlushStateToDisk(params, state, FLUSH_STATE_ALWAYS)) { if (!FlushStateToDisk(params, state, FlushStateMode::ALWAYS)) {
return false; return false;
} }
} }

View file

@ -29,7 +29,7 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
// Check if this deployment is always active. // Check if this deployment is always active.
if (nTimeStart == Consensus::BIP9Deployment::ALWAYS_ACTIVE) { if (nTimeStart == Consensus::BIP9Deployment::ALWAYS_ACTIVE) {
return THRESHOLD_ACTIVE; return ThresholdState::ACTIVE;
} }
// A block's state is always the same as that of the first of its period, so it is computed based on a pindexPrev whose height equals a multiple of nPeriod - 1. // A block's state is always the same as that of the first of its period, so it is computed based on a pindexPrev whose height equals a multiple of nPeriod - 1.
@ -42,12 +42,12 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
while (cache.count(pindexPrev) == 0) { while (cache.count(pindexPrev) == 0) {
if (pindexPrev == nullptr) { if (pindexPrev == nullptr) {
// The genesis block is by definition defined. // The genesis block is by definition defined.
cache[pindexPrev] = THRESHOLD_DEFINED; cache[pindexPrev] = ThresholdState::DEFINED;
break; break;
} }
if (pindexPrev->GetMedianTimePast() < nTimeStart) { if (pindexPrev->GetMedianTimePast() < nTimeStart) {
// Optimization: don't recompute down further, as we know every earlier block will be before the start time // Optimization: don't recompute down further, as we know every earlier block will be before the start time
cache[pindexPrev] = THRESHOLD_DEFINED; cache[pindexPrev] = ThresholdState::DEFINED;
break; break;
} }
vToCompute.push_back(pindexPrev); vToCompute.push_back(pindexPrev);
@ -65,17 +65,17 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
vToCompute.pop_back(); vToCompute.pop_back();
switch (state) { switch (state) {
case THRESHOLD_DEFINED: { case ThresholdState::DEFINED: {
if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) { if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
stateNext = THRESHOLD_FAILED; stateNext = ThresholdState::FAILED;
} else if (pindexPrev->GetMedianTimePast() >= nTimeStart) { } else if (pindexPrev->GetMedianTimePast() >= nTimeStart) {
stateNext = THRESHOLD_STARTED; stateNext = ThresholdState::STARTED;
} }
break; break;
} }
case THRESHOLD_STARTED: { case ThresholdState::STARTED: {
if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) { if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
stateNext = THRESHOLD_FAILED; stateNext = ThresholdState::FAILED;
break; break;
} }
// We need to count // We need to count
@ -88,17 +88,17 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
pindexCount = pindexCount->pprev; pindexCount = pindexCount->pprev;
} }
if (count >= nThreshold) { if (count >= nThreshold) {
stateNext = THRESHOLD_LOCKED_IN; stateNext = ThresholdState::LOCKED_IN;
} }
break; break;
} }
case THRESHOLD_LOCKED_IN: { case ThresholdState::LOCKED_IN: {
// Always progresses into ACTIVE. // Always progresses into ACTIVE.
stateNext = THRESHOLD_ACTIVE; stateNext = ThresholdState::ACTIVE;
break; break;
} }
case THRESHOLD_FAILED: case ThresholdState::FAILED:
case THRESHOLD_ACTIVE: { case ThresholdState::ACTIVE: {
// Nothing happens, these are terminal states. // Nothing happens, these are terminal states.
break; break;
} }
@ -149,7 +149,7 @@ int AbstractThresholdConditionChecker::GetStateSinceHeightFor(const CBlockIndex*
const ThresholdState initialState = GetStateFor(pindexPrev, params, cache); const ThresholdState initialState = GetStateFor(pindexPrev, params, cache);
// BIP 9 about state DEFINED: "The genesis block is by definition in this state for each deployment." // BIP 9 about state DEFINED: "The genesis block is by definition in this state for each deployment."
if (initialState == THRESHOLD_DEFINED) { if (initialState == ThresholdState::DEFINED) {
return 0; return 0;
} }

View file

@ -17,12 +17,12 @@ static const int32_t VERSIONBITS_TOP_MASK = 0xE0000000UL;
/** Total bits available for versionbits */ /** Total bits available for versionbits */
static const int32_t VERSIONBITS_NUM_BITS = 29; static const int32_t VERSIONBITS_NUM_BITS = 29;
enum ThresholdState { enum class ThresholdState {
THRESHOLD_DEFINED, DEFINED,
THRESHOLD_STARTED, STARTED,
THRESHOLD_LOCKED_IN, LOCKED_IN,
THRESHOLD_ACTIVE, ACTIVE,
THRESHOLD_FAILED, FAILED,
}; };
// A map that gives the state for blocks whose height is a multiple of Period(). // A map that gives the state for blocks whose height is a multiple of Period().

View file

@ -235,13 +235,13 @@ CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, recoverFunc_type
Db db(dbenv.get(), 0); Db db(dbenv.get(), 0);
int result = db.verify(strFile.c_str(), nullptr, nullptr, 0); int result = db.verify(strFile.c_str(), nullptr, nullptr, 0);
if (result == 0) if (result == 0)
return VERIFY_OK; return VerifyResult::VERIFY_OK;
else if (recoverFunc == nullptr) else if (recoverFunc == nullptr)
return RECOVER_FAIL; return VerifyResult::RECOVER_FAIL;
// Try to recover: // Try to recover:
bool fRecovered = (*recoverFunc)(fs::path(strPath) / strFile, out_backup_filename); bool fRecovered = (*recoverFunc)(fs::path(strPath) / strFile, out_backup_filename);
return (fRecovered ? RECOVER_OK : RECOVER_FAIL); return (fRecovered ? VerifyResult::RECOVER_OK : VerifyResult::RECOVER_FAIL);
} }
bool CDB::Recover(const fs::path& file_path, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& newFilename) bool CDB::Recover(const fs::path& file_path, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& newFilename)
@ -347,7 +347,7 @@ bool CDB::VerifyDatabaseFile(const fs::path& file_path, std::string& warningStr,
{ {
std::string backup_filename; std::string backup_filename;
CDBEnv::VerifyResult r = env->Verify(walletFile, recoverFunc, backup_filename); CDBEnv::VerifyResult r = env->Verify(walletFile, recoverFunc, backup_filename);
if (r == CDBEnv::RECOVER_OK) if (r == CDBEnv::VerifyResult::RECOVER_OK)
{ {
warningStr = strprintf(_("Warning: Wallet file corrupt, data salvaged!" warningStr = strprintf(_("Warning: Wallet file corrupt, data salvaged!"
" Original %s saved as %s in %s; if" " Original %s saved as %s in %s; if"
@ -355,7 +355,7 @@ bool CDB::VerifyDatabaseFile(const fs::path& file_path, std::string& warningStr,
" restore from a backup."), " restore from a backup."),
walletFile, backup_filename, walletDir); walletFile, backup_filename, walletDir);
} }
if (r == CDBEnv::RECOVER_FAIL) if (r == CDBEnv::VerifyResult::RECOVER_FAIL)
{ {
errorStr = strprintf(_("%s corrupt, salvage failed"), walletFile); errorStr = strprintf(_("%s corrupt, salvage failed"), walletFile);
return false; return false;

View file

@ -53,7 +53,7 @@ public:
* This must be called BEFORE strFile is opened. * This must be called BEFORE strFile is opened.
* Returns true if strFile is OK. * Returns true if strFile is OK.
*/ */
enum VerifyResult { VERIFY_OK, enum class VerifyResult { VERIFY_OK,
RECOVER_OK, RECOVER_OK,
RECOVER_FAIL }; RECOVER_FAIL };
typedef bool (*recoverFunc_type)(const fs::path& file_path, std::string& out_backup_filename); typedef bool (*recoverFunc_type)(const fs::path& file_path, std::string& out_backup_filename);

View file

@ -406,7 +406,7 @@ UniValue removeprunedfunds(const JSONRPCRequest& request)
vHash.push_back(hash); vHash.push_back(hash);
std::vector<uint256> vHashOut; std::vector<uint256> vHashOut;
if (pwallet->ZapSelectTx(vHash, vHashOut) != DB_LOAD_OK) { if (pwallet->ZapSelectTx(vHash, vHashOut) != DBErrors::LOAD_OK) {
throw JSONRPCError(RPC_WALLET_ERROR, "Could not properly delete the transaction."); throw JSONRPCError(RPC_WALLET_ERROR, "Could not properly delete the transaction.");
} }

View file

@ -113,9 +113,9 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
if (confirms <= 0) { if (confirms <= 0) {
LOCK(mempool.cs); LOCK(mempool.cs);
RBFTransactionState rbfState = IsRBFOptIn(*wtx.tx, mempool); RBFTransactionState rbfState = IsRBFOptIn(*wtx.tx, mempool);
if (rbfState == RBF_TRANSACTIONSTATE_UNKNOWN) if (rbfState == RBFTransactionState::UNKNOWN)
rbfStatus = "unknown"; rbfStatus = "unknown";
else if (rbfState == RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125) else if (rbfState == RBFTransactionState::REPLACEABLE_BIP125)
rbfStatus = "yes"; rbfStatus = "yes";
} }
entry.pushKV("bip125-replaceable", rbfStatus); entry.pushKV("bip125-replaceable", rbfStatus);

View file

@ -18,7 +18,7 @@ GetResults(CWallet& wallet, std::map<CAmount, CAccountingEntry>& results)
std::list<CAccountingEntry> aes; std::list<CAccountingEntry> aes;
results.clear(); results.clear();
BOOST_CHECK(wallet.ReorderTransactions() == DB_LOAD_OK); BOOST_CHECK(wallet.ReorderTransactions() == DBErrors::LOAD_OK);
wallet.ListAccountCreditDebit("", aes); wallet.ListAccountCreditDebit("", aes);
for (CAccountingEntry& ae : aes) for (CAccountingEntry& ae : aes)
{ {

View file

@ -727,11 +727,11 @@ DBErrors CWallet::ReorderTransactions()
if (pwtx) if (pwtx)
{ {
if (!walletdb.WriteTx(*pwtx)) if (!walletdb.WriteTx(*pwtx))
return DB_LOAD_FAIL; return DBErrors::LOAD_FAIL;
} }
else else
if (!walletdb.WriteAccountingEntry(pacentry->nEntryNo, *pacentry)) if (!walletdb.WriteAccountingEntry(pacentry->nEntryNo, *pacentry))
return DB_LOAD_FAIL; return DBErrors::LOAD_FAIL;
} }
else else
{ {
@ -751,16 +751,16 @@ DBErrors CWallet::ReorderTransactions()
if (pwtx) if (pwtx)
{ {
if (!walletdb.WriteTx(*pwtx)) if (!walletdb.WriteTx(*pwtx))
return DB_LOAD_FAIL; return DBErrors::LOAD_FAIL;
} }
else else
if (!walletdb.WriteAccountingEntry(pacentry->nEntryNo, *pacentry)) if (!walletdb.WriteAccountingEntry(pacentry->nEntryNo, *pacentry))
return DB_LOAD_FAIL; return DBErrors::LOAD_FAIL;
} }
} }
walletdb.WriteOrderPosNext(nOrderPosNext); walletdb.WriteOrderPosNext(nOrderPosNext);
return DB_LOAD_OK; return DBErrors::LOAD_OK;
} }
int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb) int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
@ -3146,7 +3146,7 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
fFirstRunRet = false; fFirstRunRet = false;
DBErrors nLoadWalletRet = CWalletDB(*dbw,"cr+").LoadWallet(this); DBErrors nLoadWalletRet = CWalletDB(*dbw,"cr+").LoadWallet(this);
if (nLoadWalletRet == DB_NEED_REWRITE) if (nLoadWalletRet == DBErrors::NEED_REWRITE)
{ {
if (dbw->Rewrite("\x04pool")) if (dbw->Rewrite("\x04pool"))
{ {
@ -3162,12 +3162,12 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
// This wallet is in its first run if all of these are empty // This wallet is in its first run if all of these are empty
fFirstRunRet = mapKeys.empty() && mapCryptedKeys.empty() && mapWatchKeys.empty() && setWatchOnly.empty() && mapScripts.empty(); fFirstRunRet = mapKeys.empty() && mapCryptedKeys.empty() && mapWatchKeys.empty() && setWatchOnly.empty() && mapScripts.empty();
if (nLoadWalletRet != DB_LOAD_OK) if (nLoadWalletRet != DBErrors::LOAD_OK)
return nLoadWalletRet; return nLoadWalletRet;
uiInterface.LoadWallet(this); uiInterface.LoadWallet(this);
return DB_LOAD_OK; return DBErrors::LOAD_OK;
} }
DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut) DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut)
@ -3177,7 +3177,7 @@ DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256
for (uint256 hash : vHashOut) for (uint256 hash : vHashOut)
mapWallet.erase(hash); mapWallet.erase(hash);
if (nZapSelectTxRet == DB_NEED_REWRITE) if (nZapSelectTxRet == DBErrors::NEED_REWRITE)
{ {
if (dbw->Rewrite("\x04pool")) if (dbw->Rewrite("\x04pool"))
{ {
@ -3190,19 +3190,19 @@ DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256
} }
} }
if (nZapSelectTxRet != DB_LOAD_OK) if (nZapSelectTxRet != DBErrors::LOAD_OK)
return nZapSelectTxRet; return nZapSelectTxRet;
MarkDirty(); MarkDirty();
return DB_LOAD_OK; return DBErrors::LOAD_OK;
} }
DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx) DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
{ {
DBErrors nZapWalletTxRet = CWalletDB(*dbw,"cr+").ZapWalletTx(vWtx); DBErrors nZapWalletTxRet = CWalletDB(*dbw,"cr+").ZapWalletTx(vWtx);
if (nZapWalletTxRet == DB_NEED_REWRITE) if (nZapWalletTxRet == DBErrors::NEED_REWRITE)
{ {
if (dbw->Rewrite("\x04pool")) if (dbw->Rewrite("\x04pool"))
{ {
@ -3216,10 +3216,10 @@ DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
} }
} }
if (nZapWalletTxRet != DB_LOAD_OK) if (nZapWalletTxRet != DBErrors::LOAD_OK)
return nZapWalletTxRet; return nZapWalletTxRet;
return DB_LOAD_OK; return DBErrors::LOAD_OK;
} }
@ -3931,7 +3931,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
std::unique_ptr<CWallet> tempWallet = MakeUnique<CWallet>(name, CWalletDBWrapper::Create(path)); std::unique_ptr<CWallet> tempWallet = MakeUnique<CWallet>(name, CWalletDBWrapper::Create(path));
DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
if (nZapWalletRet != DB_LOAD_OK) { if (nZapWalletRet != DBErrors::LOAD_OK) {
InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
return nullptr; return nullptr;
} }
@ -3943,23 +3943,23 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
bool fFirstRun = true; bool fFirstRun = true;
CWallet *walletInstance = new CWallet(name, CWalletDBWrapper::Create(path)); CWallet *walletInstance = new CWallet(name, CWalletDBWrapper::Create(path));
DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
if (nLoadWalletRet != DB_LOAD_OK) if (nLoadWalletRet != DBErrors::LOAD_OK)
{ {
if (nLoadWalletRet == DB_CORRUPT) { if (nLoadWalletRet == DBErrors::CORRUPT) {
InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
return nullptr; return nullptr;
} }
else if (nLoadWalletRet == DB_NONCRITICAL_ERROR) else if (nLoadWalletRet == DBErrors::NONCRITICAL_ERROR)
{ {
InitWarning(strprintf(_("Error reading %s! All keys read correctly, but transaction data" InitWarning(strprintf(_("Error reading %s! All keys read correctly, but transaction data"
" or address book entries might be missing or incorrect."), " or address book entries might be missing or incorrect."),
walletFile)); walletFile));
} }
else if (nLoadWalletRet == DB_TOO_NEW) { else if (nLoadWalletRet == DBErrors::TOO_NEW) {
InitError(strprintf(_("Error loading %s: Wallet requires newer version of %s"), walletFile, _(PACKAGE_NAME))); InitError(strprintf(_("Error loading %s: Wallet requires newer version of %s"), walletFile, _(PACKAGE_NAME)));
return nullptr; return nullptr;
} }
else if (nLoadWalletRet == DB_NEED_REWRITE) else if (nLoadWalletRet == DBErrors::NEED_REWRITE)
{ {
InitError(strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME))); InitError(strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)));
return nullptr; return nullptr;

View file

@ -522,7 +522,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
{ {
CWalletScanState wss; CWalletScanState wss;
bool fNoncriticalErrors = false; bool fNoncriticalErrors = false;
DBErrors result = DB_LOAD_OK; DBErrors result = DBErrors::LOAD_OK;
LOCK(pwallet->cs_wallet); LOCK(pwallet->cs_wallet);
try { try {
@ -530,7 +530,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
if (batch.Read((std::string)"minversion", nMinVersion)) if (batch.Read((std::string)"minversion", nMinVersion))
{ {
if (nMinVersion > CLIENT_VERSION) if (nMinVersion > CLIENT_VERSION)
return DB_TOO_NEW; return DBErrors::TOO_NEW;
pwallet->LoadMinVersion(nMinVersion); pwallet->LoadMinVersion(nMinVersion);
} }
@ -539,7 +539,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
if (!pcursor) if (!pcursor)
{ {
LogPrintf("Error getting wallet database cursor\n"); LogPrintf("Error getting wallet database cursor\n");
return DB_CORRUPT; return DBErrors::CORRUPT;
} }
while (true) while (true)
@ -553,7 +553,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
else if (ret != 0) else if (ret != 0)
{ {
LogPrintf("Error reading next record from wallet database\n"); LogPrintf("Error reading next record from wallet database\n");
return DB_CORRUPT; return DBErrors::CORRUPT;
} }
// Try to be tolerant of single corrupt records: // Try to be tolerant of single corrupt records:
@ -563,7 +563,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
// losing keys is considered a catastrophic error, anything else // losing keys is considered a catastrophic error, anything else
// we assume the user can live with: // we assume the user can live with:
if (IsKeyType(strType) || strType == "defaultkey") if (IsKeyType(strType) || strType == "defaultkey")
result = DB_CORRUPT; result = DBErrors::CORRUPT;
else else
{ {
// Leave other errors alone, if we try to fix them we might make things worse. // Leave other errors alone, if we try to fix them we might make things worse.
@ -582,15 +582,15 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
throw; throw;
} }
catch (...) { catch (...) {
result = DB_CORRUPT; result = DBErrors::CORRUPT;
} }
if (fNoncriticalErrors && result == DB_LOAD_OK) if (fNoncriticalErrors && result == DBErrors::LOAD_OK)
result = DB_NONCRITICAL_ERROR; result = DBErrors::NONCRITICAL_ERROR;
// Any wallet corruption at all: skip any rewriting or // Any wallet corruption at all: skip any rewriting or
// upgrading, we don't want to make it worse. // upgrading, we don't want to make it worse.
if (result != DB_LOAD_OK) if (result != DBErrors::LOAD_OK)
return result; return result;
LogPrintf("nFileVersion = %d\n", wss.nFileVersion); LogPrintf("nFileVersion = %d\n", wss.nFileVersion);
@ -607,7 +607,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
// Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc: // Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc:
if (wss.fIsEncrypted && (wss.nFileVersion == 40000 || wss.nFileVersion == 50000)) if (wss.fIsEncrypted && (wss.nFileVersion == 40000 || wss.nFileVersion == 50000))
return DB_NEED_REWRITE; return DBErrors::NEED_REWRITE;
if (wss.nFileVersion < CLIENT_VERSION) // Update if (wss.nFileVersion < CLIENT_VERSION) // Update
WriteVersion(CLIENT_VERSION); WriteVersion(CLIENT_VERSION);
@ -626,14 +626,14 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
DBErrors CWalletDB::FindWalletTx(std::vector<uint256>& vTxHash, std::vector<CWalletTx>& vWtx) DBErrors CWalletDB::FindWalletTx(std::vector<uint256>& vTxHash, std::vector<CWalletTx>& vWtx)
{ {
DBErrors result = DB_LOAD_OK; DBErrors result = DBErrors::LOAD_OK;
try { try {
int nMinVersion = 0; int nMinVersion = 0;
if (batch.Read((std::string)"minversion", nMinVersion)) if (batch.Read((std::string)"minversion", nMinVersion))
{ {
if (nMinVersion > CLIENT_VERSION) if (nMinVersion > CLIENT_VERSION)
return DB_TOO_NEW; return DBErrors::TOO_NEW;
} }
// Get cursor // Get cursor
@ -641,7 +641,7 @@ DBErrors CWalletDB::FindWalletTx(std::vector<uint256>& vTxHash, std::vector<CWal
if (!pcursor) if (!pcursor)
{ {
LogPrintf("Error getting wallet database cursor\n"); LogPrintf("Error getting wallet database cursor\n");
return DB_CORRUPT; return DBErrors::CORRUPT;
} }
while (true) while (true)
@ -655,7 +655,7 @@ DBErrors CWalletDB::FindWalletTx(std::vector<uint256>& vTxHash, std::vector<CWal
else if (ret != 0) else if (ret != 0)
{ {
LogPrintf("Error reading next record from wallet database\n"); LogPrintf("Error reading next record from wallet database\n");
return DB_CORRUPT; return DBErrors::CORRUPT;
} }
std::string strType; std::string strType;
@ -677,7 +677,7 @@ DBErrors CWalletDB::FindWalletTx(std::vector<uint256>& vTxHash, std::vector<CWal
throw; throw;
} }
catch (...) { catch (...) {
result = DB_CORRUPT; result = DBErrors::CORRUPT;
} }
return result; return result;
@ -689,7 +689,7 @@ DBErrors CWalletDB::ZapSelectTx(std::vector<uint256>& vTxHashIn, std::vector<uin
std::vector<uint256> vTxHash; std::vector<uint256> vTxHash;
std::vector<CWalletTx> vWtx; std::vector<CWalletTx> vWtx;
DBErrors err = FindWalletTx(vTxHash, vWtx); DBErrors err = FindWalletTx(vTxHash, vWtx);
if (err != DB_LOAD_OK) { if (err != DBErrors::LOAD_OK) {
return err; return err;
} }
@ -716,9 +716,9 @@ DBErrors CWalletDB::ZapSelectTx(std::vector<uint256>& vTxHashIn, std::vector<uin
} }
if (delerror) { if (delerror) {
return DB_CORRUPT; return DBErrors::CORRUPT;
} }
return DB_LOAD_OK; return DBErrors::LOAD_OK;
} }
DBErrors CWalletDB::ZapWalletTx(std::vector<CWalletTx>& vWtx) DBErrors CWalletDB::ZapWalletTx(std::vector<CWalletTx>& vWtx)
@ -726,16 +726,16 @@ DBErrors CWalletDB::ZapWalletTx(std::vector<CWalletTx>& vWtx)
// build list of wallet TXs // build list of wallet TXs
std::vector<uint256> vTxHash; std::vector<uint256> vTxHash;
DBErrors err = FindWalletTx(vTxHash, vWtx); DBErrors err = FindWalletTx(vTxHash, vWtx);
if (err != DB_LOAD_OK) if (err != DBErrors::LOAD_OK)
return err; return err;
// erase each wallet TX // erase each wallet TX
for (uint256& hash : vTxHash) { for (uint256& hash : vTxHash) {
if (!EraseTx(hash)) if (!EraseTx(hash))
return DB_CORRUPT; return DBErrors::CORRUPT;
} }
return DB_LOAD_OK; return DBErrors::LOAD_OK;
} }
void MaybeCompactWalletDB() void MaybeCompactWalletDB()

View file

@ -46,14 +46,14 @@ class uint160;
class uint256; class uint256;
/** Error statuses for the wallet database */ /** Error statuses for the wallet database */
enum DBErrors enum class DBErrors
{ {
DB_LOAD_OK, LOAD_OK,
DB_CORRUPT, CORRUPT,
DB_NONCRITICAL_ERROR, NONCRITICAL_ERROR,
DB_TOO_NEW, TOO_NEW,
DB_LOAD_FAIL, LOAD_FAIL,
DB_NEED_REWRITE NEED_REWRITE
}; };
/* simple HD chain data model */ /* simple HD chain data model */