[Pruning] Pruning configuration settings (#2947)
* [Pruning] Pruning configuration settings Splitting https://github.com/nanocurrency/nano-node/pull/2881 * Enable optional ledger pruning with node launch flag `--enable_pruning` for automatic node background actions. * Pruning rules can be configured in [node.experimental] config with “max_pruning_age” (Time in seconds to limit for blocks age after pruning. Also period for automatic node pruning task, default 1 day, 5 minutes for beta network) & “max_pruning_depth” (Limit for full blocks in chain after pruning, default 0 - unlimited). By default all confirmed blocks older than 1 day can be pruned, except genesis block & last confirmed block in each account chain. * `--enable_pruning` flag & config option “enable_voting” are mutually exclusive to prevent representatives start with pruned ledger. Pruning is not available for any representatives. * Update ledger.pruning status if there are any pruned blocks in ledger * Remove unused variables
This commit is contained in:
parent
ec163548e4
commit
29f2a735b8
9 changed files with 65 additions and 1 deletions
|
|
@ -513,6 +513,8 @@ TEST (toml, daemon_config_deserialize_no_defaults)
|
||||||
|
|
||||||
[node.experimental]
|
[node.experimental]
|
||||||
secondary_work_peers = ["dev.org:998"]
|
secondary_work_peers = ["dev.org:998"]
|
||||||
|
max_pruning_age = 999
|
||||||
|
max_pruning_depth = 999
|
||||||
|
|
||||||
[opencl]
|
[opencl]
|
||||||
device = 999
|
device = 999
|
||||||
|
|
@ -567,6 +569,8 @@ TEST (toml, daemon_config_deserialize_no_defaults)
|
||||||
ASSERT_NE (conf.node.frontiers_confirmation, defaults.node.frontiers_confirmation);
|
ASSERT_NE (conf.node.frontiers_confirmation, defaults.node.frontiers_confirmation);
|
||||||
ASSERT_NE (conf.node.network_threads, defaults.node.network_threads);
|
ASSERT_NE (conf.node.network_threads, defaults.node.network_threads);
|
||||||
ASSERT_NE (conf.node.secondary_work_peers, defaults.node.secondary_work_peers);
|
ASSERT_NE (conf.node.secondary_work_peers, defaults.node.secondary_work_peers);
|
||||||
|
ASSERT_NE (conf.node.max_pruning_age, defaults.node.max_pruning_age);
|
||||||
|
ASSERT_NE (conf.node.max_pruning_depth, defaults.node.max_pruning_depth);
|
||||||
ASSERT_NE (conf.node.work_watcher_period, defaults.node.work_watcher_period);
|
ASSERT_NE (conf.node.work_watcher_period, defaults.node.work_watcher_period);
|
||||||
ASSERT_NE (conf.node.online_weight_minimum, defaults.node.online_weight_minimum);
|
ASSERT_NE (conf.node.online_weight_minimum, defaults.node.online_weight_minimum);
|
||||||
ASSERT_NE (conf.node.online_weight_quorum, defaults.node.online_weight_quorum);
|
ASSERT_NE (conf.node.online_weight_quorum, defaults.node.online_weight_quorum);
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#include <nano/lib/threading.hpp>
|
#include <nano/lib/threading.hpp>
|
||||||
#include <nano/lib/utility.hpp>
|
#include <nano/lib/utility.hpp>
|
||||||
#include <nano/nano_node/daemon.hpp>
|
#include <nano/nano_node/daemon.hpp>
|
||||||
|
#include <nano/node/cli.hpp>
|
||||||
#include <nano/node/daemonconfig.hpp>
|
#include <nano/node/daemonconfig.hpp>
|
||||||
#include <nano/node/ipc/ipc_server.hpp>
|
#include <nano/node/ipc/ipc_server.hpp>
|
||||||
#include <nano/node/json_handler.hpp>
|
#include <nano/node/json_handler.hpp>
|
||||||
|
|
@ -42,6 +43,10 @@ void nano_daemon::daemon::run (boost::filesystem::path const & data_path, nano::
|
||||||
auto error = nano::read_node_config_toml (data_path, config, flags.config_overrides);
|
auto error = nano::read_node_config_toml (data_path, config, flags.config_overrides);
|
||||||
nano::set_use_memory_pools (config.node.use_memory_pools);
|
nano::set_use_memory_pools (config.node.use_memory_pools);
|
||||||
if (!error)
|
if (!error)
|
||||||
|
{
|
||||||
|
error = nano::flags_config_conflicts (flags, config.node);
|
||||||
|
}
|
||||||
|
if (!error)
|
||||||
{
|
{
|
||||||
config.node.logging.init (data_path);
|
config.node.logging.init (data_path);
|
||||||
nano::logger_mt logger{ config.node.logging.min_time_between_log_output };
|
nano::logger_mt logger{ config.node.logging.min_time_between_log_output };
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,11 @@ int run_wallet (QApplication & application, int argc, char * const * argv, boost
|
||||||
error = read_wallet_config (wallet_config, data_path);
|
error = read_wallet_config (wallet_config, data_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!error)
|
||||||
|
{
|
||||||
|
error = nano::flags_config_conflicts (flags, config.node);
|
||||||
|
}
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
nano::set_use_memory_pools (config.node.use_memory_pools);
|
nano::set_use_memory_pools (config.node.use_memory_pools);
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ std::string nano::error_cli_messages::message (int ev) const
|
||||||
return "Flags --disable_tcp_realtime and --disable_udp cannot be used together";
|
return "Flags --disable_tcp_realtime and --disable_udp cannot be used together";
|
||||||
case nano::error_cli::ambiguous_udp_options:
|
case nano::error_cli::ambiguous_udp_options:
|
||||||
return "Flags --disable_udp and --enable_udp cannot be used together";
|
return "Flags --disable_udp and --enable_udp cannot be used together";
|
||||||
|
case nano::error_cli::ambiguous_pruning_voting_options:
|
||||||
|
return "Flag --enable_pruning and enable_voting in node config cannot be used together";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Invalid error code";
|
return "Invalid error code";
|
||||||
|
|
@ -97,6 +99,7 @@ void nano::add_node_flag_options (boost::program_options::options_description &
|
||||||
("disable_unchecked_drop", "Disables drop of unchecked table at startup")
|
("disable_unchecked_drop", "Disables drop of unchecked table at startup")
|
||||||
("disable_providing_telemetry_metrics", "Disable using any node information in the telemetry_ack messages.")
|
("disable_providing_telemetry_metrics", "Disable using any node information in the telemetry_ack messages.")
|
||||||
("disable_block_processor_unchecked_deletion", "Disable deletion of unchecked blocks after processing")
|
("disable_block_processor_unchecked_deletion", "Disable deletion of unchecked blocks after processing")
|
||||||
|
("enable_pruning", "Enable experimental ledger pruning")
|
||||||
("allow_bootstrap_peers_duplicates", "Allow multiple connections to same peer in bootstrap attempts")
|
("allow_bootstrap_peers_duplicates", "Allow multiple connections to same peer in bootstrap attempts")
|
||||||
("fast_bootstrap", "Increase bootstrap speed for high end nodes with higher limits")
|
("fast_bootstrap", "Increase bootstrap speed for high end nodes with higher limits")
|
||||||
("block_processor_batch_size", boost::program_options::value<std::size_t>(), "Increase block processor transaction batch write size, default 0 (limited by config block_processor_batch_max_time), 256k for fast_bootstrap")
|
("block_processor_batch_size", boost::program_options::value<std::size_t>(), "Increase block processor transaction batch write size, default 0 (limited by config block_processor_batch_max_time), 256k for fast_bootstrap")
|
||||||
|
|
@ -133,6 +136,7 @@ std::error_code nano::update_flags (nano::node_flags & flags_a, boost::program_o
|
||||||
flags_a.disable_unchecked_cleanup = (vm.count ("disable_unchecked_cleanup") > 0);
|
flags_a.disable_unchecked_cleanup = (vm.count ("disable_unchecked_cleanup") > 0);
|
||||||
flags_a.disable_unchecked_drop = (vm.count ("disable_unchecked_drop") > 0);
|
flags_a.disable_unchecked_drop = (vm.count ("disable_unchecked_drop") > 0);
|
||||||
flags_a.disable_block_processor_unchecked_deletion = (vm.count ("disable_block_processor_unchecked_deletion") > 0);
|
flags_a.disable_block_processor_unchecked_deletion = (vm.count ("disable_block_processor_unchecked_deletion") > 0);
|
||||||
|
flags_a.enable_pruning = (vm.count ("enable_pruning") > 0);
|
||||||
flags_a.allow_bootstrap_peers_duplicates = (vm.count ("allow_bootstrap_peers_duplicates") > 0);
|
flags_a.allow_bootstrap_peers_duplicates = (vm.count ("allow_bootstrap_peers_duplicates") > 0);
|
||||||
flags_a.fast_bootstrap = (vm.count ("fast_bootstrap") > 0);
|
flags_a.fast_bootstrap = (vm.count ("fast_bootstrap") > 0);
|
||||||
if (flags_a.fast_bootstrap)
|
if (flags_a.fast_bootstrap)
|
||||||
|
|
@ -176,6 +180,16 @@ std::error_code nano::update_flags (nano::node_flags & flags_a, boost::program_o
|
||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::error_code nano::flags_config_conflicts (nano::node_flags const & flags_a, nano::node_config const & config_a)
|
||||||
|
{
|
||||||
|
std::error_code ec;
|
||||||
|
if (flags_a.enable_pruning && config_a.enable_voting)
|
||||||
|
{
|
||||||
|
ec = nano::error_cli::ambiguous_pruning_voting_options;
|
||||||
|
}
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
void database_write_lock_error (std::error_code & ec)
|
void database_write_lock_error (std::error_code & ec)
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,14 @@ enum class error_cli
|
||||||
database_write_error = 5,
|
database_write_error = 5,
|
||||||
reading_config = 6,
|
reading_config = 6,
|
||||||
disable_all_network = 7,
|
disable_all_network = 7,
|
||||||
ambiguous_udp_options = 8
|
ambiguous_udp_options = 8,
|
||||||
|
ambiguous_pruning_voting_options = 9
|
||||||
};
|
};
|
||||||
|
|
||||||
void add_node_options (boost::program_options::options_description &);
|
void add_node_options (boost::program_options::options_description &);
|
||||||
void add_node_flag_options (boost::program_options::options_description &);
|
void add_node_flag_options (boost::program_options::options_description &);
|
||||||
std::error_code update_flags (nano::node_flags &, boost::program_options::variables_map const &);
|
std::error_code update_flags (nano::node_flags &, boost::program_options::variables_map const &);
|
||||||
|
std::error_code flags_config_conflicts (nano::node_flags const &, nano::node_config const &);
|
||||||
std::error_code handle_node_options (boost::program_options::variables_map const &);
|
std::error_code handle_node_options (boost::program_options::variables_map const &);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -424,6 +424,26 @@ node_seq (seq)
|
||||||
logger.always_log ("Dropping unchecked blocks");
|
logger.always_log ("Dropping unchecked blocks");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ledger.pruning = flags.enable_pruning || store.pruned_count (store.tx_begin_read ()) > 0;
|
||||||
|
|
||||||
|
if (ledger.pruning)
|
||||||
|
{
|
||||||
|
if (config.enable_voting && !flags.inactive_node)
|
||||||
|
{
|
||||||
|
std::string str = "Incompatibility detected between config node.enable_voting and existing pruned blocks";
|
||||||
|
logger.always_log (str);
|
||||||
|
std::cerr << str << std::endl;
|
||||||
|
std::exit (1);
|
||||||
|
}
|
||||||
|
else if (!flags.enable_pruning && !flags.inactive_node)
|
||||||
|
{
|
||||||
|
std::string str = "To start node with existing pruned blocks use launch flag --enable_pruning";
|
||||||
|
logger.always_log (str);
|
||||||
|
std::cerr << str << std::endl;
|
||||||
|
std::exit (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
node_initialized_latch.count_down ();
|
node_initialized_latch.count_down ();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,8 @@ nano::error nano::node_config::serialize_toml (nano::tomlconfig & toml) const
|
||||||
{
|
{
|
||||||
secondary_work_peers_l->push_back (boost::str (boost::format ("%1%:%2%") % i->first % i->second));
|
secondary_work_peers_l->push_back (boost::str (boost::format ("%1%:%2%") % i->first % i->second));
|
||||||
}
|
}
|
||||||
|
experimental_l.put ("max_pruning_age", max_pruning_age.count (), "Time limit for blocks age after pruning.\ntype:seconds");
|
||||||
|
experimental_l.put ("max_pruning_depth", max_pruning_depth, "Limit for full blocks in chain after pruning.\ntype:uint64");
|
||||||
toml.put_child ("experimental", experimental_l);
|
toml.put_child ("experimental", experimental_l);
|
||||||
|
|
||||||
nano::tomlconfig callback_l;
|
nano::tomlconfig callback_l;
|
||||||
|
|
@ -389,6 +391,10 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml)
|
||||||
this->deserialize_address (entry_a, this->secondary_work_peers);
|
this->deserialize_address (entry_a, this->secondary_work_peers);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
auto max_pruning_age_l (max_pruning_age.count ());
|
||||||
|
experimental_config_l.get ("max_pruning_age", max_pruning_age_l);
|
||||||
|
max_pruning_age = std::chrono::seconds (max_pruning_age_l);
|
||||||
|
experimental_config_l.get<uint64_t> ("max_pruning_depth", max_pruning_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate ranges
|
// Validate ranges
|
||||||
|
|
@ -437,6 +443,10 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml)
|
||||||
{
|
{
|
||||||
toml.get_error ().set ((boost::format ("block_processor_batch_max_time value must be equal or larger than %1%ms") % network_params.node.process_confirmed_interval.count ()).str ());
|
toml.get_error ().set ((boost::format ("block_processor_batch_max_time value must be equal or larger than %1%ms") % network_params.node.process_confirmed_interval.count ()).str ());
|
||||||
}
|
}
|
||||||
|
if (max_pruning_age < std::chrono::seconds (5 * 60) && !network.is_dev_network ())
|
||||||
|
{
|
||||||
|
toml.get_error ().set ("max_pruning_age must be greater than or equal to 5 minutes");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (std::runtime_error const & ex)
|
catch (std::runtime_error const & ex)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,8 @@ public:
|
||||||
std::chrono::seconds work_watcher_period{ std::chrono::seconds (5) };
|
std::chrono::seconds work_watcher_period{ std::chrono::seconds (5) };
|
||||||
double max_work_generate_multiplier{ 64. };
|
double max_work_generate_multiplier{ 64. };
|
||||||
uint32_t max_queued_requests{ 512 };
|
uint32_t max_queued_requests{ 512 };
|
||||||
|
std::chrono::seconds max_pruning_age{ !network_params.network.is_beta_network () ? std::chrono::seconds (24 * 60 * 60) : std::chrono::seconds (5 * 60) }; // 1 day; 5 minutes for beta network
|
||||||
|
uint64_t max_pruning_depth{ 0 };
|
||||||
nano::rocksdb_config rocksdb_config;
|
nano::rocksdb_config rocksdb_config;
|
||||||
nano::lmdb_config lmdb_config;
|
nano::lmdb_config lmdb_config;
|
||||||
nano::frontiers_confirmation_mode frontiers_confirmation{ nano::frontiers_confirmation_mode::automatic };
|
nano::frontiers_confirmation_mode frontiers_confirmation{ nano::frontiers_confirmation_mode::automatic };
|
||||||
|
|
@ -139,6 +141,7 @@ public:
|
||||||
bool allow_bootstrap_peers_duplicates{ false };
|
bool allow_bootstrap_peers_duplicates{ false };
|
||||||
bool disable_max_peers_per_ip{ false }; // For testing only
|
bool disable_max_peers_per_ip{ false }; // For testing only
|
||||||
bool force_use_write_database_queue{ false }; // For testing only. RocksDB does not use the database queue, but some tests rely on it being used.
|
bool force_use_write_database_queue{ false }; // For testing only. RocksDB does not use the database queue, but some tests rely on it being used.
|
||||||
|
bool enable_pruning{ false };
|
||||||
bool fast_bootstrap{ false };
|
bool fast_bootstrap{ false };
|
||||||
bool read_only{ false };
|
bool read_only{ false };
|
||||||
nano::confirmation_height_mode confirmation_height_processor_mode{ nano::confirmation_height_mode::automatic };
|
nano::confirmation_height_mode confirmation_height_processor_mode{ nano::confirmation_height_mode::automatic };
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ public:
|
||||||
std::atomic<size_t> bootstrap_weights_size{ 0 };
|
std::atomic<size_t> bootstrap_weights_size{ 0 };
|
||||||
uint64_t bootstrap_weight_max_blocks{ 1 };
|
uint64_t bootstrap_weight_max_blocks{ 1 };
|
||||||
std::atomic<bool> check_bootstrap_weights;
|
std::atomic<bool> check_bootstrap_weights;
|
||||||
|
bool pruning{ false };
|
||||||
std::function<void()> epoch_2_started_cb;
|
std::function<void()> epoch_2_started_cb;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue