Skip to content

Commit

Permalink
Improved inactive_vote_cache (#3907)
Browse files Browse the repository at this point in the history
  • Loading branch information
pwojcikdev committed Aug 29, 2022
1 parent fb5ddf0 commit 3f8cd4a
Show file tree
Hide file tree
Showing 15 changed files with 826 additions and 245 deletions.
1 change: 1 addition & 0 deletions nano/core_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ add_executable(
uint256_union.cpp
unchecked_map.cpp
utility.cpp
vote_cache.cpp
vote_processor.cpp
voting.cpp
wallet.cpp
Expand Down
38 changes: 18 additions & 20 deletions nano/core_test/active_transactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ TEST (active_transactions, inactive_votes_cache)
.build_shared ();
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector<nano::block_hash> (1, send->hash ())));
node.vote_processor.vote (vote, std::make_shared<nano::transport::inproc::channel> (node, node));
ASSERT_TIMELY (5s, node.active.inactive_votes_cache_size () == 1);
ASSERT_TIMELY (5s, node.inactive_vote_cache.cache_size () == 1);
node.process_active (send);
node.block_processor.flush ();
ASSERT_TIMELY (5s, node.ledger.block_confirmed (node.store.tx_begin_read (), send->hash ()));
Expand All @@ -243,7 +243,7 @@ TEST (active_transactions, inactive_votes_cache_non_final)
.build_shared ();
auto vote (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector<nano::block_hash> (1, send->hash ()))); // Non-final vote
node.vote_processor.vote (vote, std::make_shared<nano::transport::inproc::channel> (node, node));
ASSERT_TIMELY (5s, node.active.inactive_votes_cache_size () == 1);
ASSERT_TIMELY (5s, node.inactive_vote_cache.cache_size () == 1);
node.process_active (send);
node.block_processor.flush ();
ASSERT_TIMELY (5s, node.stats.count (nano::stat::type::election, nano::stat::detail::vote_cached) == 1);
Expand Down Expand Up @@ -280,7 +280,7 @@ TEST (active_transactions, inactive_votes_cache_fork)

auto const vote = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::vote::timestamp_max, nano::vote::duration_max, std::vector<nano::block_hash> (1, send1->hash ()));
node.vote_processor.vote (vote, std::make_shared<nano::transport::inproc::channel> (node, node));
ASSERT_TIMELY (5s, node.active.inactive_votes_cache_size () == 1);
ASSERT_TIMELY (5s, node.inactive_vote_cache.cache_size () == 1);

node.process_active (send2);

Expand Down Expand Up @@ -335,12 +335,11 @@ TEST (active_transactions, inactive_votes_cache_existing_vote)
ASSERT_EQ (nano::vote::timestamp_min * 1, last_vote1.timestamp);
// Attempt to change vote with inactive_votes_cache
nano::unique_lock<nano::mutex> active_lock (node.active.mutex);
node.active.add_inactive_votes_cache (active_lock, send->hash (), key.pub, 0);
active_lock.unlock ();
const auto cache (node.active.find_inactive_votes_cache (send->hash ()));
active_lock.lock ();
ASSERT_EQ (1, cache.voters.size ());
cache.fill (election);
node.inactive_vote_cache.vote (send->hash (), vote1);
auto cache = node.inactive_vote_cache.find (send->hash ());
ASSERT_TRUE (cache);
ASSERT_EQ (1, cache->voters.size ());
cache->fill (election);
// Check that election data is not changed
ASSERT_EQ (2, election->votes ().size ());
auto last_vote2 (election->votes ()[key.pub]);
Expand Down Expand Up @@ -394,8 +393,9 @@ TEST (active_transactions, DISABLED_inactive_votes_cache_multiple_votes)
node.vote_processor.vote (vote1, std::make_shared<nano::transport::inproc::channel> (node, node));
auto vote2 (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector<nano::block_hash> (1, send1->hash ())));
node.vote_processor.vote (vote2, std::make_shared<nano::transport::inproc::channel> (node, node));
ASSERT_TIMELY (5s, node.active.find_inactive_votes_cache (send1->hash ()).voters.size () == 2);
ASSERT_EQ (1, node.active.inactive_votes_cache_size ());
ASSERT_TIMELY (5s, node.inactive_vote_cache.find (send1->hash ()));
ASSERT_TIMELY (5s, node.inactive_vote_cache.find (send1->hash ())->voters.size () == 2);
ASSERT_EQ (1, node.inactive_vote_cache.cache_size ());
node.scheduler.activate (nano::dev::genesis_key.pub, node.store.tx_begin_read ());
node.scheduler.flush ();
auto election = node.active.election (send1->qualified_root ());
Expand Down Expand Up @@ -475,7 +475,7 @@ TEST (active_transactions, inactive_votes_cache_election_start)
std::vector<nano::block_hash> hashes{ open1->hash (), open2->hash (), send4->hash () };
auto vote1 (std::make_shared<nano::vote> (key1.pub, key1.prv, 0, 0, hashes));
node.vote_processor.vote (vote1, std::make_shared<nano::transport::inproc::channel> (node, node));
ASSERT_TIMELY (5s, node.active.inactive_votes_cache_size () == 3);
ASSERT_TIMELY (5s, node.inactive_vote_cache.cache_size () == 3);
ASSERT_TRUE (node.active.empty ());
ASSERT_EQ (1, node.ledger.cache.cemented_count);
// 2 votes are required to start election (dev network)
Expand All @@ -490,11 +490,9 @@ TEST (active_transactions, inactive_votes_cache_election_start)
ASSERT_TIMELY (5s, 5 == node.ledger.cache.cemented_count);
// A late block arrival also checks the inactive votes cache
ASSERT_TRUE (node.active.empty ());
auto send4_cache (node.active.find_inactive_votes_cache (send4->hash ()));
ASSERT_EQ (3, send4_cache.voters.size ());
ASSERT_TRUE (send4_cache.status.bootstrap_started);
ASSERT_TRUE (send4_cache.status.confirmed);
ASSERT_TRUE (send4_cache.status.election_started); // already marked even though the block does not exist
auto send4_cache (node.inactive_vote_cache.find (send4->hash ()));
ASSERT_TRUE (send4_cache);
ASSERT_EQ (3, send4_cache->voters.size ());
node.process_active (send3);
node.block_processor.flush ();
// An election is started for send6 but does not confirm
Expand Down Expand Up @@ -1520,7 +1518,7 @@ TEST (active_transactions, limit_vote_hinted_elections)
// Inactive vote
auto vote1 (std::make_shared<nano::vote> (rep1.pub, rep1.prv, 0, 0, std::vector<nano::block_hash>{ receive0->hash (), receive1->hash () }));
node.vote_processor.vote (vote1, std::make_shared<nano::transport::inproc::channel> (node, node));
ASSERT_TIMELY (1s, node.active.inactive_votes_cache_size () == 2);
ASSERT_TIMELY (1s, node.inactive_vote_cache.cache_size () == 2);
ASSERT_TRUE (node.active.empty ());
ASSERT_EQ (7, node.ledger.cache.cemented_count);

Expand All @@ -1544,15 +1542,15 @@ TEST (active_transactions, limit_vote_hinted_elections)
node.vote_processor.vote (vote4, std::make_shared<nano::transport::inproc::channel> (node, node));
ASSERT_TIMELY (1s, node.active.empty ());
ASSERT_EQ (8, node.ledger.cache.cemented_count);
ASSERT_TIMELY (1s, node.active.inactive_votes_cache_size () == 1);
ASSERT_TIMELY (1s, node.inactive_vote_cache.cache_size () == 1);

// Now it should be possible to vote hint second block
auto vote5 = (std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, 0, 0, std::vector<nano::block_hash>{ receive1->hash () }));
node.vote_processor.vote (vote5, std::make_shared<nano::transport::inproc::channel> (node, node));
ASSERT_TIMELY (1s, node.stats.count (nano::stat::type::election, nano::stat::detail::election_hinted_overflow) == 1);
ASSERT_TIMELY (1s, 1 == node.active.size ());
ASSERT_EQ (8, node.ledger.cache.cemented_count);
ASSERT_TIMELY (1s, node.active.inactive_votes_cache_size () == 1);
ASSERT_TIMELY (1s, node.inactive_vote_cache.cache_size () == 1);

// Ensure there was no overflow
ASSERT_EQ (0, node.stats.count (nano::stat::type::election, nano::stat::detail::election_drop_overflow));
Expand Down
11 changes: 0 additions & 11 deletions nano/core_test/memory_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,4 @@ TEST (memory_pool, validate_cleanup)
ASSERT_EQ (nano::determine_shared_ptr_pool_size<nano::change_block> (), get_allocated_size<nano::change_block> () - sizeof (size_t));
ASSERT_EQ (nano::determine_shared_ptr_pool_size<nano::state_block> (), get_allocated_size<nano::state_block> () - sizeof (size_t));
ASSERT_EQ (nano::determine_shared_ptr_pool_size<nano::vote> (), get_allocated_size<nano::vote> () - sizeof (size_t));

{
nano::active_transactions::ordered_cache inactive_votes_cache;
nano::account representative{ 1 };
nano::block_hash hash{ 1 };
uint64_t timestamp{ 1 };
nano::inactive_cache_status default_status{};
inactive_votes_cache.emplace (std::chrono::steady_clock::now (), hash, representative, timestamp, default_status);
}

ASSERT_TRUE (nano::purge_singleton_inactive_votes_cache_pool_memory ());
}
Loading

0 comments on commit 3f8cd4a

Please sign in to comment.