Merge pull request #4891 from pwojcikdev/fix-pruning

Do not refresh transactions while holding iterators when pruning
This commit is contained in:
Piotr Wójcik 2025-04-23 00:22:29 +02:00 committed by GitHub
commit b5384a9a8b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 17 additions and 12 deletions

View file

@ -3409,7 +3409,7 @@ TEST (node, pruning_automatic)
ASSERT_TRUE (nano::test::block_or_pruned_all_exists (node1, { nano::dev::genesis, send1, send2 }));
}
TEST (node, DISABLED_pruning_age)
TEST (node, pruning_age)
{
nano::test::system system{};
@ -3470,7 +3470,7 @@ TEST (node, DISABLED_pruning_age)
// Test that a node configured with `enable_pruning` will
// prune DEEP-enough confirmed blocks by explicitly saying `node.ledger_pruning` in the unit test
TEST (node, DISABLED_pruning_depth)
TEST (node, pruning_depth)
{
nano::test::system system{};

View file

@ -427,12 +427,15 @@ nano::node::node (std::shared_ptr<boost::asio::io_context> io_ctx_a, std::filesy
logger.critical (nano::log::type::node, "Incompatibility detected between config node.enable_voting and existing pruned blocks");
std::exit (1);
}
else if (!flags.enable_pruning && !flags.inactive_node)
if (!flags.enable_pruning && !flags.inactive_node)
{
logger.critical (nano::log::type::node, "To start node with existing pruned blocks use launch flag --enable_pruning");
std::exit (1);
}
logger.warn (nano::log::type::node, "WARNING: Ledger pruning is enabled. This feature is experimental and may result in node instability! Please see release notes for more information.");
}
cementing_set.cemented_observers.add ([this] (auto const & block) {
// TODO: Is it neccessary to call this for all blocks?
if (block->is_send ())

View file

@ -38,13 +38,19 @@ void nano::pruning::stop ()
void nano::pruning::ongoing_ledger_pruning ()
{
if (stopped)
{
return;
}
auto bootstrap_weight_reached (ledger.block_count () >= ledger.bootstrap_weight_max_blocks);
ledger_pruning (flags.block_processor_batch_size != 0 ? flags.block_processor_batch_size : 2 * 1024, bootstrap_weight_reached);
auto const ledger_pruning_interval (bootstrap_weight_reached ? config.max_pruning_age : std::min (config.max_pruning_age, std::chrono::seconds (15 * 60)));
logger.debug (nano::log::type::pruning, "Next pruning iteration in {}s", ledger_pruning_interval.count ());
workers.post_delayed (ledger_pruning_interval, [this] () {
workers.post ([this] () {
ongoing_ledger_pruning ();
});
ongoing_ledger_pruning ();
});
}
@ -89,7 +95,7 @@ void nano::pruning::ledger_pruning (uint64_t const batch_size_a, bool bootstrap_
}
}
logger.debug (nano::log::type::pruning, "Total recently pruned block count: {}", pruned_count);
logger.info (nano::log::type::pruning, "Recently pruned blocks: {}", pruned_count);
}
bool nano::pruning::collect_ledger_pruning_targets (std::deque<nano::block_hash> & pruning_targets_a, nano::account & last_account_a, uint64_t const batch_read_size_a, uint64_t const max_depth_a, uint64_t const cutoff_time_a)
@ -122,11 +128,7 @@ bool nano::pruning::collect_ledger_pruning_targets (std::deque<nano::block_hash>
release_assert (depth != 0);
hash = 0;
}
if (++depth % batch_read_size_a == 0)
{
// FIXME: This is triggering an assertion where the iterator is still used after transaction is refreshed
transaction.refresh ();
}
++depth;
}
if (!hash.is_zero ())
{