Merge pull request #3813 from clemahieu/remove_vote_by_block
This commit is contained in:
commit
32a3222849
22 changed files with 143 additions and 475 deletions
|
@ -542,7 +542,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, nano::vote::timestamp_max, nano::vote::duration_max, send1));
|
||||
auto vote_send1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector<nano::block_hash>{ send1->hash () }));
|
||||
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));
|
||||
|
@ -550,7 +550,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, nano::vote::timestamp_max, nano::vote::duration_max, open1));
|
||||
auto vote_open1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector<nano::block_hash>{ open1->hash () }));
|
||||
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 ());
|
||||
|
@ -570,8 +570,8 @@ TEST (active_transactions, vote_replays)
|
|||
node.process_active (send2);
|
||||
nano::blocks_confirm (node, { send2 });
|
||||
ASSERT_EQ (1, node.active.size ());
|
||||
auto vote1_send2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, send2));
|
||||
auto vote2_send2 (std::make_shared<nano::vote> (key.pub, key.prv, 0, 0, send2));
|
||||
auto vote1_send2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector<nano::block_hash>{ send2->hash () }));
|
||||
auto vote2_send2 (std::make_shared<nano::vote> (key.pub, key.prv, 0, 0, std::vector<nano::block_hash>{ send2->hash () }));
|
||||
ASSERT_EQ (nano::vote_code::vote, node.active.vote (vote2_send2));
|
||||
ASSERT_EQ (1, node.active.size ());
|
||||
ASSERT_EQ (nano::vote_code::replay, node.active.vote (vote2_send2));
|
||||
|
@ -1021,7 +1021,7 @@ TEST (active_transactions, conflicting_block_vote_existing_election)
|
|||
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
|
||||
.work (*system.work.generate (nano::dev::genesis->hash ()))
|
||||
.build_shared ();
|
||||
auto vote_fork (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, fork));
|
||||
auto vote_fork (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector<nano::block_hash>{ fork->hash () }));
|
||||
|
||||
ASSERT_EQ (nano::process_result::progress, node.process_local (send).code);
|
||||
node.scheduler.flush ();
|
||||
|
|
|
@ -27,26 +27,19 @@ TEST (conflicts, start_stop)
|
|||
|
||||
TEST (conflicts, add_existing)
|
||||
{
|
||||
nano::system system (1);
|
||||
auto & node1 (*system.nodes[0]);
|
||||
nano::system system{ 1 };
|
||||
auto & node1 = *system.nodes[0];
|
||||
nano::keypair key1;
|
||||
auto send1 (std::make_shared<nano::send_block> (nano::dev::genesis->hash (), key1.pub, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, 0));
|
||||
auto send1 = std::make_shared<nano::send_block> (nano::dev::genesis->hash (), key1.pub, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, 0);
|
||||
node1.work_generate_blocking (*send1);
|
||||
ASSERT_EQ (nano::process_result::progress, node1.process (*send1).code);
|
||||
node1.scheduler.activate (nano::dev::genesis_key.pub, node1.store.tx_begin_read ());
|
||||
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);
|
||||
send2->sideband_set ({});
|
||||
node1.scheduler.activate (nano::dev::genesis_key.pub, node1.store.tx_begin_read ());
|
||||
node1.scheduler.flush ();
|
||||
auto election1 = node1.active.election (send2->qualified_root ());
|
||||
ASSERT_NE (nullptr, election1);
|
||||
ASSERT_EQ (1, node1.active.size ());
|
||||
auto vote1 (std::make_shared<nano::vote> (key2.pub, key2.prv, 0, 0, send2));
|
||||
node1.active.vote (vote1);
|
||||
ASSERT_EQ (2, election1->votes ().size ());
|
||||
auto votes (election1->votes ());
|
||||
ASSERT_NE (votes.end (), votes.find (key2.pub));
|
||||
node1.block_processor.add (send2);
|
||||
ASSERT_TIMELY (5s, node1.active.active (*send2));
|
||||
}
|
||||
|
||||
TEST (conflicts, add_two)
|
||||
|
@ -148,35 +141,6 @@ TEST (vote_uniquer, null)
|
|||
ASSERT_EQ (nullptr, uniquer.unique (nullptr));
|
||||
}
|
||||
|
||||
// Show that an identical vote can be uniqued
|
||||
TEST (vote_uniquer, same_vote)
|
||||
{
|
||||
nano::block_uniquer block_uniquer;
|
||||
nano::vote_uniquer uniquer (block_uniquer);
|
||||
nano::keypair key;
|
||||
auto vote1 (std::make_shared<nano::vote> (key.pub, key.prv, 0, 0, std::make_shared<nano::state_block> (0, 0, 0, 0, 0, key.prv, key.pub, 0)));
|
||||
auto vote2 (std::make_shared<nano::vote> (*vote1));
|
||||
ASSERT_EQ (vote1, uniquer.unique (vote1));
|
||||
ASSERT_EQ (vote1, uniquer.unique (vote2));
|
||||
}
|
||||
|
||||
// Show that a different vote for the same block will have the block uniqued
|
||||
TEST (vote_uniquer, same_block)
|
||||
{
|
||||
nano::block_uniquer block_uniquer;
|
||||
nano::vote_uniquer uniquer (block_uniquer);
|
||||
nano::keypair key1;
|
||||
nano::keypair key2;
|
||||
auto block1 (std::make_shared<nano::state_block> (0, 0, 0, 0, 0, key1.prv, key1.pub, 0));
|
||||
auto block2 (std::make_shared<nano::state_block> (*block1));
|
||||
auto vote1 (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, 0, block1));
|
||||
auto vote2 (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, 0, block2));
|
||||
ASSERT_EQ (vote1, uniquer.unique (vote1));
|
||||
ASSERT_EQ (vote2, uniquer.unique (vote2));
|
||||
ASSERT_NE (vote1, vote2);
|
||||
ASSERT_EQ (boost::get<std::shared_ptr<nano::block>> (vote1->blocks[0]), boost::get<std::shared_ptr<nano::block>> (vote2->blocks[0]));
|
||||
}
|
||||
|
||||
TEST (vote_uniquer, vbh_one)
|
||||
{
|
||||
nano::block_uniquer block_uniquer;
|
||||
|
@ -213,10 +177,10 @@ TEST (vote_uniquer, cleanup)
|
|||
nano::block_uniquer block_uniquer;
|
||||
nano::vote_uniquer uniquer (block_uniquer);
|
||||
nano::keypair key;
|
||||
auto vote1 (std::make_shared<nano::vote> (key.pub, key.prv, 0, 0, std::make_shared<nano::state_block> (0, 0, 0, 0, 0, key.prv, key.pub, 0)));
|
||||
auto vote2 (std::make_shared<nano::vote> (key.pub, key.prv, nano::vote::timestamp_min * 1, 0, std::make_shared<nano::state_block> (0, 0, 0, 0, 0, key.prv, key.pub, 0)));
|
||||
auto vote3 (uniquer.unique (vote1));
|
||||
auto vote4 (uniquer.unique (vote2));
|
||||
auto vote1 = std::make_shared<nano::vote> (key.pub, key.prv, 0, 0, std::vector<nano::block_hash>{ nano::block_hash{ 0 } });
|
||||
auto vote2 = std::make_shared<nano::vote> (key.pub, key.prv, nano::vote::timestamp_min * 1, 0, std::vector<nano::block_hash>{ nano::block_hash{ 0 } });
|
||||
auto vote3 = uniquer.unique (vote1);
|
||||
auto vote4 = uniquer.unique (vote2);
|
||||
vote2.reset ();
|
||||
vote4.reset ();
|
||||
ASSERT_EQ (2, uniquer.size ());
|
||||
|
|
|
@ -58,7 +58,7 @@ TEST (election, quorum_minimum_flip_success)
|
|||
ASSERT_TIMELY (5s, (election = node1.active.election (send2->qualified_root ())) != nullptr)
|
||||
ASSERT_TIMELY (5s, election->blocks ().size () == 2);
|
||||
|
||||
auto const vote1 = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, send2);
|
||||
auto const vote1 = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector<nano::block_hash>{ send2->hash () });
|
||||
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
|
||||
|
||||
ASSERT_TIMELY (5s, election->confirmed ());
|
||||
|
@ -109,7 +109,7 @@ TEST (election, quorum_minimum_flip_fail)
|
|||
ASSERT_TIMELY (5s, (election = node1.active.election (send2->qualified_root ())) != nullptr)
|
||||
ASSERT_TIMELY (5s, election->blocks ().size () == 2);
|
||||
|
||||
auto const vote1 = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, send2);
|
||||
auto const vote1 = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector<nano::block_hash>{ send2->hash () });
|
||||
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
|
||||
|
||||
// give the election 5 seconds before asserting it is not confirmed so that in case
|
||||
|
@ -146,7 +146,7 @@ TEST (election, quorum_minimum_confirm_success)
|
|||
auto election = node1.active.election (send1->qualified_root ());
|
||||
ASSERT_NE (nullptr, election);
|
||||
ASSERT_EQ (1, election->blocks ().size ());
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, send1));
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector<nano::block_hash>{ send1->hash () }));
|
||||
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
|
||||
node1.block_processor.flush ();
|
||||
ASSERT_NE (nullptr, node1.block (send1->hash ()));
|
||||
|
@ -179,7 +179,7 @@ TEST (election, quorum_minimum_confirm_fail)
|
|||
auto election = node1.active.election (send1->qualified_root ());
|
||||
ASSERT_NE (nullptr, election);
|
||||
ASSERT_EQ (1, election->blocks ().size ());
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, send1));
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector<nano::block_hash>{ send1->hash () }));
|
||||
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
|
||||
node1.block_processor.flush ();
|
||||
ASSERT_NE (nullptr, node1.block (send1->hash ()));
|
||||
|
@ -236,13 +236,13 @@ TEST (election, quorum_minimum_update_weight_before_quorum_checks)
|
|||
ASSERT_TIMELY (5s, (election = node1.active.election (send1->qualified_root ())) != nullptr);
|
||||
ASSERT_EQ (1, election->blocks ().size ());
|
||||
|
||||
auto const vote1 = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, send1);
|
||||
auto const vote1 = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector<nano::block_hash>{ send1->hash () });
|
||||
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
|
||||
|
||||
auto channel = node1.network.find_channel (node2.network.endpoint ());
|
||||
ASSERT_NE (channel, nullptr);
|
||||
|
||||
auto const vote2 = std::make_shared<nano::vote> (key1.pub, key1.prv, nano::vote::timestamp_max, nano::vote::duration_max, send1);
|
||||
auto const vote2 = std::make_shared<nano::vote> (key1.pub, key1.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector<nano::block_hash>{ send1->hash () });
|
||||
ASSERT_TIMELY (10s, !node1.rep_crawler.response (channel, vote2));
|
||||
|
||||
ASSERT_FALSE (election->confirmed ());
|
||||
|
|
|
@ -646,7 +646,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, nano::vote::timestamp_min * 1, 0, send1));
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, std::vector<nano::block_hash>{ send1->hash () }));
|
||||
vote1->signature.bytes[0] ^= 1;
|
||||
ASSERT_EQ (nano::vote_code::invalid, node1.vote_processor.vote_blocking (vote1, std::make_shared<nano::transport::inproc::channel> (node1, node1)));
|
||||
vote1->signature.bytes[0] ^= 1;
|
||||
|
@ -667,9 +667,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, nano::vote::timestamp_min * 1, 0, send1));
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, std::vector<nano::block_hash>{ send1->hash () }));
|
||||
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, nano::vote::timestamp_min * 2, 0, send1));
|
||||
auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, 0, std::vector<nano::block_hash>{ send1->hash () }));
|
||||
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2));
|
||||
ASSERT_EQ (2, election1->votes ().size ());
|
||||
auto votes1 (election1->votes ());
|
||||
|
@ -682,33 +682,6 @@ TEST (votes, add_one)
|
|||
ASSERT_EQ (nano::dev::constants.genesis_amount - 100, winner.first);
|
||||
}
|
||||
|
||||
TEST (votes, add_two)
|
||||
{
|
||||
nano::system system{ 1 };
|
||||
auto & node1 = *system.nodes[0];
|
||||
nano::keypair key1;
|
||||
auto send1 = std::make_shared<nano::send_block> (nano::dev::genesis->hash (), key1.pub, nano::dev::constants.genesis_amount - 100, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, 0);
|
||||
node1.work_generate_blocking (*send1);
|
||||
auto transaction = node1.store.tx_begin_write ();
|
||||
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code);
|
||||
node1.block_confirm (send1);
|
||||
node1.scheduler.flush ();
|
||||
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, nano::vote::timestamp_min * 1, 0, 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, nano::vote::timestamp_min * 1, 0, send1);
|
||||
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
|
||||
ASSERT_EQ (3, election1->votes ().size ());
|
||||
auto votes1 = election1->votes ();
|
||||
ASSERT_NE (votes1.end (), votes1.find (nano::dev::genesis_key.pub));
|
||||
ASSERT_EQ (send1->hash (), votes1[nano::dev::genesis_key.pub].hash);
|
||||
ASSERT_NE (votes1.end (), votes1.find (key2.pub));
|
||||
ASSERT_EQ (send2->hash (), votes1[key2.pub].hash);
|
||||
ASSERT_EQ (*send1, *election1->winner ());
|
||||
}
|
||||
|
||||
namespace nano
|
||||
{
|
||||
// Higher timestamps change the vote
|
||||
|
@ -735,7 +708,7 @@ 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, nano::vote::timestamp_min * 1, 0, send1));
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, std::vector<nano::block_hash>{ send1->hash () }));
|
||||
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1));
|
||||
// Block is already processed from vote
|
||||
ASSERT_TRUE (node1.active.publish (send1));
|
||||
|
@ -751,13 +724,14 @@ 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, nano::vote::timestamp_min * 2, 0, send2));
|
||||
ASSERT_FALSE (node1.active.publish (send2));
|
||||
ASSERT_TIMELY (5s, node1.active.active (*send2));
|
||||
auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, 0, std::vector<nano::block_hash>{ send2->hash () }));
|
||||
// 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 (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 ();
|
||||
|
@ -785,13 +759,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, nano::vote::timestamp_min * 2, 0, send1));
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, 0, std::vector<nano::block_hash>{ send1->hash () }));
|
||||
auto channel (std::make_shared<nano::transport::inproc::channel> (node1, 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, nano::vote::timestamp_min * 1, 0, send2));
|
||||
auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, std::vector<nano::block_hash>{ send2->hash () }));
|
||||
{
|
||||
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);
|
||||
|
@ -827,13 +801,13 @@ TEST (votes, DISABLED_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, nano::vote::timestamp_min * 2, 0, send1));
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, 0, std::vector<nano::block_hash>{ send1->hash () }));
|
||||
auto channel (std::make_shared<nano::transport::inproc::channel> (node1, 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, nano::vote::timestamp_min * 1, 0, send2));
|
||||
auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, std::vector<nano::block_hash>{ send2->hash () }));
|
||||
auto vote_result2 (node1.vote_processor.vote_blocking (vote2, channel));
|
||||
ASSERT_EQ (nano::vote_code::vote, vote_result2);
|
||||
ASSERT_EQ (2, election1->votes ().size ());
|
||||
|
@ -861,13 +835,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, nano::vote::timestamp_min * 1, 0, send1));
|
||||
auto vote1 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, std::vector<nano::block_hash>{ send1->hash () }));
|
||||
auto channel (std::make_shared<nano::transport::inproc::channel> (node1, 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, nano::vote::timestamp_min * 2, 0, send2));
|
||||
auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, 0, std::vector<nano::block_hash>{ send2->hash () }));
|
||||
node1.vote_processor.vote_blocking (vote2, channel);
|
||||
ASSERT_EQ (2, election1->votes ().size ());
|
||||
auto votes (election1->votes ());
|
||||
|
|
|
@ -71,25 +71,6 @@ TEST (message, publish_serialization)
|
|||
ASSERT_EQ (nano::message_type::publish, header.type);
|
||||
}
|
||||
|
||||
TEST (message, confirm_ack_serialization)
|
||||
{
|
||||
nano::keypair key1;
|
||||
auto vote (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, 0, std::make_shared<nano::send_block> (0, 1, 2, key1.prv, 4, 5)));
|
||||
nano::confirm_ack con1{ nano::dev::network_params.network, vote };
|
||||
std::vector<uint8_t> bytes;
|
||||
{
|
||||
nano::vectorstream stream1 (bytes);
|
||||
con1.serialize (stream1);
|
||||
}
|
||||
nano::bufferstream stream2 (bytes.data (), bytes.size ());
|
||||
bool error (false);
|
||||
nano::message_header header (error, stream2);
|
||||
nano::confirm_ack con2 (error, stream2, header);
|
||||
ASSERT_FALSE (error);
|
||||
ASSERT_EQ (con1, con2);
|
||||
ASSERT_EQ (header.block_type (), nano::block_type::send);
|
||||
}
|
||||
|
||||
TEST (message, confirm_ack_hash_serialization)
|
||||
{
|
||||
std::vector<nano::block_hash> hashes;
|
||||
|
@ -115,12 +96,7 @@ TEST (message, confirm_ack_hash_serialization)
|
|||
nano::confirm_ack con2 (error, stream2, header);
|
||||
ASSERT_FALSE (error);
|
||||
ASSERT_EQ (con1, con2);
|
||||
std::vector<nano::block_hash> vote_blocks;
|
||||
for (auto block : con2.vote->blocks)
|
||||
{
|
||||
vote_blocks.push_back (boost::get<nano::block_hash> (block));
|
||||
}
|
||||
ASSERT_EQ (hashes, vote_blocks);
|
||||
ASSERT_EQ (hashes, con2.vote->hashes);
|
||||
// Check overflow with max hashes
|
||||
ASSERT_EQ (header.count_get (), hashes.size ());
|
||||
ASSERT_EQ (header.block_type (), nano::block_type::not_a_block);
|
||||
|
@ -218,3 +194,13 @@ TEST (message, message_header_to_string)
|
|||
std::string header_string = keepalive_msg.header.to_string ();
|
||||
ASSERT_EQ (expected_str, header_string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a confirm_ack can encode an empty hash set
|
||||
*/
|
||||
TEST (confirm_ack, empty_vote_hashes)
|
||||
{
|
||||
nano::keypair key;
|
||||
auto vote = std::make_shared<nano::vote> (key.pub, key.prv, 0, 0, std::vector<nano::block_hash>{} /* empty */);
|
||||
nano::confirm_ack message{ nano::dev::network_params.network, vote };
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ TEST (message_parser, exact_confirm_ack_size)
|
|||
nano::vote_uniquer vote_uniquer (block_uniquer);
|
||||
nano::message_parser parser (filter, block_uniquer, vote_uniquer, visitor, system.work, nano::dev::network_params.network);
|
||||
auto block (std::make_shared<nano::send_block> (1, 1, 2, nano::keypair ().prv, 4, *system.work.generate (nano::root (1))));
|
||||
auto vote (std::make_shared<nano::vote> (0, nano::keypair ().prv, 0, 0, std::move (block)));
|
||||
auto vote (std::make_shared<nano::vote> (0, nano::keypair ().prv, 0, 0, std::vector<nano::block_hash>{ block->hash () }));
|
||||
nano::confirm_ack message{ nano::dev::network_params.network, vote };
|
||||
std::vector<uint8_t> bytes;
|
||||
{
|
||||
|
|
|
@ -372,7 +372,7 @@ TEST (receivable_processor, confirm_insufficient_pos)
|
|||
ASSERT_EQ (nano::process_result::progress, node1.process (*block1).code);
|
||||
node1.scheduler.activate (nano::dev::genesis_key.pub, node1.store.tx_begin_read ());
|
||||
nano::keypair key1;
|
||||
auto vote (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, 0, block1));
|
||||
auto vote (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, 0, std::vector<nano::block_hash>{ block1->hash () }));
|
||||
nano::confirm_ack con1{ nano::dev::network_params.network, vote };
|
||||
node1.network.inbound (con1, node1.network.udp_channels.create (node1.network.endpoint ()));
|
||||
}
|
||||
|
@ -385,7 +385,7 @@ TEST (receivable_processor, confirm_sufficient_pos)
|
|||
node1.work_generate_blocking (*block1);
|
||||
ASSERT_EQ (nano::process_result::progress, node1.process (*block1).code);
|
||||
node1.scheduler.activate (nano::dev::genesis_key.pub, node1.store.tx_begin_read ());
|
||||
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, block1));
|
||||
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector<nano::block_hash>{ block1->hash () }));
|
||||
nano::confirm_ack con1{ nano::dev::network_params.network, vote };
|
||||
node1.network.inbound (con1, node1.network.udp_channels.create (node1.network.endpoint ()));
|
||||
}
|
||||
|
|
|
@ -1154,7 +1154,7 @@ TEST (node, fork_no_vote_quorum)
|
|||
nano::raw_key key3;
|
||||
auto transaction (system.wallet (1)->wallets.tx_begin_read ());
|
||||
ASSERT_FALSE (system.wallet (1)->store.fetch (transaction, key1, key3));
|
||||
auto vote (std::make_shared<nano::vote> (key1, key3, 0, 0, send2));
|
||||
auto vote = std::make_shared<nano::vote> (key1, key3, 0, 0, std::vector<nano::block_hash>{ send2->hash () });
|
||||
nano::confirm_ack confirm{ nano::dev::network_params.network, vote };
|
||||
std::vector<uint8_t> buffer;
|
||||
{
|
||||
|
@ -1816,9 +1816,9 @@ TEST (node, rep_weight)
|
|||
ASSERT_NE (nullptr, channel2);
|
||||
std::shared_ptr<nano::transport::channel> channel3 = nano::establish_tcp (system, node, node3.network.endpoint ());
|
||||
ASSERT_NE (nullptr, channel3);
|
||||
auto vote0 = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, nano::dev::genesis);
|
||||
auto vote1 = std::make_shared<nano::vote> (keypair1.pub, keypair1.prv, 0, 0, nano::dev::genesis);
|
||||
auto vote2 = std::make_shared<nano::vote> (keypair2.pub, keypair2.prv, 0, 0, nano::dev::genesis);
|
||||
auto vote0 = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector<nano::block_hash>{ nano::dev::genesis->hash () });
|
||||
auto vote1 = std::make_shared<nano::vote> (keypair1.pub, keypair1.prv, 0, 0, std::vector<nano::block_hash>{ nano::dev::genesis->hash () });
|
||||
auto vote2 = std::make_shared<nano::vote> (keypair2.pub, keypair2.prv, 0, 0, std::vector<nano::block_hash>{ nano::dev::genesis->hash () });
|
||||
node.rep_crawler.response (channel1, vote0);
|
||||
node.rep_crawler.response (channel2, vote1);
|
||||
node.rep_crawler.response (channel3, vote2);
|
||||
|
@ -1895,7 +1895,7 @@ TEST (node, rep_remove)
|
|||
std::shared_ptr<nano::transport::channel> channel0 (std::make_shared<nano::transport::channel_udp> (node.network.udp_channels, endpoint0, node.network_params.network.protocol_version));
|
||||
auto channel_udp = node.network.udp_channels.insert (endpoint0, node.network_params.network.protocol_version);
|
||||
ASSERT_NE (channel_udp, nullptr);
|
||||
auto vote1 = std::make_shared<nano::vote> (keypair1.pub, keypair1.prv, 0, 0, nano::dev::genesis);
|
||||
auto vote1 = std::make_shared<nano::vote> (keypair1.pub, keypair1.prv, 0, 0, std::vector<nano::block_hash>{ nano::dev::genesis->hash () });
|
||||
ASSERT_FALSE (node.rep_crawler.response (channel0, vote1));
|
||||
ASSERT_TIMELY (5s, node.rep_crawler.representative_count () == 1);
|
||||
auto reps (node.rep_crawler.representatives (1));
|
||||
|
@ -1916,13 +1916,13 @@ TEST (node, rep_remove)
|
|||
system.wallet (1)->insert_adhoc (nano::dev::genesis_key.prv);
|
||||
auto channel1 (node.network.find_channel (node1->network.endpoint ()));
|
||||
ASSERT_NE (nullptr, channel1);
|
||||
auto vote2 = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, nano::dev::genesis);
|
||||
auto vote2 = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector<nano::block_hash>{ nano::dev::genesis->hash () });
|
||||
node.rep_crawler.response (channel1, vote2);
|
||||
ASSERT_TIMELY (10s, node.rep_crawler.representative_count () == 1);
|
||||
auto node2 (std::make_shared<nano::node> (system.io_ctx, nano::unique_path (), nano::node_config (nano::get_available_port (), system.logging), system.work));
|
||||
node2->start ();
|
||||
std::weak_ptr<nano::node> node_w (node.shared ());
|
||||
auto vote3 = std::make_shared<nano::vote> (keypair2.pub, keypair2.prv, 0, 0, nano::dev::genesis);
|
||||
auto vote3 = std::make_shared<nano::vote> (keypair2.pub, keypair2.prv, 0, 0, std::vector<nano::block_hash>{ nano::dev::genesis->hash () });
|
||||
node.network.tcp_channels.start_tcp (node2->network.endpoint ());
|
||||
std::shared_ptr<nano::transport::channel> channel2;
|
||||
ASSERT_TIMELY (10s, (channel2 = node.network.tcp_channels.find_channel (nano::transport::map_endpoint_to_tcp (node2->network.endpoint ()))) != nullptr);
|
||||
|
@ -2455,8 +2455,8 @@ TEST (node, local_votes_cache_generate_new_vote)
|
|||
ASSERT_TIMELY (3s, !node.history.votes (nano::dev::genesis->root (), nano::dev::genesis->hash ()).empty ());
|
||||
auto votes1 (node.history.votes (nano::dev::genesis->root (), nano::dev::genesis->hash ()));
|
||||
ASSERT_EQ (1, votes1.size ());
|
||||
ASSERT_EQ (1, votes1[0]->blocks.size ());
|
||||
ASSERT_EQ (nano::dev::genesis->hash (), boost::get<nano::block_hash> (votes1[0]->blocks[0]));
|
||||
ASSERT_EQ (1, votes1[0]->hashes.size ());
|
||||
ASSERT_EQ (nano::dev::genesis->hash (), votes1[0]->hashes[0]);
|
||||
ASSERT_TIMELY (3s, node.stats.count (nano::stat::type::requests, nano::stat::detail::requests_generated_votes) == 1);
|
||||
auto send1 = nano::state_block_builder ()
|
||||
.account (nano::dev::genesis_key.pub)
|
||||
|
@ -2475,7 +2475,7 @@ TEST (node, local_votes_cache_generate_new_vote)
|
|||
ASSERT_TIMELY (3s, !node.history.votes (send1->root (), send1->hash ()).empty ());
|
||||
auto votes2 (node.history.votes (send1->root (), send1->hash ()));
|
||||
ASSERT_EQ (1, votes2.size ());
|
||||
ASSERT_EQ (1, votes2[0]->blocks.size ());
|
||||
ASSERT_EQ (1, votes2[0]->hashes.size ());
|
||||
ASSERT_TIMELY (3s, node.stats.count (nano::stat::type::requests, nano::stat::detail::requests_generated_votes) == 2);
|
||||
ASSERT_FALSE (node.history.votes (nano::dev::genesis->root (), nano::dev::genesis->hash ()).empty ());
|
||||
ASSERT_FALSE (node.history.votes (send1->root (), send1->hash ()).empty ());
|
||||
|
@ -2522,7 +2522,7 @@ TEST (node, local_votes_cache_fork)
|
|||
node1.history.add (send1->root (), send1->hash (), vote);
|
||||
auto votes2 (node1.history.votes (send1->root (), send1->hash ()));
|
||||
ASSERT_EQ (1, votes2.size ());
|
||||
ASSERT_EQ (1, votes2[0]->blocks.size ());
|
||||
ASSERT_EQ (1, votes2[0]->hashes.size ());
|
||||
// Start election for forked block
|
||||
node_config.peering_port = nano::get_available_port ();
|
||||
auto & node2 (*system.add_node (node_config, node_flags));
|
||||
|
@ -2557,7 +2557,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, nano::vote::timestamp_max, nano::vote::duration_max, send2));
|
||||
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector<nano::block_hash>{ send2->hash () }));
|
||||
ASSERT_TRUE (node1.active.active (*send1));
|
||||
ASSERT_TIMELY (10s, node2.active.active (*send1));
|
||||
node1.vote_processor.vote (vote, std::make_shared<nano::transport::inproc::channel> (node1, node1));
|
||||
|
@ -2609,9 +2609,9 @@ TEST (node, vote_by_hash_bundle)
|
|||
system.wallet (0)->insert_adhoc (key1.prv);
|
||||
|
||||
system.nodes[0]->observers.vote.add ([&max_hashes] (std::shared_ptr<nano::vote> const & vote_a, std::shared_ptr<nano::transport::channel> const &, nano::vote_code) {
|
||||
if (vote_a->blocks.size () > max_hashes)
|
||||
if (vote_a->hashes.size () > max_hashes)
|
||||
{
|
||||
max_hashes = vote_a->blocks.size ();
|
||||
max_hashes = vote_a->hashes.size ();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -2830,8 +2830,8 @@ TEST (node, DISABLED_fork_invalid_block_signature)
|
|||
.build_shared ();
|
||||
auto send2_corrupt (std::make_shared<nano::send_block> (*send2));
|
||||
send2_corrupt->signature = nano::signature (123);
|
||||
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, send2));
|
||||
auto vote_corrupt (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, send2_corrupt));
|
||||
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector<nano::block_hash>{ send2->hash () }));
|
||||
auto vote_corrupt (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector<nano::block_hash>{ send2_corrupt->hash () }));
|
||||
|
||||
node1.process_active (send1);
|
||||
ASSERT_TIMELY (5s, node1.block (send1->hash ()));
|
||||
|
|
|
@ -333,4 +333,13 @@ TEST (vote, timestamp_and_duration_masking)
|
|||
ASSERT_EQ (vote->timestamp (), 0x1230);
|
||||
ASSERT_EQ (vote->duration ().count (), 524288);
|
||||
ASSERT_EQ (vote->duration_bits (), 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a vote can encode an empty hash set
|
||||
*/
|
||||
TEST (vote, empty_hashes)
|
||||
{
|
||||
nano::keypair key;
|
||||
auto vote = std::make_shared<nano::vote> (key.pub, key.prv, 0, 0, std::vector<nano::block_hash>{} /* empty */);
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ TEST (vote_generator, cache)
|
|||
ASSERT_TIMELY (1s, !node.history.votes (epoch1->root (), epoch1->hash ()).empty ());
|
||||
auto votes (node.history.votes (epoch1->root (), epoch1->hash ()));
|
||||
ASSERT_FALSE (votes.empty ());
|
||||
ASSERT_TRUE (std::any_of (votes[0]->begin (), votes[0]->end (), [hash = epoch1->hash ()] (nano::block_hash const & hash_a) { return hash_a == hash; }));
|
||||
ASSERT_TRUE (std::any_of (votes[0]->hashes.begin (), votes[0]->hashes.end (), [hash = epoch1->hash ()] (nano::block_hash const & hash_a) { return hash_a == hash; }));
|
||||
}
|
||||
|
||||
TEST (vote_generator, multiple_representatives)
|
||||
|
|
|
@ -599,7 +599,7 @@ TEST (websocket, vote_options_type)
|
|||
ASSERT_TIMELY (5s, ack_ready);
|
||||
|
||||
// Custom made votes for simplicity
|
||||
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, nano::dev::genesis));
|
||||
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector<nano::block_hash>{ nano::dev::genesis->hash () }));
|
||||
nano::websocket::message_builder builder;
|
||||
auto msg (builder.vote_received (vote, nano::vote_code::replay));
|
||||
node1->websocket_server->broadcast (msg);
|
||||
|
|
|
@ -863,42 +863,21 @@ nano::vote_code nano::active_transactions::vote (std::shared_ptr<nano::vote> con
|
|||
std::vector<std::pair<std::shared_ptr<nano::election>, nano::block_hash>> process;
|
||||
{
|
||||
nano::unique_lock<nano::mutex> lock (mutex);
|
||||
for (auto vote_block : vote_a->blocks)
|
||||
for (auto const & hash : vote_a->hashes)
|
||||
{
|
||||
auto & recently_confirmed_by_hash (recently_confirmed.get<tag_hash> ());
|
||||
if (vote_block.which ())
|
||||
auto existing (blocks.find (hash));
|
||||
if (existing != blocks.end ())
|
||||
{
|
||||
auto const & block_hash (boost::get<nano::block_hash> (vote_block));
|
||||
auto existing (blocks.find (block_hash));
|
||||
if (existing != blocks.end ())
|
||||
{
|
||||
process.emplace_back (existing->second, block_hash);
|
||||
}
|
||||
else if (recently_confirmed_by_hash.count (block_hash) == 0)
|
||||
{
|
||||
add_inactive_votes_cache (lock, block_hash, vote_a->account, vote_a->timestamp ());
|
||||
}
|
||||
else
|
||||
{
|
||||
++recently_confirmed_counter;
|
||||
}
|
||||
process.emplace_back (existing->second, hash);
|
||||
}
|
||||
else if (recently_confirmed_by_hash.count (hash) == 0)
|
||||
{
|
||||
add_inactive_votes_cache (lock, hash, vote_a->account, vote_a->timestamp ());
|
||||
}
|
||||
else
|
||||
{
|
||||
auto block (boost::get<std::shared_ptr<nano::block>> (vote_block));
|
||||
auto existing (roots.get<tag_root> ().find (block->qualified_root ()));
|
||||
if (existing != roots.get<tag_root> ().end ())
|
||||
{
|
||||
process.emplace_back (existing->election, block->hash ());
|
||||
}
|
||||
else if (recently_confirmed_by_hash.count (block->hash ()) == 0)
|
||||
{
|
||||
add_inactive_votes_cache (lock, block->hash (), vote_a->account, vote_a->timestamp ());
|
||||
}
|
||||
else
|
||||
{
|
||||
++recently_confirmed_counter;
|
||||
}
|
||||
++recently_confirmed_counter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -925,7 +904,7 @@ nano::vote_code nano::active_transactions::vote (std::shared_ptr<nano::vote> con
|
|||
}
|
||||
result = replay ? nano::vote_code::replay : nano::vote_code::vote;
|
||||
}
|
||||
else if (recently_confirmed_counter == vote_a->blocks.size ())
|
||||
else if (recently_confirmed_counter == vote_a->hashes.size ())
|
||||
{
|
||||
result = nano::vote_code::replay;
|
||||
}
|
||||
|
|
|
@ -512,33 +512,14 @@ void nano::bootstrap_server::receive_confirm_ack_action (boost::system::error_co
|
|||
{
|
||||
if (!ec)
|
||||
{
|
||||
auto error (false);
|
||||
nano::bufferstream stream (receive_buffer->data (), size_a);
|
||||
auto request (std::make_unique<nano::confirm_ack> (error, stream, header_a));
|
||||
auto error = false;
|
||||
nano::bufferstream stream{ receive_buffer->data (), size_a };
|
||||
auto request = std::make_unique<nano::confirm_ack> (error, stream, header_a);
|
||||
if (!error)
|
||||
{
|
||||
if (is_realtime_connection ())
|
||||
{
|
||||
bool process_vote (true);
|
||||
if (header_a.block_type () != nano::block_type::not_a_block)
|
||||
{
|
||||
for (auto & vote_block : request->vote->blocks)
|
||||
{
|
||||
if (!vote_block.which ())
|
||||
{
|
||||
auto const & block (boost::get<std::shared_ptr<nano::block>> (vote_block));
|
||||
if (node->network_params.work.validate_entry (*block))
|
||||
{
|
||||
process_vote = false;
|
||||
node->stats.inc_detail_only (nano::stat::type::error, nano::stat::detail::insufficient_work);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (process_vote)
|
||||
{
|
||||
add_request (std::unique_ptr<nano::message> (request.release ()));
|
||||
}
|
||||
add_request (std::move (request));
|
||||
}
|
||||
receive ();
|
||||
}
|
||||
|
|
|
@ -285,7 +285,7 @@ std::size_t nano::message_header::payload_length_bytes () const
|
|||
}
|
||||
case nano::message_type::confirm_ack:
|
||||
{
|
||||
return nano::confirm_ack::size (block_type (), count_get ());
|
||||
return nano::confirm_ack::size (count_get ());
|
||||
}
|
||||
case nano::message_type::confirm_req:
|
||||
{
|
||||
|
@ -523,22 +523,7 @@ void nano::message_parser::deserialize_confirm_ack (nano::stream & stream_a, nan
|
|||
nano::confirm_ack incoming (error, stream_a, header_a, &vote_uniquer);
|
||||
if (!error && at_end (stream_a))
|
||||
{
|
||||
for (auto & vote_block : incoming.vote->blocks)
|
||||
{
|
||||
if (!vote_block.which ())
|
||||
{
|
||||
auto const & block (boost::get<std::shared_ptr<nano::block>> (vote_block));
|
||||
if (network.work.validate_entry (*block))
|
||||
{
|
||||
status = parse_status::insufficient_work;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (status == parse_status::success)
|
||||
{
|
||||
visitor.confirm_ack (incoming);
|
||||
}
|
||||
visitor.confirm_ack (incoming);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -840,7 +825,7 @@ std::size_t nano::confirm_req::size (nano::block_type type_a, std::size_t count)
|
|||
|
||||
nano::confirm_ack::confirm_ack (bool & error_a, nano::stream & stream_a, nano::message_header const & header_a, nano::vote_uniquer * uniquer_a) :
|
||||
message (header_a),
|
||||
vote (nano::make_shared<nano::vote> (error_a, stream_a, header.block_type ()))
|
||||
vote (nano::make_shared<nano::vote> (error_a, stream_a))
|
||||
{
|
||||
if (!error_a && uniquer_a)
|
||||
{
|
||||
|
@ -852,25 +837,16 @@ nano::confirm_ack::confirm_ack (nano::network_constants const & constants, std::
|
|||
message (constants, nano::message_type::confirm_ack),
|
||||
vote (vote_a)
|
||||
{
|
||||
debug_assert (!vote_a->blocks.empty ());
|
||||
auto & first_vote_block (vote_a->blocks[0]);
|
||||
if (first_vote_block.which ())
|
||||
{
|
||||
header.block_type_set (nano::block_type::not_a_block);
|
||||
debug_assert (vote_a->blocks.size () < 16);
|
||||
header.count_set (static_cast<uint8_t> (vote_a->blocks.size ()));
|
||||
}
|
||||
else
|
||||
{
|
||||
header.block_type_set (boost::get<std::shared_ptr<nano::block>> (first_vote_block)->type ());
|
||||
}
|
||||
header.block_type_set (nano::block_type::not_a_block);
|
||||
debug_assert (vote_a->hashes.size () < 16);
|
||||
header.count_set (static_cast<uint8_t> (vote_a->hashes.size ()));
|
||||
}
|
||||
|
||||
void nano::confirm_ack::serialize (nano::stream & stream_a) const
|
||||
{
|
||||
debug_assert (header.block_type () == nano::block_type::not_a_block || header.block_type () == nano::block_type::send || header.block_type () == nano::block_type::receive || header.block_type () == nano::block_type::open || header.block_type () == nano::block_type::change || header.block_type () == nano::block_type::state);
|
||||
header.serialize (stream_a);
|
||||
vote->serialize (stream_a, header.block_type ());
|
||||
vote->serialize (stream_a);
|
||||
}
|
||||
|
||||
bool nano::confirm_ack::operator== (nano::confirm_ack const & other_a) const
|
||||
|
@ -884,17 +860,9 @@ void nano::confirm_ack::visit (nano::message_visitor & visitor_a) const
|
|||
visitor_a.confirm_ack (*this);
|
||||
}
|
||||
|
||||
std::size_t nano::confirm_ack::size (nano::block_type type_a, std::size_t count)
|
||||
std::size_t nano::confirm_ack::size (std::size_t count)
|
||||
{
|
||||
std::size_t result (sizeof (nano::account) + sizeof (nano::signature) + sizeof (uint64_t));
|
||||
if (type_a != nano::block_type::invalid && type_a != nano::block_type::not_a_block)
|
||||
{
|
||||
result += nano::block::size (type_a);
|
||||
}
|
||||
else if (type_a == nano::block_type::not_a_block)
|
||||
{
|
||||
result += count * sizeof (nano::block_hash);
|
||||
}
|
||||
std::size_t result = sizeof (nano::account) + sizeof (nano::signature) + sizeof (uint64_t) + count * sizeof (nano::block_hash);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -347,7 +347,7 @@ public:
|
|||
void visit (nano::message_visitor &) const override;
|
||||
bool operator== (nano::confirm_ack const &) const;
|
||||
std::shared_ptr<nano::vote> vote;
|
||||
static std::size_t size (nano::block_type, std::size_t = 0);
|
||||
static std::size_t size (std::size_t count);
|
||||
};
|
||||
|
||||
class frontier_req final : public message
|
||||
|
|
|
@ -38,7 +38,7 @@ void nano::gap_cache::erase (nano::block_hash const & hash_a)
|
|||
void nano::gap_cache::vote (std::shared_ptr<nano::vote> const & vote_a)
|
||||
{
|
||||
nano::lock_guard<nano::mutex> lock (mutex);
|
||||
for (auto hash : *vote_a)
|
||||
for (auto const & hash : vote_a->hashes)
|
||||
{
|
||||
auto & gap_blocks_by_hash (blocks.get<tag_hash> ());
|
||||
auto existing (gap_blocks_by_hash.find (hash));
|
||||
|
|
|
@ -484,24 +484,6 @@ public:
|
|||
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.header.block_type () != nano::block_type::not_a_block)
|
||||
{
|
||||
for (auto & vote_block : message_a.vote->blocks)
|
||||
{
|
||||
if (!vote_block.which ())
|
||||
{
|
||||
auto const & block (boost::get<std::shared_ptr<nano::block>> (vote_block));
|
||||
if (!node.block_processor.full ())
|
||||
{
|
||||
node.process_active (block);
|
||||
}
|
||||
else
|
||||
{
|
||||
node.stats.inc (nano::stat::type::drop, nano::stat::detail::confirm_ack, nano::stat::dir::in);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node.vote_processor.vote (message_a.vote, channel);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -233,7 +233,7 @@ bool nano::rep_crawler::response (std::shared_ptr<nano::transport::channel> cons
|
|||
{
|
||||
bool error = true;
|
||||
nano::lock_guard<nano::mutex> lock (active_mutex);
|
||||
for (auto i = vote_a->begin (), n = vote_a->end (); i != n; ++i)
|
||||
for (auto i = vote_a->hashes.begin (), n = vote_a->hashes.end (); i != n; ++i)
|
||||
{
|
||||
if (active.count (*i) != 0)
|
||||
{
|
||||
|
|
|
@ -326,7 +326,7 @@ void nano::vote_generator::reply (nano::unique_lock<nano::mutex> & lock_a, reque
|
|||
{
|
||||
if (cached_sent.insert (cached_vote).second)
|
||||
{
|
||||
stats.add (nano::stat::type::requests, nano::stat::detail::requests_cached_late_hashes, stat::dir::in, cached_vote->blocks.size ());
|
||||
stats.add (nano::stat::type::requests, nano::stat::detail::requests_cached_late_hashes, stat::dir::in, cached_vote->hashes.size ());
|
||||
stats.inc (nano::stat::type::requests, nano::stat::detail::requests_cached_late_votes, stat::dir::in);
|
||||
reply_action (cached_vote, request_a.second);
|
||||
}
|
||||
|
|
|
@ -451,38 +451,7 @@ nano::block_info::block_info (nano::account const & account_a, nano::amount cons
|
|||
|
||||
bool nano::vote::operator== (nano::vote const & other_a) const
|
||||
{
|
||||
auto blocks_equal (true);
|
||||
if (blocks.size () != other_a.blocks.size ())
|
||||
{
|
||||
blocks_equal = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto i (0); blocks_equal && i < blocks.size (); ++i)
|
||||
{
|
||||
auto block (blocks[i]);
|
||||
auto other_block (other_a.blocks[i]);
|
||||
if (block.which () != other_block.which ())
|
||||
{
|
||||
blocks_equal = false;
|
||||
}
|
||||
else if (block.which ())
|
||||
{
|
||||
if (boost::get<nano::block_hash> (block) != boost::get<nano::block_hash> (other_block))
|
||||
{
|
||||
blocks_equal = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(*boost::get<std::shared_ptr<nano::block>> (block) == *boost::get<std::shared_ptr<nano::block>> (other_block)))
|
||||
{
|
||||
blocks_equal = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return timestamp_m == other_a.timestamp_m && blocks_equal && account == other_a.account && signature == other_a.signature;
|
||||
return timestamp_m == other_a.timestamp_m && hashes == other_a.hashes && account == other_a.account && signature == other_a.signature;
|
||||
}
|
||||
|
||||
bool nano::vote::operator!= (nano::vote const & other_a) const
|
||||
|
@ -498,17 +467,10 @@ void nano::vote::serialize_json (boost::property_tree::ptree & tree) const
|
|||
tree.put ("timestamp", std::to_string (timestamp ()));
|
||||
tree.put ("duration", std::to_string (duration_bits ()));
|
||||
boost::property_tree::ptree blocks_tree;
|
||||
for (auto block : blocks)
|
||||
for (auto const & hash : hashes)
|
||||
{
|
||||
boost::property_tree::ptree entry;
|
||||
if (block.which ())
|
||||
{
|
||||
entry.put ("", boost::get<nano::block_hash> (block).to_string ());
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.put ("", boost::get<std::shared_ptr<nano::block>> (block)->hash ().to_string ());
|
||||
}
|
||||
entry.put ("", hash.to_string ());
|
||||
blocks_tree.push_back (std::make_pair ("", entry));
|
||||
}
|
||||
tree.add_child ("blocks", blocks_tree);
|
||||
|
@ -551,78 +513,29 @@ std::chrono::milliseconds nano::vote::duration () const
|
|||
|
||||
nano::vote::vote (nano::vote const & other_a) :
|
||||
timestamp_m{ other_a.timestamp_m },
|
||||
blocks (other_a.blocks),
|
||||
hashes{ other_a.hashes },
|
||||
account (other_a.account),
|
||||
signature (other_a.signature)
|
||||
{
|
||||
}
|
||||
|
||||
nano::vote::vote (bool & error_a, nano::stream & stream_a, nano::block_uniquer * uniquer_a)
|
||||
nano::vote::vote (bool & error_a, nano::stream & stream_a)
|
||||
{
|
||||
error_a = deserialize (stream_a, uniquer_a);
|
||||
error_a = deserialize (stream_a);
|
||||
}
|
||||
|
||||
nano::vote::vote (bool & error_a, nano::stream & stream_a, nano::block_type type_a, nano::block_uniquer * uniquer_a)
|
||||
{
|
||||
try
|
||||
{
|
||||
nano::read (stream_a, account.bytes);
|
||||
nano::read (stream_a, signature.bytes);
|
||||
nano::read (stream_a, timestamp_m);
|
||||
|
||||
while (stream_a.in_avail () > 0)
|
||||
{
|
||||
if (type_a == nano::block_type::not_a_block)
|
||||
{
|
||||
nano::block_hash block_hash;
|
||||
nano::read (stream_a, block_hash);
|
||||
blocks.push_back (block_hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto block (nano::deserialize_block (stream_a, type_a, uniquer_a));
|
||||
if (block == nullptr)
|
||||
{
|
||||
throw std::runtime_error ("Block is null");
|
||||
}
|
||||
blocks.push_back (block);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error const &)
|
||||
{
|
||||
error_a = true;
|
||||
}
|
||||
|
||||
if (blocks.empty ())
|
||||
{
|
||||
error_a = true;
|
||||
}
|
||||
}
|
||||
|
||||
nano::vote::vote (nano::account const & account_a, nano::raw_key const & prv_a, uint64_t timestamp_a, uint8_t duration, std::shared_ptr<nano::block> const & block_a) :
|
||||
timestamp_m{ packed_timestamp (timestamp_a, duration) },
|
||||
blocks (1, block_a),
|
||||
account (account_a),
|
||||
signature (nano::sign_message (prv_a, account_a, hash ()))
|
||||
{
|
||||
}
|
||||
|
||||
nano::vote::vote (nano::account const & account_a, nano::raw_key const & prv_a, uint64_t timestamp_a, uint8_t duration, 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, uint8_t duration, std::vector<nano::block_hash> const & hashes) :
|
||||
hashes{ hashes },
|
||||
timestamp_m{ packed_timestamp (timestamp_a, duration) },
|
||||
account (account_a)
|
||||
{
|
||||
debug_assert (!blocks_a.empty ());
|
||||
debug_assert (blocks_a.size () <= 12);
|
||||
blocks.reserve (blocks_a.size ());
|
||||
std::copy (blocks_a.cbegin (), blocks_a.cend (), std::back_inserter (blocks));
|
||||
signature = nano::sign_message (prv_a, account_a, hash ());
|
||||
}
|
||||
|
||||
std::string nano::vote::hashes_string () const
|
||||
{
|
||||
std::string result;
|
||||
for (auto hash : *this)
|
||||
for (auto const & hash : hashes)
|
||||
{
|
||||
result += hash.to_string ();
|
||||
result += ", ";
|
||||
|
@ -637,11 +550,8 @@ nano::block_hash nano::vote::hash () const
|
|||
nano::block_hash result;
|
||||
blake2b_state hash;
|
||||
blake2b_init (&hash, sizeof (result.bytes));
|
||||
if (blocks.size () > 1 || (!blocks.empty () && blocks.front ().which ()))
|
||||
{
|
||||
blake2b_update (&hash, hash_prefix.data (), hash_prefix.size ());
|
||||
}
|
||||
for (auto block_hash : *this)
|
||||
blake2b_update (&hash, hash_prefix.data (), hash_prefix.size ());
|
||||
for (auto const & block_hash : hashes)
|
||||
{
|
||||
blake2b_update (&hash, block_hash.bytes.data (), sizeof (block_hash.bytes));
|
||||
}
|
||||
|
@ -668,99 +578,37 @@ nano::block_hash nano::vote::full_hash () const
|
|||
return result;
|
||||
}
|
||||
|
||||
void nano::vote::serialize (nano::stream & stream_a, nano::block_type type) const
|
||||
{
|
||||
write (stream_a, account);
|
||||
write (stream_a, signature);
|
||||
write (stream_a, boost::endian::native_to_little (timestamp_m));
|
||||
for (auto const & block : blocks)
|
||||
{
|
||||
if (block.which ())
|
||||
{
|
||||
debug_assert (type == nano::block_type::not_a_block);
|
||||
write (stream_a, boost::get<nano::block_hash> (block));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (type == nano::block_type::not_a_block)
|
||||
{
|
||||
write (stream_a, boost::get<std::shared_ptr<nano::block>> (block)->hash ());
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::get<std::shared_ptr<nano::block>> (block)->serialize (stream_a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nano::vote::serialize (nano::stream & stream_a) const
|
||||
{
|
||||
write (stream_a, account);
|
||||
write (stream_a, signature);
|
||||
write (stream_a, boost::endian::native_to_little (timestamp_m));
|
||||
for (auto const & block : blocks)
|
||||
for (auto const & hash : hashes)
|
||||
{
|
||||
if (block.which ())
|
||||
{
|
||||
write (stream_a, nano::block_type::not_a_block);
|
||||
write (stream_a, boost::get<nano::block_hash> (block));
|
||||
}
|
||||
else
|
||||
{
|
||||
nano::serialize_block (stream_a, *boost::get<std::shared_ptr<nano::block>> (block));
|
||||
}
|
||||
write (stream_a, hash);
|
||||
}
|
||||
}
|
||||
|
||||
bool nano::vote::deserialize (nano::stream & stream_a, nano::block_uniquer * uniquer_a)
|
||||
bool nano::vote::deserialize (nano::stream & stream_a)
|
||||
{
|
||||
auto error (false);
|
||||
auto error = false;
|
||||
try
|
||||
{
|
||||
nano::read (stream_a, account);
|
||||
nano::read (stream_a, signature);
|
||||
nano::read (stream_a, account.bytes);
|
||||
nano::read (stream_a, signature.bytes);
|
||||
nano::read (stream_a, timestamp_m);
|
||||
boost::endian::little_to_native_inplace (timestamp_m);
|
||||
|
||||
nano::block_type type;
|
||||
|
||||
while (true)
|
||||
while (stream_a.in_avail () > 0)
|
||||
{
|
||||
if (nano::try_read (stream_a, type))
|
||||
{
|
||||
// Reached the end of the stream
|
||||
break;
|
||||
}
|
||||
|
||||
if (type == nano::block_type::not_a_block)
|
||||
{
|
||||
nano::block_hash block_hash;
|
||||
nano::read (stream_a, block_hash);
|
||||
blocks.push_back (block_hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto block (nano::deserialize_block (stream_a, type, uniquer_a));
|
||||
if (block == nullptr)
|
||||
{
|
||||
throw std::runtime_error ("Block is empty");
|
||||
}
|
||||
|
||||
blocks.push_back (block);
|
||||
}
|
||||
nano::block_hash block_hash;
|
||||
nano::read (stream_a, block_hash);
|
||||
hashes.push_back (block_hash);
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error const &)
|
||||
{
|
||||
error = true;
|
||||
}
|
||||
|
||||
if (blocks.empty ())
|
||||
{
|
||||
error = true;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -776,28 +624,9 @@ uint64_t nano::vote::packed_timestamp (uint64_t timestamp, uint8_t duration) con
|
|||
return (timestamp & timestamp_mask) | duration;
|
||||
}
|
||||
|
||||
nano::block_hash nano::iterate_vote_blocks_as_hash::operator() (boost::variant<std::shared_ptr<nano::block>, nano::block_hash> const & item) const
|
||||
nano::block_hash nano::iterate_vote_blocks_as_hash::operator() (nano::block_hash const & item) const
|
||||
{
|
||||
nano::block_hash result;
|
||||
if (item.which ())
|
||||
{
|
||||
result = boost::get<nano::block_hash> (item);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = boost::get<std::shared_ptr<nano::block>> (item)->hash ();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
boost::transform_iterator<nano::iterate_vote_blocks_as_hash, nano::vote_blocks_vec_iter> nano::vote::begin () const
|
||||
{
|
||||
return boost::transform_iterator<nano::iterate_vote_blocks_as_hash, nano::vote_blocks_vec_iter> (blocks.begin (), nano::iterate_vote_blocks_as_hash ());
|
||||
}
|
||||
|
||||
boost::transform_iterator<nano::iterate_vote_blocks_as_hash, nano::vote_blocks_vec_iter> nano::vote::end () const
|
||||
{
|
||||
return boost::transform_iterator<nano::iterate_vote_blocks_as_hash, nano::vote_blocks_vec_iter> (blocks.end (), nano::iterate_vote_blocks_as_hash ());
|
||||
return item;
|
||||
}
|
||||
|
||||
nano::vote_uniquer::vote_uniquer (nano::block_uniquer & uniquer_a) :
|
||||
|
@ -807,16 +636,12 @@ nano::vote_uniquer::vote_uniquer (nano::block_uniquer & uniquer_a) :
|
|||
|
||||
std::shared_ptr<nano::vote> nano::vote_uniquer::unique (std::shared_ptr<nano::vote> const & vote_a)
|
||||
{
|
||||
auto result (vote_a);
|
||||
if (result != nullptr && !result->blocks.empty ())
|
||||
auto result = vote_a;
|
||||
if (result != nullptr)
|
||||
{
|
||||
if (!result->blocks.front ().which ())
|
||||
{
|
||||
result->blocks.front () = uniquer.unique (boost::get<std::shared_ptr<nano::block>> (result->blocks.front ()));
|
||||
}
|
||||
nano::block_hash key (vote_a->full_hash ());
|
||||
nano::lock_guard<nano::mutex> lock (mutex);
|
||||
auto & existing (votes[key]);
|
||||
nano::block_hash key = vote_a->full_hash ();
|
||||
nano::lock_guard<nano::mutex> lock{ mutex };
|
||||
auto & existing = votes[key];
|
||||
if (auto block_l = existing.lock ())
|
||||
{
|
||||
result = block_l;
|
||||
|
|
|
@ -246,31 +246,32 @@ namespace confirmation_height
|
|||
uint64_t const unbounded_cutoff{ 16384 };
|
||||
}
|
||||
|
||||
using vote_blocks_vec_iter = std::vector<boost::variant<std::shared_ptr<nano::block>, nano::block_hash>>::const_iterator;
|
||||
using vote_blocks_vec_iter = std::vector<nano::block_hash>::const_iterator;
|
||||
class iterate_vote_blocks_as_hash final
|
||||
{
|
||||
public:
|
||||
iterate_vote_blocks_as_hash () = default;
|
||||
nano::block_hash operator() (boost::variant<std::shared_ptr<nano::block>, nano::block_hash> const & item) const;
|
||||
nano::block_hash operator() (nano::block_hash const & item) const;
|
||||
};
|
||||
class vote final
|
||||
{
|
||||
public:
|
||||
vote () = default;
|
||||
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 timestamp, uint8_t duration, std::shared_ptr<nano::block> const &);
|
||||
vote (bool &, nano::stream &);
|
||||
vote (nano::account const &, nano::raw_key const &, uint64_t timestamp, uint8_t duration, std::vector<nano::block_hash> const &);
|
||||
std::string hashes_string () const;
|
||||
nano::block_hash hash () const;
|
||||
nano::block_hash full_hash () const;
|
||||
bool operator== (nano::vote const &) const;
|
||||
bool operator!= (nano::vote const &) const;
|
||||
void serialize (nano::stream &, nano::block_type) const;
|
||||
void serialize (nano::stream &) const;
|
||||
void serialize_json (boost::property_tree::ptree & tree) const;
|
||||
bool deserialize (nano::stream &, nano::block_uniquer * = nullptr);
|
||||
/**
|
||||
* Deserializes a vote from the bytes in `stream'
|
||||
* Returns true if there was an error
|
||||
*/
|
||||
bool deserialize (nano::stream &);
|
||||
bool validate () 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;
|
||||
|
@ -288,8 +289,8 @@ private:
|
|||
uint64_t timestamp_m;
|
||||
|
||||
public:
|
||||
// The blocks, or block hashes, that this vote is for
|
||||
std::vector<boost::variant<std::shared_ptr<nano::block>, nano::block_hash>> blocks;
|
||||
// The hashes for which this vote directly covers
|
||||
std::vector<nano::block_hash> hashes;
|
||||
// Account that's voting
|
||||
nano::account account;
|
||||
// Signature of timestamp + block hashes
|
||||
|
|
|
@ -464,10 +464,9 @@ TEST (store, vote_load)
|
|||
{
|
||||
nano::system system (1);
|
||||
auto & node (*system.nodes[0]);
|
||||
auto block (std::make_shared<nano::send_block> (0, 0, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, 0));
|
||||
for (auto i (0); i < 1000000; ++i)
|
||||
{
|
||||
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, i, 0, block));
|
||||
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, i, 0, std::vector<nano::block_hash>{ i }));
|
||||
node.vote_processor.vote (vote, std::make_shared<nano::transport::inproc::channel> (node, node));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue