Add frontiers confirmation modes (#2175)
always - always algressive confirm frontiers automatic - confirm frontiers in always mode if node contains representative with at least 50% of principal weight, confirm frontiers less often otherwise disabled - do not confirm frontiers * Use node::minimum_principal_weight () * More agressive settings for wallets accounts prioritization * Update node.rep_self_vote test * Update TOML config
This commit is contained in:
parent
f8401179e3
commit
2f7e6c280e
13 changed files with 243 additions and 95 deletions
|
@ -39,9 +39,8 @@ TEST (active_transactions, adjusted_difficulty_priority)
|
|||
nano::system system;
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.enable_voting = false;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto & node1 = *system.add_node (node_config, node_flags);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto & node1 = *system.add_node (node_config);
|
||||
nano::genesis genesis;
|
||||
nano::keypair key1, key2, key3;
|
||||
|
||||
|
@ -123,10 +122,9 @@ TEST (active_transactions, keep_local)
|
|||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.enable_voting = false;
|
||||
node_config.active_elections_size = 3; //bound to 3, wont drop wallet created transactions, but good to test dropping remote
|
||||
//delay_frontier_confirmation_height_updating to allow the test to before
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto & node1 = *system.add_node (node_config, node_flags);
|
||||
// Disable frontier confirmation to allow the test to finish before
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto & node1 = *system.add_node (node_config);
|
||||
auto & wallet (*system.wallet (0));
|
||||
nano::genesis genesis;
|
||||
//key 1/2 will be managed by the wallet
|
||||
|
@ -179,10 +177,9 @@ TEST (active_transactions, prioritize_chains)
|
|||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.enable_voting = false;
|
||||
node_config.active_elections_size = 4; //bound to 3, wont drop wallet created transactions, but good to test dropping remote
|
||||
//delay_frontier_confirmation_height_updating to allow the test to before
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto & node1 = *system.add_node (node_config, node_flags);
|
||||
// Disable frontier confirmation to allow the test to finish before
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto & node1 = *system.add_node (node_config);
|
||||
nano::genesis genesis;
|
||||
nano::keypair key1, key2, key3;
|
||||
|
||||
|
|
|
@ -193,9 +193,9 @@ TEST (conflicts, reprioritize)
|
|||
TEST (conflicts, dependency)
|
||||
{
|
||||
nano::system system;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto node1 = system.add_node (nano::node_config (24000, system.logging), node_flags);
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node1 = system.add_node (node_config);
|
||||
nano::genesis genesis;
|
||||
nano::keypair key1;
|
||||
auto send1 (std::make_shared<nano::send_block> (genesis.hash (), key1.pub, nano::genesis_amount - nano::xrb_ratio, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
|
||||
|
|
|
@ -815,9 +815,8 @@ TEST (votes, add_existing)
|
|||
nano::system system;
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.online_weight_minimum = std::numeric_limits<nano::uint128_t>::max ();
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto & node1 = *system.add_node (node_config, node_flags);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto & node1 = *system.add_node (node_config);
|
||||
nano::genesis genesis;
|
||||
nano::keypair key1;
|
||||
auto send1 (std::make_shared<nano::send_block> (genesis.hash (), key1.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
|
||||
|
|
|
@ -1559,10 +1559,11 @@ TEST (confirmation_height, single)
|
|||
TEST (confirmation_height, multiple_accounts)
|
||||
{
|
||||
nano::system system;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
system.add_node (nano::node_config (24001, system.logging), node_flags);
|
||||
system.add_node (nano::node_config (24002, system.logging), node_flags);
|
||||
nano::node_config node_config (24001, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
system.add_node (node_config);
|
||||
node_config.peering_port = 24002;
|
||||
system.add_node (node_config);
|
||||
nano::keypair key1;
|
||||
nano::keypair key2;
|
||||
nano::keypair key3;
|
||||
|
@ -1757,10 +1758,11 @@ TEST (confirmation_height, gap_bootstrap)
|
|||
TEST (confirmation_height, gap_live)
|
||||
{
|
||||
nano::system system;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
system.add_node (nano::node_config (24001, system.logging), node_flags);
|
||||
system.add_node (nano::node_config (24002, system.logging), node_flags);
|
||||
nano::node_config node_config (24001, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
system.add_node (node_config);
|
||||
node_config.peering_port = 24002;
|
||||
system.add_node (node_config);
|
||||
nano::keypair destination;
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
system.wallet (1)->insert_adhoc (destination.prv);
|
||||
|
@ -1837,9 +1839,9 @@ TEST (confirmation_height, gap_live)
|
|||
TEST (confirmation_height, send_receive_between_2_accounts)
|
||||
{
|
||||
nano::system system;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto node = system.add_node (nano::node_config (24000, system.logging), node_flags);
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node = system.add_node (node_config);
|
||||
nano::keypair key1;
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
nano::block_hash latest (node->latest (nano::test_genesis_key.pub));
|
||||
|
@ -1917,9 +1919,9 @@ TEST (confirmation_height, send_receive_between_2_accounts)
|
|||
TEST (confirmation_height, send_receive_self)
|
||||
{
|
||||
nano::system system;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto node = system.add_node (nano::node_config (24000, system.logging), node_flags);
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node = system.add_node (node_config);
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
nano::block_hash latest (node->latest (nano::test_genesis_key.pub));
|
||||
|
||||
|
@ -1976,9 +1978,9 @@ TEST (confirmation_height, send_receive_self)
|
|||
TEST (confirmation_height, all_block_types)
|
||||
{
|
||||
nano::system system;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto node = system.add_node (nano::node_config (24000, system.logging), node_flags);
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node = system.add_node (node_config);
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
nano::block_hash latest (node->latest (nano::test_genesis_key.pub));
|
||||
nano::keypair key1;
|
||||
|
@ -2178,9 +2180,9 @@ TEST (confirmation_height, observers)
|
|||
TEST (confirmation_height, modified_chain)
|
||||
{
|
||||
nano::system system;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto node = system.add_node (nano::node_config (24000, system.logging), node_flags);
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node = system.add_node (node_config);
|
||||
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
nano::block_hash latest (node->latest (nano::test_genesis_key.pub));
|
||||
|
@ -2216,9 +2218,9 @@ namespace nano
|
|||
TEST (confirmation_height, pending_observer_callbacks)
|
||||
{
|
||||
nano::system system;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto node = system.add_node (nano::node_config (24000, system.logging), node_flags);
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node = system.add_node (node_config);
|
||||
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
nano::block_hash latest (node->latest (nano::test_genesis_key.pub));
|
||||
|
|
|
@ -1709,9 +1709,8 @@ TEST (node, rep_self_vote)
|
|||
nano::system system;
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.online_weight_minimum = std::numeric_limits<nano::uint128_t>::max ();
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto node0 = system.add_node (node_config, node_flags);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node0 = system.add_node (node_config);
|
||||
nano::keypair rep_big;
|
||||
{
|
||||
auto transaction0 (node0->store.tx_begin_write ());
|
||||
|
@ -1814,10 +1813,11 @@ TEST (node, bootstrap_bulk_push)
|
|||
TEST (node, bootstrap_fork_open)
|
||||
{
|
||||
nano::system system0;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto node0 = system0.add_node (nano::node_config (24000, system0.logging), node_flags);
|
||||
auto node1 = system0.add_node (nano::node_config (24001, system0.logging), node_flags);
|
||||
nano::node_config node_config (24000, system0.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node0 = system0.add_node (node_config);
|
||||
node_config.peering_port = 24001;
|
||||
auto node1 = system0.add_node (node_config);
|
||||
system0.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
nano::keypair key0;
|
||||
nano::send_block send0 (system0.nodes[0]->latest (nano::test_genesis_key.pub), key0.pub, nano::genesis_amount - 500, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0);
|
||||
|
@ -1853,7 +1853,7 @@ TEST (node, bootstrap_confirm_frontiers)
|
|||
nano::system system0 (24000, 1);
|
||||
nano::system system1 (24001, 1);
|
||||
auto node0 (system0.nodes[0]);
|
||||
auto node1 (system1.nodes[0]);
|
||||
auto node1 (system0.nodes[0]);
|
||||
system0.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
nano::keypair key0;
|
||||
// node0 knows about send0 but node1 doesn't.
|
||||
|
@ -2585,10 +2585,11 @@ TEST (node, vote_by_hash_epoch_block_republish)
|
|||
TEST (node, epoch_conflict_confirm)
|
||||
{
|
||||
nano::system system;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto node0 = system.add_node (nano::node_config (24000, system.logging), node_flags);
|
||||
auto node1 = system.add_node (nano::node_config (24001, system.logging), node_flags);
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node0 = system.add_node (node_config);
|
||||
node_config.peering_port = 24001;
|
||||
auto node1 = system.add_node (node_config);
|
||||
nano::keypair key;
|
||||
nano::genesis genesis;
|
||||
nano::keypair epoch_signer (nano::test_genesis_key);
|
||||
|
@ -2786,9 +2787,9 @@ TEST (node, block_processor_reject_state)
|
|||
TEST (node, block_processor_reject_rolled_back)
|
||||
{
|
||||
nano::system system;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto & node = *system.add_node (nano::node_config (24000, system.logging), node_flags);
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto & node = *system.add_node (node_config);
|
||||
nano::genesis genesis;
|
||||
auto send1 (std::make_shared<nano::state_block> (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
|
||||
node.work_generate_blocking (*send1);
|
||||
|
@ -3084,10 +3085,11 @@ TEST (node, bidirectional_tcp)
|
|||
{
|
||||
nano::system system;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
node_flags.disable_udp = true; // Disable UDP connections
|
||||
auto node1 = system.add_node (nano::node_config (24000, system.logging), node_flags);
|
||||
nano::node_config node_config (24001, system.logging);
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node1 = system.add_node (node_config, node_flags);
|
||||
node_config.peering_port = 24001;
|
||||
node_config.tcp_incoming_connections_max = 0; // Disable incoming TCP connections for node 2
|
||||
auto node2 = system.add_node (node_config, node_flags);
|
||||
// Check network connections
|
||||
|
@ -3155,9 +3157,9 @@ TEST (confirmation_height, prioritize_frontiers)
|
|||
{
|
||||
nano::system system;
|
||||
// Prevent frontiers being confirmed as it will affect the priorization checking
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto node = system.add_node (nano::node_config (24001, system.logging), node_flags);
|
||||
nano::node_config node_config (24001, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node = system.add_node (node_config);
|
||||
|
||||
nano::keypair key1;
|
||||
nano::keypair key2;
|
||||
|
@ -3274,13 +3276,9 @@ TEST (confirmation_height, prioritize_frontiers)
|
|||
transaction.refresh ();
|
||||
node->active.prioritize_frontiers_for_confirmation (transaction, std::chrono::seconds (1), std::chrono::seconds (1));
|
||||
ASSERT_TRUE (priority_orders_match (node->active.priority_wallet_cementable_frontiers, std::array<nano::account, num_accounts>{ key3.pub, nano::genesis_account, key4.pub, key1.pub, key2.pub }));
|
||||
node->active.confirm_frontiers (transaction);
|
||||
|
||||
// Check that the active transactions roots contains the frontiers
|
||||
{
|
||||
std::lock_guard<std::mutex> guard (node->active.mutex);
|
||||
node->active.next_frontier_check = std::chrono::steady_clock::now ();
|
||||
}
|
||||
|
||||
system.deadline_set (std::chrono::seconds (10));
|
||||
while (node->active.size () != num_accounts)
|
||||
{
|
||||
|
@ -3295,6 +3293,61 @@ TEST (confirmation_height, prioritize_frontiers)
|
|||
}
|
||||
}
|
||||
|
||||
TEST (confirmation_height, frontiers_confirmation_mode)
|
||||
{
|
||||
nano::genesis genesis;
|
||||
nano::keypair key;
|
||||
// Always mode
|
||||
{
|
||||
nano::system system;
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::always;
|
||||
auto node = system.add_node (node_config);
|
||||
nano::state_block send (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, node->work_generate_blocking (genesis.hash ()));
|
||||
{
|
||||
auto transaction = node->store.tx_begin_write ();
|
||||
ASSERT_EQ (nano::process_result::progress, node->ledger.process (transaction, send).code);
|
||||
}
|
||||
system.deadline_set (5s);
|
||||
while (node->active.size () != 1)
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
}
|
||||
// Auto mode
|
||||
{
|
||||
nano::system system;
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::automatic;
|
||||
auto node = system.add_node (node_config);
|
||||
nano::state_block send (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, node->work_generate_blocking (genesis.hash ()));
|
||||
{
|
||||
auto transaction = node->store.tx_begin_write ();
|
||||
ASSERT_EQ (nano::process_result::progress, node->ledger.process (transaction, send).code);
|
||||
}
|
||||
system.deadline_set (5s);
|
||||
while (node->active.size () != 1)
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
}
|
||||
// Disabled mode
|
||||
{
|
||||
nano::system system;
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node = system.add_node (node_config);
|
||||
nano::state_block send (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, node->work_generate_blocking (genesis.hash ()));
|
||||
{
|
||||
auto transaction = node->store.tx_begin_write ();
|
||||
ASSERT_EQ (nano::process_result::progress, node->ledger.process (transaction, send).code);
|
||||
}
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
std::this_thread::sleep_for (std::chrono::seconds (1));
|
||||
ASSERT_EQ (0, node->active.size ());
|
||||
}
|
||||
}
|
||||
|
||||
TEST (active_difficulty, recalculate_work)
|
||||
{
|
||||
nano::system system;
|
||||
|
|
|
@ -257,6 +257,7 @@ TEST (toml, daemon_config_deserialize_no_defaults)
|
|||
work_threads = 999
|
||||
work_watcher_period = 999
|
||||
max_work_generate_multiplier = 1.0
|
||||
frontiers_confirmation = "always"
|
||||
[node.diagnostics.txn_tracking]
|
||||
enable = true
|
||||
ignore_writes_below_block_processor_max_time = false
|
||||
|
@ -369,6 +370,7 @@ TEST (toml, daemon_config_deserialize_no_defaults)
|
|||
ASSERT_NE (conf.node.io_threads, defaults.node.io_threads);
|
||||
ASSERT_NE (conf.node.lmdb_max_dbs, defaults.node.lmdb_max_dbs);
|
||||
ASSERT_NE (conf.node.max_work_generate_multiplier, defaults.node.max_work_generate_multiplier);
|
||||
ASSERT_NE (conf.node.frontiers_confirmation, defaults.node.frontiers_confirmation);
|
||||
ASSERT_NE (conf.node.network_threads, defaults.node.network_threads);
|
||||
ASSERT_NE (conf.node.work_watcher_period, defaults.node.work_watcher_period);
|
||||
ASSERT_NE (conf.node.online_weight_minimum, defaults.node.online_weight_minimum);
|
||||
|
@ -551,4 +553,18 @@ TEST (toml, daemon_config_deserialize_errors)
|
|||
conf.deserialize_toml (toml);
|
||||
|
||||
ASSERT_EQ (toml.get_error ().get_message (), "max_work_generate_multiplier must be greater than or equal to 1");
|
||||
|
||||
std::stringstream ss_frontiers_confirmation;
|
||||
ss_frontiers_confirmation << R"toml(
|
||||
[node]
|
||||
frontiers_confirmation = "randomstring"
|
||||
)toml";
|
||||
|
||||
nano::tomlconfig toml2;
|
||||
toml2.read (ss_frontiers_confirmation);
|
||||
nano::daemon_config conf2;
|
||||
conf2.deserialize_toml (toml2);
|
||||
|
||||
ASSERT_EQ (toml2.get_error ().get_message (), "frontiers_confirmation value is invalid (available: always, auto, disabled)");
|
||||
ASSERT_EQ (conf2.node.frontiers_confirmation, nano::frontiers_confirmation_mode::invalid);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ nano::active_transactions::active_transactions (nano::node & node_a) :
|
|||
node (node_a),
|
||||
multipliers_cb (20, 1.),
|
||||
trended_active_difficulty (node.network_params.network.publish_threshold),
|
||||
next_frontier_check (steady_clock::now () + (node_a.flags.delay_frontier_confirmation_height_updating ? 60s : 0s)),
|
||||
next_frontier_check (steady_clock::now ()),
|
||||
thread ([this]() {
|
||||
nano::thread_role::set (nano::thread_role::name::request_loop);
|
||||
request_loop ();
|
||||
|
@ -35,8 +35,10 @@ void nano::active_transactions::confirm_frontiers (nano::transaction const & tra
|
|||
{
|
||||
// Limit maximum count of elections to start
|
||||
bool representative (node.config.enable_voting && node.wallets.reps_count > 0);
|
||||
/* Check less frequently for non-representative nodes */
|
||||
auto representative_factor = representative ? 3min : 15min;
|
||||
bool half_princpal_representative (representative && node.wallets.half_principal_reps_count > 0);
|
||||
/* Check less frequently for regular nodes in auto mode */
|
||||
bool agressive_mode (half_princpal_representative || node.config.frontiers_confirmation == nano::frontiers_confirmation_mode::always);
|
||||
auto agressive_factor = agressive_mode ? 3min : 15min;
|
||||
// Decrease check time for test network
|
||||
auto is_test_network = node.network_params.network.is_test_network ();
|
||||
int test_network_factor = is_test_network ? 1000 : 1;
|
||||
|
@ -46,10 +48,11 @@ void nano::active_transactions::confirm_frontiers (nano::transaction const & tra
|
|||
auto check_time_exceeded = std::chrono::steady_clock::now () >= next_frontier_check;
|
||||
lk.unlock ();
|
||||
auto low_active_elections = roots_size < max_elections;
|
||||
bool wallets_check_required = (!skip_wallets || !priority_wallet_cementable_frontiers.empty ()) && !agressive_mode;
|
||||
// To minimise dropping real-time transactions, set the maximum number of elections
|
||||
// for cementing frontiers to half the total active election maximum.
|
||||
const auto max_active = node.config.active_elections_size / 2;
|
||||
if (roots_size <= max_active && (check_time_exceeded || (!is_test_network && low_active_elections)))
|
||||
if (roots_size <= max_active && (check_time_exceeded || wallets_check_required || (!is_test_network && low_active_elections && agressive_mode)))
|
||||
{
|
||||
// When the number of active elections is low increase max number of elections for setting confirmation height.
|
||||
if (max_active > roots_size + max_elections)
|
||||
|
@ -100,7 +103,7 @@ void nano::active_transactions::confirm_frontiers (nano::transaction const & tra
|
|||
// 4 times slower check if all frontiers were confirmed
|
||||
auto fully_confirmed_factor = frontiers_fully_confirmed ? 4 : 1;
|
||||
// Calculate next check time
|
||||
next_frontier_check = steady_clock::now () + (representative_factor * fully_confirmed_factor / test_network_factor);
|
||||
next_frontier_check = steady_clock::now () + (agressive_factor * fully_confirmed_factor / test_network_factor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,9 +118,10 @@ void nano::active_transactions::request_confirm (std::unique_lock<std::mutex> &
|
|||
std::deque<std::shared_ptr<nano::block>> rebroadcast_bundle;
|
||||
std::deque<std::pair<std::shared_ptr<nano::block>, std::shared_ptr<std::vector<std::shared_ptr<nano::transport::channel>>>>> confirm_req_bundle;
|
||||
|
||||
// Confirm frontiers when there aren't many confirmations already pending and node finished initial bootstrap
|
||||
/* Confirm frontiers when there aren't many confirmations already pending and node finished initial bootstrap
|
||||
In auto mode start confirm only if node contains almost principal representative (half of required for principal weight) */
|
||||
lock_a.unlock ();
|
||||
if (node.pending_confirmation_height.size () < confirmed_frontiers_max_pending_cut_off && node.store.block_count (transaction).sum () >= node.ledger.bootstrap_weight_max_blocks)
|
||||
if (node.config.frontiers_confirmation != nano::frontiers_confirmation_mode::disabled && node.pending_confirmation_height.size () < confirmed_frontiers_max_pending_cut_off && node.store.block_count (transaction).sum () >= node.ledger.bootstrap_weight_max_blocks)
|
||||
{
|
||||
confirm_frontiers (transaction);
|
||||
}
|
||||
|
@ -401,6 +405,10 @@ void nano::active_transactions::prioritize_frontiers_for_confirmation (nano::tra
|
|||
std::lock_guard<std::mutex> lock (node.wallets.mutex);
|
||||
auto wallet_transaction (node.wallets.tx_begin_read ());
|
||||
auto const & items = node.wallets.items;
|
||||
if (items.empty ())
|
||||
{
|
||||
skip_wallets = true;
|
||||
}
|
||||
for (auto item_it = items.cbegin (); item_it != items.cend (); ++item_it)
|
||||
{
|
||||
// Skip this wallet if it has been traversed already while there are others still awaiting
|
||||
|
|
|
@ -98,6 +98,7 @@ nano::error nano::node_config::serialize_toml (nano::tomlconfig & toml) const
|
|||
toml.put ("backup_before_upgrade", backup_before_upgrade, "Backup the ledger database before performing upgrades\ntype:bool");
|
||||
toml.put ("work_watcher_period", work_watcher_period.count (), "Time between checks for confirmation and re-generating higher difficulty work if unconfirmed, for blocks in the work watcher.\ntype:seconds");
|
||||
toml.put ("max_work_generate_multiplier", max_work_generate_multiplier, "Maximum allowed difficulty multiplier for work generation\ntype:double,[1..]");
|
||||
toml.put ("frontiers_confirmation", serialize_frontiers_confirmation (frontiers_confirmation), "Mode for force frontiers confirmation\ntype:string");
|
||||
|
||||
auto work_peers_l (toml.create_array ("work_peers", "A list of \"address:port\" entries to identify work peers"));
|
||||
for (auto i (work_peers.begin ()), n (work_peers.end ()); i != n; ++i)
|
||||
|
@ -319,6 +320,12 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml)
|
|||
toml.get<double> ("max_work_generate_multiplier", max_work_generate_multiplier);
|
||||
max_work_generate_difficulty = nano::difficulty::from_multiplier (max_work_generate_multiplier, network.publish_threshold);
|
||||
|
||||
if (toml.has_key ("frontiers_confirmation"))
|
||||
{
|
||||
auto frontiers_confirmation_l (toml.get<std::string> ("frontiers_confirmation"));
|
||||
frontiers_confirmation = deserialize_frontiers_confirmation (frontiers_confirmation_l);
|
||||
}
|
||||
|
||||
// Validate ranges
|
||||
if (online_weight_quorum > 100)
|
||||
{
|
||||
|
@ -352,6 +359,10 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml)
|
|||
{
|
||||
toml.get_error ().set ("max_work_generate_multiplier must be greater than or equal to 1");
|
||||
}
|
||||
if (frontiers_confirmation == nano::frontiers_confirmation_mode::invalid)
|
||||
{
|
||||
toml.get_error ().set ("frontiers_confirmation value is invalid (available: always, auto, disabled)");
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error const & ex)
|
||||
{
|
||||
|
@ -761,6 +772,41 @@ nano::error nano::node_config::deserialize_json (bool & upgraded_a, nano::jsonco
|
|||
return json.get_error ();
|
||||
}
|
||||
|
||||
std::string nano::node_config::serialize_frontiers_confirmation (nano::frontiers_confirmation_mode mode_a) const
|
||||
{
|
||||
switch (mode_a)
|
||||
{
|
||||
case nano::frontiers_confirmation_mode::always:
|
||||
return "always";
|
||||
case nano::frontiers_confirmation_mode::automatic:
|
||||
return "auto";
|
||||
case nano::frontiers_confirmation_mode::disabled:
|
||||
return "disabled";
|
||||
default:
|
||||
return "auto";
|
||||
}
|
||||
}
|
||||
|
||||
nano::frontiers_confirmation_mode nano::node_config::deserialize_frontiers_confirmation (std::string const & string_a)
|
||||
{
|
||||
if (string_a == "always")
|
||||
{
|
||||
return nano::frontiers_confirmation_mode::always;
|
||||
}
|
||||
else if (string_a == "auto")
|
||||
{
|
||||
return nano::frontiers_confirmation_mode::automatic;
|
||||
}
|
||||
else if (string_a == "disabled")
|
||||
{
|
||||
return nano::frontiers_confirmation_mode::disabled;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nano::frontiers_confirmation_mode::invalid;
|
||||
}
|
||||
}
|
||||
|
||||
nano::account nano::node_config::random_representative ()
|
||||
{
|
||||
assert (!preconfigured_representatives.empty ());
|
||||
|
|
|
@ -17,6 +17,15 @@
|
|||
namespace nano
|
||||
{
|
||||
class tomlconfig;
|
||||
|
||||
enum class frontiers_confirmation_mode : uint8_t
|
||||
{
|
||||
always, // Always confirm frontiers
|
||||
automatic, // Always mode if node contains representative with at least 50% of principal weight, less frequest requests if not
|
||||
disabled, // Do not confirm frontiers
|
||||
invalid
|
||||
};
|
||||
|
||||
/**
|
||||
* Node configuration
|
||||
*/
|
||||
|
@ -84,6 +93,9 @@ public:
|
|||
std::chrono::seconds work_watcher_period{ std::chrono::seconds (5) };
|
||||
double max_work_generate_multiplier{ 64. };
|
||||
uint64_t max_work_generate_difficulty{ nano::network_constants::publish_full_threshold };
|
||||
nano::frontiers_confirmation_mode frontiers_confirmation{ nano::frontiers_confirmation_mode::automatic };
|
||||
std::string serialize_frontiers_confirmation (nano::frontiers_confirmation_mode) const;
|
||||
nano::frontiers_confirmation_mode deserialize_frontiers_confirmation (std::string const &);
|
||||
static unsigned json_version ()
|
||||
{
|
||||
return 18;
|
||||
|
@ -104,7 +116,6 @@ public:
|
|||
bool disable_unchecked_cleanup{ false };
|
||||
bool disable_unchecked_drop{ true };
|
||||
bool fast_bootstrap{ false };
|
||||
bool delay_frontier_confirmation_height_updating{ false };
|
||||
bool read_only{ false };
|
||||
size_t sideband_batch_size{ 512 };
|
||||
size_t block_processor_batch_size{ 0 };
|
||||
|
|
|
@ -808,12 +808,12 @@ nano::public_key nano::wallet::deterministic_insert (nano::transaction const & t
|
|||
{
|
||||
work_ensure (key, key);
|
||||
}
|
||||
auto half_principal_weight (wallets.node.minimum_principal_weight () / 2);
|
||||
auto block_transaction (wallets.node.store.tx_begin_read ());
|
||||
if (wallets.node.ledger.weight (block_transaction, key) >= wallets.node.config.vote_minimum.number ())
|
||||
if (wallets.check_rep (block_transaction, key, half_principal_weight))
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (representatives_mutex);
|
||||
representatives.insert (key);
|
||||
++wallets.reps_count;
|
||||
}
|
||||
}
|
||||
return key;
|
||||
|
@ -852,11 +852,11 @@ nano::public_key nano::wallet::insert_adhoc (nano::transaction const & transacti
|
|||
{
|
||||
work_ensure (key, wallets.node.ledger.latest_root (block_transaction, key));
|
||||
}
|
||||
if (wallets.node.ledger.weight (block_transaction, key) >= wallets.node.config.vote_minimum.number ())
|
||||
auto half_principal_weight (wallets.node.minimum_principal_weight () / 2);
|
||||
if (wallets.check_rep (block_transaction, key, half_principal_weight))
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (representatives_mutex);
|
||||
representatives.insert (key);
|
||||
++wallets.reps_count;
|
||||
}
|
||||
}
|
||||
return key;
|
||||
|
@ -1864,10 +1864,28 @@ void nano::wallets::clear_send_ids (nano::transaction const & transaction_a)
|
|||
assert (status == 0);
|
||||
}
|
||||
|
||||
bool nano::wallets::check_rep (nano::transaction const & transaction_a, nano::account const & account_a, nano::uint128_t const & half_principal_weight_a)
|
||||
{
|
||||
bool result (false);
|
||||
auto weight (node.ledger.weight (transaction_a, account_a));
|
||||
if (weight >= node.config.vote_minimum.number ())
|
||||
{
|
||||
result = true;
|
||||
++reps_count;
|
||||
if (weight >= half_principal_weight_a)
|
||||
{
|
||||
++half_principal_reps_count;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void nano::wallets::compute_reps ()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
reps_count = 0;
|
||||
half_principal_reps_count = 0;
|
||||
auto half_principal_weight (node.minimum_principal_weight () / 2);
|
||||
auto ledger_transaction (node.store.tx_begin_read ());
|
||||
auto transaction (tx_begin_read ());
|
||||
for (auto i (items.begin ()), n (items.end ()); i != n; ++i)
|
||||
|
@ -1877,10 +1895,9 @@ void nano::wallets::compute_reps ()
|
|||
for (auto ii (wallet.store.begin (transaction)), nn (wallet.store.end ()); ii != nn; ++ii)
|
||||
{
|
||||
auto account (ii->first);
|
||||
if (node.ledger.weight (ledger_transaction, account) >= node.config.vote_minimum.number ())
|
||||
if (check_rep (ledger_transaction, account, half_principal_weight))
|
||||
{
|
||||
representatives_l.insert (account);
|
||||
++reps_count;
|
||||
}
|
||||
}
|
||||
std::lock_guard<std::mutex> representatives_lock (wallet.representatives_mutex);
|
||||
|
|
|
@ -199,6 +199,7 @@ public:
|
|||
bool exists (nano::transaction const &, nano::public_key const &);
|
||||
void stop ();
|
||||
void clear_send_ids (nano::transaction const &);
|
||||
bool check_rep (nano::transaction const &, nano::account const &, nano::uint128_t const &);
|
||||
void compute_reps ();
|
||||
void ongoing_compute_reps ();
|
||||
void split_if_needed (nano::transaction &, nano::block_store &);
|
||||
|
@ -221,6 +222,7 @@ public:
|
|||
static nano::uint128_t const generate_priority;
|
||||
static nano::uint128_t const high_priority;
|
||||
std::atomic<uint64_t> reps_count{ 0 };
|
||||
std::atomic<uint64_t> half_principal_reps_count{ 0 }; // Representatives with at least 50% of principal representative requirements
|
||||
|
||||
/** Start read-write transaction */
|
||||
nano::write_transaction tx_begin_write ();
|
||||
|
|
|
@ -5863,9 +5863,9 @@ TEST (rpc, confirmation_height_currently_processing)
|
|||
{
|
||||
// The chains should be longer than the batch_write_size to test the amount of blocks confirmed is correct.
|
||||
nano::system system;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto node = system.add_node (nano::node_config (24000, system.logging), node_flags);
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node = system.add_node (node_config);
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
|
||||
// Do enough blocks to reliably call RPC before the confirmation height has finished
|
||||
|
|
|
@ -462,9 +462,8 @@ TEST (confirmation_height, many_accounts_single_confirmation)
|
|||
nano::system system;
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.online_weight_minimum = 100;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto node = system.add_node (node_config, node_flags);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node = system.add_node (node_config);
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
|
||||
// As this test can take a while extend the next frontier check
|
||||
|
@ -534,9 +533,8 @@ TEST (confirmation_height, many_accounts_many_confirmations)
|
|||
nano::system system;
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.online_weight_minimum = 100;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto node = system.add_node (node_config, node_flags);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node = system.add_node (node_config);
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
|
||||
// As this test can take a while extend the next frontier check
|
||||
|
@ -580,9 +578,9 @@ TEST (confirmation_height, many_accounts_many_confirmations)
|
|||
TEST (confirmation_height, long_chains)
|
||||
{
|
||||
nano::system system;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto node = system.add_node (nano::node_config (24000, system.logging), node_flags);
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node = system.add_node (node_config);
|
||||
nano::keypair key1;
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
nano::block_hash latest (node->latest (nano::test_genesis_key.pub));
|
||||
|
@ -673,9 +671,8 @@ TEST (confirmation_height, prioritize_frontiers_overwrite)
|
|||
{
|
||||
nano::system system;
|
||||
nano::node_config node_config (24000, system.logging);
|
||||
nano::node_flags node_flags;
|
||||
node_flags.delay_frontier_confirmation_height_updating = true;
|
||||
auto node = system.add_node (node_config, node_flags);
|
||||
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
|
||||
auto node = system.add_node (node_config);
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
|
||||
// As this test can take a while extend the next frontier check
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue