Merge pull request #3544 from nanocurrency/vote_timestamp_encapsulation

Vote timestamp encapsulation
This commit is contained in:
clemahieu 2021-11-05 15:22:36 +00:00 committed by GitHub
commit 8ab08a18b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 87 additions and 83 deletions

View file

@ -197,7 +197,7 @@ TEST (active_transactions, inactive_votes_cache)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub) .sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*system.work.generate (latest)) .work (*system.work.generate (latest))
.build_shared (); .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)); node.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node));
ASSERT_TIMELY (5s, node.active.inactive_votes_cache_size () == 1); ASSERT_TIMELY (5s, node.active.inactive_votes_cache_size () == 1);
node.process_active (send); node.process_active (send);
@ -252,7 +252,7 @@ TEST (active_transactions, inactive_votes_cache_fork)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub) .sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*system.work.generate (latest)) .work (*system.work.generate (latest))
.build_shared (); .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)); node.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node));
auto channel1 (node.network.udp_channels.create (node.network.endpoint ())); auto channel1 (node.network.udp_channels.create (node.network.endpoint ()));
ASSERT_TIMELY (5s, node.active.inactive_votes_cache_size () == 1); ASSERT_TIMELY (5s, node.active.inactive_votes_cache_size () == 1);
@ -306,13 +306,13 @@ TEST (active_transactions, inactive_votes_cache_existing_vote)
ASSERT_NE (nullptr, election); ASSERT_NE (nullptr, election);
ASSERT_GT (node.weight (key.pub), node.minimum_principal_weight ()); ASSERT_GT (node.weight (key.pub), node.minimum_principal_weight ());
// Insert vote // 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)); node.vote_processor.vote (vote1, std::make_shared<nano::transport::channel_loopback> (node));
ASSERT_TIMELY (5s, election->votes ().size () == 2); ASSERT_TIMELY (5s, election->votes ().size () == 2);
ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::vote_new)); ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::vote_new));
auto last_vote1 (election->votes ()[key.pub]); auto last_vote1 (election->votes ()[key.pub]);
ASSERT_EQ (send->hash (), last_vote1.hash); 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 // Attempt to change vote with inactive_votes_cache
nano::unique_lock<nano::mutex> active_lock (node.active.mutex); nano::unique_lock<nano::mutex> active_lock (node.active.mutex);
node.active.add_inactive_votes_cache (active_lock, send->hash (), key.pub, 0); node.active.add_inactive_votes_cache (active_lock, send->hash (), key.pub, 0);
@ -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) // Only open1 & open2 blocks elections should start (send4 is missing previous block in ledger)
ASSERT_TIMELY (5s, 2 == node.active.size ()); ASSERT_TIMELY (5s, 2 == node.active.size ());
// Confirm elections with weight quorum // 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)); node.vote_processor.vote (vote0, std::make_shared<nano::transport::channel_loopback> (node));
ASSERT_TIMELY (5s, node.active.empty ()); ASSERT_TIMELY (5s, node.active.empty ());
ASSERT_TIMELY (5s, 5 == node.ledger.cache.cemented_count); ASSERT_TIMELY (5s, 5 == node.ledger.cache.cemented_count);
@ -519,7 +519,7 @@ TEST (active_transactions, vote_replays)
nano::blocks_confirm (node, { send1, open1 }); nano::blocks_confirm (node, { send1, open1 });
ASSERT_EQ (2, node.active.size ()); 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 // 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 (nano::vote_code::vote, node.active.vote (vote_send1));
ASSERT_EQ (2, node.active.size ()); ASSERT_EQ (2, node.active.size ());
ASSERT_EQ (nano::vote_code::replay, node.active.vote (vote_send1)); ASSERT_EQ (nano::vote_code::replay, node.active.vote (vote_send1));
@ -527,7 +527,7 @@ TEST (active_transactions, vote_replays)
ASSERT_TIMELY (3s, node.active.size () == 1); ASSERT_TIMELY (3s, node.active.size () == 1);
ASSERT_EQ (nano::vote_code::replay, node.active.vote (vote_send1)); ASSERT_EQ (nano::vote_code::replay, node.active.vote (vote_send1));
// Open new account // 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::vote, node.active.vote (vote_open1));
ASSERT_EQ (nano::vote_code::replay, node.active.vote (vote_open1)); ASSERT_EQ (nano::vote_code::replay, node.active.vote (vote_open1));
ASSERT_TIMELY (3s, node.active.empty ()); ASSERT_TIMELY (3s, node.active.empty ());
@ -547,7 +547,7 @@ TEST (active_transactions, vote_replays)
node.process_active (send2); node.process_active (send2);
nano::blocks_confirm (node, { send2 }); nano::blocks_confirm (node, { send2 });
ASSERT_EQ (1, node.active.size ()); 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)); 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 (nano::vote_code::vote, node.active.vote (vote2_send2));
ASSERT_EQ (1, node.active.size ()); ASSERT_EQ (1, node.active.size ());
@ -690,7 +690,7 @@ TEST (active_transactions, republish_winner)
node1.block_processor.flush (); node1.block_processor.flush ();
auto election = node1.active.election (fork->qualified_root ()); auto election = node1.active.election (fork->qualified_root ());
ASSERT_NE (nullptr, election); 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.vote (vote, std::make_shared<nano::transport::channel_loopback> (node1));
node1.vote_processor.flush (); node1.vote_processor.flush ();
node1.block_processor.flush (); node1.block_processor.flush ();
@ -798,7 +798,7 @@ TEST (active_transactions, fork_replacement_tally)
.build_shared (); .build_shared ();
node1.process_active (open); node1.process_active (open);
// Confirmation // 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.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node1));
} }
node1.block_processor.flush (); node1.block_processor.flush ();
@ -981,7 +981,7 @@ TEST (active_transactions, conflicting_block_vote_existing_election)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub) .sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*system.work.generate (nano::dev::genesis->hash ())) .work (*system.work.generate (nano::dev::genesis->hash ()))
.build_shared (); .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); ASSERT_EQ (nano::process_result::progress, node.process_local (send).code);
node.scheduler.flush (); node.scheduler.flush ();

View file

@ -144,7 +144,7 @@ TEST (vote_uniquer, cleanup)
nano::vote_uniquer uniquer (block_uniquer); nano::vote_uniquer uniquer (block_uniquer);
nano::keypair key; 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, 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 vote3 (uniquer.unique (vote1));
auto vote4 (uniquer.unique (vote2)); auto vote4 (uniquer.unique (vote2));
vote2.reset (); vote2.reset ();

View file

@ -55,7 +55,7 @@ TEST (election, quorum_minimum_flip_success)
auto election = node1.active.election (send1->qualified_root ()); auto election = node1.active.election (send1->qualified_root ());
ASSERT_NE (nullptr, election); ASSERT_NE (nullptr, election);
ASSERT_EQ (2, election->blocks ().size ()); 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)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
node1.block_processor.flush (); node1.block_processor.flush ();
ASSERT_NE (nullptr, node1.block (send2->hash ())); ASSERT_NE (nullptr, node1.block (send2->hash ()));
@ -101,7 +101,7 @@ TEST (election, quorum_minimum_flip_fail)
auto election = node1.active.election (send1->qualified_root ()); auto election = node1.active.election (send1->qualified_root ());
ASSERT_NE (nullptr, election); ASSERT_NE (nullptr, election);
ASSERT_EQ (2, election->blocks ().size ()); 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)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
node1.block_processor.flush (); node1.block_processor.flush ();
ASSERT_NE (nullptr, node1.block (send1->hash ())); ASSERT_NE (nullptr, node1.block (send1->hash ()));
@ -134,7 +134,7 @@ TEST (election, quorum_minimum_confirm_success)
auto election = node1.active.election (send1->qualified_root ()); auto election = node1.active.election (send1->qualified_root ());
ASSERT_NE (nullptr, election); ASSERT_NE (nullptr, election);
ASSERT_EQ (1, election->blocks ().size ()); 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)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
node1.block_processor.flush (); node1.block_processor.flush ();
ASSERT_NE (nullptr, node1.block (send1->hash ())); ASSERT_NE (nullptr, node1.block (send1->hash ()));
@ -167,7 +167,7 @@ TEST (election, quorum_minimum_confirm_fail)
auto election = node1.active.election (send1->qualified_root ()); auto election = node1.active.election (send1->qualified_root ());
ASSERT_NE (nullptr, election); ASSERT_NE (nullptr, election);
ASSERT_EQ (1, election->blocks ().size ()); 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)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
node1.block_processor.flush (); node1.block_processor.flush ();
ASSERT_NE (nullptr, node1.block (send1->hash ())); ASSERT_NE (nullptr, node1.block (send1->hash ()));
@ -241,9 +241,9 @@ TEST (election, DISABLED_quorum_minimum_update_weight_before_quorum_checks)
auto election = node1.active.election (send1->qualified_root ()); auto election = node1.active.election (send1->qualified_root ());
ASSERT_NE (nullptr, election); ASSERT_NE (nullptr, election);
ASSERT_EQ (1, election->blocks ().size ()); 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)); 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 ()); auto channel = node1.network.find_channel (node2.network.endpoint ());
ASSERT_NE (channel, nullptr); ASSERT_NE (channel, nullptr);
ASSERT_TIMELY (10s, !node1.rep_crawler.response (channel, vote2)); ASSERT_TIMELY (10s, !node1.rep_crawler.response (channel, vote2));

View file

@ -645,7 +645,7 @@ TEST (votes, check_signature)
node1.scheduler.flush (); node1.scheduler.flush ();
auto election1 = node1.active.election (send1->qualified_root ()); auto election1 = node1.active.election (send1->qualified_root ());
ASSERT_EQ (1, election1->votes ().size ()); ASSERT_EQ (1, election1->votes ().size ());
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 1, send1)); auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, send1));
vote1->signature.bytes[0] ^= 1; vote1->signature.bytes[0] ^= 1;
ASSERT_EQ (nano::vote_code::invalid, node1.vote_processor.vote_blocking (vote1, std::make_shared<nano::transport::channel_loopback> (node1))); ASSERT_EQ (nano::vote_code::invalid, node1.vote_processor.vote_blocking (vote1, std::make_shared<nano::transport::channel_loopback> (node1)));
vote1->signature.bytes[0] ^= 1; vote1->signature.bytes[0] ^= 1;
@ -666,9 +666,9 @@ TEST (votes, add_one)
node1.scheduler.flush (); node1.scheduler.flush ();
auto election1 = node1.active.election (send1->qualified_root ()); auto election1 = node1.active.election (send1->qualified_root ());
ASSERT_EQ (1, election1->votes ().size ()); ASSERT_EQ (1, election1->votes ().size ());
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 1, send1)); auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, send1));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 2, send1)); auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, send1));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2));
ASSERT_EQ (2, election1->votes ().size ()); ASSERT_EQ (2, election1->votes ().size ());
auto votes1 (election1->votes ()); auto votes1 (election1->votes ());
@ -695,9 +695,9 @@ TEST (votes, add_two)
auto election1 = node1.active.election (send1->qualified_root ()); auto election1 = node1.active.election (send1->qualified_root ());
nano::keypair key2; nano::keypair key2;
auto send2 = std::make_shared<nano::send_block> (nano::dev::genesis->hash (), key2.pub, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, 0); auto send2 = std::make_shared<nano::send_block> (nano::dev::genesis->hash (), key2.pub, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, 0);
auto vote2 = std::make_shared<nano::vote> (key2.pub, key2.prv, 1, send2); auto vote2 = std::make_shared<nano::vote> (key2.pub, key2.prv, nano::vote::timestamp_min * 1, send2);
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2));
auto vote1 = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 1, send1); auto vote1 = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, send1);
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
ASSERT_EQ (3, election1->votes ().size ()); ASSERT_EQ (3, election1->votes ().size ());
auto votes1 = election1->votes (); auto votes1 = election1->votes ();
@ -734,11 +734,11 @@ TEST (votes, add_existing)
node1.scheduler.activate (nano::dev::genesis_key.pub, node1.store.tx_begin_read ()); node1.scheduler.activate (nano::dev::genesis_key.pub, node1.store.tx_begin_read ());
node1.scheduler.flush (); node1.scheduler.flush ();
auto election1 = node1.active.election (send1->qualified_root ()); auto election1 = node1.active.election (send1->qualified_root ());
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 1, send1)); auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, send1));
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
// Block is already processed from vote // Block is already processed from vote
ASSERT_TRUE (node1.active.publish (send1)); ASSERT_TRUE (node1.active.publish (send1));
ASSERT_EQ (1, election1->last_votes[nano::dev::genesis_key.pub].timestamp); ASSERT_EQ (nano::vote::timestamp_min * 1, election1->last_votes[nano::dev::genesis_key.pub].timestamp);
nano::keypair key2; nano::keypair key2;
std::shared_ptr<nano::block> send2 = builder.state () std::shared_ptr<nano::block> send2 = builder.state ()
.account (nano::dev::genesis_key.pub) .account (nano::dev::genesis_key.pub)
@ -750,20 +750,20 @@ TEST (votes, add_existing)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub) .sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.build (); .build ();
node1.work_generate_blocking (*send2); node1.work_generate_blocking (*send2);
auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 2, send2)); auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, send2));
// Pretend we've waited the timeout // Pretend we've waited the timeout
nano::unique_lock<nano::mutex> lock (election1->mutex); nano::unique_lock<nano::mutex> lock (election1->mutex);
election1->last_votes[nano::dev::genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20); election1->last_votes[nano::dev::genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20);
lock.unlock (); lock.unlock ();
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2));
ASSERT_FALSE (node1.active.publish (send2)); ASSERT_FALSE (node1.active.publish (send2));
ASSERT_EQ (2, election1->last_votes[nano::dev::genesis_key.pub].timestamp); ASSERT_EQ (nano::vote::timestamp_min * 2, election1->last_votes[nano::dev::genesis_key.pub].timestamp);
// Also resend the old vote, and see if we respect the timestamp // Also resend the old vote, and see if we respect the timestamp
lock.lock (); lock.lock ();
election1->last_votes[nano::dev::genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20); election1->last_votes[nano::dev::genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20);
lock.unlock (); lock.unlock ();
ASSERT_EQ (nano::vote_code::replay, node1.active.vote (vote1)); ASSERT_EQ (nano::vote_code::replay, node1.active.vote (vote1));
ASSERT_EQ (2, election1->votes ()[nano::dev::genesis_key.pub].timestamp); ASSERT_EQ (nano::vote::timestamp_min * 2, election1->votes ()[nano::dev::genesis_key.pub].timestamp);
auto votes (election1->votes ()); auto votes (election1->votes ());
ASSERT_EQ (2, votes.size ()); ASSERT_EQ (2, votes.size ());
ASSERT_NE (votes.end (), votes.find (nano::dev::genesis_key.pub)); ASSERT_NE (votes.end (), votes.find (nano::dev::genesis_key.pub));
@ -784,13 +784,13 @@ TEST (votes, add_old)
node1.block_confirm (send1); node1.block_confirm (send1);
node1.scheduler.flush (); node1.scheduler.flush ();
auto election1 = node1.active.election (send1->qualified_root ()); auto election1 = node1.active.election (send1->qualified_root ());
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 2, send1)); auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, send1));
auto channel (std::make_shared<nano::transport::channel_loopback> (node1)); auto channel (std::make_shared<nano::transport::channel_loopback> (node1));
node1.vote_processor.vote_blocking (vote1, channel); node1.vote_processor.vote_blocking (vote1, channel);
nano::keypair key2; nano::keypair key2;
auto send2 (std::make_shared<nano::send_block> (nano::dev::genesis->hash (), key2.pub, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, 0)); auto send2 (std::make_shared<nano::send_block> (nano::dev::genesis->hash (), key2.pub, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, 0));
node1.work_generate_blocking (*send2); node1.work_generate_blocking (*send2);
auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 1, send2)); auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, send2));
{ {
nano::lock_guard<nano::mutex> lock (election1->mutex); nano::lock_guard<nano::mutex> lock (election1->mutex);
election1->last_votes[nano::dev::genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20); election1->last_votes[nano::dev::genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20);
@ -823,13 +823,13 @@ TEST (votes, add_old_different_account)
ASSERT_NE (nullptr, election2); ASSERT_NE (nullptr, election2);
ASSERT_EQ (1, election1->votes ().size ()); ASSERT_EQ (1, election1->votes ().size ());
ASSERT_EQ (1, election2->votes ().size ()); ASSERT_EQ (1, election2->votes ().size ());
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 2, send1)); auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, send1));
auto channel (std::make_shared<nano::transport::channel_loopback> (node1)); auto channel (std::make_shared<nano::transport::channel_loopback> (node1));
auto vote_result1 (node1.vote_processor.vote_blocking (vote1, channel)); auto vote_result1 (node1.vote_processor.vote_blocking (vote1, channel));
ASSERT_EQ (nano::vote_code::vote, vote_result1); ASSERT_EQ (nano::vote_code::vote, vote_result1);
ASSERT_EQ (2, election1->votes ().size ()); ASSERT_EQ (2, election1->votes ().size ());
ASSERT_EQ (1, election2->votes ().size ()); ASSERT_EQ (1, election2->votes ().size ());
auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 1, send2)); auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, send2));
auto vote_result2 (node1.vote_processor.vote_blocking (vote2, channel)); auto vote_result2 (node1.vote_processor.vote_blocking (vote2, channel));
ASSERT_EQ (nano::vote_code::vote, vote_result2); ASSERT_EQ (nano::vote_code::vote, vote_result2);
ASSERT_EQ (2, election1->votes ().size ()); ASSERT_EQ (2, election1->votes ().size ());
@ -857,13 +857,13 @@ TEST (votes, add_cooldown)
node1.block_confirm (send1); node1.block_confirm (send1);
node1.scheduler.flush (); node1.scheduler.flush ();
auto election1 = node1.active.election (send1->qualified_root ()); auto election1 = node1.active.election (send1->qualified_root ());
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 1, send1)); auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, send1));
auto channel (std::make_shared<nano::transport::channel_loopback> (node1)); auto channel (std::make_shared<nano::transport::channel_loopback> (node1));
node1.vote_processor.vote_blocking (vote1, channel); node1.vote_processor.vote_blocking (vote1, channel);
nano::keypair key2; nano::keypair key2;
auto send2 (std::make_shared<nano::send_block> (nano::dev::genesis->hash (), key2.pub, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, 0)); auto send2 (std::make_shared<nano::send_block> (nano::dev::genesis->hash (), key2.pub, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, 0));
node1.work_generate_blocking (*send2); node1.work_generate_blocking (*send2);
auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 2, send2)); auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, send2));
node1.vote_processor.vote_blocking (vote2, channel); node1.vote_processor.vote_blocking (vote2, channel);
ASSERT_EQ (2, election1->votes ().size ()); ASSERT_EQ (2, election1->votes ().size ());
auto votes (election1->votes ()); auto votes (election1->votes ());

View file

@ -2925,7 +2925,7 @@ TEST (node, vote_republish)
node1.process_active (send1); node1.process_active (send1);
ASSERT_TIMELY (5s, node2.block (send1->hash ())); ASSERT_TIMELY (5s, node2.block (send1->hash ()));
node1.process_active (send2); node1.process_active (send2);
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), send2)); auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, send2));
ASSERT_TRUE (node1.active.active (*send1)); ASSERT_TRUE (node1.active.active (*send1));
ASSERT_TIMELY (10s, node2.active.active (*send1)); ASSERT_TIMELY (10s, node2.active.active (*send1));
node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node1)); node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node1));
@ -3020,7 +3020,7 @@ TEST (node, vote_by_hash_republish)
node1.process_active (send2); node1.process_active (send2);
std::vector<nano::block_hash> vote_blocks; std::vector<nano::block_hash> vote_blocks;
vote_blocks.push_back (send2->hash ()); vote_blocks.push_back (send2->hash ());
auto vote = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), vote_blocks); // Final vote for confirmation auto vote = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, vote_blocks); // Final vote for confirmation
ASSERT_TRUE (node1.active.active (*send1)); ASSERT_TRUE (node1.active.active (*send1));
ASSERT_TRUE (node2.active.active (*send1)); ASSERT_TRUE (node2.active.active (*send1));
node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node1)); node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node1));
@ -3539,7 +3539,7 @@ TEST (node, confirm_back)
ASSERT_EQ (3, node.active.size ()); ASSERT_EQ (3, node.active.size ());
std::vector<nano::block_hash> vote_blocks; std::vector<nano::block_hash> vote_blocks;
vote_blocks.push_back (send2->hash ()); vote_blocks.push_back (send2->hash ());
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, std::numeric_limits<uint64_t>::max (), vote_blocks)); auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, vote_blocks));
node.vote_processor.vote_blocking (vote, std::make_shared<nano::transport::channel_loopback> (node)); node.vote_processor.vote_blocking (vote, std::make_shared<nano::transport::channel_loopback> (node));
ASSERT_TIMELY (10s, node.active.empty ()); ASSERT_TIMELY (10s, node.active.empty ());
} }
@ -4089,7 +4089,7 @@ TEST (node, rollback_gap_source)
ASSERT_EQ (2, election->blocks ().size ()); ASSERT_EQ (2, election->blocks ().size ());
ASSERT_EQ (1, election->votes ().size ()); ASSERT_EQ (1, election->votes ().size ());
// Confirm open // Confirm open
auto vote1 (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, open->hash ()))); auto vote1 (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, open->hash ())));
node.vote_processor.vote (vote1, std::make_shared<nano::transport::channel_loopback> (node)); node.vote_processor.vote (vote1, std::make_shared<nano::transport::channel_loopback> (node));
ASSERT_TIMELY (5s, election->votes ().size () == 2); ASSERT_TIMELY (5s, election->votes ().size () == 2);
ASSERT_TIMELY (3s, election->confirmed ()); ASSERT_TIMELY (3s, election->confirmed ());
@ -4116,7 +4116,7 @@ TEST (node, rollback_gap_source)
node.block_processor.flush (); node.block_processor.flush ();
ASSERT_EQ (2, election->blocks ().size ()); ASSERT_EQ (2, election->blocks ().size ());
// Confirm open (again) // Confirm open (again)
auto vote1 (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, open->hash ()))); auto vote1 (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, open->hash ())));
node.vote_processor.vote (vote1, std::make_shared<nano::transport::channel_loopback> (node)); node.vote_processor.vote (vote1, std::make_shared<nano::transport::channel_loopback> (node));
ASSERT_TIMELY (5s, election->votes ().size () == 2); ASSERT_TIMELY (5s, election->votes ().size () == 2);
} }

View file

@ -12,7 +12,7 @@ TEST (vote_processor, codes)
nano::system system (1); nano::system system (1);
auto & node (*system.nodes[0]); auto & node (*system.nodes[0]);
nano::keypair key; nano::keypair key;
auto vote (std::make_shared<nano::vote> (key.pub, key.prv, 1, std::vector<nano::block_hash>{ nano::dev::genesis->hash () })); auto vote (std::make_shared<nano::vote> (key.pub, key.prv, nano::vote::timestamp_min * 1, std::vector<nano::block_hash>{ nano::dev::genesis->hash () }));
auto vote_invalid = std::make_shared<nano::vote> (*vote); auto vote_invalid = std::make_shared<nano::vote> (*vote);
vote_invalid->signature.bytes[0] ^= 1; vote_invalid->signature.bytes[0] ^= 1;
auto channel (std::make_shared<nano::transport::channel_loopback> (node)); auto channel (std::make_shared<nano::transport::channel_loopback> (node));
@ -37,12 +37,6 @@ TEST (vote_processor, codes)
// Invalid takes precedence // Invalid takes precedence
ASSERT_EQ (nano::vote_code::invalid, node.vote_processor.vote_blocking (vote_invalid, channel)); ASSERT_EQ (nano::vote_code::invalid, node.vote_processor.vote_blocking (vote_invalid, channel));
// A higher timestamp is not a replay
++vote->timestamp;
ASSERT_EQ (nano::vote_code::invalid, node.vote_processor.vote_blocking (vote, channel));
vote->signature = nano::sign_message (key.prv, key.pub, vote->hash ());
ASSERT_EQ (nano::vote_code::vote, node.vote_processor.vote_blocking (vote, channel));
// Once the election is removed (confirmed / dropped) the vote is again indeterminate // Once the election is removed (confirmed / dropped) the vote is again indeterminate
node.active.erase (*nano::dev::genesis); node.active.erase (*nano::dev::genesis);
ASSERT_EQ (nano::vote_code::indeterminate, node.vote_processor.vote_blocking (vote, channel)); ASSERT_EQ (nano::vote_code::indeterminate, node.vote_processor.vote_blocking (vote, channel));
@ -52,13 +46,11 @@ TEST (vote_processor, flush)
{ {
nano::system system (1); nano::system system (1);
auto & node (*system.nodes[0]); auto & node (*system.nodes[0]);
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 1, std::vector<nano::block_hash>{ nano::dev::genesis->hash () }));
auto channel (std::make_shared<nano::transport::channel_loopback> (node)); auto channel (std::make_shared<nano::transport::channel_loopback> (node));
for (unsigned i = 0; i < 2000; ++i) for (unsigned i = 0; i < 2000; ++i)
{ {
auto new_vote (std::make_shared<nano::vote> (*vote)); auto vote = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * (1 + i), std::vector<nano::block_hash>{ nano::dev::genesis->hash () });
node.vote_processor.vote (new_vote, channel); node.vote_processor.vote (vote, channel);
++vote->timestamp; // invalidates votes without signing again
} }
node.vote_processor.flush (); node.vote_processor.flush ();
ASSERT_TRUE (node.vote_processor.empty ()); ASSERT_TRUE (node.vote_processor.empty ());
@ -69,7 +61,7 @@ TEST (vote_processor, invalid_signature)
nano::system system{ 1 }; nano::system system{ 1 };
auto & node = *system.nodes[0]; auto & node = *system.nodes[0];
nano::keypair key; nano::keypair key;
auto vote = std::make_shared<nano::vote> (key.pub, key.prv, 1, std::vector<nano::block_hash>{ nano::dev::genesis->hash () }); auto vote = std::make_shared<nano::vote> (key.pub, key.prv, nano::vote::timestamp_min * 1, std::vector<nano::block_hash>{ nano::dev::genesis->hash () });
auto vote_invalid = std::make_shared<nano::vote> (*vote); auto vote_invalid = std::make_shared<nano::vote> (*vote);
vote_invalid->signature.bytes[0] ^= 1; vote_invalid->signature.bytes[0] ^= 1;
auto channel = std::make_shared<nano::transport::channel_loopback> (node); auto channel = std::make_shared<nano::transport::channel_loopback> (node);
@ -93,7 +85,7 @@ TEST (vote_processor, no_capacity)
node_flags.vote_processor_capacity = 0; node_flags.vote_processor_capacity = 0;
auto & node (*system.add_node (node_flags)); auto & node (*system.add_node (node_flags));
nano::keypair key; nano::keypair key;
auto vote (std::make_shared<nano::vote> (key.pub, key.prv, 1, std::vector<nano::block_hash>{ nano::dev::genesis->hash () })); auto vote (std::make_shared<nano::vote> (key.pub, key.prv, nano::vote::timestamp_min * 1, std::vector<nano::block_hash>{ nano::dev::genesis->hash () }));
auto channel (std::make_shared<nano::transport::channel_loopback> (node)); auto channel (std::make_shared<nano::transport::channel_loopback> (node));
ASSERT_TRUE (node.vote_processor.vote (vote, channel)); ASSERT_TRUE (node.vote_processor.vote (vote, channel));
} }
@ -105,7 +97,7 @@ TEST (vote_processor, overflow)
node_flags.vote_processor_capacity = 1; node_flags.vote_processor_capacity = 1;
auto & node (*system.add_node (node_flags)); auto & node (*system.add_node (node_flags));
nano::keypair key; nano::keypair key;
auto vote (std::make_shared<nano::vote> (key.pub, key.prv, 1, std::vector<nano::block_hash>{ nano::dev::genesis->hash () })); auto vote (std::make_shared<nano::vote> (key.pub, key.prv, nano::vote::timestamp_min * 1, std::vector<nano::block_hash>{ nano::dev::genesis->hash () }));
auto channel (std::make_shared<nano::transport::channel_loopback> (node)); auto channel (std::make_shared<nano::transport::channel_loopback> (node));
// No way to lock the processor, but queueing votes in quick succession must result in overflow // No way to lock the processor, but queueing votes in quick succession must result in overflow
@ -206,7 +198,7 @@ TEST (vote_processor, DISABLED_no_broadcast_local)
ASSERT_TRUE (node.wallets.reps ().exists (nano::dev::genesis_key.pub)); ASSERT_TRUE (node.wallets.reps ().exists (nano::dev::genesis_key.pub));
ASSERT_FALSE (node.wallets.reps ().have_half_rep ()); ASSERT_FALSE (node.wallets.reps ().have_half_rep ());
// Process a vote // Process a vote
auto vote = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::milliseconds_since_epoch (), std::vector<nano::block_hash>{ send->hash () }); auto vote = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::milliseconds_since_epoch () & nano::vote::timestamp_max, std::vector<nano::block_hash>{ send->hash () });
ASSERT_EQ (nano::vote_code::vote, node.active.vote (vote)); ASSERT_EQ (nano::vote_code::vote, node.active.vote (vote));
// Make sure the vote was processed // Make sure the vote was processed
auto election (node.active.election (send->qualified_root ())); auto election (node.active.election (send->qualified_root ()));
@ -214,7 +206,7 @@ TEST (vote_processor, DISABLED_no_broadcast_local)
auto votes (election->votes ()); auto votes (election->votes ());
auto existing (votes.find (nano::dev::genesis_key.pub)); auto existing (votes.find (nano::dev::genesis_key.pub));
ASSERT_NE (votes.end (), existing); ASSERT_NE (votes.end (), existing);
ASSERT_EQ (vote->timestamp, existing->second.timestamp); ASSERT_EQ (vote->timestamp (), existing->second.timestamp);
// Ensure the vote, from a local representative, was not broadcast on processing - it should be flooded on generation instead // Ensure the vote, from a local representative, was not broadcast on processing - it should be flooded on generation instead
ASSERT_EQ (0, node.stats.count (nano::stat::type::message, nano::stat::detail::confirm_ack, nano::stat::dir::out)); ASSERT_EQ (0, node.stats.count (nano::stat::type::message, nano::stat::detail::confirm_ack, nano::stat::dir::out));
ASSERT_EQ (1, node.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out)); ASSERT_EQ (1, node.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out));
@ -239,7 +231,7 @@ TEST (vote_processor, DISABLED_no_broadcast_local)
ASSERT_EQ (node.config.vote_minimum, node.weight (nano::dev::genesis_key.pub)); ASSERT_EQ (node.config.vote_minimum, node.weight (nano::dev::genesis_key.pub));
node.block_confirm (send2); node.block_confirm (send2);
// Process a vote // Process a vote
auto vote2 = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::milliseconds_since_epoch (), std::vector<nano::block_hash>{ send2->hash () }); auto vote2 = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::milliseconds_since_epoch () * nano::vote::timestamp_max, std::vector<nano::block_hash>{ send2->hash () });
ASSERT_EQ (nano::vote_code::vote, node.active.vote (vote2)); ASSERT_EQ (nano::vote_code::vote, node.active.vote (vote2));
// Make sure the vote was processed // Make sure the vote was processed
auto election2 (node.active.election (send2->qualified_root ())); auto election2 (node.active.election (send2->qualified_root ()));
@ -247,7 +239,7 @@ TEST (vote_processor, DISABLED_no_broadcast_local)
auto votes2 (election2->votes ()); auto votes2 (election2->votes ());
auto existing2 (votes2.find (nano::dev::genesis_key.pub)); auto existing2 (votes2.find (nano::dev::genesis_key.pub));
ASSERT_NE (votes2.end (), existing2); ASSERT_NE (votes2.end (), existing2);
ASSERT_EQ (vote2->timestamp, existing2->second.timestamp); ASSERT_EQ (vote2->timestamp (), existing2->second.timestamp);
// Ensure the vote was broadcast // Ensure the vote was broadcast
ASSERT_EQ (1, node.stats.count (nano::stat::type::message, nano::stat::detail::confirm_ack, nano::stat::dir::out)); ASSERT_EQ (1, node.stats.count (nano::stat::type::message, nano::stat::detail::confirm_ack, nano::stat::dir::out));
ASSERT_EQ (2, node.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out)); ASSERT_EQ (2, node.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out));
@ -273,7 +265,7 @@ TEST (vote_processor, DISABLED_no_broadcast_local)
ASSERT_TRUE (node.wallets.reps ().exists (nano::dev::genesis_key.pub)); ASSERT_TRUE (node.wallets.reps ().exists (nano::dev::genesis_key.pub));
ASSERT_TRUE (node.wallets.reps ().have_half_rep ()); ASSERT_TRUE (node.wallets.reps ().have_half_rep ());
// Process a vote // Process a vote
auto vote3 = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::milliseconds_since_epoch (), std::vector<nano::block_hash>{ open->hash () }); auto vote3 = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::milliseconds_since_epoch () * nano::vote::timestamp_max, std::vector<nano::block_hash>{ open->hash () });
ASSERT_EQ (nano::vote_code::vote, node.active.vote (vote3)); ASSERT_EQ (nano::vote_code::vote, node.active.vote (vote3));
// Make sure the vote was processed // Make sure the vote was processed
auto election3 (node.active.election (open->qualified_root ())); auto election3 (node.active.election (open->qualified_root ()));
@ -281,7 +273,7 @@ TEST (vote_processor, DISABLED_no_broadcast_local)
auto votes3 (election3->votes ()); auto votes3 (election3->votes ());
auto existing3 (votes3.find (nano::dev::genesis_key.pub)); auto existing3 (votes3.find (nano::dev::genesis_key.pub));
ASSERT_NE (votes3.end (), existing3); ASSERT_NE (votes3.end (), existing3);
ASSERT_EQ (vote3->timestamp, existing3->second.timestamp); ASSERT_EQ (vote3->timestamp (), existing3->second.timestamp);
// Ensure the vote wass not broadcasst // Ensure the vote wass not broadcasst
ASSERT_EQ (1, node.stats.count (nano::stat::type::message, nano::stat::detail::confirm_ack, nano::stat::dir::out)); ASSERT_EQ (1, node.stats.count (nano::stat::type::message, nano::stat::detail::confirm_ack, nano::stat::dir::out));
ASSERT_EQ (3, node.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out)); ASSERT_EQ (3, node.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out));

View file

@ -872,7 +872,7 @@ nano::vote_code nano::active_transactions::vote (std::shared_ptr<nano::vote> con
} }
else if (recently_confirmed_by_hash.count (block_hash) == 0) else if (recently_confirmed_by_hash.count (block_hash) == 0)
{ {
add_inactive_votes_cache (lock, block_hash, vote_a->account, vote_a->timestamp); add_inactive_votes_cache (lock, block_hash, vote_a->account, vote_a->timestamp ());
} }
else else
{ {
@ -889,7 +889,7 @@ nano::vote_code nano::active_transactions::vote (std::shared_ptr<nano::vote> con
} }
else if (recently_confirmed_by_hash.count (block->hash ()) == 0) else if (recently_confirmed_by_hash.count (block->hash ()) == 0)
{ {
add_inactive_votes_cache (lock, block->hash (), vote_a->account, vote_a->timestamp); add_inactive_votes_cache (lock, block->hash (), vote_a->account, vote_a->timestamp ());
} }
else else
{ {
@ -905,7 +905,7 @@ nano::vote_code nano::active_transactions::vote (std::shared_ptr<nano::vote> con
bool processed (false); bool processed (false);
for (auto const & [election, block_hash] : process) for (auto const & [election, block_hash] : process)
{ {
auto const result_l = election->vote (vote_a->account, vote_a->timestamp, block_hash); auto const result_l = election->vote (vote_a->account, vote_a->timestamp (), block_hash);
processed = processed || result_l.processed; processed = processed || result_l.processed;
replay = replay || result_l.replay; replay = replay || result_l.replay;
} }

View file

@ -474,7 +474,7 @@ public:
{ {
if (node.config.logging.network_message_logging ()) if (node.config.logging.network_message_logging ())
{ {
node.logger.try_log (boost::str (boost::format ("Received confirm_ack message from %1% for %2% timestamp %3%") % channel->to_string () % message_a.vote->hashes_string () % std::to_string (message_a.vote->timestamp))); node.logger.try_log (boost::str (boost::format ("Received confirm_ack message from %1% for %2% timestamp %3%") % channel->to_string () % message_a.vote->hashes_string () % std::to_string (message_a.vote->timestamp ())));
} }
node.stats.inc (nano::stat::type::message, nano::stat::detail::confirm_ack, nano::stat::dir::in); node.stats.inc (nano::stat::type::message, nano::stat::detail::confirm_ack, nano::stat::dir::in);
if (!message_a.vote->account.is_zero ()) if (!message_a.vote->account.is_zero ())

View file

@ -198,7 +198,7 @@ nano::vote_code nano::vote_processor::vote_blocking (std::shared_ptr<nano::vote>
} }
if (config.logging.vote_logging ()) if (config.logging.vote_logging ())
{ {
logger.try_log (boost::str (boost::format ("Vote from: %1% timestamp: %2% block(s): %3%status: %4%") % vote_a->account.to_account () % std::to_string (vote_a->timestamp) % vote_a->hashes_string () % status)); logger.try_log (boost::str (boost::format ("Vote from: %1% timestamp: %2% block(s): %3% status: %4%") % vote_a->account.to_account () % std::to_string (vote_a->timestamp ()) % vote_a->hashes_string () % status));
} }
return result; return result;
} }

View file

@ -75,11 +75,11 @@ void nano::local_vote_history::add (nano::root const & root_a, nano::block_hash
auto range (history_by_root.equal_range (root_a)); auto range (history_by_root.equal_range (root_a));
for (auto i (range.first); i != range.second;) for (auto i (range.first); i != range.second;)
{ {
if (i->hash != hash_a || (vote_a->account == i->vote->account && i->vote->timestamp <= vote_a->timestamp)) if (i->hash != hash_a || (vote_a->account == i->vote->account && i->vote->timestamp () <= vote_a->timestamp ()))
{ {
i = history_by_root.erase (i); i = history_by_root.erase (i);
} }
else if (vote_a->account == i->vote->account && i->vote->timestamp > vote_a->timestamp) else if (vote_a->account == i->vote->account && i->vote->timestamp () > vote_a->timestamp ())
{ {
add_vote = false; add_vote = false;
++i; ++i;
@ -123,7 +123,7 @@ std::vector<std::shared_ptr<nano::vote>> nano::local_vote_history::votes (nano::
auto range (history.get<tag_root> ().equal_range (root_a)); auto range (history.get<tag_root> ().equal_range (root_a));
// clang-format off // clang-format off
nano::transform_if (range.first, range.second, std::back_inserter (result), nano::transform_if (range.first, range.second, std::back_inserter (result),
[&hash_a, is_final_a](auto const & entry) { return entry.hash == hash_a && (!is_final_a || entry.vote->timestamp == std::numeric_limits<uint64_t>::max ()); }, [&hash_a, is_final_a](auto const & entry) { return entry.hash == hash_a && (!is_final_a || entry.vote->timestamp () == std::numeric_limits<uint64_t>::max ()); },
[](auto const & entry) { return entry.vote; }); [](auto const & entry) { return entry.vote; });
// clang-format on // clang-format on
return result; return result;
@ -361,7 +361,7 @@ void nano::vote_generator::vote (std::vector<nano::block_hash> const & hashes_a,
debug_assert (hashes_a.size () == roots_a.size ()); debug_assert (hashes_a.size () == roots_a.size ());
std::vector<std::shared_ptr<nano::vote>> votes_l; std::vector<std::shared_ptr<nano::vote>> votes_l;
wallets.foreach_representative ([this, &hashes_a, &votes_l] (nano::public_key const & pub_a, nano::raw_key const & prv_a) { wallets.foreach_representative ([this, &hashes_a, &votes_l] (nano::public_key const & pub_a, nano::raw_key const & prv_a) {
auto timestamp (this->is_final ? std::numeric_limits<uint64_t>::max () : nano::milliseconds_since_epoch ()); auto timestamp = this->is_final ? nano::vote::timestamp_max : nano::milliseconds_since_epoch ();
votes_l.emplace_back (std::make_shared<nano::vote> (pub_a, prv_a, timestamp, hashes_a)); votes_l.emplace_back (std::make_shared<nano::vote> (pub_a, prv_a, timestamp, hashes_a));
}); });
for (auto const & vote_l : votes_l) for (auto const & vote_l : votes_l)

View file

@ -473,7 +473,7 @@ bool nano::vote::operator== (nano::vote const & other_a) const
} }
} }
} }
return timestamp == other_a.timestamp && blocks_equal && account == other_a.account && signature == other_a.signature; return timestamp_m == other_a.timestamp_m && blocks_equal && account == other_a.account && signature == other_a.signature;
} }
bool nano::vote::operator!= (nano::vote const & other_a) const bool nano::vote::operator!= (nano::vote const & other_a) const
@ -485,8 +485,8 @@ void nano::vote::serialize_json (boost::property_tree::ptree & tree) const
{ {
tree.put ("account", account.to_account ()); tree.put ("account", account.to_account ());
tree.put ("signature", signature.number ()); tree.put ("signature", signature.number ());
tree.put ("sequence", std::to_string (timestamp)); tree.put ("sequence", std::to_string (timestamp ()));
tree.put ("timestamp", std::to_string (timestamp)); tree.put ("timestamp", std::to_string (timestamp ()));
boost::property_tree::ptree blocks_tree; boost::property_tree::ptree blocks_tree;
for (auto block : blocks) for (auto block : blocks)
{ {
@ -513,8 +513,13 @@ std::string nano::vote::to_json () const
return stream.str (); return stream.str ();
} }
uint64_t nano::vote::timestamp () const
{
return timestamp_m;
}
nano::vote::vote (nano::vote const & other_a) : nano::vote::vote (nano::vote const & other_a) :
timestamp{ other_a.timestamp }, timestamp_m{ other_a.timestamp_m },
blocks (other_a.blocks), blocks (other_a.blocks),
account (other_a.account), account (other_a.account),
signature (other_a.signature) signature (other_a.signature)
@ -532,7 +537,7 @@ nano::vote::vote (bool & error_a, nano::stream & stream_a, nano::block_type type
{ {
nano::read (stream_a, account.bytes); nano::read (stream_a, account.bytes);
nano::read (stream_a, signature.bytes); nano::read (stream_a, signature.bytes);
nano::read (stream_a, timestamp); nano::read (stream_a, timestamp_m);
while (stream_a.in_avail () > 0) while (stream_a.in_avail () > 0)
{ {
@ -565,7 +570,7 @@ nano::vote::vote (bool & error_a, nano::stream & stream_a, nano::block_type type
} }
nano::vote::vote (nano::account const & account_a, nano::raw_key const & prv_a, uint64_t timestamp_a, std::shared_ptr<nano::block> const & block_a) : nano::vote::vote (nano::account const & account_a, nano::raw_key const & prv_a, uint64_t timestamp_a, std::shared_ptr<nano::block> const & block_a) :
timestamp{ timestamp_a }, timestamp_m{ timestamp_a },
blocks (1, block_a), blocks (1, block_a),
account (account_a), account (account_a),
signature (nano::sign_message (prv_a, account_a, hash ())) signature (nano::sign_message (prv_a, account_a, hash ()))
@ -573,7 +578,7 @@ nano::vote::vote (nano::account const & account_a, nano::raw_key const & prv_a,
} }
nano::vote::vote (nano::account const & account_a, nano::raw_key const & prv_a, uint64_t timestamp_a, std::vector<nano::block_hash> const & blocks_a) : nano::vote::vote (nano::account const & account_a, nano::raw_key const & prv_a, uint64_t timestamp_a, std::vector<nano::block_hash> const & blocks_a) :
timestamp{ timestamp_a }, timestamp_m{ timestamp_a },
account (account_a) account (account_a)
{ {
debug_assert (!blocks_a.empty ()); debug_assert (!blocks_a.empty ());
@ -614,7 +619,7 @@ nano::block_hash nano::vote::hash () const
uint64_t qword; uint64_t qword;
std::array<uint8_t, 8> bytes; std::array<uint8_t, 8> bytes;
}; };
qword = timestamp; qword = timestamp_m;
blake2b_update (&hash, bytes.data (), sizeof (bytes)); blake2b_update (&hash, bytes.data (), sizeof (bytes));
blake2b_final (&hash, result.bytes.data (), sizeof (result.bytes)); blake2b_final (&hash, result.bytes.data (), sizeof (result.bytes));
return result; return result;
@ -636,7 +641,7 @@ void nano::vote::serialize (nano::stream & stream_a, nano::block_type type) cons
{ {
write (stream_a, account); write (stream_a, account);
write (stream_a, signature); write (stream_a, signature);
write (stream_a, boost::endian::native_to_little (timestamp)); write (stream_a, boost::endian::native_to_little (timestamp_m));
for (auto const & block : blocks) for (auto const & block : blocks)
{ {
if (block.which ()) if (block.which ())
@ -662,7 +667,7 @@ void nano::vote::serialize (nano::stream & stream_a) const
{ {
write (stream_a, account); write (stream_a, account);
write (stream_a, signature); write (stream_a, signature);
write (stream_a, boost::endian::native_to_little (timestamp)); write (stream_a, boost::endian::native_to_little (timestamp_m));
for (auto const & block : blocks) for (auto const & block : blocks)
{ {
if (block.which ()) if (block.which ())
@ -684,8 +689,8 @@ bool nano::vote::deserialize (nano::stream & stream_a, nano::block_uniquer * uni
{ {
nano::read (stream_a, account); nano::read (stream_a, account);
nano::read (stream_a, signature); nano::read (stream_a, signature);
nano::read (stream_a, timestamp); nano::read (stream_a, timestamp_m);
boost::endian::little_to_native_inplace (timestamp); boost::endian::little_to_native_inplace (timestamp_m);
nano::block_type type; nano::block_type type;

View file

@ -249,8 +249,8 @@ public:
vote (nano::vote const &); vote (nano::vote const &);
vote (bool &, nano::stream &, nano::block_uniquer * = nullptr); vote (bool &, nano::stream &, nano::block_uniquer * = nullptr);
vote (bool &, nano::stream &, nano::block_type, nano::block_uniquer * = nullptr); vote (bool &, nano::stream &, nano::block_type, nano::block_uniquer * = nullptr);
vote (nano::account const &, nano::raw_key const &, uint64_t, std::shared_ptr<nano::block> const &); vote (nano::account const &, nano::raw_key const &, uint64_t timestamp, std::shared_ptr<nano::block> const &);
vote (nano::account const &, nano::raw_key const &, uint64_t, std::vector<nano::block_hash> const &); vote (nano::account const &, nano::raw_key const &, uint64_t timestamp, std::vector<nano::block_hash> const &);
std::string hashes_string () const; std::string hashes_string () const;
nano::block_hash hash () const; nano::block_hash hash () const;
nano::block_hash full_hash () const; nano::block_hash full_hash () const;
@ -264,8 +264,15 @@ public:
boost::transform_iterator<nano::iterate_vote_blocks_as_hash, nano::vote_blocks_vec_iter> begin () const; boost::transform_iterator<nano::iterate_vote_blocks_as_hash, nano::vote_blocks_vec_iter> begin () const;
boost::transform_iterator<nano::iterate_vote_blocks_as_hash, nano::vote_blocks_vec_iter> end () const; boost::transform_iterator<nano::iterate_vote_blocks_as_hash, nano::vote_blocks_vec_iter> end () const;
std::string to_json () const; std::string to_json () const;
uint64_t timestamp () const;
static uint64_t constexpr timestamp_max = { 0xffff'ffff'ffff'ffffULL };
static uint64_t constexpr timestamp_min = { 0x0000'0000'0000'0001ULL };
private:
// Vote timestamp // Vote timestamp
uint64_t timestamp; uint64_t timestamp_m;
public:
// The blocks, or block hashes, that this vote is for // The blocks, or block hashes, that this vote is for
std::vector<boost::variant<std::shared_ptr<nano::block>, nano::block_hash>> blocks; std::vector<boost::variant<std::shared_ptr<nano::block>, nano::block_hash>> blocks;
// Account that's voting // Account that's voting