Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13711303
D17723.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
13 KB
Subscribers
None
D17723.diff
View Options
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -641,7 +641,9 @@
init.cpp
init/common.cpp
invrequest.cpp
+ kernel/checks.cpp
kernel/coinstats.cpp
+ kernel/context.cpp
kernel/cs_main.cpp
kernel/disconnected_transactions.cpp
kernel/mempool_persist.cpp
@@ -847,7 +849,9 @@
add_library(bitcoinkernel
kernel/bitcoinkernel.cpp
kernel/chainparams.cpp
+ kernel/checks.cpp
kernel/coinstats.cpp
+ kernel/context.cpp
kernel/cs_main.cpp
kernel/disconnected_transactions.cpp
kernel/mempool_persist.cpp
diff --git a/src/bitcoin-chainstate.cpp b/src/bitcoin-chainstate.cpp
--- a/src/bitcoin-chainstate.cpp
+++ b/src/bitcoin-chainstate.cpp
@@ -13,6 +13,8 @@
#include <kernel/chainparams.h>
#include <kernel/chainstatemanager_opts.h>
+#include <kernel/checks.h>
+#include <kernel/context.h>
#include <kernel/validation_cache_sizes.h>
#include <chainparams.h>
@@ -20,7 +22,6 @@
#include <config.h>
#include <consensus/validation.h>
#include <core_io.h>
-#include <init/common.h>
#include <node/blockstorage.h>
#include <node/caches.h>
#include <node/chainstate.h>
@@ -32,6 +33,7 @@
#include <validation.h>
#include <validationinterface.h>
+#include <cassert>
#include <cstdint>
#include <filesystem>
#include <functional>
@@ -66,7 +68,11 @@
config.SetChainParams(*chainparams);
// ECC_Start, etc.
- init::SetGlobals();
+ kernel::Context kernel_context{};
+ // We can't use a goto here, but we can use an assert since none of the
+ // things instantiated so far requires running the epilogue to be torn down
+ // properly
+ assert(!kernel::SanityChecks(kernel_context).has_value());
// Necessary for CheckInputScripts (eventually called by ProcessNewBlock),
// which will try the script cache first and fall back to actually
@@ -327,6 +333,4 @@
}
}
GetMainSignals().UnregisterBackgroundSignalScheduler();
-
- init::UnsetGlobals();
}
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -240,11 +240,14 @@
// up on console
return false;
}
- if (!AppInitSanityChecks()) {
+
+ node.kernel = std::make_unique<kernel::Context>();
+ if (!AppInitSanityChecks(*node.kernel)) {
// InitError will have been called with detailed error, which ends
// up on console
return false;
}
+
if (args.GetBoolArg("-daemon", DEFAULT_DAEMON) ||
args.GetBoolArg("-daemonwait", DEFAULT_DAEMONWAIT)) {
#if HAVE_DECL_FORK
diff --git a/src/init.h b/src/init.h
--- a/src/init.h
+++ b/src/init.h
@@ -25,6 +25,9 @@
namespace interfaces {
struct BlockAndHeaderTipInfo;
}
+namespace kernel {
+struct Context;
+}
namespace node {
struct NodeContext;
} // namespace node
@@ -60,7 +63,7 @@
* @pre Parameters should be parsed and config file should be read,
* AppInitParameterInteraction should have been called.
*/
-bool AppInitSanityChecks();
+bool AppInitSanityChecks(const kernel::Context &kernel);
/**
* Lock bitcoin data directory.
* @note This should only be done after daemonization.
diff --git a/src/init.cpp b/src/init.cpp
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -9,6 +9,7 @@
#include <init.h>
+#include <kernel/checks.h>
#include <kernel/mempool_persist.h>
#include <kernel/validation_cache_sizes.h>
@@ -360,7 +361,7 @@
node.chain_clients.clear();
UnregisterAllValidationInterfaces();
GetMainSignals().UnregisterBackgroundSignalScheduler();
- init::UnsetGlobals();
+ node.kernel.reset();
node.mempool.reset();
node.chainman.reset();
node.scheduler.reset();
@@ -2079,13 +2080,25 @@
return true;
}
-bool AppInitSanityChecks() {
+bool AppInitSanityChecks(const kernel::Context &kernel) {
// Step 4: sanity checks
+ auto maybe_error = kernel::SanityChecks(kernel);
+
+ if (maybe_error.has_value()) {
+ switch (maybe_error.value()) {
+ case kernel::SanityCheckError::ERROR_ECC:
+ InitError(Untranslated("Elliptic curve cryptography sanity "
+ "check failure. Aborting."));
+ break;
+ case kernel::SanityCheckError::ERROR_RANDOM:
+ InitError(Untranslated(
+ "OS cryptographic RNG sanity check failure. Aborting."));
+ break;
+ case kernel::SanityCheckError::ERROR_CHRONO:
+ InitError(Untranslated("Clock epoch mismatch. Aborting."));
+ break;
+ } // no default case, so the compiler can warn about missing cases
- init::SetGlobals();
-
- // Sanity check
- if (!init::SanityChecks()) {
return InitError(strprintf(
_("Initialization sanity check failed. %s is shutting down."),
PACKAGE_NAME));
diff --git a/src/init/common.h b/src/init/common.h
--- a/src/init/common.h
+++ b/src/init/common.h
@@ -11,13 +11,6 @@
class ArgsManager;
namespace init {
-void SetGlobals();
-void UnsetGlobals();
-/**
- * Ensure a usable environment with all
- * necessary library support.
- */
-bool SanityChecks();
void AddLoggingArgs(ArgsManager &args);
void SetLoggingOptions(const ArgsManager &args);
void SetLoggingCategories(const ArgsManager &args);
diff --git a/src/init/common.cpp b/src/init/common.cpp
--- a/src/init/common.cpp
+++ b/src/init/common.cpp
@@ -8,55 +8,16 @@
#include <clientversion.h>
#include <common/args.h>
-#include <crypto/sha256.h>
-#include <key.h>
#include <logging.h>
#include <node/miner.h>
#include <node/ui_interface.h>
-#include <pubkey.h>
-#include <random.h>
#include <util/fs_helpers.h>
#include <util/time.h>
#include <util/translation.h>
-#include <memory>
-
using node::DEFAULT_PRINTPRIORITY;
-static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
-
namespace init {
-void SetGlobals() {
- std::string sha256_algo = SHA256AutoDetect();
- LogPrintf("Using the '%s' SHA256 implementation\n", sha256_algo);
- RandomInit();
- ECC_Start();
- globalVerifyHandle.reset(new ECCVerifyHandle());
-}
-
-void UnsetGlobals() {
- globalVerifyHandle.reset();
- ECC_Stop();
-}
-
-bool SanityChecks() {
- if (!ECC_InitSanityCheck()) {
- return InitError(Untranslated(
- "Elliptic curve cryptography sanity check failure. Aborting."));
- }
-
- if (!Random_SanityCheck()) {
- return InitError(Untranslated(
- "OS cryptographic RNG sanity check failure. Aborting."));
- }
-
- if (!ChronoSanityCheck()) {
- return InitError(Untranslated("Clock epoch mismatch. Aborting."));
- }
-
- return true;
-}
-
void AddLoggingArgs(ArgsManager &argsman) {
argsman.AddArg(
"-debuglogfile=<file>",
diff --git a/src/kernel/checks.h b/src/kernel/checks.h
new file mode 100644
--- /dev/null
+++ b/src/kernel/checks.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2022 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_KERNEL_CHECKS_H
+#define BITCOIN_KERNEL_CHECKS_H
+
+#include <optional>
+
+namespace kernel {
+
+struct Context;
+
+enum class SanityCheckError {
+ ERROR_ECC,
+ ERROR_RANDOM,
+ ERROR_CHRONO,
+};
+
+/**
+ * Ensure a usable environment with all necessary library support.
+ */
+std::optional<SanityCheckError> SanityChecks(const Context &);
+
+} // namespace kernel
+
+#endif // BITCOIN_KERNEL_CHECKS_H
diff --git a/src/kernel/checks.cpp b/src/kernel/checks.cpp
new file mode 100644
--- /dev/null
+++ b/src/kernel/checks.cpp
@@ -0,0 +1,29 @@
+// Copyright (c) 2022 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 <kernel/checks.h>
+
+#include <key.h>
+#include <random.h>
+#include <util/time.h>
+
+namespace kernel {
+
+std::optional<SanityCheckError> SanityChecks(const Context &) {
+ if (!ECC_InitSanityCheck()) {
+ return SanityCheckError::ERROR_ECC;
+ }
+
+ if (!Random_SanityCheck()) {
+ return SanityCheckError::ERROR_RANDOM;
+ }
+
+ if (!ChronoSanityCheck()) {
+ return SanityCheckError::ERROR_CHRONO;
+ }
+
+ return std::nullopt;
+}
+
+} // namespace kernel
diff --git a/src/kernel/context.h b/src/kernel/context.h
new file mode 100644
--- /dev/null
+++ b/src/kernel/context.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2022 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_KERNEL_CONTEXT_H
+#define BITCOIN_KERNEL_CONTEXT_H
+
+#include <memory>
+
+class ECCVerifyHandle;
+
+namespace kernel {
+//! Context struct holding the kernel library's logically global state, and
+//! passed to external libbitcoin_kernel functions which need access to this
+//! state. The kernel library API is a work in progress, so state organization
+//! and member list will evolve over time.
+//!
+//! State stored directly in this struct should be simple. More complex state
+//! should be stored to std::unique_ptr members pointing to opaque types.
+struct Context {
+ std::unique_ptr<ECCVerifyHandle> ecc_verify_handle;
+
+ //! Declare default constructor and destructor that are not inline, so code
+ //! instantiating the kernel::Context struct doesn't need to #include class
+ //! definitions for all the unique_ptr members.
+ Context();
+ ~Context();
+};
+} // namespace kernel
+
+#endif // BITCOIN_KERNEL_CONTEXT_H
diff --git a/src/kernel/context.cpp b/src/kernel/context.cpp
new file mode 100644
--- /dev/null
+++ b/src/kernel/context.cpp
@@ -0,0 +1,30 @@
+// Copyright (c) 2022 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 <kernel/context.h>
+
+#include <crypto/sha256.h>
+#include <key.h>
+#include <logging.h>
+#include <pubkey.h>
+#include <random.h>
+
+#include <string>
+
+namespace kernel {
+
+Context::Context() {
+ std::string sha256_algo = SHA256AutoDetect();
+ LogPrintf("Using the '%s' SHA256 implementation\n", sha256_algo);
+ RandomInit();
+ ECC_Start();
+ ecc_verify_handle.reset(new ECCVerifyHandle());
+}
+
+Context::~Context() {
+ ecc_verify_handle.reset();
+ ECC_Stop();
+}
+
+} // namespace kernel
diff --git a/src/node/context.h b/src/node/context.h
--- a/src/node/context.h
+++ b/src/node/context.h
@@ -5,6 +5,8 @@
#ifndef BITCOIN_NODE_CONTEXT_H
#define BITCOIN_NODE_CONTEXT_H
+#include <kernel/context.h>
+
#include <cassert>
#include <functional>
#include <memory>
@@ -41,6 +43,8 @@
//! any member functions. It should just be a collection of references that can
//! be used without pulling in unwanted dependencies or functionality.
struct NodeContext {
+ //! libbitcoin_kernel context
+ std::unique_ptr<kernel::Context> kernel;
std::unique_ptr<AddrMan> addrman;
std::unique_ptr<CConnman> connman;
std::unique_ptr<CTxMemPool> mempool;
diff --git a/src/node/context.cpp b/src/node/context.cpp
--- a/src/node/context.cpp
+++ b/src/node/context.cpp
@@ -8,6 +8,7 @@
#include <avalanche/processor.h>
#include <banman.h>
#include <interfaces/chain.h>
+#include <kernel/context.h>
#include <net.h>
#include <net_processing.h>
#include <node/kernel_notifications.h>
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -75,10 +75,26 @@
}
bilingual_str getWarnings() override { return GetWarnings(true); }
bool baseInitialize(Config &config) override {
- return AppInitBasicSetup(gArgs) &&
- AppInitParameterInteraction(config, gArgs) &&
- AppInitSanityChecks() && AppInitLockDataDirectory() &&
- AppInitInterfaces(*m_context);
+ if (!AppInitBasicSetup(gArgs)) {
+ return false;
+ }
+ if (!AppInitParameterInteraction(config, gArgs)) {
+ return false;
+ }
+
+ m_context->kernel = std::make_unique<kernel::Context>();
+ if (!AppInitSanityChecks(*m_context->kernel)) {
+ return false;
+ }
+
+ if (!AppInitLockDataDirectory()) {
+ return false;
+ }
+ if (!AppInitInterfaces(*m_context)) {
+ return false;
+ }
+
+ return true;
}
bool appInitMain(Config &config, RPCServer &rpcServer,
HTTPRPCRequestProcessor &httpRPCRequestProcessor,
diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h
--- a/src/test/util/setup_common.h
+++ b/src/test/util/setup_common.h
@@ -46,7 +46,7 @@
* This just configures logging, data dir and chain parameters.
*/
struct BasicTestingSetup {
- ECCVerifyHandle globalVerifyHandle;
+ // keep as first member to be destructed last
node::NodeContext m_node;
explicit BasicTestingSetup(
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -17,6 +17,7 @@
#include <consensus/validation.h>
#include <crypto/sha256.h>
#include <init.h>
+#include <init/common.h>
#include <interfaces/chain.h>
#include <logging.h>
#include <mempool_args.h>
@@ -132,8 +133,7 @@
InitLogging(*m_node.args);
AppInitParameterInteraction(config, *m_node.args);
LogInstance().StartLogging();
- SHA256AutoDetect();
- ECC_Start();
+ m_node.kernel = std::make_unique<kernel::Context>();
SetupEnvironment();
SetupNetworking();
@@ -158,7 +158,6 @@
LogInstance().DisconnectTestLogger();
fs::remove_all(m_path_root);
gArgs.ClearArgs();
- ECC_Stop();
}
CTxMemPool::Options MemPoolOptionsForTest(const NodeContext &node) {
CTxMemPool::Options mempool_opts{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 26, 11:28 (16 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5573407
Default Alt Text
D17723.diff (13 KB)
Attached To
D17723: [kernel 2c/n] Introduce kernel::Context, encapsulate global init/teardown
Event Timeline
Log In to Comment