Skip to content

Commit

Permalink
Merge pull request #609 from AntelopeIO/GH-608-max-reversible-sync
Browse files Browse the repository at this point in the history
[1.0] Add max_reversible_blocks_allowed(), use in net_plugin to limit sync-fetch-span
  • Loading branch information
heifner authored Aug 21, 2024
2 parents 09f89c3 + 2921b6f commit 7254bab
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 24 deletions.
28 changes: 19 additions & 9 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1117,13 +1117,6 @@ struct controller_impl {
return prev->block_num();
}

// returns 0 for legacy
size_t fork_db_savanna_size() const {
return fork_db.apply_s<size_t>([&](const auto& forkdb) {
return forkdb.size();
});
}

bool fork_db_block_exists( const block_id_type& id ) const {
return fork_db.apply<bool>([&](const auto& forkdb) {
return forkdb.block_exists(id);
Expand Down Expand Up @@ -4840,16 +4833,29 @@ struct controller_impl {
return conf.block_validation_mode == validation_mode::LIGHT || conf.trusted_producers.count(producer);
}

int32_t max_reversible_blocks_allowed() const {
if (conf.max_reversible_blocks == 0)
return std::numeric_limits<int32_t>::max();

return fork_db.apply<int32_t>(
[&](const fork_database_legacy_t& forkdb) {
return std::numeric_limits<int32_t>::max();
},
[&](const fork_database_if_t& forkdb) {
return conf.max_reversible_blocks - forkdb.size();
});
}

bool should_terminate(block_num_type reversible_block_num) const {
assert(reversible_block_num > 0);
if (conf.terminate_at_block > 0 && conf.terminate_at_block <= reversible_block_num) {
ilog("Block ${n} reached configured maximum block ${num}; terminating",
("n", reversible_block_num)("num", conf.terminate_at_block) );
return true;
}
if (conf.max_reversible_blocks > 0 && fork_db_savanna_size() >= conf.max_reversible_blocks) {
if (max_reversible_blocks_allowed() <= 0) {
elog("Exceeded max reversible blocks allowed, fork db size ${s} >= max-reversible-blocks ${m}",
("s", fork_db_savanna_size())("m", conf.max_reversible_blocks));
("s", fork_db_size())("m", conf.max_reversible_blocks));
return true;
}
return false;
Expand Down Expand Up @@ -5660,6 +5666,10 @@ bool controller::should_terminate() const {
return my->should_terminate();
}

int32_t controller:: max_reversible_blocks_allowed() const {
return my->max_reversible_blocks_allowed();
}

const apply_handler* controller::find_apply_handler( account_name receiver, account_name scope, action_name act ) const
{
auto native_handler_scope = my->apply_handlers.find( receiver );
Expand Down
7 changes: 6 additions & 1 deletion libraries/chain/include/eosio/chain/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ namespace eosio::chain {
uint32_t sig_cpu_bill_pct = chain::config::default_sig_cpu_bill_pct;
uint16_t chain_thread_pool_size = chain::config::default_controller_thread_pool_size;
uint16_t vote_thread_pool_size = 0;
uint32_t max_reversible_blocks = chain::config::default_max_reversible_blocks;
int32_t max_reversible_blocks = chain::config::default_max_reversible_blocks;
bool read_only = false;
bool force_all_checks = false;
bool disable_replay_opts = false;
Expand Down Expand Up @@ -396,6 +396,11 @@ namespace eosio::chain {
/// not-thread-safe
bool should_terminate() const;

/// Difference between max-reversible-blocks and fork database size.
/// Can return MAX_INT32 if disabled or pre-Savanna
/// @return the number of reversible blocks still allowed
int32_t max_reversible_blocks_allowed() const;

void set_subjective_cpu_leeway(fc::microseconds leeway);
std::optional<fc::microseconds> get_subjective_cpu_leeway() const;
void set_greylist_limit( uint32_t limit );
Expand Down
21 changes: 20 additions & 1 deletion libraries/chain/include/eosio/chain/fork_database.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ namespace eosio::chain {
}

/// @param legacy_f the lambda to execute if in legacy mode
/// @param savanna_f the lambda to execute if in savanna instant-finality mode
/// @param savanna_f the lambda to execute if in savanna mode
template <class R, class LegacyF, class SavannaF>
R apply(const LegacyF& legacy_f, const SavannaF& savanna_f) {
if constexpr (std::is_same_v<void, R>) {
Expand All @@ -281,6 +281,25 @@ namespace eosio::chain {
}
}

/// @param legacy_f the lambda to execute if in legacy mode
/// @param savanna_f the lambda to execute if in savanna mode
template <class R, class LegacyF, class SavannaF>
R apply(const LegacyF& legacy_f, const SavannaF& savanna_f) const {
if constexpr (std::is_same_v<void, R>) {
if (in_use.load() == in_use_t::legacy) {
legacy_f(fork_db_l);
} else {
savanna_f(fork_db_s);
}
} else {
if (in_use.load() == in_use_t::legacy) {
return legacy_f(fork_db_l);
} else {
return savanna_f(fork_db_s);
}
}
}

// Update max_supported_version if the persistent file format changes.
static constexpr uint32_t min_supported_version = 1;
static constexpr uint32_t max_supported_version = 2;
Expand Down
8 changes: 6 additions & 2 deletions plugins/chain_plugin/chain_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ void chain_plugin::set_program_options(options_description& cli, options_descrip
"'none' - EOS VM OC tier-up is completely disabled.\n")
#endif
("enable-account-queries", bpo::value<bool>()->default_value(false), "enable queries to find accounts by various metadata.")
("max-reversible-blocks", bpo::value<uint32_t>()->default_value(config::default_max_reversible_blocks),
("max-reversible-blocks", bpo::value<int32_t>()->default_value(config::default_max_reversible_blocks),
"Approximate maximum allowed reversible blocks before shutdown. Will shut down if limit reached. Specify 0 to disable.")
("transaction-retry-max-storage-size-gb", bpo::value<uint64_t>(),
"Maximum size (in GiB) allowed to be allocated for the Transaction Retry feature. Setting above 0 enables this feature.")
Expand Down Expand Up @@ -954,7 +954,11 @@ void chain_plugin_impl::plugin_initialize(const variables_map& options) {

account_queries_enabled = options.at("enable-account-queries").as<bool>();

chain_config->max_reversible_blocks = options.at("max-reversible-blocks").as<uint32_t>();
chain_config->max_reversible_blocks = options.at("max-reversible-blocks").as<int32_t>();
if (chain_config->max_reversible_blocks == -1) // allow -1 or 0 for disable
chain_config->max_reversible_blocks = 0;
EOS_ASSERT(chain_config->max_reversible_blocks >= 0, plugin_config_exception,
"max-reversible-blocks ${m} must be > 0", ("m", chain_config->max_reversible_blocks));

chain_config->integrity_hash_on_start = options.at("integrity-hash-on-start").as<bool>();
chain_config->integrity_hash_on_stop = options.at("integrity-hash-on-stop").as<bool>();
Expand Down
20 changes: 9 additions & 11 deletions plugins/net_plugin/net_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,6 @@ namespace eosio {

const uint32_t sync_fetch_span {0};
const uint32_t sync_peer_limit {0};
const size_t max_reversible_blocks {0};

alignas(hardware_destructive_interference_sz)
std::atomic<stages> sync_state{in_sync};
Expand Down Expand Up @@ -259,7 +258,7 @@ namespace eosio {
immediately, // closing connection immediately
handshake // sending handshake message
};
explicit sync_manager( uint32_t span, uint32_t sync_peer_limit, size_t max_reversible_blocks, uint32_t min_blocks_distance );
explicit sync_manager( uint32_t span, uint32_t sync_peer_limit, uint32_t min_blocks_distance );
static void send_handshakes();
bool syncing_from_peer() const { return sync_state == lib_catchup; }
bool is_in_sync() const { return sync_state == in_sync; }
Expand Down Expand Up @@ -1989,30 +1988,30 @@ namespace eosio {
}
//-----------------------------------------------------------

sync_manager::sync_manager( uint32_t span, uint32_t sync_peer_limit, size_t max_reversible_blocks, uint32_t min_blocks_distance )
sync_manager::sync_manager( uint32_t span, uint32_t sync_peer_limit, uint32_t min_blocks_distance )
:sync_known_lib_num( 0 )
,sync_last_requested_num( 0 )
,sync_next_expected_num( 1 )
,sync_source()
,sync_fetch_span( span )
,sync_peer_limit( sync_peer_limit )
,max_reversible_blocks(max_reversible_blocks)
,sync_state(in_sync)
,min_blocks_distance(min_blocks_distance)
{
}

uint32_t sync_manager::active_sync_fetch_span() const {
auto fork_db_size = my_impl->chain_plug->chain().fork_db_size();
int32_t reversible_remaining = max_reversible_blocks - fork_db_size - 1;
int32_t reversible_remaining = my_impl->chain_plug->chain().max_reversible_blocks_allowed();
if (reversible_remaining <= 0) {
fc_wlog(logger, "max-reversible-blocks ${m} exceeded, remaining ${r}, fork_db_size ${fs}",
("m", max_reversible_blocks)("r", reversible_remaining)("fs", fork_db_size));
auto fork_db_size = my_impl->chain_plug->chain().fork_db_size();
fc_wlog(logger, "max-reversible-blocks exceeded by ${ex}, fork_db_size ${fs}",
("ex", -reversible_remaining)("fs", fork_db_size));
reversible_remaining = 0;
}
if (reversible_remaining < sync_fetch_span) {
fc_wlog(logger, "sync-fetch-span ${sfs} restricted to ${r} by max-reversible-blocks ${m}, fork_db_size ${fs}",
("sfs", sync_fetch_span)("r", reversible_remaining)("m", max_reversible_blocks)("fs", fork_db_size));
auto fork_db_size = my_impl->chain_plug->chain().fork_db_size();
fc_wlog(logger, "sync-fetch-span ${sfs} restricted to ${r} by max-reversible-blocks, fork_db_size ${fs}",
("sfs", sync_fetch_span)("r", reversible_remaining)("fs", fork_db_size));
return reversible_remaining;
}
return sync_fetch_span;
Expand Down Expand Up @@ -4297,7 +4296,6 @@ namespace eosio {
sync_master = std::make_unique<sync_manager>(
options.at( "sync-fetch-span" ).as<uint32_t>(),
options.at( "sync-peer-limit" ).as<uint32_t>(),
chain_plug->chain_config().max_reversible_blocks,
min_blocks_distance);

connections.init( std::chrono::milliseconds( options.at("p2p-keepalive-interval-ms").as<int>() * 2 ),
Expand Down
2 changes: 2 additions & 0 deletions tests/nodeos_startup_catchup.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@
specificExtraNodeosArgs[pnodes+7] = f' --sync-fetch-span 1597 '
specificExtraNodeosArgs[pnodes+8] = f' --sync-fetch-span 6765 '
specificExtraNodeosArgs[pnodes+9] = f' --sync-fetch-span 28657 '
if not activateIF:
specificExtraNodeosArgs[pnodes+9] += " --max-reversible-blocks 2 " # should be ignored for pre-savanna blocks
specificExtraNodeosArgs[pnodes+10] = f' --sync-fetch-span 89 --read-mode irreversible '
specificExtraNodeosArgs[pnodes+11] = f' --sync-fetch-span 377 --read-mode irreversible '
if cluster.launch(prodCount=prodCount, specificExtraNodeosArgs=specificExtraNodeosArgs, activateIF=activateIF, onlyBios=False,
Expand Down

0 comments on commit 7254bab

Please sign in to comment.