Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Confirm delta #2884

Merged
merged 12 commits into from
Nov 6, 2020
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion nano/core_test/bootstrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ TEST (bootstrap_processor, frontiers_unconfirmed_threshold)
nano::keypair key1, key2;
// Generating invalid chain
auto threshold (node1->gap_cache.bootstrap_threshold () + 1);
ASSERT_LT (threshold, node1->config.online_weight_minimum.number ());
ASSERT_LT (threshold, node1->online_reps.delta ());
auto send1 (std::make_shared<nano::state_block> (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - threshold, key1.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (genesis.hash ())));
ASSERT_EQ (nano::process_result::progress, node1->process (*send1).code);
auto send2 (std::make_shared<nano::state_block> (nano::dev_genesis_key.pub, send1->hash (), nano::dev_genesis_key.pub, nano::genesis_amount - threshold - nano::Gxrb_ratio, key2.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (send1->hash ())));
Expand Down
14 changes: 7 additions & 7 deletions nano/core_test/confirmation_height.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ TEST (confirmation_height, multiple_accounts)
nano::block_hash latest1 (system.nodes[0]->latest (nano::dev_genesis_key.pub));

// Send to all accounts
nano::send_block send1 (latest1, key1.pub, system.nodes.front ()->config.online_weight_minimum.number () + 300, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (latest1));
nano::send_block send2 (send1.hash (), key2.pub, system.nodes.front ()->config.online_weight_minimum.number () + 200, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (send1.hash ()));
nano::send_block send3 (send2.hash (), key3.pub, system.nodes.front ()->config.online_weight_minimum.number () + 100, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (send2.hash ()));
nano::send_block send1 (latest1, key1.pub, node->online_reps.delta () + 300, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (latest1));
nano::send_block send2 (send1.hash (), key2.pub, node->online_reps.delta () + 200, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (send1.hash ()));
nano::send_block send3 (send2.hash (), key3.pub, node->online_reps.delta () + 100, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (send2.hash ()));

// Open all accounts
nano::open_block open1 (send1.hash (), nano::genesis_account, key1.pub, key1.prv, key1.pub, *system.work.generate (key1.pub));
Expand Down Expand Up @@ -393,7 +393,7 @@ TEST (confirmation_height, send_receive_between_2_accounts)
nano::keypair key1;
nano::block_hash latest (node->latest (nano::dev_genesis_key.pub));

nano::send_block send1 (latest, key1.pub, node->config.online_weight_minimum.number () + 2, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (latest));
nano::send_block send1 (latest, key1.pub, node->online_reps.delta () + 2, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (latest));

nano::open_block open1 (send1.hash (), nano::genesis_account, key1.pub, key1.prv, key1.pub, *system.work.generate (key1.pub));
nano::send_block send2 (open1.hash (), nano::genesis_account, 1000, key1.prv, key1.pub, *system.work.generate (open1.hash ()));
Expand All @@ -404,11 +404,11 @@ TEST (confirmation_height, send_receive_between_2_accounts)
nano::receive_block receive2 (receive1.hash (), send3.hash (), nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (receive1.hash ()));
nano::receive_block receive3 (receive2.hash (), send4.hash (), nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (receive2.hash ()));

nano::send_block send5 (receive3.hash (), key1.pub, node->config.online_weight_minimum.number () + 1, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (receive3.hash ()));
nano::send_block send5 (receive3.hash (), key1.pub, node->online_reps.delta () + 1, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (receive3.hash ()));
auto receive4 = std::make_shared<nano::receive_block> (send4.hash (), send5.hash (), key1.prv, key1.pub, *system.work.generate (send4.hash ()));
// Unpocketed send
nano::keypair key2;
nano::send_block send6 (send5.hash (), key2.pub, node->config.online_weight_minimum.number (), nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (send5.hash ()));
nano::send_block send6 (send5.hash (), key2.pub, node->online_reps.delta (), nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (send5.hash ()));
{
auto transaction = node->store.tx_begin_write ();
ASSERT_EQ (nano::process_result::progress, node->ledger.process (transaction, send1).code);
Expand Down Expand Up @@ -487,7 +487,7 @@ TEST (confirmation_height, send_receive_self)

// Send to another account to prevent automatic receiving on the genesis account
nano::keypair key1;
nano::send_block send4 (receive3->hash (), key1.pub, node->config.online_weight_minimum.number (), nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (receive3->hash ()));
nano::send_block send4 (receive3->hash (), key1.pub, node->online_reps.delta (), nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (receive3->hash ()));
{
auto transaction = node->store.tx_begin_write ();
ASSERT_EQ (nano::process_result::progress, node->ledger.process (transaction, send1).code);
Expand Down
152 changes: 152 additions & 0 deletions nano/core_test/election.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,155 @@ TEST (election, construction)
auto election = node.active.insert (genesis.open).election;
election->transition_active ();
}

TEST (election, quorum_minimum_flip_success)
{
nano::system system;
nano::node_config node_config (nano::get_available_port (), system.logging);
node_config.online_weight_minimum = nano::genesis_amount;
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto & node1 = *system.add_node (node_config);
nano::keypair key1;
nano::block_builder builder;
auto send1 = builder.state ()
.account (nano::dev_genesis_key.pub)
.previous (nano::genesis_hash)
.representative (nano::dev_genesis_key.pub)
.balance (node1.online_reps.delta ())
.link (key1.pub)
.work (0)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.build_shared ();
node1.work_generate_blocking (*send1);
nano::keypair key2;
auto send2 = builder.state ()
.account (nano::dev_genesis_key.pub)
.previous (nano::genesis_hash)
.representative (nano::dev_genesis_key.pub)
.balance (node1.online_reps.delta ())
.link (key2.pub)
.work (0)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.build_shared ();
node1.work_generate_blocking (*send2);
node1.process_active (send1);
node1.process_active (send2);
node1.block_processor.flush ();
auto election{ node1.active.insert (send1) };
ASSERT_FALSE (election.inserted);
ASSERT_NE (nullptr, election.election);
ASSERT_EQ (2, election.election->blocks ().size ());
auto vote1 (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send2));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
node1.block_processor.flush ();
ASSERT_NE (nullptr, node1.block (send2->hash ()));
ASSERT_TRUE (election.election->confirmed ());
}

TEST (election, quorum_minimum_flip_fail)
{
nano::system system;
nano::node_config node_config (nano::get_available_port (), system.logging);
node_config.online_weight_minimum = nano::genesis_amount;
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto & node1 = *system.add_node (node_config);
nano::keypair key1;
nano::block_builder builder;
auto send1 = builder.state ()
.account (nano::dev_genesis_key.pub)
.previous (nano::genesis_hash)
.representative (nano::dev_genesis_key.pub)
.balance (node1.online_reps.delta () - 1)
.link (key1.pub)
.work (0)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.build_shared ();
node1.work_generate_blocking (*send1);
nano::keypair key2;
auto send2 = builder.state ()
.account (nano::dev_genesis_key.pub)
.previous (nano::genesis_hash)
.representative (nano::dev_genesis_key.pub)
.balance (node1.online_reps.delta () - 1)
.link (key2.pub)
.work (0)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.build_shared ();
node1.work_generate_blocking (*send2);
node1.process_active (send1);
node1.process_active (send2);
node1.block_processor.flush ();
auto election{ node1.active.insert (send1) };
ASSERT_FALSE (election.inserted);
ASSERT_NE (nullptr, election.election);
ASSERT_EQ (2, election.election->blocks ().size ());
auto vote1 (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send2));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
node1.block_processor.flush ();
ASSERT_NE (nullptr, node1.block (send1->hash ()));
ASSERT_FALSE (election.election->confirmed ());
}

TEST (election, quorum_minimum_confirm_success)
{
nano::system system;
nano::node_config node_config (nano::get_available_port (), system.logging);
node_config.online_weight_minimum = nano::genesis_amount;
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto & node1 = *system.add_node (node_config);
nano::keypair key1;
nano::block_builder builder;
auto send1 = builder.state ()
.account (nano::dev_genesis_key.pub)
.previous (nano::genesis_hash)
.representative (nano::dev_genesis_key.pub)
.balance (node1.online_reps.delta ())
.link (key1.pub)
.work (0)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.build_shared ();
node1.work_generate_blocking (*send1);
node1.process_active (send1);
node1.block_processor.flush ();
auto election{ node1.active.insert (send1) };
ASSERT_FALSE (election.inserted);
ASSERT_NE (nullptr, election.election);
ASSERT_EQ (1, election.election->blocks ().size ());
auto vote1 (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send1));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
node1.block_processor.flush ();
ASSERT_NE (nullptr, node1.block (send1->hash ()));
ASSERT_TRUE (election.election->confirmed ());
}

TEST (election, quorum_minimum_confirm_fail)
{
nano::system system;
nano::node_config node_config (nano::get_available_port (), system.logging);
node_config.online_weight_minimum = nano::genesis_amount;
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto & node1 = *system.add_node (node_config);
nano::keypair key1;
nano::block_builder builder;
auto send1 = builder.state ()
.account (nano::dev_genesis_key.pub)
.previous (nano::genesis_hash)
.representative (nano::dev_genesis_key.pub)
.balance (node1.online_reps.delta () - 1)
.link (key1.pub)
.work (0)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.build_shared ();
node1.work_generate_blocking (*send1);
node1.process_active (send1);
node1.block_processor.flush ();
auto election{ node1.active.insert (send1) };
ASSERT_FALSE (election.inserted);
ASSERT_NE (nullptr, election.election);
ASSERT_EQ (1, election.election->blocks ().size ());
auto vote1 (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send1));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
node1.block_processor.flush ();
ASSERT_NE (nullptr, node1.block (send1->hash ()));
ASSERT_FALSE (election.election->confirmed ());
}
29 changes: 21 additions & 8 deletions nano/core_test/ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -837,25 +837,38 @@ TEST (votes, add_existing)
{
nano::system system;
nano::node_config node_config (nano::get_available_port (), system.logging);
node_config.online_weight_minimum = std::numeric_limits<nano::uint128_t>::max ();
node_config.online_weight_minimum = nano::genesis_amount;
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::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0));
nano::block_builder builder;
std::shared_ptr<nano::block> send1 = builder.state ()
.account (nano::dev_genesis_key.pub)
.previous (nano::genesis_hash)
.representative (nano::dev_genesis_key.pub) // No representative, blocks can't confirm
.balance (nano::genesis_amount / 2 - nano::Gxrb_ratio)
.link (key1.pub)
.work (0)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.build ();
node1.work_generate_blocking (*send1);
{
auto transaction (node1.store.tx_begin_write ());
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
}
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (node1.store.tx_begin_write (), *send1).code);
auto election1 = node1.active.insert (send1);
auto vote1 (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send1));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
// Block is already processed from vote
ASSERT_TRUE (node1.active.publish (send1));
ASSERT_EQ (1, election1.election->last_votes[nano::dev_genesis_key.pub].timestamp);
nano::keypair key2;
auto send2 (std::make_shared<nano::send_block> (genesis.hash (), key2.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0));
std::shared_ptr<nano::block> send2 = builder.state ()
.account (nano::dev_genesis_key.pub)
.previous (nano::genesis_hash)
.representative (nano::dev_genesis_key.pub) // No representative, blocks can't confirm
.balance (nano::genesis_amount / 2 - nano::Gxrb_ratio)
.link (key2.pub)
.work (0)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.build ();
node1.work_generate_blocking (*send2);
auto vote2 (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 2, send2));
// Pretend we've waited the timeout
Expand Down
49 changes: 13 additions & 36 deletions nano/core_test/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,14 +229,14 @@ TEST (node, quick_confirm)
auto send = nano::send_block_builder ()
.previous (previous)
.destination (key.pub)
.balance (node1.config.online_weight_minimum.number () + 1)
.balance (node1.online_reps.delta () + 1)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.work (*system.work.generate (previous))
.build_shared ();
node1.process_active (send);
ASSERT_TIMELY (10s, !node1.balance (key.pub).is_zero ());
ASSERT_EQ (node1.balance (nano::dev_genesis_key.pub), node1.config.online_weight_minimum.number () + 1);
ASSERT_EQ (node1.balance (key.pub), genesis_start_balance - (node1.config.online_weight_minimum.number () + 1));
ASSERT_EQ (node1.balance (nano::dev_genesis_key.pub), node1.online_reps.delta () + 1);
ASSERT_EQ (node1.balance (key.pub), genesis_start_balance - (node1.online_reps.delta () + 1));
}

TEST (node, node_receive_quorum)
Expand Down Expand Up @@ -2415,15 +2415,19 @@ TEST (node, online_reps)
nano::system system (1);
auto & node1 (*system.nodes[0]);
// 1 sample of minimum weight
ASSERT_EQ (node1.config.online_weight_minimum, node1.online_reps.online_stake ());
ASSERT_EQ (node1.config.online_weight_minimum, node1.online_reps.trended ());
auto vote (std::make_shared<nano::vote> ());
ASSERT_EQ (0, node1.online_reps.online ());
node1.online_reps.observe (nano::dev_genesis_key.pub);
ASSERT_EQ (nano::genesis_amount, node1.online_reps.online ());
// 1 minimum, 1 maximum
ASSERT_EQ (node1.config.online_weight_minimum, node1.online_reps.trended ());
node1.online_reps.sample ();
ASSERT_EQ (nano::genesis_amount, node1.online_reps.online_stake ());
ASSERT_EQ (nano::genesis_amount, node1.online_reps.trended ());
node1.online_reps.clear ();
// 2 minimum, 1 maximum
node1.online_reps.sample ();
ASSERT_EQ (node1.config.online_weight_minimum, node1.online_reps.online_stake ());
ASSERT_EQ (node1.config.online_weight_minimum, node1.online_reps.trended ());
}

TEST (node, block_confirm)
Expand Down Expand Up @@ -2537,8 +2541,8 @@ TEST (node, confirm_quorum)
auto & node1 (*system.nodes[0]);
nano::genesis genesis;
system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv);
// Put greater than online_weight_minimum in pending so quorum can't be reached
nano::amount new_balance (node1.config.online_weight_minimum.number () - nano::Gxrb_ratio);
// Put greater than node.delta () in pending so quorum can't be reached
nano::amount new_balance (node1.online_reps.delta () - nano::Gxrb_ratio);
auto send1 = nano::state_block_builder ()
.account (nano::dev_genesis_key.pub)
.previous (genesis.hash ())
Expand Down Expand Up @@ -3855,7 +3859,7 @@ TEST (node, rollback_vote_self)
auto & node = *system.add_node (flags);
nano::state_block_builder builder;
nano::keypair key;
auto weight = node.config.online_weight_minimum.number ();
auto weight = node.online_reps.delta ();
auto send1 = builder.make_block ()
.account (nano::dev_genesis_key.pub)
.previous (nano::genesis_hash)
Expand Down Expand Up @@ -4490,33 +4494,6 @@ TEST (rep_crawler, local)
}
}

TEST (online_reps, backup)
{
nano::logger_mt logger;
auto store = nano::make_store (logger, nano::unique_path ());
ASSERT_TRUE (!store->init_error ());
nano::stat stats;
nano::ledger ledger (*store, stats);
{
nano::genesis genesis;
auto transaction (store->tx_begin_write ());
store->initialize (transaction, genesis, ledger.cache);
}
nano::network_params params;
nano::online_reps online_reps (ledger, params, 0);
ASSERT_EQ (0, online_reps.list ().size ());
online_reps.observe (nano::dev_genesis_key.pub);
// The reported list of online reps is the union of the current list and the backup list, which changes when sampling
ASSERT_EQ (1, online_reps.list ().size ());
ASSERT_TRUE (online_reps.online_stake ().is_zero ());
online_reps.sample ();
ASSERT_EQ (1, online_reps.list ().size ());
// The trend is also correctly updated
ASSERT_EQ (nano::genesis_amount, online_reps.online_stake ());
online_reps.sample ();
ASSERT_EQ (0, online_reps.list ().size ());
}

namespace
{
void add_required_children_node_config_tree (nano::jsonconfig & tree)
Expand Down
Loading