diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index 162fe52fc5..c58c239b64 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -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::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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector{ 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::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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector{ 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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, send2)); - auto vote2_send2 (std::make_shared (key.pub, key.prv, 0, 0, send2)); + auto vote1_send2 (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector{ send2->hash () })); + auto vote2_send2 (std::make_shared (key.pub, key.prv, 0, 0, std::vector{ 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::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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector{ fork->hash () })); ASSERT_EQ (nano::process_result::progress, node.process_local (send).code); node.scheduler.flush (); diff --git a/nano/core_test/conflicts.cpp b/nano/core_test/conflicts.cpp index 575b64567f..453e85e0d2 100644 --- a/nano/core_test/conflicts.cpp +++ b/nano/core_test/conflicts.cpp @@ -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::dev::genesis->hash (), key1.pub, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, 0)); + auto send1 = std::make_shared (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::dev::genesis->hash (), key2.pub, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, 0)); + auto send2 = std::make_shared (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 (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 (key.pub, key.prv, 0, 0, std::make_shared (0, 0, 0, 0, 0, key.prv, key.pub, 0))); - auto vote2 (std::make_shared (*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 (0, 0, 0, 0, 0, key1.prv, key1.pub, 0)); - auto block2 (std::make_shared (*block1)); - auto vote1 (std::make_shared (key1.pub, key1.prv, 0, 0, block1)); - auto vote2 (std::make_shared (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> (vote1->blocks[0]), boost::get> (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 (key.pub, key.prv, 0, 0, std::make_shared (0, 0, 0, 0, 0, key.prv, key.pub, 0))); - auto vote2 (std::make_shared (key.pub, key.prv, nano::vote::timestamp_min * 1, 0, std::make_shared (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 (key.pub, key.prv, 0, 0, std::vector{ nano::block_hash{ 0 } }); + auto vote2 = std::make_shared (key.pub, key.prv, nano::vote::timestamp_min * 1, 0, std::vector{ nano::block_hash{ 0 } }); + auto vote3 = uniquer.unique (vote1); + auto vote4 = uniquer.unique (vote2); vote2.reset (); vote4.reset (); ASSERT_EQ (2, uniquer.size ()); diff --git a/nano/core_test/election.cpp b/nano/core_test/election.cpp index 52eca131fb..d79c8fad78 100644 --- a/nano/core_test/election.cpp +++ b/nano/core_test/election.cpp @@ -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::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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector{ 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::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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector{ 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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, send1)); + auto vote1 (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector{ 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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, send1)); + auto vote1 (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector{ 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::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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector{ 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 (key1.pub, key1.prv, nano::vote::timestamp_max, nano::vote::duration_max, send1); + auto const vote2 = std::make_shared (key1.pub, key1.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector{ send1->hash () }); ASSERT_TIMELY (10s, !node1.rep_crawler.response (channel, vote2)); ASSERT_FALSE (election->confirmed ()); diff --git a/nano/core_test/ledger.cpp b/nano/core_test/ledger.cpp index ac9ea40fa1..0fcab39e4c 100644 --- a/nano/core_test/ledger.cpp +++ b/nano/core_test/ledger.cpp @@ -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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, send1)); + auto vote1 (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, std::vector{ send1->hash () })); vote1->signature.bytes[0] ^= 1; ASSERT_EQ (nano::vote_code::invalid, node1.vote_processor.vote_blocking (vote1, std::make_shared (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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, send1)); + auto vote1 (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, std::vector{ send1->hash () })); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); - auto vote2 (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, 0, send1)); + auto vote2 (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, 0, std::vector{ 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::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::dev::genesis->hash (), key2.pub, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, 0); - auto vote2 = std::make_shared (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::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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, send1)); + auto vote1 (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, std::vector{ 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::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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, 0, std::vector{ send2->hash () })); // Pretend we've waited the timeout nano::unique_lock 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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, 0, send1)); + auto vote1 (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, 0, std::vector{ send1->hash () })); auto channel (std::make_shared (node1, node1)); node1.vote_processor.vote_blocking (vote1, channel); nano::keypair key2; auto send2 (std::make_shared (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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, send2)); + auto vote2 (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, std::vector{ send2->hash () })); { nano::lock_guard 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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, 0, send1)); + auto vote1 (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, 0, std::vector{ send1->hash () })); auto channel (std::make_shared (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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, send2)); + auto vote2 (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, std::vector{ 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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, send1)); + auto vote1 (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 1, 0, std::vector{ send1->hash () })); auto channel (std::make_shared (node1, node1)); node1.vote_processor.vote_blocking (vote1, channel); nano::keypair key2; auto send2 (std::make_shared (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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, 0, send2)); + auto vote2 (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_min * 2, 0, std::vector{ send2->hash () })); node1.vote_processor.vote_blocking (vote2, channel); ASSERT_EQ (2, election1->votes ().size ()); auto votes (election1->votes ()); diff --git a/nano/core_test/message.cpp b/nano/core_test/message.cpp index 515d451b9c..3a44370979 100644 --- a/nano/core_test/message.cpp +++ b/nano/core_test/message.cpp @@ -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 (key1.pub, key1.prv, 0, 0, std::make_shared (0, 1, 2, key1.prv, 4, 5))); - nano::confirm_ack con1{ nano::dev::network_params.network, vote }; - std::vector 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 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 vote_blocks; - for (auto block : con2.vote->blocks) - { - vote_blocks.push_back (boost::get (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 (key.pub, key.prv, 0, 0, std::vector{} /* empty */); + nano::confirm_ack message{ nano::dev::network_params.network, vote }; +} diff --git a/nano/core_test/message_parser.cpp b/nano/core_test/message_parser.cpp index 5430cc3ec2..56afa3c0de 100644 --- a/nano/core_test/message_parser.cpp +++ b/nano/core_test/message_parser.cpp @@ -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 (1, 1, 2, nano::keypair ().prv, 4, *system.work.generate (nano::root (1)))); - auto vote (std::make_shared (0, nano::keypair ().prv, 0, 0, std::move (block))); + auto vote (std::make_shared (0, nano::keypair ().prv, 0, 0, std::vector{ block->hash () })); nano::confirm_ack message{ nano::dev::network_params.network, vote }; std::vector bytes; { diff --git a/nano/core_test/network.cpp b/nano/core_test/network.cpp index 536073b1ab..70ea3f9dba 100644 --- a/nano/core_test/network.cpp +++ b/nano/core_test/network.cpp @@ -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 (key1.pub, key1.prv, 0, 0, block1)); + auto vote (std::make_shared (key1.pub, key1.prv, 0, 0, std::vector{ 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::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, block1)); + auto vote (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector{ block1->hash () })); nano::confirm_ack con1{ nano::dev::network_params.network, vote }; node1.network.inbound (con1, node1.network.udp_channels.create (node1.network.endpoint ())); } diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index 39d638cd68..11721ee7ba 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -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 (key1, key3, 0, 0, send2)); + auto vote = std::make_shared (key1, key3, 0, 0, std::vector{ send2->hash () }); nano::confirm_ack confirm{ nano::dev::network_params.network, vote }; std::vector buffer; { @@ -1816,9 +1816,9 @@ TEST (node, rep_weight) ASSERT_NE (nullptr, channel2); std::shared_ptr channel3 = nano::establish_tcp (system, node, node3.network.endpoint ()); ASSERT_NE (nullptr, channel3); - auto vote0 = std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, nano::dev::genesis); - auto vote1 = std::make_shared (keypair1.pub, keypair1.prv, 0, 0, nano::dev::genesis); - auto vote2 = std::make_shared (keypair2.pub, keypair2.prv, 0, 0, nano::dev::genesis); + auto vote0 = std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector{ nano::dev::genesis->hash () }); + auto vote1 = std::make_shared (keypair1.pub, keypair1.prv, 0, 0, std::vector{ nano::dev::genesis->hash () }); + auto vote2 = std::make_shared (keypair2.pub, keypair2.prv, 0, 0, std::vector{ 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 channel0 (std::make_shared (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 (keypair1.pub, keypair1.prv, 0, 0, nano::dev::genesis); + auto vote1 = std::make_shared (keypair1.pub, keypair1.prv, 0, 0, std::vector{ 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::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, nano::dev::genesis); + auto vote2 = std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector{ nano::dev::genesis->hash () }); node.rep_crawler.response (channel1, vote2); ASSERT_TIMELY (10s, node.rep_crawler.representative_count () == 1); auto node2 (std::make_shared (system.io_ctx, nano::unique_path (), nano::node_config (nano::get_available_port (), system.logging), system.work)); node2->start (); std::weak_ptr node_w (node.shared ()); - auto vote3 = std::make_shared (keypair2.pub, keypair2.prv, 0, 0, nano::dev::genesis); + auto vote3 = std::make_shared (keypair2.pub, keypair2.prv, 0, 0, std::vector{ nano::dev::genesis->hash () }); node.network.tcp_channels.start_tcp (node2->network.endpoint ()); std::shared_ptr 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 (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::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, send2)); + auto vote (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector{ send2->hash () })); ASSERT_TRUE (node1.active.active (*send1)); ASSERT_TIMELY (10s, node2.active.active (*send1)); node1.vote_processor.vote (vote, std::make_shared (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 const & vote_a, std::shared_ptr 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 (*send2)); send2_corrupt->signature = nano::signature (123); - auto vote (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, send2)); - auto vote_corrupt (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, send2_corrupt)); + auto vote (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector{ send2->hash () })); + auto vote_corrupt (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector{ send2_corrupt->hash () })); node1.process_active (send1); ASSERT_TIMELY (5s, node1.block (send1->hash ())); diff --git a/nano/core_test/vote_processor.cpp b/nano/core_test/vote_processor.cpp index 7fe9a47f9c..52b4078935 100644 --- a/nano/core_test/vote_processor.cpp +++ b/nano/core_test/vote_processor.cpp @@ -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); -} \ No newline at end of file +} + +/** + * Test that a vote can encode an empty hash set + */ +TEST (vote, empty_hashes) +{ + nano::keypair key; + auto vote = std::make_shared (key.pub, key.prv, 0, 0, std::vector{} /* empty */); +} diff --git a/nano/core_test/voting.cpp b/nano/core_test/voting.cpp index 8f52473efa..29a961c669 100644 --- a/nano/core_test/voting.cpp +++ b/nano/core_test/voting.cpp @@ -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) diff --git a/nano/core_test/websocket.cpp b/nano/core_test/websocket.cpp index 3e01d2df93..4f3d192871 100644 --- a/nano/core_test/websocket.cpp +++ b/nano/core_test/websocket.cpp @@ -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::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, nano::dev::genesis)); + auto vote (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector{ nano::dev::genesis->hash () })); nano::websocket::message_builder builder; auto msg (builder.vote_received (vote, nano::vote_code::replay)); node1->websocket_server->broadcast (msg); diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index ae25d7e5c0..3b389d6d40 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -863,42 +863,21 @@ nano::vote_code nano::active_transactions::vote (std::shared_ptr con std::vector, nano::block_hash>> process; { nano::unique_lock lock (mutex); - for (auto vote_block : vote_a->blocks) + for (auto const & hash : vote_a->hashes) { auto & recently_confirmed_by_hash (recently_confirmed.get ()); - if (vote_block.which ()) + auto existing (blocks.find (hash)); + if (existing != blocks.end ()) { - auto const & block_hash (boost::get (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> (vote_block)); - auto existing (roots.get ().find (block->qualified_root ())); - if (existing != roots.get ().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 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; } diff --git a/nano/node/bootstrap/bootstrap_server.cpp b/nano/node/bootstrap/bootstrap_server.cpp index 87222c9c3a..ae9e5f4bef 100644 --- a/nano/node/bootstrap/bootstrap_server.cpp +++ b/nano/node/bootstrap/bootstrap_server.cpp @@ -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 (error, stream, header_a)); + auto error = false; + nano::bufferstream stream{ receive_buffer->data (), size_a }; + auto request = std::make_unique (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> (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 (request.release ())); - } + add_request (std::move (request)); } receive (); } diff --git a/nano/node/common.cpp b/nano/node/common.cpp index b709738a50..5a3462eea9 100644 --- a/nano/node/common.cpp +++ b/nano/node/common.cpp @@ -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> (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 (error_a, stream_a, header.block_type ())) + vote (nano::make_shared (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 (vote_a->blocks.size ())); - } - else - { - header.block_type_set (boost::get> (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 (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; } diff --git a/nano/node/common.hpp b/nano/node/common.hpp index d9784aa541..d104e51386 100644 --- a/nano/node/common.hpp +++ b/nano/node/common.hpp @@ -347,7 +347,7 @@ class confirm_ack final : public message void visit (nano::message_visitor &) const override; bool operator== (nano::confirm_ack const &) const; std::shared_ptr 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 diff --git a/nano/node/gap_cache.cpp b/nano/node/gap_cache.cpp index 2b04836b57..0700b06e88 100644 --- a/nano/node/gap_cache.cpp +++ b/nano/node/gap_cache.cpp @@ -38,7 +38,7 @@ void nano::gap_cache::erase (nano::block_hash const & hash_a) void nano::gap_cache::vote (std::shared_ptr const & vote_a) { nano::lock_guard lock (mutex); - for (auto hash : *vote_a) + for (auto const & hash : vote_a->hashes) { auto & gap_blocks_by_hash (blocks.get ()); auto existing (gap_blocks_by_hash.find (hash)); diff --git a/nano/node/network.cpp b/nano/node/network.cpp index 64c6ec6730..e9fa2296ce 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -484,24 +484,6 @@ class network_message_visitor : public nano::message_visitor 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> (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); } } diff --git a/nano/node/repcrawler.cpp b/nano/node/repcrawler.cpp index d8e307fbd6..095e5ce398 100644 --- a/nano/node/repcrawler.cpp +++ b/nano/node/repcrawler.cpp @@ -233,7 +233,7 @@ bool nano::rep_crawler::response (std::shared_ptr cons { bool error = true; nano::lock_guard 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) { diff --git a/nano/node/voting.cpp b/nano/node/voting.cpp index b9ad78cf86..d61409f25b 100644 --- a/nano/node/voting.cpp +++ b/nano/node/voting.cpp @@ -326,7 +326,7 @@ void nano::vote_generator::reply (nano::unique_lock & 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); } diff --git a/nano/secure/common.cpp b/nano/secure/common.cpp index 387b76b3c6..89b8a2b941 100644 --- a/nano/secure/common.cpp +++ b/nano/secure/common.cpp @@ -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 (block) != boost::get (other_block)) - { - blocks_equal = false; - } - } - else - { - if (!(*boost::get> (block) == *boost::get> (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 (block).to_string ()); - } - else - { - entry.put ("", boost::get> (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 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 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 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 (block)); - } - else - { - if (type == nano::block_type::not_a_block) - { - write (stream_a, boost::get> (block)->hash ()); - } - else - { - boost::get> (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 (block)); - } - else - { - nano::serialize_block (stream_a, *boost::get> (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, 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 (item); - } - else - { - result = boost::get> (item)->hash (); - } - return result; -} - -boost::transform_iterator nano::vote::begin () const -{ - return boost::transform_iterator (blocks.begin (), nano::iterate_vote_blocks_as_hash ()); -} - -boost::transform_iterator nano::vote::end () const -{ - return boost::transform_iterator (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_uniquer::unique (std::shared_ptr 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> (result->blocks.front ())); - } - nano::block_hash key (vote_a->full_hash ()); - nano::lock_guard lock (mutex); - auto & existing (votes[key]); + nano::block_hash key = vote_a->full_hash (); + nano::lock_guard lock{ mutex }; + auto & existing = votes[key]; if (auto block_l = existing.lock ()) { result = block_l; diff --git a/nano/secure/common.hpp b/nano/secure/common.hpp index e99197bee0..879b55d815 100644 --- a/nano/secure/common.hpp +++ b/nano/secure/common.hpp @@ -246,31 +246,32 @@ namespace confirmation_height uint64_t const unbounded_cutoff{ 16384 }; } -using vote_blocks_vec_iter = std::vector, nano::block_hash>>::const_iterator; +using vote_blocks_vec_iter = std::vector::const_iterator; class iterate_vote_blocks_as_hash final { public: iterate_vote_blocks_as_hash () = default; - nano::block_hash operator() (boost::variant, 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 const &); + vote (bool &, nano::stream &); vote (nano::account const &, nano::raw_key const &, uint64_t timestamp, uint8_t duration, std::vector 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 begin () const; boost::transform_iterator end () const; @@ -288,8 +289,8 @@ class vote final uint64_t timestamp_m; public: - // The blocks, or block hashes, that this vote is for - std::vector, nano::block_hash>> blocks; + // The hashes for which this vote directly covers + std::vector hashes; // Account that's voting nano::account account; // Signature of timestamp + block hashes diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index 6e53968ba3..0d58f84c9a 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -464,10 +464,9 @@ TEST (store, vote_load) { nano::system system (1); auto & node (*system.nodes[0]); - auto block (std::make_shared (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::dev::genesis_key.pub, nano::dev::genesis_key.prv, i, 0, block)); + auto vote (std::make_shared (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, i, 0, std::vector{ i })); node.vote_processor.vote (vote, std::make_shared (node, node)); } }