diff --git a/src/Makefile.am b/src/Makefile.am index f7d7a5d37..a1b9b4cb8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -187,6 +187,7 @@ BITCOIN_CORE_H = \ validation.h \ validationinterface.h \ versionbits.h \ + versionbitsinfo.h \ walletinitinterface.h \ wallet/coincontrol.h \ wallet/crypter.h \ @@ -400,6 +401,7 @@ libbitcoin_common_a_SOURCES = \ script/ismine.cpp \ script/sign.cpp \ script/standard.cpp \ + versionbitsinfo.cpp \ warnings.cpp \ $(BITCOIN_CORE_H) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index b80cc2c25..0574e2395 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -10,9 +10,13 @@ #include #include #include +#include #include +#include +#include + static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) { CMutableTransaction txNew; @@ -52,12 +56,6 @@ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward); } -void CChainParams::UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout) -{ - consensus.vDeployments[d].nStartTime = nStartTime; - consensus.vDeployments[d].nTimeout = nTimeout; -} - /** * Main network */ @@ -270,7 +268,7 @@ public: */ class CRegTestParams : public CChainParams { public: - CRegTestParams() { + explicit CRegTestParams(const ArgsManager& args) { strNetworkID = "regtest"; consensus.nSubsidyHalvingInterval = 150; consensus.BIP16Exception = uint256(); @@ -308,6 +306,8 @@ public: nDefaultPort = 18444; nPruneAfterHeight = 1000; + UpdateVersionBitsParametersFromArgs(args); + genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); @@ -343,23 +343,65 @@ public: /* enable fallback fee on regtest */ m_fallback_fee_enabled = true; } + + /** + * Allows modifying the Version Bits regtest parameters. + */ + void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout) + { + consensus.vDeployments[d].nStartTime = nStartTime; + consensus.vDeployments[d].nTimeout = nTimeout; + } + void UpdateVersionBitsParametersFromArgs(const ArgsManager& args); }; -static std::unique_ptr globalChainParams; +void CRegTestParams::UpdateVersionBitsParametersFromArgs(const ArgsManager& args) +{ + if (!args.IsArgSet("-vbparams")) return; + + for (const std::string& strDeployment : args.GetArgs("-vbparams")) { + std::vector vDeploymentParams; + boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":")); + if (vDeploymentParams.size() != 3) { + throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end"); + } + int64_t nStartTime, nTimeout; + if (!ParseInt64(vDeploymentParams[1], &nStartTime)) { + throw std::runtime_error(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1])); + } + if (!ParseInt64(vDeploymentParams[2], &nTimeout)) { + throw std::runtime_error(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2])); + } + bool found = false; + for (int j=0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) { + if (vDeploymentParams[0] == VersionBitsDeploymentInfo[j].name) { + UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout); + found = true; + LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld\n", vDeploymentParams[0], nStartTime, nTimeout); + break; + } + } + if (!found) { + throw std::runtime_error(strprintf("Invalid deployment (%s)", vDeploymentParams[0])); + } + } +} + +static std::unique_ptr globalChainParams; const CChainParams &Params() { assert(globalChainParams); return *globalChainParams; } -std::unique_ptr CreateChainParams(const std::string& chain) +std::unique_ptr CreateChainParams(const std::string& chain) { if (chain == CBaseChainParams::MAIN) return std::unique_ptr(new CMainParams()); else if (chain == CBaseChainParams::TESTNET) return std::unique_ptr(new CTestNetParams()); else if (chain == CBaseChainParams::REGTEST) - return std::unique_ptr(new CRegTestParams()); + return std::unique_ptr(new CRegTestParams(gArgs)); throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain)); } @@ -368,8 +410,3 @@ void SelectParams(const std::string& network) SelectBaseParams(network); globalChainParams = CreateChainParams(network); } - -void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout) -{ - globalChainParams->UpdateVersionBitsParameters(d, nStartTime, nTimeout); -} diff --git a/src/chainparams.h b/src/chainparams.h index 722e52ff4..19818b40a 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -80,7 +80,6 @@ public: const std::vector& FixedSeeds() const { return vFixedSeeds; } const CCheckpointData& Checkpoints() const { return checkpointData; } const ChainTxData& TxData() const { return chainTxData; } - void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout); protected: CChainParams() {} @@ -107,7 +106,7 @@ protected: * @returns a CChainParams* of the chosen chain. * @throws a std::runtime_error if the chain is not supported. */ -std::unique_ptr CreateChainParams(const std::string& chain); +std::unique_ptr CreateChainParams(const std::string& chain); /** * Return the currently selected parameters. This won't change after app @@ -121,9 +120,4 @@ const CChainParams &Params(); */ void SelectParams(const std::string& chain); -/** - * Allows modifying the Version Bits regtest parameters. - */ -void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout); - #endif // BITCOIN_CHAINPARAMS_H diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index e9e8ce03b..870640e77 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -20,6 +20,7 @@ void SetupChainParamsBaseOptions() gArgs.AddArg("-regtest", "Enter regression test mode, which uses a special chain in which blocks can be solved instantly. " "This is intended for regression testing tools and app development.", true, OptionsCategory::CHAINPARAMS); gArgs.AddArg("-testnet", "Use the test chain", false, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-vbparams=deployment:start:end", "Use given start/end times for specified version bits deployment (regtest-only)", true, OptionsCategory::CHAINPARAMS); } static std::unique_ptr globalChainBaseParams; diff --git a/src/init.cpp b/src/init.cpp index d10edbd8b..00d97629f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -445,7 +445,6 @@ void SetupServerArgs() gArgs.AddArg("-limitancestorsize=", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT), true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-limitdescendantcount=", strprintf("Do not accept transactions if any ancestor would have or more in-mempool descendants (default: %u)", DEFAULT_DESCENDANT_LIMIT), true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-limitdescendantsize=", strprintf("Do not accept transactions if any ancestor would have more than kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT), true, OptionsCategory::DEBUG_TEST); - gArgs.AddArg("-vbparams=deployment:start:end", "Use given start/end times for specified version bits deployment (regtest-only)", true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-addrmantest", "Allows to test address relay on localhost", true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-debug=", "Output debugging information (default: -nodebug, supplying is optional). " "If is not supplied or if = 1, output all debugging information. can be: " + ListLogCategories() + ".", false, OptionsCategory::DEBUG_TEST); @@ -1101,39 +1100,6 @@ bool AppInitParameterInteraction() fEnableReplacement = (std::find(vstrReplacementModes.begin(), vstrReplacementModes.end(), "fee") != vstrReplacementModes.end()); } - if (gArgs.IsArgSet("-vbparams")) { - // Allow overriding version bits parameters for testing - if (!chainparams.MineBlocksOnDemand()) { - return InitError("Version bits parameters may only be overridden on regtest."); - } - for (const std::string& strDeployment : gArgs.GetArgs("-vbparams")) { - std::vector vDeploymentParams; - boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":")); - if (vDeploymentParams.size() != 3) { - return InitError("Version bits parameters malformed, expecting deployment:start:end"); - } - int64_t nStartTime, nTimeout; - if (!ParseInt64(vDeploymentParams[1], &nStartTime)) { - return InitError(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1])); - } - if (!ParseInt64(vDeploymentParams[2], &nTimeout)) { - return InitError(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2])); - } - bool found = false; - for (int j=0; j<(int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) - { - if (vDeploymentParams[0].compare(VersionBitsDeploymentInfo[j].name) == 0) { - UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout); - found = true; - LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld\n", vDeploymentParams[0], nStartTime, nTimeout); - break; - } - } - if (!found) { - return InitError(strprintf("Invalid deployment (%s)", vDeploymentParams[0])); - } - } - } return true; } diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 47ee4fd6d..1eca0277b 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 17695ff4a..1b2fc2c15 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 766e34e5b..f7874e688 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -58,6 +59,9 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName) InitSignatureCache(); InitScriptExecutionCache(); fCheckBlockIndex = true; + // CreateAndProcessBlock() does not support building SegWit blocks, so don't activate in these tests. + // TODO: fix the code to support SegWit blocks. + gArgs.ForceSetArg("-vbparams", strprintf("segwit:0:%d", (int64_t)Consensus::BIP9Deployment::NO_TIMEOUT)); SelectParams(chainName); noui_connect(); } @@ -128,9 +132,6 @@ TestingSetup::~TestingSetup() TestChain100Setup::TestChain100Setup() : TestingSetup(CBaseChainParams::REGTEST) { - // CreateAndProcessBlock() does not support building SegWit blocks, so don't activate in these tests. - // TODO: fix the code to support SegWit blocks. - UpdateVersionBitsParameters(Consensus::DEPLOYMENT_SEGWIT, 0, Consensus::BIP9Deployment::NO_TIMEOUT); // Generate a 100-block chain: coinbaseKey.MakeNewKey(true); CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; diff --git a/src/versionbits.cpp b/src/versionbits.cpp index b0d2bc8a1..3f297c0eb 100644 --- a/src/versionbits.cpp +++ b/src/versionbits.cpp @@ -5,21 +5,6 @@ #include #include -const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] = { - { - /*.name =*/ "testdummy", - /*.gbt_force =*/ true, - }, - { - /*.name =*/ "csv", - /*.gbt_force =*/ true, - }, - { - /*.name =*/ "segwit", - /*.gbt_force =*/ true, - } -}; - ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const { int nPeriod = Period(params); diff --git a/src/versionbits.h b/src/versionbits.h index e4bf9cb9b..cdc947cd9 100644 --- a/src/versionbits.h +++ b/src/versionbits.h @@ -30,13 +30,6 @@ enum class ThresholdState { // will either be nullptr or a block with (height + 1) % Period() == 0. typedef std::map ThresholdConditionCache; -struct VBDeploymentInfo { - /** Deployment name */ - const char *name; - /** Whether GBT clients can safely ignore this rule in simplified usage */ - bool gbt_force; -}; - struct BIP9Stats { int period; int threshold; @@ -45,8 +38,6 @@ struct BIP9Stats { bool possible; }; -extern const struct VBDeploymentInfo VersionBitsDeploymentInfo[]; - /** * Abstract class that implements BIP9-style threshold logic, and caches results. */ diff --git a/src/versionbitsinfo.cpp b/src/versionbitsinfo.cpp new file mode 100644 index 000000000..ecf348292 --- /dev/null +++ b/src/versionbitsinfo.cpp @@ -0,0 +1,22 @@ +// Copyright (c) 2016-2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include + +const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] = { + { + /*.name =*/ "testdummy", + /*.gbt_force =*/ true, + }, + { + /*.name =*/ "csv", + /*.gbt_force =*/ true, + }, + { + /*.name =*/ "segwit", + /*.gbt_force =*/ true, + } +}; diff --git a/src/versionbitsinfo.h b/src/versionbitsinfo.h new file mode 100644 index 000000000..a7822bc74 --- /dev/null +++ b/src/versionbitsinfo.h @@ -0,0 +1,17 @@ +// Copyright (c) 2016-2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_VERSIONBITSINFO_H +#define BITCOIN_VERSIONBITSINFO_H + +struct VBDeploymentInfo { + /** Deployment name */ + const char *name; + /** Whether GBT clients can safely ignore this rule in simplified usage */ + bool gbt_force; +}; + +extern const struct VBDeploymentInfo VersionBitsDeploymentInfo[]; + +#endif // BITCOIN_VERSIONBITSINFO_H