Skip to content

Commit 09938a4

Browse files
committed
kernel: Remove StartShutdown calls from validation code
This change drops the last kernel dependency on shutdown.cpp. It also adds new hooks for libbitcoinkernel applications to be able to stop kernel operations after blocks are imported and each time the chain tip changes. This is a refactoring that mostly does not affect behavior, except it does change the behavior of the -stopatheight option in a small way: - Previously the -stopatheight option would shut down the node at or above the specified height. It would not stop connecting blocks after the specified height if they were already downloaded. - Now, the -stopatheight option will shut down the node exactly at the specified height, without validating and connecting the downloaded blocks after it. Since blocks above the specified height are no longer validated, it means -stopatheight option is only guaranteed to return a valid chain with the specified height. But it is possible for the resulting chain to not be the most-work chain, if the blocks above the height which are not validated turn out to actually be invalid.
1 parent 75135c6 commit 09938a4

15 files changed

+79
-26
lines changed

doc/release-notes-28048.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- The `-stopatheight` option will now stop exactly at the specified height, rather than at or above the specified height. Since the node shuts down as soon as it find a valid chain at the specified height, it is possible for the resulting chain to no longer be the most-work chain, if some of the blocks above the specified height are invalid.

src/Makefile.am

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,6 @@ libbitcoinkernel_la_SOURCES = \
956956
script/script_error.cpp \
957957
script/sigcache.cpp \
958958
script/standard.cpp \
959-
shutdown.cpp \
960959
signet.cpp \
961960
support/cleanse.cpp \
962961
support/lockedpool.cpp \

src/bitcoin-chainstate.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,15 @@ int main(int argc, char* argv[])
8181
class KernelNotifications : public kernel::Notifications
8282
{
8383
public:
84-
void blockTip(SynchronizationState, CBlockIndex&) override
84+
kernel::InterruptResult blocksImported() override
85+
{
86+
std::cout << "Block import finished" << std::endl;
87+
return {};
88+
}
89+
kernel::InterruptResult blockTip(SynchronizationState, CBlockIndex&) override
8590
{
8691
std::cout << "Block tip changed" << std::endl;
92+
return {};
8793
}
8894
void headerTip(SynchronizationState, int64_t height, int64_t timestamp, bool presync) override
8995
{

src/init.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@
114114
#include <zmq/zmqrpc.h>
115115
#endif
116116

117-
using kernel::DEFAULT_STOPAFTERBLOCKIMPORT;
117+
using node::DEFAULT_STOPAFTERBLOCKIMPORT;
118+
using node::DEFAULT_STOPATHEIGHT;
118119
using kernel::DumpMempool;
119120
using kernel::ValidationCacheSizes;
120121

@@ -566,7 +567,7 @@ void SetupServerArgs(ArgsManager& argsman)
566567
argsman.AddArg("-checkpoints", strprintf("Enable rejection of any forks from the known historical chain until block %s (default: %u)", defaultChainParams->Checkpoints().GetHeight(), DEFAULT_CHECKPOINTS_ENABLED), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
567568
argsman.AddArg("-deprecatedrpc=<method>", "Allows deprecated RPC method(s) to be used", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
568569
argsman.AddArg("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", DEFAULT_STOPAFTERBLOCKIMPORT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
569-
argsman.AddArg("-stopatheight", strprintf("Stop running after reaching the given height in the main chain (default: %u)", DEFAULT_STOPATHEIGHT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
570+
argsman.AddArg("-stopatheight", strprintf("Shut down the node after validating and attaching a block greater or equal to the given height to the chain. This option is mostly useful for benchmarking. (default: %u)", DEFAULT_STOPATHEIGHT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
570571
argsman.AddArg("-limitancestorcount=<n>", strprintf("Do not accept transactions if number of in-mempool ancestors is <n> or more (default: %u)", DEFAULT_ANCESTOR_LIMIT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
571572
argsman.AddArg("-limitancestorsize=<n>", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds <n> kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT_KVB), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
572573
argsman.AddArg("-limitdescendantcount=<n>", strprintf("Do not accept transactions if any ancestor would have <n> or more in-mempool descendants (default: %u)", DEFAULT_DESCENDANT_LIMIT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
@@ -1409,6 +1410,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
14091410
// ********************************************************* Step 7: load block chain
14101411

14111412
node.notifications = std::make_unique<KernelNotifications>(node.exit_status);
1413+
ReadNotificationArgs(args, *node.notifications);
14121414
fReindex = args.GetBoolArg("-reindex", false);
14131415
bool fReindexChainState = args.GetBoolArg("-reindex-chainstate", false);
14141416
ChainstateManager::Options chainman_opts{

src/kernel/blockmanager_opts.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ class CChainParams;
1414

1515
namespace kernel {
1616

17-
static constexpr bool DEFAULT_STOPAFTERBLOCKIMPORT{false};
18-
1917
/**
2018
* An options struct for `BlockManager`, more ergonomically referred to as
2119
* `BlockManager::Options` due to the using-declaration in `BlockManager`.
@@ -24,7 +22,6 @@ struct BlockManagerOpts {
2422
const CChainParams& chainparams;
2523
uint64_t prune_target{0};
2624
bool fast_prune{false};
27-
bool stop_after_block_import{DEFAULT_STOPAFTERBLOCKIMPORT};
2825
const fs::path blocks_dir;
2926
Notifications& notifications;
3027
};

src/kernel/chainstatemanager_opts.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ class CChainParams;
2121

2222
static constexpr bool DEFAULT_CHECKPOINTS_ENABLED{true};
2323
static constexpr auto DEFAULT_MAX_TIP_AGE{24h};
24-
static constexpr int DEFAULT_STOPATHEIGHT{0};
2524

2625
namespace kernel {
2726

@@ -46,7 +45,6 @@ struct ChainstateManagerOpts {
4645
DBOptions coins_db{};
4746
CoinsViewOptions coins_view{};
4847
Notifications& notifications;
49-
int stop_at_height{DEFAULT_STOPATHEIGHT};
5048
};
5149

5250
} // namespace kernel

src/kernel/notifications_interface.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,25 @@
99

1010
#include <cstdint>
1111
#include <string>
12+
#include <variant>
1213

1314
class CBlockIndex;
1415
enum class SynchronizationState;
1516

1617
namespace kernel {
1718

19+
//! Result type for use with std::variant to indiciate that an operation should be interrupted.
20+
struct Interrupted{};
21+
22+
//! Simple result type for functions that need to propagate an interrupt status and don't have other return values.
23+
using InterruptResult = std::variant<std::monostate, Interrupted>;
24+
25+
template <typename T>
26+
bool IsInterrupted(const T& result)
27+
{
28+
return std::holds_alternative<kernel::Interrupted>(result);
29+
}
30+
1831
/**
1932
* A base class defining functions for notifying about certain kernel
2033
* events.
@@ -24,7 +37,8 @@ class Notifications
2437
public:
2538
virtual ~Notifications(){};
2639

27-
virtual void blockTip(SynchronizationState state, CBlockIndex& index) {}
40+
[[nodiscard]] virtual InterruptResult blocksImported() { return {}; }
41+
[[nodiscard]] virtual InterruptResult blockTip(SynchronizationState state, CBlockIndex& index) { return {}; }
2842
virtual void headerTip(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) {}
2943
virtual void progress(const bilingual_str& title, int progress_percent, bool resume_possible) {}
3044
virtual void warning(const bilingual_str& warning) {}

src/node/blockmanager_args.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ util::Result<void> ApplyArgsManOptions(const ArgsManager& args, BlockManager::Op
3232
opts.prune_target = nPruneTarget;
3333

3434
if (auto value{args.GetBoolArg("-fastprune")}) opts.fast_prune = *value;
35-
if (auto value{args.GetBoolArg("-stopafterblockimport")}) opts.stop_after_block_import = *value;
3635

3736
return {};
3837
}

src/node/blockstorage.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -933,9 +933,11 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile
933933
}
934934
}
935935

936-
if (chainman.m_blockman.StopAfterBlockImport()) {
936+
if (kernel::IsInterrupted(chainman.GetNotifications().blocksImported())) {
937937
LogPrintf("Stopping after block import\n");
938-
StartShutdown();
938+
// Just returning void for now. This could be changed to bubble up
939+
// the kernel::Interrupted value to the caller so the caller could
940+
// distinguish between completed and interrupted operations.
939941
return;
940942
}
941943
} // End scope of ImportingNow

src/node/blockstorage.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,6 @@ class BlockManager
214214

215215
[[nodiscard]] bool LoadingBlocks() const { return m_importing || fReindex; }
216216

217-
[[nodiscard]] bool StopAfterBlockImport() const { return m_opts.stop_after_block_import; }
218-
219217
/** Calculate the amount of disk space the block & undo files currently use */
220218
uint64_t CalculateCurrentUsage();
221219

0 commit comments

Comments
 (0)