Skip to content

Commit 10a24bb

Browse files
committed
Do not allow replay-blockchain without snapshot unless a full block log is available.
1 parent e78bc6f commit 10a24bb

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

libraries/chain/block_log.cpp

+20-5
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,9 @@ namespace eosio { namespace chain {
510510
else
511511
head = {};
512512
}
513+
514+
static block_log_preamble extract_block_log_preamble(const std::filesystem::path& block_dir,
515+
const std::filesystem::path& retained_dir);
513516
}; // block_log_impl
514517

515518
/// Would remove pre-existing block log and index, never write blocks into disk.
@@ -1459,8 +1462,8 @@ namespace eosio { namespace chain {
14591462
}
14601463

14611464
// static
1462-
std::optional<block_log::chain_context> block_log::extract_chain_context(const std::filesystem::path& block_dir,
1463-
const std::filesystem::path& retained_dir) {
1465+
block_log_preamble detail::block_log_impl::extract_block_log_preamble(const std::filesystem::path& block_dir,
1466+
const std::filesystem::path& retained_dir) {
14641467
std::filesystem::path first_block_file;
14651468
if (!retained_dir.empty() && std::filesystem::exists(retained_dir)) {
14661469
for_each_file_in_dir_matches(retained_dir, R"(blocks-1-\d+\.log)",
@@ -1474,9 +1477,9 @@ namespace eosio { namespace chain {
14741477
}
14751478

14761479
if (!first_block_file.empty()) {
1477-
return block_log_data(first_block_file).get_preamble().chain_context;
1480+
return block_log_data(first_block_file).get_preamble();
14781481
}
1479-
1482+
14801483
if (!retained_dir.empty() && std::filesystem::exists(retained_dir)) {
14811484
const std::regex my_filter(R"(blocks-\d+-\d+\.log)");
14821485
std::smatch what;
@@ -1489,12 +1492,18 @@ namespace eosio { namespace chain {
14891492
std::string file = p->path().filename().string();
14901493
if (!std::regex_match(file, what, my_filter))
14911494
continue;
1492-
return block_log_data(p->path()).chain_id();
1495+
return block_log_data(p->path()).get_preamble();
14931496
}
14941497
}
14951498
return {};
14961499
}
14971500

1501+
// static
1502+
std::optional<block_log::chain_context> block_log::extract_chain_context(const std::filesystem::path& block_dir,
1503+
const std::filesystem::path& retained_dir) {
1504+
return detail::block_log_impl::extract_block_log_preamble(block_dir, retained_dir).chain_context;
1505+
}
1506+
14981507
// static
14991508
std::optional<genesis_state> block_log::extract_genesis_state(const std::filesystem::path& block_dir,
15001509
const std::filesystem::path& retained_dir) {
@@ -1516,6 +1525,12 @@ namespace eosio { namespace chain {
15161525
} , *context);
15171526
}
15181527

1528+
// static
1529+
uint32_t block_log::extract_first_block_num(const std::filesystem::path& block_dir,
1530+
const std::filesystem::path& retained_dir) {
1531+
return detail::block_log_impl::extract_block_log_preamble(block_dir, retained_dir).first_block_num;
1532+
}
1533+
15191534
// static
15201535
bool block_log::contains_genesis_state(uint32_t version, uint32_t first_block_num) {
15211536
return version < genesis_state_or_chain_id_version || first_block_num == 1;

libraries/chain/include/eosio/chain/block_log.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ namespace eosio { namespace chain {
9595
extract_chain_id(const std::filesystem::path& data_dir,
9696
const std::filesystem::path& retained_dir = std::filesystem::path{});
9797

98+
static uint32_t extract_first_block_num(const std::filesystem::path& block_dir,
99+
const std::filesystem::path& retained_dir = std::filesystem::path{});
100+
98101
static void construct_index(const std::filesystem::path& block_file_name, const std::filesystem::path& index_file_name);
99102

100103
static bool contains_genesis_state(uint32_t version, uint32_t first_block_num);

plugins/chain_plugin/chain_plugin.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,11 @@ void chain_plugin_impl::plugin_initialize(const variables_map& options) {
778778
ilog( "Replay requested: deleting state database" );
779779
if( options.at( "truncate-at-block" ).as<uint32_t>() > 0 )
780780
wlog( "The --truncate-at-block option does not work for a regular replay of the blockchain." );
781+
if (!options.count( "snapshot" )) {
782+
auto first_block = block_log::extract_first_block_num(blocks_dir, retained_dir);
783+
EOS_ASSERT(first_block == 1, plugin_config_exception,
784+
"replay-blockchain without snapshot requested without a full block log, first block: ${n}", ("n", first_block));
785+
}
781786
clear_directory_contents( chain_config->state_dir );
782787
} else if( options.at( "truncate-at-block" ).as<uint32_t>() > 0 ) {
783788
wlog( "The --truncate-at-block option can only be used with --hard-replay-blockchain." );

0 commit comments

Comments
 (0)