Skip to content

Commit 0897b18

Browse files
author
MacroFake
committed
Merge bitcoin/bitcoin#25308: refactor: Reduce number of LoadChainstate parameters and return values
1e761a0 ci: Enable IWYU in src/kernel directory (Ryan Ofsky) 6db6552 refactor: Reduce number of SanityChecks return values (Ryan Ofsky) b3e7de7 refactor: Reduce number of LoadChainstate return values (Russell Yanofsky) 3b91d4b refactor: Reduce number of LoadChainstate parameters (Russell Yanofsky) Pull request description: Replace long LoadChainstate parameters list with options struct. Replace long list of return values with simpler error strings. No changes in behavior. Motivation is just to make libbitcoin_kernel API easier to use and more future-proof, and make internal code clearer and more maintainable. ACKs for top commit: MarcoFalke: ACK 1e761a0 🕚 Tree-SHA512: 86f251ab820ca6664ade87ccac8330f79b0e48e26b98082f022f592ed1380f8eefc3cce260b85d5eea5d2f5f2531602e03d641e579c15684ecd9093b2aebcc58
2 parents 5560682 + 1e761a0 commit 0897b18

File tree

10 files changed

+168
-263
lines changed

10 files changed

+168
-263
lines changed

ci/test/06_script_b.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ if [ "${RUN_TIDY}" = "true" ]; then
4242
" src/compat"\
4343
" src/dbwrapper.cpp"\
4444
" src/init"\
45-
" src/kernel/mempool_persist.cpp"\
45+
" src/kernel"\
4646
" src/node/chainstate.cpp"\
4747
" src/policy/feerate.cpp"\
4848
" src/policy/packages.cpp"\

src/bitcoin-chainstate.cpp

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <consensus/validation.h>
1919
#include <core_io.h>
2020
#include <node/blockstorage.h>
21+
#include <node/caches.h>
2122
#include <node/chainstate.h>
2223
#include <scheduler.h>
2324
#include <script/sigcache.h>
@@ -83,27 +84,19 @@ int main(int argc, char* argv[])
8384
};
8485
ChainstateManager chainman{chainman_opts};
8586

86-
auto rv = node::LoadChainstate(false,
87-
std::ref(chainman),
88-
nullptr,
89-
false,
90-
false,
91-
2 << 20,
92-
2 << 22,
93-
(450 << 20) - (2 << 20) - (2 << 22),
94-
false,
95-
false,
96-
[]() { return false; });
97-
if (rv.has_value()) {
87+
node::CacheSizes cache_sizes;
88+
cache_sizes.block_tree_db = 2 << 20;
89+
cache_sizes.coins_db = 2 << 22;
90+
cache_sizes.coins = (450 << 20) - (2 << 20) - (2 << 22);
91+
node::ChainstateLoadOptions options;
92+
options.check_interrupt = [] { return false; };
93+
auto [status, error] = node::LoadChainstate(chainman, cache_sizes, options);
94+
if (status != node::ChainstateLoadStatus::SUCCESS) {
9895
std::cerr << "Failed to load Chain state from your datadir." << std::endl;
9996
goto epilogue;
10097
} else {
101-
auto maybe_verify_error = node::VerifyLoadedChainstate(std::ref(chainman),
102-
false,
103-
false,
104-
DEFAULT_CHECKBLOCKS,
105-
DEFAULT_CHECKLEVEL);
106-
if (maybe_verify_error.has_value()) {
98+
std::tie(status, error) = node::VerifyLoadedChainstate(chainman, options);
99+
if (status != node::ChainstateLoadStatus::SUCCESS) {
107100
std::cerr << "Failed to verify loaded Chain state from your datadir." << std::endl;
108101
goto epilogue;
109102
}

src/init.cpp

Lines changed: 36 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,6 @@ using kernel::DumpMempool;
108108

109109
using node::CacheSizes;
110110
using node::CalculateCacheSizes;
111-
using node::ChainstateLoadVerifyError;
112-
using node::ChainstateLoadingError;
113111
using node::DEFAULT_PERSIST_MEMPOOL;
114112
using node::DEFAULT_PRINTPRIORITY;
115113
using node::DEFAULT_STOPAFTERBLOCKIMPORT;
@@ -1098,21 +1096,8 @@ static bool LockDataDirectory(bool probeOnly)
10981096
bool AppInitSanityChecks(const kernel::Context& kernel)
10991097
{
11001098
// ********************************************************* Step 4: sanity checks
1101-
auto maybe_error = kernel::SanityChecks(kernel);
1102-
1103-
if (maybe_error.has_value()) {
1104-
switch (maybe_error.value()) {
1105-
case kernel::SanityCheckError::ERROR_ECC:
1106-
InitError(Untranslated("Elliptic curve cryptography sanity check failure. Aborting."));
1107-
break;
1108-
case kernel::SanityCheckError::ERROR_RANDOM:
1109-
InitError(Untranslated("OS cryptographic RNG sanity check failure. Aborting."));
1110-
break;
1111-
case kernel::SanityCheckError::ERROR_CHRONO:
1112-
InitError(Untranslated("Clock epoch mismatch. Aborting."));
1113-
break;
1114-
} // no default case, so the compiler can warn about missing cases
1115-
1099+
if (auto error = kernel::SanityChecks(kernel)) {
1100+
InitError(*error);
11161101
return InitError(strprintf(_("Initialization sanity check failed. %s is shutting down."), PACKAGE_NAME));
11171102
}
11181103

@@ -1452,112 +1437,54 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
14521437
node.chainman = std::make_unique<ChainstateManager>(chainman_opts);
14531438
ChainstateManager& chainman = *node.chainman;
14541439

1455-
const bool fReset = fReindex;
1456-
bilingual_str strLoadError;
1440+
node::ChainstateLoadOptions options;
1441+
options.mempool = Assert(node.mempool.get());
1442+
options.reindex = node::fReindex;
1443+
options.reindex_chainstate = fReindexChainState;
1444+
options.prune = node::fPruneMode;
1445+
options.check_blocks = args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
1446+
options.check_level = args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL);
1447+
options.check_interrupt = ShutdownRequested;
1448+
options.coins_error_cb = [] {
1449+
uiInterface.ThreadSafeMessageBox(
1450+
_("Error reading from database, shutting down."),
1451+
"", CClientUIInterface::MSG_ERROR);
1452+
};
14571453

14581454
uiInterface.InitMessage(_("Loading block index…").translated);
14591455
const int64_t load_block_index_start_time = GetTimeMillis();
1460-
std::optional<ChainstateLoadingError> maybe_load_error;
1461-
try {
1462-
maybe_load_error = LoadChainstate(fReset,
1463-
chainman,
1464-
Assert(node.mempool.get()),
1465-
fPruneMode,
1466-
fReindexChainState,
1467-
cache_sizes.block_tree_db,
1468-
cache_sizes.coins_db,
1469-
cache_sizes.coins,
1470-
/*block_tree_db_in_memory=*/false,
1471-
/*coins_db_in_memory=*/false,
1472-
/*shutdown_requested=*/ShutdownRequested,
1473-
/*coins_error_cb=*/[]() {
1474-
uiInterface.ThreadSafeMessageBox(
1475-
_("Error reading from database, shutting down."),
1476-
"", CClientUIInterface::MSG_ERROR);
1477-
});
1478-
} catch (const std::exception& e) {
1479-
LogPrintf("%s\n", e.what());
1480-
maybe_load_error = ChainstateLoadingError::ERROR_GENERIC_BLOCKDB_OPEN_FAILED;
1481-
}
1482-
if (maybe_load_error.has_value()) {
1483-
switch (maybe_load_error.value()) {
1484-
case ChainstateLoadingError::ERROR_LOADING_BLOCK_DB:
1485-
strLoadError = _("Error loading block database");
1486-
break;
1487-
case ChainstateLoadingError::ERROR_BAD_GENESIS_BLOCK:
1488-
// If the loaded chain has a wrong genesis, bail out immediately
1489-
// (we're likely using a testnet datadir, or the other way around).
1490-
return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
1491-
case ChainstateLoadingError::ERROR_PRUNED_NEEDS_REINDEX:
1492-
strLoadError = _("You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain");
1493-
break;
1494-
case ChainstateLoadingError::ERROR_LOAD_GENESIS_BLOCK_FAILED:
1495-
strLoadError = _("Error initializing block database");
1496-
break;
1497-
case ChainstateLoadingError::ERROR_CHAINSTATE_UPGRADE_FAILED:
1498-
return InitError(_("Unsupported chainstate database format found. "
1499-
"Please restart with -reindex-chainstate. This will "
1500-
"rebuild the chainstate database."));
1501-
case ChainstateLoadingError::ERROR_REPLAYBLOCKS_FAILED:
1502-
strLoadError = _("Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.");
1503-
break;
1504-
case ChainstateLoadingError::ERROR_LOADCHAINTIP_FAILED:
1505-
strLoadError = _("Error initializing block database");
1506-
break;
1507-
case ChainstateLoadingError::ERROR_GENERIC_BLOCKDB_OPEN_FAILED:
1508-
strLoadError = _("Error opening block database");
1509-
break;
1510-
case ChainstateLoadingError::ERROR_BLOCKS_WITNESS_INSUFFICIENTLY_VALIDATED:
1511-
strLoadError = strprintf(_("Witness data for blocks after height %d requires validation. Please restart with -reindex."),
1512-
chainman.GetConsensus().SegwitHeight);
1513-
break;
1514-
case ChainstateLoadingError::SHUTDOWN_PROBED:
1515-
break;
1516-
}
1517-
} else {
1518-
std::optional<ChainstateLoadVerifyError> maybe_verify_error;
1456+
auto catch_exceptions = [](auto&& f) {
15191457
try {
1520-
uiInterface.InitMessage(_("Verifying blocks…").translated);
1521-
auto check_blocks = args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
1522-
if (chainman.m_blockman.m_have_pruned && check_blocks > MIN_BLOCKS_TO_KEEP) {
1523-
LogPrintfCategory(BCLog::PRUNE, "pruned datadir may not have more than %d blocks; only checking available blocks\n",
1524-
MIN_BLOCKS_TO_KEEP);
1525-
}
1526-
maybe_verify_error = VerifyLoadedChainstate(chainman,
1527-
fReset,
1528-
fReindexChainState,
1529-
check_blocks,
1530-
args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL));
1458+
return f();
15311459
} catch (const std::exception& e) {
15321460
LogPrintf("%s\n", e.what());
1533-
maybe_verify_error = ChainstateLoadVerifyError::ERROR_GENERIC_FAILURE;
1461+
return std::make_tuple(node::ChainstateLoadStatus::FAILURE, _("Error opening block database"));
15341462
}
1535-
if (maybe_verify_error.has_value()) {
1536-
switch (maybe_verify_error.value()) {
1537-
case ChainstateLoadVerifyError::ERROR_BLOCK_FROM_FUTURE:
1538-
strLoadError = _("The block database contains a block which appears to be from the future. "
1539-
"This may be due to your computer's date and time being set incorrectly. "
1540-
"Only rebuild the block database if you are sure that your computer's date and time are correct");
1541-
break;
1542-
case ChainstateLoadVerifyError::ERROR_CORRUPTED_BLOCK_DB:
1543-
strLoadError = _("Corrupted block database detected");
1544-
break;
1545-
case ChainstateLoadVerifyError::ERROR_GENERIC_FAILURE:
1546-
strLoadError = _("Error opening block database");
1547-
break;
1548-
}
1549-
} else {
1463+
};
1464+
auto [status, error] = catch_exceptions([&]{ return LoadChainstate(chainman, cache_sizes, options); });
1465+
if (status == node::ChainstateLoadStatus::SUCCESS) {
1466+
uiInterface.InitMessage(_("Verifying blocks…").translated);
1467+
if (chainman.m_blockman.m_have_pruned && options.check_blocks > MIN_BLOCKS_TO_KEEP) {
1468+
LogPrintfCategory(BCLog::PRUNE, "pruned datadir may not have more than %d blocks; only checking available blocks\n",
1469+
MIN_BLOCKS_TO_KEEP);
1470+
}
1471+
std::tie(status, error) = catch_exceptions([&]{ return VerifyLoadedChainstate(chainman, options);});
1472+
if (status == node::ChainstateLoadStatus::SUCCESS) {
15501473
fLoaded = true;
15511474
LogPrintf(" block index %15dms\n", GetTimeMillis() - load_block_index_start_time);
15521475
}
15531476
}
15541477

1478+
if (status == node::ChainstateLoadStatus::FAILURE_INCOMPATIBLE_DB) {
1479+
return InitError(error);
1480+
}
1481+
15551482
if (!fLoaded && !ShutdownRequested()) {
15561483
// first suggest a reindex
1557-
if (!fReset) {
1484+
if (!options.reindex) {
15581485
bool fRet = uiInterface.ThreadSafeQuestion(
1559-
strLoadError + Untranslated(".\n\n") + _("Do you want to rebuild the block database now?"),
1560-
strLoadError.original + ".\nPlease restart with -reindex or -reindex-chainstate to recover.",
1486+
error + Untranslated(".\n\n") + _("Do you want to rebuild the block database now?"),
1487+
error.original + ".\nPlease restart with -reindex or -reindex-chainstate to recover.",
15611488
"", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
15621489
if (fRet) {
15631490
fReindex = true;
@@ -1567,7 +1494,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
15671494
return false;
15681495
}
15691496
} else {
1570-
return InitError(strLoadError);
1497+
return InitError(error);
15711498
}
15721499
}
15731500
}

src/kernel/checks.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,24 @@
77
#include <key.h>
88
#include <random.h>
99
#include <util/time.h>
10+
#include <util/translation.h>
11+
12+
#include <memory>
1013

1114
namespace kernel {
1215

13-
std::optional<SanityCheckError> SanityChecks(const Context&)
16+
std::optional<bilingual_str> SanityChecks(const Context&)
1417
{
1518
if (!ECC_InitSanityCheck()) {
16-
return SanityCheckError::ERROR_ECC;
19+
return Untranslated("Elliptic curve cryptography sanity check failure. Aborting.");
1720
}
1821

1922
if (!Random_SanityCheck()) {
20-
return SanityCheckError::ERROR_RANDOM;
23+
return Untranslated("OS cryptographic RNG sanity check failure. Aborting.");
2124
}
2225

2326
if (!ChronoSanityCheck()) {
24-
return SanityCheckError::ERROR_CHRONO;
27+
return Untranslated("Clock epoch mismatch. Aborting.");
2528
}
2629

2730
return std::nullopt;

src/kernel/checks.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,16 @@
77

88
#include <optional>
99

10+
struct bilingual_str;
11+
1012
namespace kernel {
1113

1214
struct Context;
1315

14-
enum class SanityCheckError {
15-
ERROR_ECC,
16-
ERROR_RANDOM,
17-
ERROR_CHRONO,
18-
};
19-
2016
/**
2117
* Ensure a usable environment with all necessary library support.
2218
*/
23-
std::optional<SanityCheckError> SanityChecks(const Context&);
19+
std::optional<bilingual_str> SanityChecks(const Context&);
2420

2521
}
2622

src/kernel/coinstats.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,32 @@
44

55
#include <kernel/coinstats.h>
66

7+
#include <chain.h>
78
#include <coins.h>
89
#include <crypto/muhash.h>
910
#include <hash.h>
11+
#include <node/blockstorage.h>
12+
#include <primitives/transaction.h>
13+
#include <script/script.h>
1014
#include <serialize.h>
15+
#include <span.h>
16+
#include <streams.h>
17+
#include <sync.h>
18+
#include <tinyformat.h>
1119
#include <uint256.h>
20+
#include <util/check.h>
1221
#include <util/overflow.h>
1322
#include <util/system.h>
1423
#include <validation.h>
24+
#include <version.h>
1525

26+
#include <cassert>
27+
#include <iosfwd>
28+
#include <iterator>
1629
#include <map>
30+
#include <memory>
31+
#include <string>
32+
#include <utility>
1733

1834
namespace kernel {
1935

src/kernel/coinstats.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@
55
#ifndef BITCOIN_KERNEL_COINSTATS_H
66
#define BITCOIN_KERNEL_COINSTATS_H
77

8-
#include <chain.h>
9-
#include <coins.h>
108
#include <consensus/amount.h>
119
#include <streams.h>
1210
#include <uint256.h>
1311

1412
#include <cstdint>
1513
#include <functional>
14+
#include <optional>
1615

1716
class CCoinsView;
17+
class Coin;
18+
class COutPoint;
19+
class CScript;
1820
namespace node {
1921
class BlockManager;
2022
} // namespace node

0 commit comments

Comments
 (0)