mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-24 18:23:26 -03:00
Merge bitcoin/bitcoin#30967: refactor: Replace g_genesis_wait_cv with m_tip_block_cv
Some checks are pending
Some checks are pending
fa22e5c430
refactor: Remove dead code that assumed tip == nullptr (MarcoFalke)fa2e443965
refactor: Replace g_genesis_wait_cv with m_tip_block_cv (MarcoFalke)fa7f52af1a
refactor: Use wait_for predicate to check for interrupt (MarcoFalke)5ca28ef28b
refactor: Split up NodeContext shutdown_signal and shutdown_request (Ryan Ofsky)fad8e7fba7
bugfix: Mark m_tip_block_cv as guarded by m_tip_block_mutex (MarcoFalke)fa18586c29
refactor: Add missing GUARDED_BY(m_tip_block_mutex) (MarcoFalke)fa4c075033
doc: Clarify waitTipChanged docs (MarcoFalke) Pull request description: `g_genesis_wait_cv` is similar to `m_tip_block_cv` but shuffling everything through a redundant `boost::signals2`. So remove it, along with some other dead code, as well as minor fixups. ACKs for top commit: ryanofsky: Code review ACKfa22e5c430
(just rebased since last review) Sjors: ACKfa22e5c430
TheCharlatan: ACKfa22e5c430
Tree-SHA512: a2cb59b651aaf85a3574723adfe403487566788ad945933b0458816ccc841fce08ca77b31afbd2d6adb5bf1deed7229c028bee74fb4bbaf6576e9edcfa0ad817
This commit is contained in:
commit
5837e3463f
20 changed files with 87 additions and 114 deletions
|
@ -274,7 +274,7 @@ MAIN_FUNCTION
|
|||
if (ProcessInitCommands(args)) return EXIT_SUCCESS;
|
||||
|
||||
// Start application
|
||||
if (!AppInit(node) || !Assert(node.shutdown)->wait()) {
|
||||
if (!AppInit(node) || !Assert(node.shutdown_signal)->wait()) {
|
||||
node.exit_status = EXIT_FAILURE;
|
||||
}
|
||||
Interrupt(node);
|
||||
|
|
|
@ -31,7 +31,7 @@ template <typename... Args>
|
|||
void BaseIndex::FatalErrorf(util::ConstevalFormatString<sizeof...(Args)> fmt, const Args&... args)
|
||||
{
|
||||
auto message = tfm::format(fmt, args...);
|
||||
node::AbortNode(m_chain->context()->shutdown, m_chain->context()->exit_status, Untranslated(message), m_chain->context()->warnings.get());
|
||||
node::AbortNode(m_chain->context()->shutdown_request, m_chain->context()->exit_status, Untranslated(message), m_chain->context()->warnings.get());
|
||||
}
|
||||
|
||||
CBlockLocator GetLocator(interfaces::Chain& chain, const uint256& block_hash)
|
||||
|
|
76
src/init.cpp
76
src/init.cpp
|
@ -207,7 +207,14 @@ void InitContext(NodeContext& node)
|
|||
g_shutdown.emplace();
|
||||
|
||||
node.args = &gArgs;
|
||||
node.shutdown = &*g_shutdown;
|
||||
node.shutdown_signal = &*g_shutdown;
|
||||
node.shutdown_request = [&node] {
|
||||
assert(node.shutdown_signal);
|
||||
if (!(*node.shutdown_signal)()) return false;
|
||||
// Wake any threads that may be waiting for the tip to change.
|
||||
if (node.notifications) WITH_LOCK(node.notifications->m_tip_block_mutex, node.notifications->m_tip_block_cv.notify_all());
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -235,7 +242,7 @@ void InitContext(NodeContext& node)
|
|||
|
||||
bool ShutdownRequested(node::NodeContext& node)
|
||||
{
|
||||
return bool{*Assert(node.shutdown)};
|
||||
return bool{*Assert(node.shutdown_signal)};
|
||||
}
|
||||
|
||||
#if HAVE_SYSTEM
|
||||
|
@ -286,7 +293,7 @@ void Shutdown(NodeContext& node)
|
|||
|
||||
StopHTTPRPC();
|
||||
StopREST();
|
||||
StopRPC(&node);
|
||||
StopRPC();
|
||||
StopHTTPServer();
|
||||
for (const auto& client : node.chain_clients) {
|
||||
client->flush();
|
||||
|
@ -678,21 +685,6 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
|
|||
argsman.AddHiddenArgs(hidden_args);
|
||||
}
|
||||
|
||||
static bool fHaveGenesis = false;
|
||||
static GlobalMutex g_genesis_wait_mutex;
|
||||
static std::condition_variable g_genesis_wait_cv;
|
||||
|
||||
static void BlockNotifyGenesisWait(const CBlockIndex* pBlockIndex)
|
||||
{
|
||||
if (pBlockIndex != nullptr) {
|
||||
{
|
||||
LOCK(g_genesis_wait_mutex);
|
||||
fHaveGenesis = true;
|
||||
}
|
||||
g_genesis_wait_cv.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
#if HAVE_SYSTEM
|
||||
static void StartupNotify(const ArgsManager& args)
|
||||
{
|
||||
|
@ -707,7 +699,7 @@ static void StartupNotify(const ArgsManager& args)
|
|||
static bool AppInitServers(NodeContext& node)
|
||||
{
|
||||
const ArgsManager& args = *Assert(node.args);
|
||||
if (!InitHTTPServer(*Assert(node.shutdown))) {
|
||||
if (!InitHTTPServer(*Assert(node.shutdown_signal))) {
|
||||
return false;
|
||||
}
|
||||
StartRPC();
|
||||
|
@ -1216,7 +1208,7 @@ static ChainstateLoadResult InitAndLoadChainstate(
|
|||
};
|
||||
Assert(ApplyArgsManOptions(args, blockman_opts)); // no error can happen, already checked in AppInitParameterInteraction
|
||||
try {
|
||||
node.chainman = std::make_unique<ChainstateManager>(*Assert(node.shutdown), chainman_opts, blockman_opts);
|
||||
node.chainman = std::make_unique<ChainstateManager>(*Assert(node.shutdown_signal), chainman_opts, blockman_opts);
|
||||
} catch (std::exception& e) {
|
||||
return {ChainstateLoadStatus::FAILURE_FATAL, strprintf(Untranslated("Failed to initialize ChainstateManager: %s"), e.what())};
|
||||
}
|
||||
|
@ -1327,7 +1319,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
constexpr uint64_t min_disk_space = 50 << 20; // 50 MB
|
||||
if (!CheckDiskSpace(args.GetBlocksDirPath(), min_disk_space)) {
|
||||
LogError("Shutting down due to lack of disk space!\n");
|
||||
if (!(*Assert(node.shutdown))()) {
|
||||
if (!(Assert(node.shutdown_request))()) {
|
||||
LogError("Failed to send shutdown signal after disk space check\n");
|
||||
}
|
||||
}
|
||||
|
@ -1608,8 +1600,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
|
||||
// ********************************************************* Step 7: load block chain
|
||||
|
||||
node.notifications = std::make_unique<KernelNotifications>(*Assert(node.shutdown), node.exit_status, *Assert(node.warnings));
|
||||
ReadNotificationArgs(args, *node.notifications);
|
||||
node.notifications = std::make_unique<KernelNotifications>(Assert(node.shutdown_request), node.exit_status, *Assert(node.warnings));
|
||||
auto& kernel_notifications{*node.notifications};
|
||||
ReadNotificationArgs(args, kernel_notifications);
|
||||
|
||||
// cache size calculations
|
||||
CacheSizes cache_sizes = CalculateCacheSizes(args, g_enabled_filter_types.size());
|
||||
|
@ -1649,7 +1642,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
return false;
|
||||
}
|
||||
do_reindex = true;
|
||||
if (!Assert(node.shutdown)->reset()) {
|
||||
if (!Assert(node.shutdown_signal)->reset()) {
|
||||
LogError("Internal error: failed to reset shutdown signal.\n");
|
||||
}
|
||||
std::tie(status, error) = InitAndLoadChainstate(
|
||||
|
@ -1761,15 +1754,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
boost::signals2::connection block_notify_genesis_wait_connection;
|
||||
if (WITH_LOCK(chainman.GetMutex(), return chainman.ActiveChain().Tip() == nullptr)) {
|
||||
block_notify_genesis_wait_connection = uiInterface.NotifyBlockTip_connect(std::bind(BlockNotifyGenesisWait, std::placeholders::_2));
|
||||
} else {
|
||||
fHaveGenesis = true;
|
||||
}
|
||||
|
||||
#if HAVE_SYSTEM
|
||||
const std::string block_notify = args.GetArg("-blocknotify", "");
|
||||
if (!block_notify.empty()) {
|
||||
|
@ -1794,7 +1778,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
ImportBlocks(chainman, vImportFiles);
|
||||
if (args.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) {
|
||||
LogPrintf("Stopping after block import\n");
|
||||
if (!(*Assert(node.shutdown))()) {
|
||||
if (!(Assert(node.shutdown_request))()) {
|
||||
LogError("Failed to send shutdown signal after finishing block import\n");
|
||||
}
|
||||
return;
|
||||
|
@ -1814,15 +1798,11 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
});
|
||||
|
||||
// Wait for genesis block to be processed
|
||||
{
|
||||
WAIT_LOCK(g_genesis_wait_mutex, lock);
|
||||
// We previously could hang here if shutdown was requested prior to
|
||||
// ImportBlocks getting started, so instead we just wait on a timer to
|
||||
// check ShutdownRequested() regularly.
|
||||
while (!fHaveGenesis && !ShutdownRequested(node)) {
|
||||
g_genesis_wait_cv.wait_for(lock, std::chrono::milliseconds(500));
|
||||
}
|
||||
block_notify_genesis_wait_connection.disconnect();
|
||||
if (WITH_LOCK(chainman.GetMutex(), return chainman.ActiveTip() == nullptr)) {
|
||||
WAIT_LOCK(kernel_notifications.m_tip_block_mutex, lock);
|
||||
kernel_notifications.m_tip_block_cv.wait(lock, [&]() EXCLUSIVE_LOCKS_REQUIRED(kernel_notifications.m_tip_block_mutex) {
|
||||
return !kernel_notifications.m_tip_block.IsNull() || ShutdownRequested(node);
|
||||
});
|
||||
}
|
||||
|
||||
if (ShutdownRequested(node)) {
|
||||
|
@ -1831,17 +1811,17 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
|
||||
// ********************************************************* Step 12: start node
|
||||
|
||||
//// debug print
|
||||
int64_t best_block_time{};
|
||||
{
|
||||
LOCK(cs_main);
|
||||
LOCK(chainman.GetMutex());
|
||||
const auto& tip{*Assert(chainman.ActiveTip())};
|
||||
LogPrintf("block tree size = %u\n", chainman.BlockIndex().size());
|
||||
chain_active_height = chainman.ActiveChain().Height();
|
||||
best_block_time = chainman.ActiveChain().Tip() ? chainman.ActiveChain().Tip()->GetBlockTime() : chainman.GetParams().GenesisBlock().GetBlockTime();
|
||||
chain_active_height = tip.nHeight;
|
||||
best_block_time = tip.GetBlockTime();
|
||||
if (tip_info) {
|
||||
tip_info->block_height = chain_active_height;
|
||||
tip_info->block_time = best_block_time;
|
||||
tip_info->verification_progress = GuessVerificationProgress(chainman.GetParams().TxData(), chainman.ActiveChain().Tip());
|
||||
tip_info->verification_progress = GuessVerificationProgress(chainman.GetParams().TxData(), &tip);
|
||||
}
|
||||
if (tip_info && chainman.m_best_header) {
|
||||
tip_info->header_height = chainman.m_best_header->nHeight;
|
||||
|
|
|
@ -61,11 +61,11 @@ public:
|
|||
virtual std::optional<BlockRef> getTip() = 0;
|
||||
|
||||
/**
|
||||
* Waits for the tip to change
|
||||
* Waits for the connected tip to change. If the tip was not connected on
|
||||
* startup, this will wait.
|
||||
*
|
||||
* @param[in] current_tip block hash of the current chain tip. Function waits
|
||||
* for the chain tip to change if this matches, otherwise
|
||||
* it returns right away.
|
||||
* for the chain tip to differ from this.
|
||||
* @param[in] timeout how long to wait for a new tip
|
||||
* @returns Hash and height of the current chain tip after this call.
|
||||
*/
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
|
||||
namespace node {
|
||||
|
||||
void AbortNode(util::SignalInterrupt* shutdown, std::atomic<int>& exit_status, const bilingual_str& message, node::Warnings* warnings)
|
||||
void AbortNode(const std::function<bool()>& shutdown_request, std::atomic<int>& exit_status, const bilingual_str& message, node::Warnings* warnings)
|
||||
{
|
||||
if (warnings) warnings->Set(Warning::FATAL_INTERNAL_ERROR, message);
|
||||
InitError(_("A fatal internal error occurred, see debug.log for details: ") + message);
|
||||
exit_status.store(EXIT_FAILURE);
|
||||
if (shutdown && !(*shutdown)()) {
|
||||
if (shutdown_request && !shutdown_request()) {
|
||||
LogError("Failed to send shutdown signal\n");
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,16 +6,13 @@
|
|||
#define BITCOIN_NODE_ABORT_H
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
|
||||
struct bilingual_str;
|
||||
|
||||
namespace util {
|
||||
class SignalInterrupt;
|
||||
} // namespace util
|
||||
|
||||
namespace node {
|
||||
class Warnings;
|
||||
void AbortNode(util::SignalInterrupt* shutdown, std::atomic<int>& exit_status, const bilingual_str& message, node::Warnings* warnings);
|
||||
void AbortNode(const std::function<bool()>& shutdown_request, std::atomic<int>& exit_status, const bilingual_str& message, node::Warnings* warnings);
|
||||
} // namespace node
|
||||
|
||||
#endif // BITCOIN_NODE_ABORT_H
|
||||
|
|
|
@ -59,8 +59,10 @@ struct NodeContext {
|
|||
std::unique_ptr<ECC_Context> ecc_context;
|
||||
//! Init interface for initializing current process and connecting to other processes.
|
||||
interfaces::Init* init{nullptr};
|
||||
//! Function to request a shutdown.
|
||||
std::function<bool()> shutdown_request;
|
||||
//! Interrupt object used to track whether node shutdown was requested.
|
||||
util::SignalInterrupt* shutdown{nullptr};
|
||||
util::SignalInterrupt* shutdown_signal{nullptr};
|
||||
std::unique_ptr<AddrMan> addrman;
|
||||
std::unique_ptr<CConnman> connman;
|
||||
std::unique_ptr<CTxMemPool> mempool;
|
||||
|
|
|
@ -134,13 +134,15 @@ public:
|
|||
}
|
||||
void startShutdown() override
|
||||
{
|
||||
if (!(*Assert(Assert(m_context)->shutdown))()) {
|
||||
NodeContext& ctx{*Assert(m_context)};
|
||||
if (!(Assert(ctx.shutdown_request))()) {
|
||||
LogError("Failed to send shutdown signal\n");
|
||||
}
|
||||
|
||||
// Stop RPC for clean shutdown if any of waitfor* commands is executed.
|
||||
if (args().GetBoolArg("-server", false)) {
|
||||
InterruptRPC();
|
||||
StopRPC(m_context);
|
||||
StopRPC();
|
||||
}
|
||||
}
|
||||
bool shutdownRequested() override { return ShutdownRequested(*Assert(m_context)); };
|
||||
|
@ -938,19 +940,12 @@ public:
|
|||
|
||||
BlockRef waitTipChanged(uint256 current_tip, MillisecondsDouble timeout) override
|
||||
{
|
||||
// Interrupt check interval
|
||||
const MillisecondsDouble tick{1000};
|
||||
auto now{std::chrono::steady_clock::now()};
|
||||
auto deadline = now + timeout;
|
||||
// std::chrono does not check against overflow
|
||||
if (deadline < now) deadline = std::chrono::steady_clock::time_point::max();
|
||||
if (timeout > std::chrono::years{100}) timeout = std::chrono::years{100}; // Upper bound to avoid UB in std::chrono
|
||||
{
|
||||
WAIT_LOCK(notifications().m_tip_block_mutex, lock);
|
||||
while ((notifications().m_tip_block == uint256() || notifications().m_tip_block == current_tip) && !chainman().m_interrupt) {
|
||||
now = std::chrono::steady_clock::now();
|
||||
if (now >= deadline) break;
|
||||
notifications().m_tip_block_cv.wait_until(lock, std::min(deadline, now + tick));
|
||||
}
|
||||
notifications().m_tip_block_cv.wait_for(lock, timeout, [&]() EXCLUSIVE_LOCKS_REQUIRED(notifications().m_tip_block_mutex) {
|
||||
return (notifications().m_tip_block != current_tip && notifications().m_tip_block != uint256::ZERO) || chainman().m_interrupt;
|
||||
});
|
||||
}
|
||||
// Must release m_tip_block_mutex before locking cs_main, to avoid deadlocks.
|
||||
LOCK(::cs_main);
|
||||
|
|
|
@ -58,7 +58,7 @@ kernel::InterruptResult KernelNotifications::blockTip(SynchronizationState state
|
|||
|
||||
uiInterface.NotifyBlockTip(state, &index);
|
||||
if (m_stop_at_height && index.nHeight >= m_stop_at_height) {
|
||||
if (!m_shutdown()) {
|
||||
if (!m_shutdown_request()) {
|
||||
LogError("Failed to send shutdown signal after reaching stop height\n");
|
||||
}
|
||||
return kernel::Interrupted{};
|
||||
|
@ -90,12 +90,12 @@ void KernelNotifications::warningUnset(kernel::Warning id)
|
|||
|
||||
void KernelNotifications::flushError(const bilingual_str& message)
|
||||
{
|
||||
AbortNode(&m_shutdown, m_exit_status, message, &m_warnings);
|
||||
AbortNode(m_shutdown_request, m_exit_status, message, &m_warnings);
|
||||
}
|
||||
|
||||
void KernelNotifications::fatalError(const bilingual_str& message)
|
||||
{
|
||||
node::AbortNode(m_shutdown_on_fatal_error ? &m_shutdown : nullptr,
|
||||
node::AbortNode(m_shutdown_on_fatal_error ? m_shutdown_request : nullptr,
|
||||
m_exit_status, message, &m_warnings);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
|
||||
class ArgsManager;
|
||||
class CBlockIndex;
|
||||
|
@ -23,10 +24,6 @@ namespace kernel {
|
|||
enum class Warning;
|
||||
} // namespace kernel
|
||||
|
||||
namespace util {
|
||||
class SignalInterrupt;
|
||||
} // namespace util
|
||||
|
||||
namespace node {
|
||||
|
||||
class Warnings;
|
||||
|
@ -35,8 +32,8 @@ static constexpr int DEFAULT_STOPATHEIGHT{0};
|
|||
class KernelNotifications : public kernel::Notifications
|
||||
{
|
||||
public:
|
||||
KernelNotifications(util::SignalInterrupt& shutdown, std::atomic<int>& exit_status, node::Warnings& warnings)
|
||||
: m_shutdown(shutdown), m_exit_status{exit_status}, m_warnings{warnings} {}
|
||||
KernelNotifications(const std::function<bool()>& shutdown_request, std::atomic<int>& exit_status, node::Warnings& warnings)
|
||||
: m_shutdown_request(shutdown_request), m_exit_status{exit_status}, m_warnings{warnings} {}
|
||||
|
||||
[[nodiscard]] kernel::InterruptResult blockTip(SynchronizationState state, CBlockIndex& index) override EXCLUSIVE_LOCKS_REQUIRED(!m_tip_block_mutex);
|
||||
|
||||
|
@ -58,12 +55,14 @@ public:
|
|||
bool m_shutdown_on_fatal_error{true};
|
||||
|
||||
Mutex m_tip_block_mutex;
|
||||
std::condition_variable m_tip_block_cv;
|
||||
std::condition_variable m_tip_block_cv GUARDED_BY(m_tip_block_mutex);
|
||||
//! The block for which the last blockTip notification was received for.
|
||||
uint256 m_tip_block;
|
||||
//! The initial ZERO means that no block has been connected yet, which may
|
||||
//! be true even long after startup, until shutdown.
|
||||
uint256 m_tip_block GUARDED_BY(m_tip_block_mutex){uint256::ZERO};
|
||||
|
||||
private:
|
||||
util::SignalInterrupt& m_shutdown;
|
||||
const std::function<bool()>& m_shutdown_request;
|
||||
std::atomic<int>& m_exit_status;
|
||||
node::Warnings& m_warnings;
|
||||
};
|
||||
|
|
|
@ -169,7 +169,7 @@ static RPCHelpMan stop()
|
|||
{
|
||||
// Event loop will exit after current HTTP requests have been handled, so
|
||||
// this reply will get back to the client.
|
||||
CHECK_NONFATAL((*CHECK_NONFATAL(EnsureAnyNodeContext(jsonRequest.context).shutdown))());
|
||||
CHECK_NONFATAL((CHECK_NONFATAL(EnsureAnyNodeContext(jsonRequest.context).shutdown_request))());
|
||||
if (jsonRequest.params[0].isNum()) {
|
||||
UninterruptibleSleep(std::chrono::milliseconds{jsonRequest.params[0].getInt<int>()});
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ void InterruptRPC()
|
|||
});
|
||||
}
|
||||
|
||||
void StopRPC(const std::any& context)
|
||||
void StopRPC()
|
||||
{
|
||||
static std::once_flag g_rpc_stop_flag;
|
||||
// This function could be called twice if the GUI has been started with -server=1.
|
||||
|
@ -303,9 +303,6 @@ void StopRPC(const std::any& context)
|
|||
LogDebug(BCLog::RPC, "Stopping RPC\n");
|
||||
WITH_LOCK(g_deadline_timers_mutex, deadlineTimers.clear());
|
||||
DeleteAuthCookie();
|
||||
node::NodeContext& node = EnsureAnyNodeContext(context);
|
||||
// The notifications interface doesn't exist between initialization step 4a and 7.
|
||||
if (node.notifications) node.notifications->m_tip_block_cv.notify_all();
|
||||
LogDebug(BCLog::RPC, "RPC stopped.\n");
|
||||
});
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include <rpc/request.h>
|
||||
#include <rpc/util.h>
|
||||
|
||||
#include <any>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <stdint.h>
|
||||
|
@ -173,7 +172,7 @@ extern CRPCTable tableRPC;
|
|||
|
||||
void StartRPC();
|
||||
void InterruptRPC();
|
||||
void StopRPC(const std::any& context);
|
||||
void StopRPC();
|
||||
UniValue JSONRPCExec(const JSONRPCRequest& jreq, bool catch_errors);
|
||||
|
||||
#endif // BITCOIN_RPC_SERVER_H
|
||||
|
|
|
@ -144,7 +144,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
|
|||
BOOST_REQUIRE(filter_index.StartBackgroundSync());
|
||||
|
||||
// Allow filter index to catch up with the block index.
|
||||
IndexWaitSynced(filter_index, *Assert(m_node.shutdown));
|
||||
IndexWaitSynced(filter_index, *Assert(m_node.shutdown_signal));
|
||||
|
||||
// Check that filter index has all blocks that were in the chain before it started.
|
||||
{
|
||||
|
|
|
@ -28,13 +28,13 @@ BOOST_FIXTURE_TEST_SUITE(blockmanager_tests, BasicTestingSetup)
|
|||
BOOST_AUTO_TEST_CASE(blockmanager_find_block_pos)
|
||||
{
|
||||
const auto params {CreateChainParams(ArgsManager{}, ChainType::MAIN)};
|
||||
KernelNotifications notifications{*Assert(m_node.shutdown), m_node.exit_status, *Assert(m_node.warnings)};
|
||||
KernelNotifications notifications{Assert(m_node.shutdown_request), m_node.exit_status, *Assert(m_node.warnings)};
|
||||
const BlockManager::Options blockman_opts{
|
||||
.chainparams = *params,
|
||||
.blocks_dir = m_args.GetBlocksDirPath(),
|
||||
.notifications = notifications,
|
||||
};
|
||||
BlockManager blockman{*Assert(m_node.shutdown), blockman_opts};
|
||||
BlockManager blockman{*Assert(m_node.shutdown_signal), blockman_opts};
|
||||
// simulate adding a genesis block normally
|
||||
BOOST_CHECK_EQUAL(blockman.SaveBlockToDisk(params->GenesisBlock(), 0).nPos, BLOCK_SERIALIZATION_HEADER_SIZE);
|
||||
// simulate what happens during reindex
|
||||
|
@ -135,13 +135,13 @@ BOOST_FIXTURE_TEST_CASE(blockmanager_block_data_availability, TestChain100Setup)
|
|||
|
||||
BOOST_AUTO_TEST_CASE(blockmanager_flush_block_file)
|
||||
{
|
||||
KernelNotifications notifications{*Assert(m_node.shutdown), m_node.exit_status, *Assert(m_node.warnings)};
|
||||
KernelNotifications notifications{Assert(m_node.shutdown_request), m_node.exit_status, *Assert(m_node.warnings)};
|
||||
node::BlockManager::Options blockman_opts{
|
||||
.chainparams = Params(),
|
||||
.blocks_dir = m_args.GetBlocksDirPath(),
|
||||
.notifications = notifications,
|
||||
};
|
||||
BlockManager blockman{*Assert(m_node.shutdown), blockman_opts};
|
||||
BlockManager blockman{*Assert(m_node.shutdown_signal), blockman_opts};
|
||||
|
||||
// Test blocks with no transactions, not even a coinbase
|
||||
CBlock block1;
|
||||
|
|
|
@ -35,7 +35,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
|
|||
|
||||
BOOST_REQUIRE(coin_stats_index.StartBackgroundSync());
|
||||
|
||||
IndexWaitSynced(coin_stats_index, *Assert(m_node.shutdown));
|
||||
IndexWaitSynced(coin_stats_index, *Assert(m_node.shutdown_signal));
|
||||
|
||||
// Check that CoinStatsIndex works for genesis block.
|
||||
const CBlockIndex* genesis_block_index;
|
||||
|
@ -86,7 +86,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_unclean_shutdown, TestChain100Setup)
|
|||
CoinStatsIndex index{interfaces::MakeChain(m_node), 1 << 20};
|
||||
BOOST_REQUIRE(index.Init());
|
||||
BOOST_REQUIRE(index.StartBackgroundSync());
|
||||
IndexWaitSynced(index, *Assert(m_node.shutdown));
|
||||
IndexWaitSynced(index, *Assert(m_node.shutdown_signal));
|
||||
std::shared_ptr<const CBlock> new_block;
|
||||
CBlockIndex* new_block_index = nullptr;
|
||||
{
|
||||
|
|
|
@ -33,7 +33,7 @@ BOOST_FIXTURE_TEST_CASE(txindex_initial_sync, TestChain100Setup)
|
|||
BOOST_REQUIRE(txindex.StartBackgroundSync());
|
||||
|
||||
// Allow tx index to catch up with the block index.
|
||||
IndexWaitSynced(txindex, *Assert(m_node.shutdown));
|
||||
IndexWaitSynced(txindex, *Assert(m_node.shutdown_signal));
|
||||
|
||||
// Check that txindex excludes genesis block transactions.
|
||||
const CBlock& genesis_block = Params().GenesisBlock();
|
||||
|
|
|
@ -104,7 +104,8 @@ static void ExitFailure(std::string_view str_err)
|
|||
BasicTestingSetup::BasicTestingSetup(const ChainType chainType, TestOpts opts)
|
||||
: m_args{}
|
||||
{
|
||||
m_node.shutdown = &m_interrupt;
|
||||
m_node.shutdown_signal = &m_interrupt;
|
||||
m_node.shutdown_request = [this]{ return m_interrupt(); };
|
||||
m_node.args = &gArgs;
|
||||
std::vector<const char*> arguments = Cat(
|
||||
{
|
||||
|
@ -224,7 +225,7 @@ ChainTestingSetup::ChainTestingSetup(const ChainType chainType, TestOpts opts)
|
|||
|
||||
m_cache_sizes = CalculateCacheSizes(m_args);
|
||||
|
||||
m_node.notifications = std::make_unique<KernelNotifications>(*Assert(m_node.shutdown), m_node.exit_status, *Assert(m_node.warnings));
|
||||
m_node.notifications = std::make_unique<KernelNotifications>(Assert(m_node.shutdown_request), m_node.exit_status, *Assert(m_node.warnings));
|
||||
|
||||
m_make_chainman = [this, &chainparams, opts] {
|
||||
Assert(!m_node.chainman);
|
||||
|
@ -245,7 +246,7 @@ ChainTestingSetup::ChainTestingSetup(const ChainType chainType, TestOpts opts)
|
|||
.blocks_dir = m_args.GetBlocksDirPath(),
|
||||
.notifications = chainman_opts.notifications,
|
||||
};
|
||||
m_node.chainman = std::make_unique<ChainstateManager>(*Assert(m_node.shutdown), chainman_opts, blockman_opts);
|
||||
m_node.chainman = std::make_unique<ChainstateManager>(*Assert(m_node.shutdown_signal), chainman_opts, blockman_opts);
|
||||
LOCK(m_node.chainman->GetMutex());
|
||||
m_node.chainman->m_blockman.m_block_tree_db = std::make_unique<BlockTreeDB>(DBParams{
|
||||
.path = m_args.GetDataDirNet() / "blocks" / "index",
|
||||
|
|
|
@ -70,14 +70,18 @@ BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
|
|||
BOOST_FIXTURE_TEST_CASE(chainstate_update_tip, TestChain100Setup)
|
||||
{
|
||||
ChainstateManager& chainman = *Assert(m_node.chainman);
|
||||
uint256 curr_tip = m_node.notifications->m_tip_block;
|
||||
const auto get_notify_tip{[&]() {
|
||||
LOCK(m_node.notifications->m_tip_block_mutex);
|
||||
return m_node.notifications->m_tip_block;
|
||||
}};
|
||||
uint256 curr_tip = get_notify_tip();
|
||||
|
||||
// Mine 10 more blocks, putting at us height 110 where a valid assumeutxo value can
|
||||
// be found.
|
||||
mineBlocks(10);
|
||||
|
||||
// After adding some blocks to the tip, best block should have changed.
|
||||
BOOST_CHECK(m_node.notifications->m_tip_block != curr_tip);
|
||||
BOOST_CHECK(get_notify_tip() != curr_tip);
|
||||
|
||||
// Grab block 1 from disk; we'll add it to the background chain later.
|
||||
std::shared_ptr<CBlock> pblockone = std::make_shared<CBlock>();
|
||||
|
@ -92,15 +96,15 @@ BOOST_FIXTURE_TEST_CASE(chainstate_update_tip, TestChain100Setup)
|
|||
// Ensure our active chain is the snapshot chainstate.
|
||||
BOOST_CHECK(WITH_LOCK(::cs_main, return chainman.IsSnapshotActive()));
|
||||
|
||||
curr_tip = m_node.notifications->m_tip_block;
|
||||
curr_tip = get_notify_tip();
|
||||
|
||||
// Mine a new block on top of the activated snapshot chainstate.
|
||||
mineBlocks(1); // Defined in TestChain100Setup.
|
||||
|
||||
// After adding some blocks to the snapshot tip, best block should have changed.
|
||||
BOOST_CHECK(m_node.notifications->m_tip_block != curr_tip);
|
||||
BOOST_CHECK(get_notify_tip() != curr_tip);
|
||||
|
||||
curr_tip = m_node.notifications->m_tip_block;
|
||||
curr_tip = get_notify_tip();
|
||||
|
||||
BOOST_CHECK_EQUAL(chainman.GetAll().size(), 2);
|
||||
|
||||
|
@ -136,10 +140,10 @@ BOOST_FIXTURE_TEST_CASE(chainstate_update_tip, TestChain100Setup)
|
|||
// Ensure tip is as expected
|
||||
BOOST_CHECK_EQUAL(background_cs.m_chain.Tip()->GetBlockHash(), pblockone->GetHash());
|
||||
|
||||
// g_best_block should be unchanged after adding a block to the background
|
||||
// get_notify_tip() should be unchanged after adding a block to the background
|
||||
// validation chain.
|
||||
BOOST_CHECK(block_added);
|
||||
BOOST_CHECK_EQUAL(curr_tip, m_node.notifications->m_tip_block);
|
||||
BOOST_CHECK_EQUAL(curr_tip, get_notify_tip());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
|
@ -382,7 +382,7 @@ struct SnapshotTestSetup : TestChain100Setup {
|
|||
LOCK(::cs_main);
|
||||
chainman.ResetChainstates();
|
||||
BOOST_CHECK_EQUAL(chainman.GetAll().size(), 0);
|
||||
m_node.notifications = std::make_unique<KernelNotifications>(*Assert(m_node.shutdown), m_node.exit_status, *Assert(m_node.warnings));
|
||||
m_node.notifications = std::make_unique<KernelNotifications>(Assert(m_node.shutdown_request), m_node.exit_status, *Assert(m_node.warnings));
|
||||
const ChainstateManager::Options chainman_opts{
|
||||
.chainparams = ::Params(),
|
||||
.datadir = chainman.m_options.datadir,
|
||||
|
@ -397,7 +397,7 @@ struct SnapshotTestSetup : TestChain100Setup {
|
|||
// For robustness, ensure the old manager is destroyed before creating a
|
||||
// new one.
|
||||
m_node.chainman.reset();
|
||||
m_node.chainman = std::make_unique<ChainstateManager>(*Assert(m_node.shutdown), chainman_opts, blockman_opts);
|
||||
m_node.chainman = std::make_unique<ChainstateManager>(*Assert(m_node.shutdown_signal), chainman_opts, blockman_opts);
|
||||
}
|
||||
return *Assert(m_node.chainman);
|
||||
}
|
||||
|
|
|
@ -3533,7 +3533,6 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr<
|
|||
m_chainman.m_options.signals->UpdatedBlockTip(pindexNewTip, pindexFork, still_in_ibd);
|
||||
}
|
||||
|
||||
// Always notify the UI if a new block tip was connected
|
||||
if (kernel::IsInterrupted(m_chainman.GetNotifications().blockTip(GetSynchronizationState(still_in_ibd, m_chainman.m_blockman.m_blockfiles_indexed), *pindexNewTip))) {
|
||||
// Just breaking and returning success for now. This could
|
||||
// be changed to bubble up the kernel::Interrupted value to
|
||||
|
|
Loading…
Add table
Reference in a new issue