aboutsummaryrefslogtreecommitdiff
path: root/src/init.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/init.cpp')
-rw-r--r--src/init.cpp82
1 files changed, 69 insertions, 13 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 04d7ed0ea3..51784fe06b 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -411,6 +411,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-limitancestorsize=<n>", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds <n> kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT));
strUsage += HelpMessageOpt("-limitdescendantcount=<n>", strprintf("Do not accept transactions if any ancestor would have <n> or more in-mempool descendants (default: %u)", DEFAULT_DESCENDANT_LIMIT));
strUsage += HelpMessageOpt("-limitdescendantsize=<n>", strprintf("Do not accept transactions if any ancestor would have more than <n> kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT));
+ strUsage += HelpMessageOpt("-bip9params=deployment:start:end", "Use given start/end times for specified BIP9 deployment (regtest-only)");
}
string debugCategories = "addrman, alert, bench, coindb, db, http, libevent, lock, mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, selectcoins, tor, zmq"; // Don't translate these and qt below
if (mode == HMM_BITCOIN_QT)
@@ -511,6 +512,21 @@ static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex
boost::thread t(runCommand, strCmd); // thread runs free
}
+static bool fHaveGenesis = false;
+static boost::mutex cs_GenesisWait;
+static CConditionVariable condvar_GenesisWait;
+
+static void BlockNotifyGenesisWait(bool, const CBlockIndex *pBlockIndex)
+{
+ if (pBlockIndex != NULL) {
+ {
+ boost::unique_lock<boost::mutex> lock_GenesisWait(cs_GenesisWait);
+ fHaveGenesis = true;
+ }
+ condvar_GenesisWait.notify_all();
+ }
+}
+
struct CImportingNow
{
CImportingNow() {
@@ -976,6 +992,41 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
fEnableReplacement = (std::find(vstrReplacementModes.begin(), vstrReplacementModes.end(), "fee") != vstrReplacementModes.end());
}
+ if (!mapMultiArgs["-bip9params"].empty()) {
+ // Allow overriding BIP9 parameters for testing
+ if (!Params().MineBlocksOnDemand()) {
+ return InitError("BIP9 parameters may only be overridden on regtest.");
+ }
+ const vector<string>& deployments = mapMultiArgs["-bip9params"];
+ for (auto i : deployments) {
+ std::vector<std::string> vDeploymentParams;
+ boost::split(vDeploymentParams, i, boost::is_any_of(":"));
+ if (vDeploymentParams.size() != 3) {
+ return InitError("BIP9 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) {
+ UpdateRegtestBIP9Parameters(Consensus::DeploymentPos(j), nStartTime, nTimeout);
+ found = true;
+ LogPrintf("Setting BIP9 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]));
+ }
+ }
+ }
+
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
// Initialize elliptic curve code
@@ -1290,7 +1341,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
break;
}
- if (!fReindex) {
+ if (!fReindex && chainActive.Tip() != NULL) {
uiInterface.InitMessage(_("Rewinding blocks..."));
if (!RewindBlockIndex(chainparams)) {
strLoadError = _("Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain");
@@ -1407,6 +1458,17 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// ********************************************************* Step 10: import blocks
+ if (!CheckDiskSpace())
+ return false;
+
+ // Either install a handler to notify us when genesis activates, or set fHaveGenesis directly.
+ // No locking, as this happens before any background thread is started.
+ if (chainActive.Tip() == NULL) {
+ uiInterface.NotifyBlockTip.connect(BlockNotifyGenesisWait);
+ } else {
+ fHaveGenesis = true;
+ }
+
if (mapArgs.count("-blocknotify"))
uiInterface.NotifyBlockTip.connect(BlockNotifyCallback);
@@ -1416,26 +1478,20 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
BOOST_FOREACH(const std::string& strFile, mapMultiArgs["-loadblock"])
vImportFiles.push_back(strFile);
}
+
threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles));
// Wait for genesis block to be processed
- bool fHaveGenesis = false;
- while (!fHaveGenesis && !fRequestShutdown) {
- {
- LOCK(cs_main);
- fHaveGenesis = (chainActive.Tip() != NULL);
- }
-
- if (!fHaveGenesis) {
- MilliSleep(10);
+ {
+ boost::unique_lock<boost::mutex> lock(cs_GenesisWait);
+ while (!fHaveGenesis) {
+ condvar_GenesisWait.wait(lock);
}
+ uiInterface.NotifyBlockTip.disconnect(BlockNotifyGenesisWait);
}
// ********************************************************* Step 11: start node
- if (!CheckDiskSpace())
- return false;
-
if (!strErrors.str().empty())
return InitError(strErrors.str());