Page MenuHomePhabricator

D17723.diff
No OneTemporary

D17723.diff

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

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)

Event Timeline