Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/bitcoin-cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ static int AppInitRPC(int argc, char* argv[])
fprintf(stderr, "Error reading configuration file: %s\n", error.c_str());
return EXIT_FAILURE;
}
// Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause)
// Check for -chain, -testnet or -regtest parameter (BaseParams() calls are only valid after this clause)
try {
SelectBaseParams(gArgs.GetChainName());
} catch (const std::exception& e) {
Expand Down
2 changes: 1 addition & 1 deletion src/bitcoin-tx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ static int AppInitRawTx(int argc, char* argv[])
return EXIT_FAILURE;
}

// Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
// Check for -chain, -testnet or -regtest parameter (Params() calls are only valid after this clause)
try {
SelectParams(gArgs.GetChainName());
} catch (const std::exception& e) {
Expand Down
2 changes: 1 addition & 1 deletion src/bitcoind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ static bool AppInit(int argc, char* argv[])
fprintf(stderr, "Error reading configuration file: %s\n", error.c_str());
return false;
}
// Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
// Check for -chain, -testnet or -regtest parameter (Params() calls are only valid after this clause)
try {
SelectParams(gArgs.GetChainName());
} catch (const std::exception& e) {
Expand Down
71 changes: 70 additions & 1 deletion src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,73 @@ void CRegTestParams::UpdateVersionBitsParametersFromArgs(const ArgsManager& args
}
}

/**
* Custom params for testing.
*/
class CCustomParams : public CRegTestParams {
void UpdateFromArgs(ArgsManager& args)
{
UpdateVersionBitsParametersFromArgs(args);

consensus.nSubsidyHalvingInterval = args.GetArg("-con_nsubsidyhalvinginterval", consensus.nSubsidyHalvingInterval);
consensus.BIP16Exception = uint256S(args.GetArg("-con_bip16exception", "0x0"));
consensus.BIP34Height = args.GetArg("-con_bip34height", consensus.BIP34Height);
consensus.BIP34Hash = uint256S(args.GetArg("-con_bip34hash", "0x0"));
consensus.BIP65Height = args.GetArg("-con_bip65height", consensus.BIP65Height);
consensus.BIP66Height = args.GetArg("-con_bip66height", consensus.BIP66Height);
consensus.powLimit = uint256S(args.GetArg("-con_powlimit", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
consensus.nPowTargetTimespan = args.GetArg("-con_npowtargettimespan", consensus.nPowTargetTimespan);
consensus.nPowTargetSpacing = args.GetArg("-con_npowtargetspacing", consensus.nPowTargetSpacing);
consensus.fPowAllowMinDifficultyBlocks = args.GetBoolArg("-con_fpowallowmindifficultyblocks", consensus.fPowAllowMinDifficultyBlocks);
consensus.fPowNoRetargeting = args.GetBoolArg("-con_fpownoretargeting", consensus.fPowNoRetargeting);
consensus.nRuleChangeActivationThreshold = (uint32_t)args.GetArg("-con_nrulechangeactivationthreshold", consensus.nRuleChangeActivationThreshold);
consensus.nMinerConfirmationWindow = (uint32_t)args.GetArg("-con_nminerconfirmationwindow", consensus.nMinerConfirmationWindow);

consensus.nMinimumChainWork = uint256S(args.GetArg("-con_nminimumchainwork", "0x0"));
consensus.defaultAssumeValid = uint256S(args.GetArg("-con_defaultassumevalid", "0x00"));

nPruneAfterHeight = (uint64_t)args.GetArg("-npruneafterheight", nPruneAfterHeight);
fDefaultConsistencyChecks = args.GetBoolArg("-fdefaultconsistencychecks", fDefaultConsistencyChecks);
fMineBlocksOnDemand = args.GetBoolArg("-fmineblocksondemand", fMineBlocksOnDemand);
m_fallback_fee_enabled = args.GetBoolArg("-fallback_fee_enabled", m_fallback_fee_enabled);

bech32_hrp = args.GetArg("-bech32_hrp", bech32_hrp);
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1, args.GetArg("-pubkeyprefix", 111));
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1, args.GetArg("-scriptprefix", 196));
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1, args.GetArg("-secretprefix", 239));

std::string extpubprefix = args.GetArg("-extpubkeyprefix", "043587CF");
assert(IsHex(extpubprefix) && extpubprefix.size() == 8 && "-extpubkeyprefix must be hex string of length 8");
base58Prefixes[EXT_PUBLIC_KEY] = ParseHex(extpubprefix);

std::string extprvprefix = args.GetArg("-extprvkeyprefix", "04358394");
assert(IsHex(extprvprefix) && extprvprefix.size() == 8 && "-extprvkeyprefix must be hex string of length 8");
base58Prefixes[EXT_SECRET_KEY] = ParseHex(extprvprefix);

const std::string magic_str = args.GetArg("-pchmessagestart", "FABFB5DA");
assert(IsHex(magic_str) && magic_str.size() == 8 && "-pchmessagestart must be hex string of length 8");
const std::vector<unsigned char> magic_byte = ParseHex(magic_str);
std::copy(begin(magic_byte), end(magic_byte), pchMessageStart);

vSeeds.clear();
if (gArgs.IsArgSet("-seednode")) {
const auto seednodes = gArgs.GetArgs("-seednode");
if (seednodes.size() != 1 || seednodes[0] != "0") {
vSeeds = seednodes;
}
}
}

public:
CCustomParams(const std::string& chain, ArgsManager& args) : CRegTestParams(args)
{
strNetworkID = chain;
UpdateFromArgs(args);
genesis = CreateGenesisBlock(strNetworkID.c_str(), CScript(OP_TRUE), 1296688602, 2, 0x207fffff, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
}
};

static std::unique_ptr<const CChainParams> globalChainParams;

const CChainParams &Params() {
Expand All @@ -404,13 +471,15 @@ const CChainParams &Params() {

std::unique_ptr<const CChainParams> CreateChainParams(const std::string& chain)
{
// Reserved names for non-custom chains
if (chain == CBaseChainParams::MAIN)
return std::unique_ptr<CChainParams>(new CMainParams());
else if (chain == CBaseChainParams::TESTNET)
return std::unique_ptr<CChainParams>(new CTestNetParams());
else if (chain == CBaseChainParams::REGTEST)
return std::unique_ptr<CChainParams>(new CRegTestParams(gArgs));
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));

return std::unique_ptr<CChainParams>(new CCustomParams(chain, gArgs));
}

void SelectParams(const std::string& network)
Expand Down
8 changes: 5 additions & 3 deletions src/chainparamsbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ const std::string CBaseChainParams::REGTEST = "regtest";

void SetupChainParamsBaseOptions()
{
gArgs.AddArg("-chain=<chain>", "Use the chain <chain> (default: main). Reserved values: main, test, regtest", false, OptionsCategory::CHAINPARAMS);
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);
gArgs.AddArg("-vbparams=deployment:start:end", "Use given start/end times for specified version bits deployment (regtest or custom only)", true, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-seednode=<ip>", "Use specified node as seed node. This option can be specified multiple times to connect to multiple nodes. (custom only)", true, OptionsCategory::CHAINPARAMS);
}

static std::unique_ptr<CBaseChainParams> globalChainBaseParams;
Expand All @@ -39,8 +41,8 @@ std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const std::string& chain
return MakeUnique<CBaseChainParams>("testnet3", 18332);
else if (chain == CBaseChainParams::REGTEST)
return MakeUnique<CBaseChainParams>("regtest", 18443);
else
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));

return MakeUnique<CBaseChainParams>(chain, 18553);
}

void SelectBaseParams(const std::string& chain)
Expand Down
1 change: 1 addition & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ void SetupServerArgs()
// Hidden Options
std::vector<std::string> hidden_args = {"-rpcssl", "-benchmark", "-h", "-help", "-socks", "-tor", "-debugnet", "-whitelistalwaysrelay",
"-prematurewitness", "-walletprematurewitness", "-promiscuousmempoolflags", "-blockminsize", "-dbcrashratio", "-forcecompactdb", "-usehd",
"-con_fpowallowmindifficultyblocks", "-con_fpownoretargeting", "-con_nsubsidyhalvinginterval", "-con_bip16exception", "-con_bip34height", "-con_bip65height", "-con_bip66height", "-con_npowtargettimespan", "-con_npowtargetspacing", "-con_nrulechangeactivationthreshold", "-con_nminerconfirmationwindow", "-con_powlimit", "-con_bip34hash", "-con_nminimumchainwork", "-con_defaultassumevalid", "-npruneafterheight", "-fdefaultconsistencychecks", "-fmineblocksondemand", "-bech32_hrp", "-fallback_fee_enabled", "-pubkeyprefix", "-scriptprefix", "-secretprefix", "-extpubkeyprefix", "-extprvkeyprefix", "-pchmessagestart",
// GUI args. These will be overwritten by SetupUIArgs for the GUI
"-allowselfsignedrootcertificates", "-choosedatadir", "-lang=<lang>", "-min", "-resetguisettings", "-rootcertificates=<file>", "-splash", "-uiplatform"};

Expand Down
4 changes: 2 additions & 2 deletions src/qt/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ int main(int argc, char *argv[])
// - QSettings() will use the new application name after this, resulting in network-specific settings
// - Needs to be done before createOptionsModel

// Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
// Check for -chain, -testnet or -regtest parameter (Params() calls are only valid after this clause)
try {
node->selectParams(gArgs.GetChainName());
} catch(std::exception &e) {
Expand All @@ -666,7 +666,7 @@ int main(int argc, char *argv[])
PaymentServer::ipcParseCommandLine(*node, argc, argv);
#endif

QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate(QString::fromStdString(Params().NetworkIDString())));
QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate(Params().NetworkIDString()));
assert(!networkStyle.isNull());
// Allow for separate UI settings for testnets
QApplication::setApplicationName(networkStyle->getAppName());
Expand Down
4 changes: 2 additions & 2 deletions src/qt/guiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ bool SetStartOnSystemStartup(bool fAutoStart)
// Start client minimized
QString strArgs = "-min";
// Set -testnet /-regtest options
strArgs += QString::fromStdString(strprintf(" -testnet=%d -regtest=%d", gArgs.GetBoolArg("-testnet", false), gArgs.GetBoolArg("-regtest", false)));
strArgs += QString::fromStdString(strprintf(" -chain=%s", gArgs.GetChainName()));

#ifdef UNICODE
boost::scoped_array<TCHAR> args(new TCHAR[strArgs.length() + 1]);
Expand Down Expand Up @@ -672,7 +672,7 @@ bool SetStartOnSystemStartup(bool fAutoStart)
optionFile << "Name=Bitcoin\n";
else
optionFile << strprintf("Name=Bitcoin (%s)\n", chain);
optionFile << "Exec=" << pszExePath << strprintf(" -min -testnet=%d -regtest=%d\n", gArgs.GetBoolArg("-testnet", false), gArgs.GetBoolArg("-regtest", false));
optionFile << "Exec=" << pszExePath << strprintf(" -min -chain=%s\n", chain);
optionFile << "Terminal=false\n";
optionFile << "Hidden=false\n";
optionFile.close();
Expand Down
17 changes: 10 additions & 7 deletions src/qt/networkstyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@

#include <qt/guiconstants.h>

#include <chainparamsbase.h>
#include <tinyformat.h>

#include <QApplication>

static const struct {
const char *networkId;
const char *appName;
const int iconColorHueShift;
const int iconColorSaturationReduction;
const char *titleAddText;
} network_styles[] = {
{"main", QAPP_APP_NAME_DEFAULT, 0, 0, ""},
{"test", QAPP_APP_NAME_TESTNET, 70, 30, QT_TRANSLATE_NOOP("SplashScreen", "[testnet]")},
{"regtest", QAPP_APP_NAME_TESTNET, 160, 30, "[regtest]"}
{"main", QAPP_APP_NAME_DEFAULT, 0, 0},
{"test", QAPP_APP_NAME_TESTNET, 70, 30},
{"regtest", QAPP_APP_NAME_TESTNET, 160, 30}
};
static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*network_styles);

Expand Down Expand Up @@ -75,8 +77,9 @@ NetworkStyle::NetworkStyle(const QString &_appName, const int iconColorHueShift,
trayAndWindowIcon = QIcon(pixmap.scaled(QSize(256,256)));
}

const NetworkStyle *NetworkStyle::instantiate(const QString &networkId)
const NetworkStyle* NetworkStyle::instantiate(const std::string& networkId)
{
std::string titleAddText = networkId == CBaseChainParams::MAIN ? "" : strprintf("[%s]", networkId);
for (unsigned x=0; x<network_styles_count; ++x)
{
if (networkId == network_styles[x].networkId)
Expand All @@ -85,8 +88,8 @@ const NetworkStyle *NetworkStyle::instantiate(const QString &networkId)
network_styles[x].appName,
network_styles[x].iconColorHueShift,
network_styles[x].iconColorSaturationReduction,
network_styles[x].titleAddText);
titleAddText.c_str());
}
}
return 0;
return new NetworkStyle(strprintf("%s-%s", QAPP_APP_NAME_DEFAULT, networkId).c_str(), 250, 30, titleAddText.c_str());
}
2 changes: 1 addition & 1 deletion src/qt/networkstyle.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class NetworkStyle
{
public:
/** Get style associated with provided BIP70 network id, or 0 if not known */
static const NetworkStyle *instantiate(const QString &networkId);
static const NetworkStyle* instantiate(const std::string& networkId);

const QString &getAppName() const { return appName; }
const QIcon &getAppIcon() const { return appIcon; }
Expand Down
8 changes: 5 additions & 3 deletions src/txdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,11 @@ bool CBlockTreeDB::LoadBlockIndexGuts(const Consensus::Params& consensusParams,
pindexNew->nStatus = diskindex.nStatus;
pindexNew->nTx = diskindex.nTx;

if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits, consensusParams))
return error("%s: CheckProofOfWork failed: %s", __func__, pindexNew->ToString());

const uint256 block_hash = pindexNew->GetBlockHash();
if (!CheckProofOfWork(block_hash, pindexNew->nBits, consensusParams) &&
block_hash != consensusParams.hashGenesisBlock) {
return error("%s: CheckProofOfWork: %s, %s", __func__, block_hash.ToString(), pindexNew->ToString());
}
pcursor->Next();
} else {
return error("%s: failed to read value", __func__);
Expand Down
12 changes: 7 additions & 5 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -961,16 +961,18 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)

std::string ArgsManager::GetChainName() const
{
bool fRegTest = ArgsManagerHelper::GetNetBoolArg(*this, "-regtest");
bool fTestNet = ArgsManagerHelper::GetNetBoolArg(*this, "-testnet");
const bool fRegTest = ArgsManagerHelper::GetNetBoolArg(*this, "-regtest");
const bool fTestNet = ArgsManagerHelper::GetNetBoolArg(*this, "-testnet");
const bool is_chain_arg_set = IsArgSet("-chain");

if (fTestNet && fRegTest)
throw std::runtime_error("Invalid combination of -regtest and -testnet.");
if ((int)is_chain_arg_set + (int)fRegTest + (int)fTestNet > 1) {
throw std::runtime_error("Invalid combination of -regtest, -testnet and -chain. Can use at most one.");
}
if (fRegTest)
return CBaseChainParams::REGTEST;
if (fTestNet)
return CBaseChainParams::TESTNET;
return CBaseChainParams::MAIN;
return GetArg("-chain", CBaseChainParams::MAIN);
}

#ifndef WIN32
Expand Down
34 changes: 19 additions & 15 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1091,8 +1091,11 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus:
}

// Check the header
if (!CheckProofOfWork(block.GetHash(), block.nBits, consensusParams))
const uint256 block_hash = block.GetHash();
if (!CheckProofOfWork(block_hash, block.nBits, consensusParams) &&
block_hash != consensusParams.hashGenesisBlock) {
return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
}

return true;
}
Expand Down Expand Up @@ -1810,6 +1813,18 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
assert(*pindex->phashBlock == block.GetHash());
int64_t nTimeStart = GetTimeMicros();

// verify that the view's current state corresponds to the previous block
const uint256 hashPrevBlock = pindex->pprev == nullptr ? uint256() : pindex->pprev->GetBlockHash();
assert(hashPrevBlock == view.GetBestBlock());

// Special case for the genesis block, skipping connection of its transactions
// (its coinbase is unspendable)
if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
if (!fJustCheck)
view.SetBestBlock(pindex->GetBlockHash());
return true;
}

// Check it again in case a previous version let a bad block in
// NOTE: We don't currently (re-)invoke ContextualCheckBlock() or
// ContextualCheckBlockHeader() here. This means that if we add a new
Expand All @@ -1833,18 +1848,6 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state));
}

// verify that the view's current state corresponds to the previous block
uint256 hashPrevBlock = pindex->pprev == nullptr ? uint256() : pindex->pprev->GetBlockHash();
assert(hashPrevBlock == view.GetBestBlock());

// Special case for the genesis block, skipping connection of its transactions
// (its coinbase is unspendable)
if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
if (!fJustCheck)
view.SetBestBlock(pindex->GetBlockHash());
return true;
}

nBlocksTotal++;

bool fScriptChecks = true;
Expand Down Expand Up @@ -3498,8 +3501,9 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CVali
if (pindex->nChainWork < nMinimumChainWork) return true;
}

if (!CheckBlock(block, state, chainparams.GetConsensus()) ||
!ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindex->pprev)) {
if (chainparams.GetConsensus().hashGenesisBlock != block.GetHash() &&
(!CheckBlock(block, state, chainparams.GetConsensus()) ||
!ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindex->pprev))) {
if (state.IsInvalid() && !state.CorruptionPossible()) {
pindex->nStatus |= BLOCK_FAILED_VALID;
setDirtyBlockIndex.insert(pindex);
Expand Down
2 changes: 1 addition & 1 deletion test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ For instance, to attach to `self.node[1]` during a run:
use the directory path to get the pid from the pid file:

```bash
cat /tmp/user/1000/testo9vsdjo3/node1/regtest/bitcoind.pid
cat /tmp/user/1000/testo9vsdjo3/node1/regtest2/bitcoind.pid
gdb /home/example/bitcoind <pid>
```

Expand Down
Loading