diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 31592b0f0a8..a9183ac970c 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -135,6 +135,7 @@ public: fDefaultConsistencyChecks = false; fRequireStandard = true; m_is_test_chain = false; + m_is_mockable_chain = false; checkpointData = { { @@ -231,7 +232,7 @@ public: fDefaultConsistencyChecks = false; fRequireStandard = false; m_is_test_chain = true; - + m_is_mockable_chain = false; checkpointData = { { @@ -303,6 +304,7 @@ public: fDefaultConsistencyChecks = true; fRequireStandard = true; m_is_test_chain = true; + m_is_mockable_chain = true; checkpointData = { { diff --git a/src/chainparams.h b/src/chainparams.h index 63398e587ed..379c75e4be1 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -68,6 +68,8 @@ public: bool RequireStandard() const { return fRequireStandard; } /** If this chain is exclusively used for testing */ bool IsTestChain() const { return m_is_test_chain; } + /** If this chain allows time to be mocked */ + bool IsMockableChain() const { return m_is_mockable_chain; } uint64_t PruneAfterHeight() const { return nPruneAfterHeight; } /** Minimum free space (in GB) needed for data directory */ uint64_t AssumedBlockchainSize() const { return m_assumed_blockchain_size; } @@ -102,6 +104,7 @@ protected: bool fDefaultConsistencyChecks; bool fRequireStandard; bool m_is_test_chain; + bool m_is_mockable_chain; CCheckpointData checkpointData; ChainTxData chainTxData; }; diff --git a/src/init.cpp b/src/init.cpp index 90d2624c7f6..24a1fd27dbe 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -157,7 +157,6 @@ NODISCARD static bool CreatePidFile() static std::unique_ptr globalVerifyHandle; static boost::thread_group threadGroup; -static CScheduler scheduler; void Interrupt(NodeContext& node) { @@ -295,6 +294,7 @@ void Shutdown(NodeContext& node) globalVerifyHandle.reset(); ECC_Stop(); if (node.mempool) node.mempool = nullptr; + node.scheduler.reset(); LogPrintf("%s: done\n", __func__); } @@ -1268,16 +1268,19 @@ bool AppInitMain(NodeContext& node) } } + assert(!node.scheduler); + node.scheduler = MakeUnique(); + // Start the lightweight task scheduler thread - CScheduler::Function serviceLoop = std::bind(&CScheduler::serviceQueue, &scheduler); + CScheduler::Function serviceLoop = [&node]{ node.scheduler->serviceQueue(); }; threadGroup.create_thread(std::bind(&TraceThread, "scheduler", serviceLoop)); // Gather some entropy once per minute. - scheduler.scheduleEvery([]{ + node.scheduler->scheduleEvery([]{ RandAddPeriodic(); }, 60000); - GetMainSignals().RegisterBackgroundSignalScheduler(scheduler); + GetMainSignals().RegisterBackgroundSignalScheduler(*node.scheduler); // Create client interfaces for wallets that are supposed to be loaded // according to -wallet and -disablewallet options. This only constructs @@ -1327,7 +1330,7 @@ bool AppInitMain(NodeContext& node) assert(!node.connman); node.connman = std::unique_ptr(new CConnman(GetRand(std::numeric_limits::max()), GetRand(std::numeric_limits::max()))); - node.peer_logic.reset(new PeerLogicValidation(node.connman.get(), node.banman.get(), scheduler)); + node.peer_logic.reset(new PeerLogicValidation(node.connman.get(), node.banman.get(), *node.scheduler)); RegisterValidationInterface(node.peer_logic.get()); // sanitize comments per BIP-0014, format user agent and check total size @@ -1819,7 +1822,7 @@ bool AppInitMain(NodeContext& node) connOptions.m_specified_outgoing = connect; } } - if (!node.connman->Start(scheduler, connOptions)) { + if (!node.connman->Start(*node.scheduler, connOptions)) { return false; } @@ -1848,11 +1851,11 @@ bool AppInitMain(NodeContext& node) uiInterface.InitMessage(_("Done loading").translated); for (const auto& client : node.chain_clients) { - client->start(scheduler); + client->start(*node.scheduler); } BanMan* banman = node.banman.get(); - scheduler.scheduleEvery([banman]{ + node.scheduler->scheduleEvery([banman]{ banman->DumpBanlist(); }, DUMP_BANS_INTERVAL * 1000); diff --git a/src/node/context.cpp b/src/node/context.cpp index 26a01420c86..5b19a41bd4c 100644 --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -8,6 +8,7 @@ #include #include #include +#include NodeContext::NodeContext() {} NodeContext::~NodeContext() {} diff --git a/src/node/context.h b/src/node/context.h index dab5b5d048d..1c592b456bf 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -10,6 +10,7 @@ class BanMan; class CConnman; +class CScheduler; class CTxMemPool; class PeerLogicValidation; namespace interfaces { @@ -34,6 +35,7 @@ struct NodeContext { std::unique_ptr banman; std::unique_ptr chain; std::vector> chain_clients; + std::unique_ptr scheduler; //! Declare default constructor and destructor that are not inline, so code //! instantiating the NodeContext struct doesn't need to #include class diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 2eaa3427eba..c1762483e92 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -27,6 +27,7 @@ public: static const CRPCConvertParam vRPCConvertParams[] = { { "setmocktime", 0, "timestamp" }, + { "mockscheduler", 0, "delta_time" }, { "utxoupdatepsbt", 1, "descriptors" }, { "generatetoaddress", 0, "nblocks" }, { "generatetoaddress", 2, "maxtries" }, diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 74faf570112..2b4ee62c712 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -5,10 +5,12 @@ #include #include +#include #include #include #include #include +#include #include