Skip to content

Commit

Permalink
Merge bitcoin#27861: kernel: Rm ShutdownRequested and AbortNode from …
Browse files Browse the repository at this point in the history
…validat…
  • Loading branch information
ryanofsky authored and sidhujag committed Jul 7, 2023
1 parent a9044ae commit 61285e8
Show file tree
Hide file tree
Showing 31 changed files with 406 additions and 212 deletions.
6 changes: 5 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ SYSCOIN_CORE_H = \
netbase.h \
netgroup.h \
netmessagemaker.h \
node/abort.h \
node/blockmanager_args.h \
node/blockstorage.h \
node/caches.h \
Expand Down Expand Up @@ -373,6 +374,7 @@ SYSCOIN_CORE_H = \
util/ranges.h \
util/result.h \
util/serfloat.h \
util/signalinterrupt.h \
util/sock.h \
util/spanparsing.h \
util/string.h \
Expand Down Expand Up @@ -527,6 +529,7 @@ libsyscoin_node_a_SOURCES = \
netfulfilledman.cpp \
netgroup.cpp \
net_processing.cpp \
node/abort.cpp \
node/blockmanager_args.cpp \
node/blockstorage.cpp \
node/caches.cpp \
Expand Down Expand Up @@ -889,6 +892,7 @@ libsyscoin_util_a_SOURCES = \
util/moneystr.cpp \
util/rbf.cpp \
util/readwritefile.cpp \
util/signalinterrupt.cpp \
util/thread.cpp \
util/threadinterrupt.cpp \
util/threadnames.cpp \
Expand Down Expand Up @@ -1088,7 +1092,6 @@ libsyscoinkernel_la_SOURCES = \
logging.cpp \
node/blockstorage.cpp \
node/chainstate.cpp \
node/interface_ui.cpp \
node/utxo_snapshot.cpp \
policy/feerate.cpp \
policy/fees.cpp \
Expand Down Expand Up @@ -1127,6 +1130,7 @@ libsyscoinkernel_la_SOURCES = \
util/moneystr.cpp \
util/rbf.cpp \
util/serfloat.cpp \
util/signalinterrupt.cpp \
util/strencodings.cpp \
util/string.cpp \
util/syserror.cpp \
Expand Down
20 changes: 11 additions & 9 deletions src/index/base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <interfaces/chain.h>
#include <kernel/chain.h>
#include <logging.h>
#include <node/abort.h>
#include <node/blockstorage.h>
#include <node/context.h>
#include <node/database_args.h>
Expand All @@ -30,9 +31,10 @@ constexpr auto SYNC_LOG_INTERVAL{30s};
constexpr auto SYNC_LOCATOR_WRITE_INTERVAL{30s};

template <typename... Args>
static void FatalError(const char* fmt, const Args&... args)
void BaseIndex::FatalErrorf(const char* fmt, const Args&... args)
{
AbortNode(tfm::format(fmt, args...));
auto message = tfm::format(fmt, args...);
node::AbortNode(m_chain->context()->exit_status, message);
}

CBlockLocator GetLocator(interfaces::Chain& chain, const uint256& block_hash)
Expand Down Expand Up @@ -197,7 +199,7 @@ void BaseIndex::ThreadSync()
break;
}
if (pindex_next->pprev != pindex && !Rewind(pindex, pindex_next->pprev)) {
FatalError("%s: Failed to rewind index %s to a previous chain tip",
FatalErrorf("%s: Failed to rewind index %s to a previous chain tip",
__func__, GetName());
return;
}
Expand All @@ -221,14 +223,14 @@ void BaseIndex::ThreadSync()
CBlock block;
interfaces::BlockInfo block_info = kernel::MakeBlockInfo(pindex);
if (!m_chainstate->m_blockman.ReadBlockFromDisk(block, *pindex)) {
FatalError("%s: Failed to read block %s from disk",
FatalErrorf("%s: Failed to read block %s from disk",
__func__, pindex->GetBlockHash().ToString());
return;
} else {
block_info.data = &block;
}
if (!CustomAppend(block_info)) {
FatalError("%s: Failed to write block %s to index database",
FatalErrorf("%s: Failed to write block %s to index database",
__func__, pindex->GetBlockHash().ToString());
return;
}
Expand Down Expand Up @@ -294,7 +296,7 @@ void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const
const CBlockIndex* best_block_index = m_best_block_index.load();
if (!best_block_index) {
if (pindex->nHeight != 0) {
FatalError("%s: First block connected is not the genesis block (height=%d)",
FatalErrorf("%s: First block connected is not the genesis block (height=%d)",
__func__, pindex->nHeight);
return;
}
Expand All @@ -312,7 +314,7 @@ void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const
return;
}
if (best_block_index != pindex->pprev && !Rewind(best_block_index, pindex->pprev)) {
FatalError("%s: Failed to rewind index %s to a previous chain tip",
FatalErrorf("%s: Failed to rewind index %s to a previous chain tip",
__func__, GetName());
return;
}
Expand All @@ -325,7 +327,7 @@ void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const
// processed, and the index object being safe to delete.
SetBestBlockIndex(pindex);
} else {
FatalError("%s: Failed to write block %s to index",
FatalErrorf("%s: Failed to write block %s to index",
__func__, pindex->GetBlockHash().ToString());
return;
}
Expand All @@ -345,7 +347,7 @@ void BaseIndex::ChainStateFlushed(const CBlockLocator& locator)
}

if (!locator_tip_index) {
FatalError("%s: First block (hash=%s) in locator was not found",
FatalErrorf("%s: First block (hash=%s) in locator was not found",
__func__, locator_tip_hash.ToString());
return;
}
Expand Down
3 changes: 3 additions & 0 deletions src/index/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ class BaseIndex : public CValidationInterface

virtual bool AllowPrune() const = 0;

template <typename... Args>
void FatalErrorf(const char* fmt, const Args&... args);

protected:
std::unique_ptr<interfaces::Chain> m_chain;
Chainstate* m_chainstate{nullptr};
Expand Down
12 changes: 5 additions & 7 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -939,10 +939,6 @@ bool AppInitBasicSetup(const ArgsManager& args, std::atomic<int>& exit_status)
// Enable heap terminate-on-corruption
HeapSetInformation(nullptr, HeapEnableTerminationOnCorruption, nullptr, 0);
#endif
if (!InitShutdownState(exit_status)) {
return InitError(Untranslated("Initializing wait-for-shutdown state failed."));
}

if (!SetupNetworking()) {
return InitError(Untranslated("Initializing networking failed."));
}
Expand Down Expand Up @@ -1142,7 +1138,7 @@ bool AppInitParameterInteraction(const ArgsManager& args)
}
// Also report errors from parsing before daemonization
{
KernelNotifications notifications{};
kernel::Notifications notifications{};
ChainstateManager::Options chainman_opts_dummy{
.chainparams = chainparams,
.datadir = args.GetDataDirNet(),
Expand All @@ -1155,6 +1151,7 @@ bool AppInitParameterInteraction(const ArgsManager& args)
BlockManager::Options blockman_opts_dummy{
.chainparams = chainman_opts_dummy.chainparams,
.blocks_dir = args.GetBlocksDirPath(),
.notifications = chainman_opts_dummy.notifications,
};
auto blockman_result{ApplyArgsManOptions(args, blockman_opts_dummy)};
if (!blockman_result) {
Expand Down Expand Up @@ -1627,7 +1624,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)

// ********************************************************* Step 7: load block chain

node.notifications = std::make_unique<KernelNotifications>();
node.notifications = std::make_unique<KernelNotifications>(node.exit_status);
// SYSCOIN
fReindex = args.GetBoolArg("-reindex", false);
bool fReindexChainState = args.GetBoolArg("-reindex-chainstate", false);
Expand Down Expand Up @@ -1657,6 +1654,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
BlockManager::Options blockman_opts{
.chainparams = chainman_opts.chainparams,
.blocks_dir = args.GetBlocksDirPath(),
.notifications = chainman_opts.notifications,
};
Assert(ApplyArgsManOptions(args, blockman_opts)); // no error can happen, already checked in AppInitParameterInteraction

Expand Down Expand Up @@ -1696,7 +1694,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
for (bool fLoaded = false; !fLoaded && !ShutdownRequested();) {
node.mempool = std::make_unique<CTxMemPool>(mempool_opts);

node.chainman = std::make_unique<ChainstateManager>(chainman_opts, blockman_opts);
node.chainman = std::make_unique<ChainstateManager>(node.kernel->interrupt, chainman_opts, blockman_opts);
ChainstateManager& chainman = *node.chainman;
// SYSCOIN
node.peerman = PeerManager::make(*node.connman, *node.addrman, node.banman.get(),
Expand Down
2 changes: 2 additions & 0 deletions src/kernel/blockmanager_opts.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef SYSCOIN_KERNEL_BLOCKMANAGER_OPTS_H
#define SYSCOIN_KERNEL_BLOCKMANAGER_OPTS_H

#include <kernel/notifications_interface.h>
#include <util/fs.h>

#include <cstdint>
Expand All @@ -25,6 +26,7 @@ struct BlockManagerOpts {
bool fast_prune{false};
bool stop_after_block_import{DEFAULT_STOPAFTERBLOCKIMPORT};
const fs::path blocks_dir;
Notifications& notifications;
};

} // namespace kernel
Expand Down
5 changes: 5 additions & 0 deletions src/kernel/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@
#include <bls/bls.h>

namespace kernel {
Context* g_context;

Context::Context()
{
assert(!g_context);
g_context = this;
std::string sha256_algo = SHA256AutoDetect();
LogPrintf("Using the '%s' SHA256 implementation\n", sha256_algo);
RandomInit();
Expand All @@ -28,6 +31,8 @@ Context::Context()
Context::~Context()
{
ECC_Stop();
assert(g_context);
g_context = nullptr;
}

} // namespace kernel
14 changes: 14 additions & 0 deletions src/kernel/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#ifndef SYSCOIN_KERNEL_CONTEXT_H
#define SYSCOIN_KERNEL_CONTEXT_H

#include <util/signalinterrupt.h>

#include <memory>

namespace kernel {
Expand All @@ -16,12 +18,24 @@ namespace kernel {
//! 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 {
//! Interrupt object that can be used to stop long-running kernel operations.
util::SignalInterrupt interrupt;

//! 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();
};

//! Global pointer to kernel::Context for legacy code. New code should avoid
//! using this, and require state it needs to be passed to it directly.
//!
//! Having this pointer is useful because it allows state be moved out of global
//! variables into the kernel::Context struct before all global references to
//! that state are removed. This allows the global references to be removed
//! incrementally, instead of all at once.
extern Context* g_context;
} // namespace kernel

#endif // SYSCOIN_KERNEL_CONTEXT_H
4 changes: 2 additions & 2 deletions src/kernel/mempool_persist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
#include <logging.h>
#include <primitives/transaction.h>
#include <serialize.h>
#include <shutdown.h>
#include <streams.h>
#include <sync.h>
#include <txmempool.h>
#include <uint256.h>
#include <util/fs.h>
#include <util/fs_helpers.h>
#include <util/signalinterrupt.h>
#include <util/time.h>
#include <validation.h>

Expand Down Expand Up @@ -95,7 +95,7 @@ bool LoadMempool(CTxMemPool& pool, const fs::path& load_path, Chainstate& active
} else {
++expired;
}
if (ShutdownRequested())
if (active_chainstate.m_chainman.m_interrupt)
return false;
}
std::map<uint256, CAmount> mapDeltas;
Expand Down
20 changes: 19 additions & 1 deletion src/kernel/notifications_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
#ifndef SYSCOIN_KERNEL_NOTIFICATIONS_INTERFACE_H
#define SYSCOIN_KERNEL_NOTIFICATIONS_INTERFACE_H

#include <util/translation.h>

#include <cstdint>
#include <string>

class CBlockIndex;
enum class SynchronizationState;
struct bilingual_str;

namespace kernel {

Expand All @@ -27,6 +28,23 @@ class Notifications
virtual void headerTip(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) {}
virtual void progress(const bilingual_str& title, int progress_percent, bool resume_possible) {}
virtual void warning(const bilingual_str& warning) {}

//! The flush error notification is sent to notify the user that an error
//! occurred while flushing block data to disk. Kernel code may ignore flush
//! errors that don't affect the immediate operation it is trying to
//! perform. Applications can choose to handle the flush error notification
//! by logging the error, or notifying the user, or triggering an early
//! shutdown as a precaution against causing more errors.
virtual void flushError(const std::string& debug_message) {}

//! The fatal error notification is sent to notify the user when an error
//! occurs in kernel code that can't be recovered from. After this
//! notification is sent, whatever function triggered the error should also
//! return an error code or raise an exception. Applications can choose to
//! handle the fatal error notification by logging the error, or notifying
//! the user, or triggering an early shutdown as a precaution against
//! causing more errors.
virtual void fatalError(const std::string& debug_message, const bilingual_str& user_message = {}) {}
};
} // namespace kernel

Expand Down
27 changes: 27 additions & 0 deletions src/node/abort.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2023 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 <node/abort.h>

#include <logging.h>
#include <node/interface_ui.h>
#include <shutdown.h>
#include <util/translation.h>
#include <warnings.h>

#include <atomic>
#include <cstdlib>
#include <string>

namespace node {

void AbortNode(std::atomic<int>& exit_status, const std::string& debug_message, const bilingual_str& user_message, bool shutdown)
{
SetMiscWarning(Untranslated(debug_message));
LogPrintf("*** %s\n", debug_message);
InitError(user_message.empty() ? _("A fatal internal error occurred, see debug.log for details") : user_message);
exit_status.store(EXIT_FAILURE);
if (shutdown) StartShutdown();
}
} // namespace node
17 changes: 17 additions & 0 deletions src/node/abort.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2023 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 SYSCOIN_NODE_ABORT_H
#define SYSCOIN_NODE_ABORT_H

#include <util/translation.h>

#include <atomic>
#include <string>

namespace node {
void AbortNode(std::atomic<int>& exit_status, const std::string& debug_message, const bilingual_str& user_message = {}, bool shutdown = true);
} // namespace node

#endif // SYSCOIN_NODE_ABORT_H
Loading

0 comments on commit 61285e8

Please sign in to comment.