Skip to content

Commit

Permalink
tracking V23develop merging (#31)
Browse files Browse the repository at this point in the history
* Redesigning vote_processor::flush test to not directly modify timestamp field. The only functional change is that each vote is now its own object rather than modifying an existing one.

* Removing timestamp changing and re-signing as this is re-testing something that's already tested above, signature correctness with respect to vote contents.

* Encapsulating vote::timestamp field as vote::timestamp_m behind vote::timestamp ().

* Add nano::vote::timestamp_min and nano::vote::timestamp_max variables and use these constants in tests.

* Formatting.

* Implement "accounts_representatives" RPC (nanocurrency#3409) (nanocurrency#3412)

* Fix crash in nano_wallet when ran with --config option (nanocurrency#3546)

* Fix conflicts.add_two unit test (nanocurrency#3545)

* Fix conflicts.add_two unit test

* Style fixes

* Address code review

Co-authored-by: clemahieu <[email protected]>
Co-authored-by: Shryder <[email protected]>
Co-authored-by: theohax <[email protected]>
  • Loading branch information
4 people authored Nov 6, 2021
1 parent f2cb6ed commit c6c6451
Show file tree
Hide file tree
Showing 16 changed files with 231 additions and 92 deletions.
22 changes: 11 additions & 11 deletions nano/core_test/active_transactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ TEST (active_transactions, inactive_votes_cache)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*system.work.generate (latest))
.build_shared ();
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), std::vector<nano::block_hash> (1, send->hash ())));
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, std::vector<nano::block_hash> (1, send->hash ())));
node.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node));
ASSERT_TIMELY (5s, node.active.inactive_votes_cache_size () == 1);
node.process_active (send);
Expand Down Expand Up @@ -252,7 +252,7 @@ TEST (active_transactions, inactive_votes_cache_fork)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*system.work.generate (latest))
.build_shared ();
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), std::vector<nano::block_hash> (1, send1->hash ())));
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, std::vector<nano::block_hash> (1, send1->hash ())));
node.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node));
auto channel1 (node.network.udp_channels.create (node.network.endpoint ()));
ASSERT_TIMELY (5s, node.active.inactive_votes_cache_size () == 1);
Expand Down Expand Up @@ -306,13 +306,13 @@ TEST (active_transactions, inactive_votes_cache_existing_vote)
ASSERT_NE (nullptr, election);
ASSERT_GT (node.weight (key.pub), node.minimum_principal_weight ());
// Insert vote
auto vote1 (std::make_shared<nano::vote> (key.pub, key.prv, 1, std::vector<nano::block_hash> (1, send->hash ())));
auto vote1 (std::make_shared<nano::vote> (key.pub, key.prv, nano::vote::timestamp_min * 1, std::vector<nano::block_hash> (1, send->hash ())));
node.vote_processor.vote (vote1, std::make_shared<nano::transport::channel_loopback> (node));
ASSERT_TIMELY (5s, election->votes ().size () == 2);
ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::vote_new));
auto last_vote1 (election->votes ()[key.pub]);
ASSERT_EQ (send->hash (), last_vote1.hash);
ASSERT_EQ (1, last_vote1.timestamp);
ASSERT_EQ (nano::vote::timestamp_min * 1, last_vote1.timestamp);
// Attempt to change vote with inactive_votes_cache
nano::unique_lock<nano::mutex> active_lock (node.active.mutex);
node.active.add_inactive_votes_cache (active_lock, send->hash (), key.pub, 0);
Expand Down Expand Up @@ -459,7 +459,7 @@ TEST (active_transactions, inactive_votes_cache_election_start)
// Only open1 & open2 blocks elections should start (send4 is missing previous block in ledger)
ASSERT_TIMELY (5s, 2 == node.active.size ());
// Confirm elections with weight quorum
auto vote0 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), hashes)); // Final vote for confirmation
auto vote0 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, hashes)); // Final vote for confirmation
node.vote_processor.vote (vote0, std::make_shared<nano::transport::channel_loopback> (node));
ASSERT_TIMELY (5s, node.active.empty ());
ASSERT_TIMELY (5s, 5 == node.ledger.cache.cemented_count);
Expand Down Expand Up @@ -519,15 +519,15 @@ TEST (active_transactions, vote_replays)
nano::blocks_confirm (node, { send1, open1 });
ASSERT_EQ (2, node.active.size ());
// First vote is not a replay and confirms the election, second vote should be a replay since the election has confirmed but not yet removed
auto vote_send1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), send1));
auto vote_send1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, send1));
ASSERT_EQ (nano::vote_code::vote, node.active.vote (vote_send1));
ASSERT_EQ (2, node.active.size ());
ASSERT_EQ (nano::vote_code::replay, node.active.vote (vote_send1));
// Wait until the election is removed, at which point the vote is still a replay since it's been recently confirmed
ASSERT_TIMELY (3s, node.active.size () == 1);
ASSERT_EQ (nano::vote_code::replay, node.active.vote (vote_send1));
// Open new account
auto vote_open1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), open1));
auto vote_open1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, open1));
ASSERT_EQ (nano::vote_code::vote, node.active.vote (vote_open1));
ASSERT_EQ (nano::vote_code::replay, node.active.vote (vote_open1));
ASSERT_TIMELY (3s, node.active.empty ());
Expand All @@ -547,7 +547,7 @@ TEST (active_transactions, vote_replays)
node.process_active (send2);
nano::blocks_confirm (node, { send2 });
ASSERT_EQ (1, node.active.size ());
auto vote1_send2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), send2));
auto vote1_send2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, send2));
auto vote2_send2 (std::make_shared<nano::vote> (key.pub, key.prv, 0, send2));
ASSERT_EQ (nano::vote_code::vote, node.active.vote (vote2_send2));
ASSERT_EQ (1, node.active.size ());
Expand Down Expand Up @@ -690,7 +690,7 @@ TEST (active_transactions, republish_winner)
node1.block_processor.flush ();
auto election = node1.active.election (fork->qualified_root ());
ASSERT_NE (nullptr, election);
auto vote = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), std::vector<nano::block_hash>{ fork->hash () });
auto vote = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, std::vector<nano::block_hash>{ fork->hash () });
node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node1));
node1.vote_processor.flush ();
node1.block_processor.flush ();
Expand Down Expand Up @@ -798,7 +798,7 @@ TEST (active_transactions, fork_replacement_tally)
.build_shared ();
node1.process_active (open);
// Confirmation
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), std::vector<nano::block_hash>{ send->hash (), open->hash () }));
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, std::vector<nano::block_hash>{ send->hash (), open->hash () }));
node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node1));
}
node1.block_processor.flush ();
Expand Down Expand Up @@ -981,7 +981,7 @@ TEST (active_transactions, conflicting_block_vote_existing_election)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*system.work.generate (nano::dev::genesis->hash ()))
.build_shared ();
auto vote_fork (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), fork));
auto vote_fork (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, fork));

ASSERT_EQ (nano::process_result::progress, node.process_local (send).code);
node.scheduler.flush ();
Expand Down
95 changes: 94 additions & 1 deletion nano/core_test/conflicts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,99 @@ TEST (conflicts, DISABLED_add_two)
ASSERT_EQ (2, node1.active.size ());
}

TEST (conflicts, add_two)
{
nano::system system{};
auto const & node = system.add_node ();

// define a functor that sends from given account to given destination,
// optionally force-confirming the send blocks *and* receiving on the destination account;
// the functor returns a pair of the send and receive blocks created or nullptrs if something failed
//
auto const do_send = [&node] (auto const & previous, auto const & from, auto const & to, bool forceConfirm = true)
-> std::pair<std::shared_ptr<nano::block>, std::shared_ptr<nano::block>> {
auto send = std::make_shared<nano::send_block> (previous->hash (), to.pub, 0, from.prv, from.pub, 0);
node->work_generate_blocking (*send);

if (nano::process_result::progress != node->process (*send).code)
{
send.reset ();
return std::make_pair (std::move (send), std::move (send));
}

if (forceConfirm)
{
node->block_confirm (send);
node->active.election (send->qualified_root ())->force_confirm ();

auto receive = std::make_shared<nano::open_block> (send->hash (), to.pub, to.pub, to.prv, to.pub, 0);
node->work_generate_blocking (*receive);

if (nano::process_result::progress != node->process (*receive).code)
{
return std::make_pair (nullptr, nullptr);
}

node->block_confirm (receive);
node->active.election (receive->qualified_root ())->force_confirm ();

return std::make_pair (std::move (send), std::move (receive));
}

return std::make_pair (std::move (send), nullptr);
};

system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv);

// send from genesis to account1 and receive it on account1
//
nano::keypair account1{};
auto const [send1, receive1] = do_send (nano::dev::genesis, nano::dev::genesis_key, account1);
ASSERT_TRUE (send1 && receive1);
// both blocks having been fully confirmed, we expect 1 (genesis) + 2 (send/receive) = 3 cemented blocks
//
ASSERT_TIMELY (3s, 3 == node->ledger.cache.cemented_count);

// send from genesis to account2 and receive it on account2
//
nano::keypair account2{};
auto const [send2, receive2] = do_send (send1, nano::dev::genesis_key, account2);
ASSERT_TRUE (send2 && receive2);
ASSERT_TIMELY (3s, 5 == node->ledger.cache.cemented_count);

// send from account1 to account3 but do not receive it on account3 and do not force confirm the send block
//
nano::keypair account3{};
{
auto const [send3, _] = do_send (receive1, account1, account3, false);
ASSERT_TRUE (send3);
// expect the number of cemented blocks not to have changed since the last operation
//
ASSERT_TIMELY (3s, 5 == node->ledger.cache.cemented_count);
}

// send from account1 to account3 but do not receive it on account3 and do not force confirm the send block
//
{
auto const [send4, _] = do_send (receive2, account2, account3, false);
ASSERT_TRUE (send4);
// expect the number of cemented blocks not to have changed since the last operation
//
ASSERT_TIMELY (3s, 5 == node->ledger.cache.cemented_count);
}

// activate elections for the previous two send blocks (to account3) that we did not forcefully confirm
//
node->scheduler.activate (account3.pub, node->store.tx_begin_read ());
node->scheduler.flush ();

// wait 3s before asserting just to make sure there would be enough time
// for the Active Elections Container to evict both elections in case they would wrongfully get confirmed
//
std::this_thread::sleep_for (3s);
ASSERT_EQ (2, node->active.size ());
}

TEST (vote_uniquer, null)
{
nano::block_uniquer block_uniquer;
Expand Down Expand Up @@ -144,7 +237,7 @@ TEST (vote_uniquer, cleanup)
nano::vote_uniquer uniquer (block_uniquer);
nano::keypair key;
auto vote1 (std::make_shared<nano::vote> (key.pub, key.prv, 0, std::make_shared<nano::state_block> (0, 0, 0, 0, 0, key.prv, key.pub, 0)));
auto vote2 (std::make_shared<nano::vote> (key.pub, key.prv, 1, std::make_shared<nano::state_block> (0, 0, 0, 0, 0, key.prv, key.pub, 0)));
auto vote2 (std::make_shared<nano::vote> (key.pub, key.prv, nano::vote::timestamp_min * 1, std::make_shared<nano::state_block> (0, 0, 0, 0, 0, key.prv, key.pub, 0)));
auto vote3 (uniquer.unique (vote1));
auto vote4 (uniquer.unique (vote2));
vote2.reset ();
Expand Down
12 changes: 6 additions & 6 deletions nano/core_test/election.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ TEST (election, quorum_minimum_flip_success)
auto election = node1.active.election (send1->qualified_root ());
ASSERT_NE (nullptr, election);
ASSERT_EQ (2, election->blocks ().size ());
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), send2));
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, send2));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
node1.block_processor.flush ();
ASSERT_NE (nullptr, node1.block (send2->hash ()));
Expand Down Expand Up @@ -101,7 +101,7 @@ TEST (election, quorum_minimum_flip_fail)
auto election = node1.active.election (send1->qualified_root ());
ASSERT_NE (nullptr, election);
ASSERT_EQ (2, election->blocks ().size ());
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), send2));
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, send2));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
node1.block_processor.flush ();
ASSERT_NE (nullptr, node1.block (send1->hash ()));
Expand Down Expand Up @@ -134,7 +134,7 @@ TEST (election, quorum_minimum_confirm_success)
auto election = node1.active.election (send1->qualified_root ());
ASSERT_NE (nullptr, election);
ASSERT_EQ (1, election->blocks ().size ());
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), send1));
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, send1));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
node1.block_processor.flush ();
ASSERT_NE (nullptr, node1.block (send1->hash ()));
Expand Down Expand Up @@ -167,7 +167,7 @@ TEST (election, quorum_minimum_confirm_fail)
auto election = node1.active.election (send1->qualified_root ());
ASSERT_NE (nullptr, election);
ASSERT_EQ (1, election->blocks ().size ());
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), send1));
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, send1));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
node1.block_processor.flush ();
ASSERT_NE (nullptr, node1.block (send1->hash ()));
Expand Down Expand Up @@ -241,9 +241,9 @@ TEST (election, DISABLED_quorum_minimum_update_weight_before_quorum_checks)
auto election = node1.active.election (send1->qualified_root ());
ASSERT_NE (nullptr, election);
ASSERT_EQ (1, election->blocks ().size ());
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), send1));
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, send1));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
auto vote2 (std::make_shared<nano::vote> (key1.pub, key1.prv, std::numeric_limits<uint64_t>::max (), send1));
auto vote2 (std::make_shared<nano::vote> (key1.pub, key1.prv, nano::vote::timestamp_max, send1));
auto channel = node1.network.find_channel (node2.network.endpoint ());
ASSERT_NE (channel, nullptr);
ASSERT_TIMELY (10s, !node1.rep_crawler.response (channel, vote2));
Expand Down
Loading

0 comments on commit c6c6451

Please sign in to comment.