Add nano::vote::timestamp_min and nano::vote::timestamp_max variables and use these constants in tests.
This commit is contained in:
		
					parent
					
						
							
								f58fbe42a1
							
						
					
				
			
			
				commit
				
					
						9f2f1b0cf8
					
				
			
		
					 9 changed files with 53 additions and 51 deletions
				
			
		| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			@ -519,7 +519,7 @@ 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));
 | 
			
		||||
| 
						 | 
				
			
			@ -527,7 +527,7 @@ TEST (active_transactions, vote_replays)
 | 
			
		|||
	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 ());
 | 
			
		||||
| 
						 | 
				
			
			@ -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 ());
 | 
			
		||||
| 
						 | 
				
			
			@ -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 ();
 | 
			
		||||
| 
						 | 
				
			
			@ -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 ();
 | 
			
		||||
| 
						 | 
				
			
			@ -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 ();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -141,7 +141,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 ();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 ()));
 | 
			
		||||
| 
						 | 
				
			
			@ -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 ()));
 | 
			
		||||
| 
						 | 
				
			
			@ -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 ()));
 | 
			
		||||
| 
						 | 
				
			
			@ -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 ()));
 | 
			
		||||
| 
						 | 
				
			
			@ -238,9 +238,9 @@ TEST (election, 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));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -645,7 +645,7 @@ TEST (votes, check_signature)
 | 
			
		|||
	node1.scheduler.flush ();
 | 
			
		||||
	auto election1 = node1.active.election (send1->qualified_root ());
 | 
			
		||||
	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;
 | 
			
		||||
	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;
 | 
			
		||||
| 
						 | 
				
			
			@ -666,9 +666,9 @@ TEST (votes, add_one)
 | 
			
		|||
	node1.scheduler.flush ();
 | 
			
		||||
	auto election1 = node1.active.election (send1->qualified_root ());
 | 
			
		||||
	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));
 | 
			
		||||
	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 (2, election1->votes ().size ());
 | 
			
		||||
	auto votes1 (election1->votes ());
 | 
			
		||||
| 
						 | 
				
			
			@ -695,9 +695,9 @@ TEST (votes, add_two)
 | 
			
		|||
	auto election1 = node1.active.election (send1->qualified_root ());
 | 
			
		||||
	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 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));
 | 
			
		||||
	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 (3, election1->votes ().size ());
 | 
			
		||||
	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.flush ();
 | 
			
		||||
	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));
 | 
			
		||||
	// Block is already processed from vote
 | 
			
		||||
	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;
 | 
			
		||||
	std::shared_ptr<nano::block> send2 = builder.state ()
 | 
			
		||||
										 .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)
 | 
			
		||||
										 .build ();
 | 
			
		||||
	node1.work_generate_blocking (*send2);
 | 
			
		||||
	auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 2, send2));
 | 
			
		||||
	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
 | 
			
		||||
	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);
 | 
			
		||||
	lock.unlock ();
 | 
			
		||||
	ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2));
 | 
			
		||||
	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
 | 
			
		||||
	lock.lock ();
 | 
			
		||||
	election1->last_votes[nano::dev::genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20);
 | 
			
		||||
	lock.unlock ();
 | 
			
		||||
	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 ());
 | 
			
		||||
	ASSERT_EQ (2, votes.size ());
 | 
			
		||||
	ASSERT_NE (votes.end (), votes.find (nano::dev::genesis_key.pub));
 | 
			
		||||
| 
						 | 
				
			
			@ -784,13 +784,13 @@ TEST (votes, add_old)
 | 
			
		|||
	node1.block_confirm (send1);
 | 
			
		||||
	node1.scheduler.flush ();
 | 
			
		||||
	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));
 | 
			
		||||
	node1.vote_processor.vote_blocking (vote1, channel);
 | 
			
		||||
	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));
 | 
			
		||||
	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);
 | 
			
		||||
		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_EQ (1, election1->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 vote_result1 (node1.vote_processor.vote_blocking (vote1, channel));
 | 
			
		||||
	ASSERT_EQ (nano::vote_code::vote, vote_result1);
 | 
			
		||||
	ASSERT_EQ (2, election1->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));
 | 
			
		||||
	ASSERT_EQ (nano::vote_code::vote, vote_result2);
 | 
			
		||||
	ASSERT_EQ (2, election1->votes ().size ());
 | 
			
		||||
| 
						 | 
				
			
			@ -857,13 +857,13 @@ TEST (votes, add_cooldown)
 | 
			
		|||
	node1.block_confirm (send1);
 | 
			
		||||
	node1.scheduler.flush ();
 | 
			
		||||
	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));
 | 
			
		||||
	node1.vote_processor.vote_blocking (vote1, channel);
 | 
			
		||||
	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));
 | 
			
		||||
	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);
 | 
			
		||||
	ASSERT_EQ (2, election1->votes ().size ());
 | 
			
		||||
	auto votes (election1->votes ());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2922,7 +2922,7 @@ TEST (node, vote_republish)
 | 
			
		|||
	node1.process_active (send1);
 | 
			
		||||
	ASSERT_TIMELY (5s, node2.block (send1->hash ()));
 | 
			
		||||
	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_TIMELY (10s, node2.active.active (*send1));
 | 
			
		||||
	node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node1));
 | 
			
		||||
| 
						 | 
				
			
			@ -3017,7 +3017,7 @@ TEST (node, vote_by_hash_republish)
 | 
			
		|||
	node1.process_active (send2);
 | 
			
		||||
	std::vector<nano::block_hash> vote_blocks;
 | 
			
		||||
	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 (node2.active.active (*send1));
 | 
			
		||||
	node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node1));
 | 
			
		||||
| 
						 | 
				
			
			@ -3533,7 +3533,7 @@ TEST (node, confirm_back)
 | 
			
		|||
	ASSERT_EQ (3, node.active.size ());
 | 
			
		||||
	std::vector<nano::block_hash> vote_blocks;
 | 
			
		||||
	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));
 | 
			
		||||
	ASSERT_TIMELY (10s, node.active.empty ());
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -4083,7 +4083,7 @@ TEST (node, rollback_gap_source)
 | 
			
		|||
		ASSERT_EQ (2, election->blocks ().size ());
 | 
			
		||||
		ASSERT_EQ (1, election->votes ().size ());
 | 
			
		||||
		// 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));
 | 
			
		||||
		ASSERT_TIMELY (5s, election->votes ().size () == 2);
 | 
			
		||||
		ASSERT_TIMELY (3s, election->confirmed ());
 | 
			
		||||
| 
						 | 
				
			
			@ -4110,7 +4110,7 @@ TEST (node, rollback_gap_source)
 | 
			
		|||
		node.block_processor.flush ();
 | 
			
		||||
		ASSERT_EQ (2, election->blocks ().size ());
 | 
			
		||||
		// 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));
 | 
			
		||||
		ASSERT_TIMELY (5s, election->votes ().size () == 2);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,7 @@ TEST (vote_processor, codes)
 | 
			
		|||
	nano::system system (1);
 | 
			
		||||
	auto & node (*system.nodes[0]);
 | 
			
		||||
	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);
 | 
			
		||||
	vote_invalid->signature.bytes[0] ^= 1;
 | 
			
		||||
	auto channel (std::make_shared<nano::transport::channel_loopback> (node));
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +49,7 @@ TEST (vote_processor, flush)
 | 
			
		|||
	auto channel (std::make_shared<nano::transport::channel_loopback> (node));
 | 
			
		||||
	for (unsigned i = 0; i < 2000; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		auto vote = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 1 + i, std::vector<nano::block_hash>{ nano::dev::genesis->hash () });
 | 
			
		||||
		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 (vote, channel);
 | 
			
		||||
	}
 | 
			
		||||
	node.vote_processor.flush ();
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +61,7 @@ TEST (vote_processor, invalid_signature)
 | 
			
		|||
	nano::system system{ 1 };
 | 
			
		||||
	auto & node = *system.nodes[0];
 | 
			
		||||
	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);
 | 
			
		||||
	vote_invalid->signature.bytes[0] ^= 1;
 | 
			
		||||
	auto channel = std::make_shared<nano::transport::channel_loopback> (node);
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +85,7 @@ TEST (vote_processor, no_capacity)
 | 
			
		|||
	node_flags.vote_processor_capacity = 0;
 | 
			
		||||
	auto & node (*system.add_node (node_flags));
 | 
			
		||||
	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));
 | 
			
		||||
	ASSERT_TRUE (node.vote_processor.vote (vote, channel));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +97,7 @@ TEST (vote_processor, overflow)
 | 
			
		|||
	node_flags.vote_processor_capacity = 1;
 | 
			
		||||
	auto & node (*system.add_node (node_flags));
 | 
			
		||||
	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));
 | 
			
		||||
 | 
			
		||||
	// No way to lock the processor, but queueing votes in quick succession must result in overflow
 | 
			
		||||
| 
						 | 
				
			
			@ -195,7 +195,7 @@ TEST (vote_processor, no_broadcast_local)
 | 
			
		|||
	ASSERT_TRUE (node.wallets.reps ().exists (nano::dev::genesis_key.pub));
 | 
			
		||||
	ASSERT_FALSE (node.wallets.reps ().have_half_rep ());
 | 
			
		||||
	// 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));
 | 
			
		||||
	// Make sure the vote was processed
 | 
			
		||||
	auto election (node.active.election (send->qualified_root ()));
 | 
			
		||||
| 
						 | 
				
			
			@ -228,7 +228,7 @@ TEST (vote_processor, no_broadcast_local)
 | 
			
		|||
	ASSERT_EQ (node.config.vote_minimum, node.weight (nano::dev::genesis_key.pub));
 | 
			
		||||
	node.block_confirm (send2);
 | 
			
		||||
	// 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));
 | 
			
		||||
	// Make sure the vote was processed
 | 
			
		||||
	auto election2 (node.active.election (send2->qualified_root ()));
 | 
			
		||||
| 
						 | 
				
			
			@ -262,7 +262,7 @@ TEST (vote_processor, no_broadcast_local)
 | 
			
		|||
	ASSERT_TRUE (node.wallets.reps ().exists (nano::dev::genesis_key.pub));
 | 
			
		||||
	ASSERT_TRUE (node.wallets.reps ().have_half_rep ());
 | 
			
		||||
	// 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));
 | 
			
		||||
	// Make sure the vote was processed
 | 
			
		||||
	auto election3 (node.active.election (open->qualified_root ()));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -198,7 +198,7 @@ nano::vote_code nano::vote_processor::vote_blocking (std::shared_ptr<nano::vote>
 | 
			
		|||
	}
 | 
			
		||||
	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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 ());
 | 
			
		||||
	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) {
 | 
			
		||||
		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));
 | 
			
		||||
	});
 | 
			
		||||
	for (auto const & vote_l : votes_l)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -249,8 +249,8 @@ public:
 | 
			
		|||
	vote (nano::vote const &);
 | 
			
		||||
	vote (bool &, nano::stream &, 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, std::vector<nano::block_hash> 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 timestamp, std::vector<nano::block_hash> const &);
 | 
			
		||||
	std::string hashes_string () const;
 | 
			
		||||
	nano::block_hash hash () const;
 | 
			
		||||
	nano::block_hash full_hash () const;
 | 
			
		||||
| 
						 | 
				
			
			@ -265,6 +265,8 @@ public:
 | 
			
		|||
	boost::transform_iterator<nano::iterate_vote_blocks_as_hash, nano::vote_blocks_vec_iter> end () 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
 | 
			
		||||
	uint64_t timestamp_m;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue