Skip to content

Commit

Permalink
Adding duration to vote timestamps. This value is packed in the 4 low…
Browse files Browse the repository at this point in the history
… order bits of the timestamp field. This forces the timestamp to have a minimum granularity of 16ms. The duration bits encode a duration = 2^(x+4) which represents 16-524,288ms in power of 2 increments.
  • Loading branch information
clemahieu committed Nov 7, 2021
1 parent cbe19d8 commit 53682a8
Show file tree
Hide file tree
Showing 17 changed files with 147 additions and 93 deletions.
36 changes: 18 additions & 18 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, nano::vote::timestamp_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, nano::vote::duration_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 All @@ -219,7 +219,7 @@ TEST (active_transactions, inactive_votes_cache_non_final)
.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, 0, std::vector<nano::block_hash> (1, send->hash ()))); // Non-final vote
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector<nano::block_hash> (1, send->hash ()))); // Non-final vote
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, nano::vote::timestamp_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, nano::vote::duration_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,7 +306,7 @@ 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, nano::vote::timestamp_min * 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, 0, 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));
Expand Down Expand Up @@ -367,9 +367,9 @@ TEST (active_transactions, inactive_votes_cache_multiple_votes)
node.block_processor.add (open);
node.block_processor.flush ();
// Process votes
auto vote1 (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, std::vector<nano::block_hash> (1, send1->hash ())));
auto vote1 (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, 0, std::vector<nano::block_hash> (1, send1->hash ())));
node.vote_processor.vote (vote1, std::make_shared<nano::transport::channel_loopback> (node));
auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, std::vector<nano::block_hash> (1, send1->hash ())));
auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector<nano::block_hash> (1, send1->hash ())));
node.vote_processor.vote (vote2, std::make_shared<nano::transport::channel_loopback> (node));
ASSERT_TIMELY (5s, node.active.find_inactive_votes_cache (send1->hash ()).voters.size () == 2);
ASSERT_EQ (1, node.active.inactive_votes_cache_size ());
Expand Down Expand Up @@ -448,18 +448,18 @@ TEST (active_transactions, inactive_votes_cache_election_start)
.build_shared ();
// Inactive votes
std::vector<nano::block_hash> hashes{ open1->hash (), open2->hash (), send4->hash () };
auto vote1 (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, hashes));
auto vote1 (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, 0, hashes));
node.vote_processor.vote (vote1, std::make_shared<nano::transport::channel_loopback> (node));
ASSERT_TIMELY (5s, node.active.inactive_votes_cache_size () == 3);
ASSERT_TRUE (node.active.empty ());
ASSERT_EQ (1, node.ledger.cache.cemented_count);
// 2 votes are required to start election (dev network)
auto vote2 (std::make_shared<nano::vote> (key2.pub, key2.prv, 0, hashes));
auto vote2 (std::make_shared<nano::vote> (key2.pub, key2.prv, 0, 0, hashes));
node.vote_processor.vote (vote2, std::make_shared<nano::transport::channel_loopback> (node));
// 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, nano::vote::timestamp_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, nano::vote::duration_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, nano::vote::timestamp_max, send1));
auto vote_send1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_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, nano::vote::timestamp_max, open1));
auto vote_open1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_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,8 +547,8 @@ 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, nano::vote::timestamp_max, send2));
auto vote2_send2 (std::make_shared<nano::vote> (key.pub, key.prv, 0, send2));
auto vote1_send2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, send2));
auto vote2_send2 (std::make_shared<nano::vote> (key.pub, key.prv, 0, 0, send2));
ASSERT_EQ (nano::vote_code::vote, node.active.vote (vote2_send2));
ASSERT_EQ (1, node.active.size ());
ASSERT_EQ (nano::vote_code::replay, node.active.vote (vote2_send2));
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, nano::vote::timestamp_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, nano::vote::duration_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, nano::vote::timestamp_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, nano::vote::duration_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 @@ -848,7 +848,7 @@ TEST (active_transactions, fork_replacement_tally)
.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> (keys[i].pub, keys[i].prv, 0, std::vector<nano::block_hash>{ fork->hash () }));
auto vote (std::make_shared<nano::vote> (keys[i].pub, keys[i].prv, 0, 0, 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.process_active (fork);
Expand Down Expand Up @@ -878,7 +878,7 @@ TEST (active_transactions, fork_replacement_tally)
ASSERT_FALSE (blocks1.find (send_last->hash ()) != blocks1.end ());

// Process vote for correct block & replace existing lowest tally block
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, std::vector<nano::block_hash>{ send_last->hash () }));
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector<nano::block_hash>{ send_last->hash () }));
node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node1));
node1.vote_processor.flush ();
node2.network.flood_block (send_last);
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, nano::vote::timestamp_max, fork));
auto vote_fork (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, fork));

ASSERT_EQ (nano::process_result::progress, node.process_local (send).code);
node.scheduler.flush ();
Expand Down
18 changes: 9 additions & 9 deletions nano/core_test/conflicts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ TEST (conflicts, add_existing)
auto election1 = node1.active.election (send2->qualified_root ());
ASSERT_NE (nullptr, election1);
ASSERT_EQ (1, node1.active.size ());
auto vote1 (std::make_shared<nano::vote> (key2.pub, key2.prv, 0, send2));
auto vote1 (std::make_shared<nano::vote> (key2.pub, key2.prv, 0, 0, send2));
node1.active.vote (vote1);
ASSERT_EQ (2, election1->votes ().size ());
auto votes (election1->votes ());
Expand Down Expand Up @@ -177,7 +177,7 @@ TEST (vote_uniquer, same_vote)
nano::block_uniquer block_uniquer;
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 vote1 (std::make_shared<nano::vote> (key.pub, key.prv, 0, 0, std::make_shared<nano::state_block> (0, 0, 0, 0, 0, key.prv, key.pub, 0)));
auto vote2 (std::make_shared<nano::vote> (*vote1));
ASSERT_EQ (vote1, uniquer.unique (vote1));
ASSERT_EQ (vote1, uniquer.unique (vote2));
Expand All @@ -192,8 +192,8 @@ TEST (vote_uniquer, same_block)
nano::keypair key2;
auto block1 (std::make_shared<nano::state_block> (0, 0, 0, 0, 0, key1.prv, key1.pub, 0));
auto block2 (std::make_shared<nano::state_block> (*block1));
auto vote1 (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, block1));
auto vote2 (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, block2));
auto vote1 (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, 0, block1));
auto vote2 (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, 0, block2));
ASSERT_EQ (vote1, uniquer.unique (vote1));
ASSERT_EQ (vote2, uniquer.unique (vote2));
ASSERT_NE (vote1, vote2);
Expand All @@ -208,7 +208,7 @@ TEST (vote_uniquer, vbh_one)
auto block (std::make_shared<nano::state_block> (0, 0, 0, 0, 0, key.prv, key.pub, 0));
std::vector<nano::block_hash> hashes;
hashes.push_back (block->hash ());
auto vote1 (std::make_shared<nano::vote> (key.pub, key.prv, 0, hashes));
auto vote1 (std::make_shared<nano::vote> (key.pub, key.prv, 0, 0, hashes));
auto vote2 (std::make_shared<nano::vote> (*vote1));
ASSERT_EQ (vote1, uniquer.unique (vote1));
ASSERT_EQ (vote1, uniquer.unique (vote2));
Expand All @@ -225,8 +225,8 @@ TEST (vote_uniquer, vbh_two)
auto block2 (std::make_shared<nano::state_block> (1, 0, 0, 0, 0, key.prv, key.pub, 0));
std::vector<nano::block_hash> hashes2;
hashes2.push_back (block2->hash ());
auto vote1 (std::make_shared<nano::vote> (key.pub, key.prv, 0, hashes1));
auto vote2 (std::make_shared<nano::vote> (key.pub, key.prv, 0, hashes2));
auto vote1 (std::make_shared<nano::vote> (key.pub, key.prv, 0, 0, hashes1));
auto vote2 (std::make_shared<nano::vote> (key.pub, key.prv, 0, 0, hashes2));
ASSERT_EQ (vote1, uniquer.unique (vote1));
ASSERT_EQ (vote2, uniquer.unique (vote2));
}
Expand All @@ -236,8 +236,8 @@ TEST (vote_uniquer, cleanup)
nano::block_uniquer block_uniquer;
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, nano::vote::timestamp_min * 1, std::make_shared<nano::state_block> (0, 0, 0, 0, 0, key.prv, key.pub, 0)));
auto vote1 (std::make_shared<nano::vote> (key.pub, key.prv, 0, 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, nano::vote::timestamp_min * 1, 0, 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, nano::vote::timestamp_max, send2));
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_mask, nano::vote::duration_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, nano::vote::timestamp_max, send2));
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_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, nano::vote::timestamp_max, send1));
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_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, nano::vote::timestamp_max, send1));
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_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, nano::vote::timestamp_max, send1));
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, send1));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
auto vote2 (std::make_shared<nano::vote> (key1.pub, key1.prv, nano::vote::timestamp_max, send1));
auto vote2 (std::make_shared<nano::vote> (key1.pub, key1.prv, nano::vote::timestamp_max, nano::vote::duration_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 53682a8

Please sign in to comment.