Generated votes cache size increase and upper bound (#2432)

* Increase generated votes cache size to 64k from 4k

* Bound size with relation to the number of voting accounts

* Literal for OSX and Windows
This commit is contained in:
Guilherme Lawless 2020-01-14 16:12:04 +00:00 committed by GitHub
commit eb2beac3a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 47 additions and 5 deletions

View file

@ -2499,6 +2499,33 @@ TEST (node, local_votes_cache_generate_new_vote)
ASSERT_FALSE (node.votes_cache.find (send2->hash ()).empty ());
}
// Tests that the max cache size is inversely proportional to the number of voting accounts
TEST (node, local_votes_cache_size)
{
nano::system system;
nano::node_config node_config (nano::get_available_port (), system.logging);
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
node_config.vote_minimum = 0; // wallet will pick up the second account as voting even if unopened
auto & node (*system.add_node (node_config));
ASSERT_EQ (node.network_params.voting.max_cache, 2); // effective cache size is 1 with 2 voting accounts
nano::genesis genesis;
nano::keypair key;
auto & wallet (*system.wallet (0));
wallet.insert_adhoc (nano::test_genesis_key.prv);
wallet.insert_adhoc (nano::keypair ().prv);
ASSERT_EQ (2, node.wallets.rep_counts ().voting);
auto transaction (node.store.tx_begin_read ());
auto vote1 (node.store.vote_generate (transaction, nano::test_genesis_key.pub, nano::test_genesis_key.prv, { genesis.open->hash () }));
nano::block_hash hash (1);
auto vote2 (node.store.vote_generate (transaction, nano::test_genesis_key.pub, nano::test_genesis_key.prv, { hash }));
node.votes_cache.add (vote1);
node.votes_cache.add (vote2);
auto existing2 (node.votes_cache.find (hash));
ASSERT_EQ (1, existing2.size ());
ASSERT_EQ (vote2, existing2.front ());
ASSERT_EQ (0, node.votes_cache.find (genesis.open->hash ()).size ());
}
TEST (node, vote_republish)
{
nano::system system (2);

View file

@ -132,6 +132,7 @@ port_mapping (*this),
vote_processor (checker, active, store, observers, stats, config, logger, online_reps, ledger, network_params),
rep_crawler (*this),
warmed_up (0),
votes_cache (wallets),
block_processor (*this, write_database_queue),
block_processor_thread ([this]() {
nano::thread_role::set (nano::thread_role::name::block_processing);

View file

@ -100,9 +100,17 @@ void nano::vote_generator::run ()
}
}
nano::votes_cache::votes_cache (nano::wallets & wallets_a) :
wallets (wallets_a)
{
}
void nano::votes_cache::add (std::shared_ptr<nano::vote> const & vote_a)
{
nano::lock_guard<std::mutex> lock (cache_mutex);
auto voting (wallets.rep_counts ().voting);
assert (voting > 0);
auto const max_cache_size (network_params.voting.max_cache / std::max (voting, static_cast<decltype (voting)> (1)));
for (auto & block : vote_a->blocks)
{
auto hash (boost::get<nano::block_hash> (block));
@ -110,7 +118,7 @@ void nano::votes_cache::add (std::shared_ptr<nano::vote> const & vote_a)
if (existing == cache.get<tag_hash> ().end ())
{
// Clean old votes
if (cache.size () >= network_params.voting.max_cache)
if (cache.size () >= max_cache_size)
{
cache.get<tag_sequence> ().pop_front ();
}

View file

@ -3,6 +3,7 @@
#include <nano/lib/locks.hpp>
#include <nano/lib/numbers.hpp>
#include <nano/lib/utility.hpp>
#include <nano/node/wallet.hpp>
#include <nano/secure/common.hpp>
#include <boost/multi_index/hashed_index.hpp>
@ -62,6 +63,7 @@ public:
class votes_cache final
{
public:
votes_cache (nano::wallets & wallets_a);
void add (std::shared_ptr<nano::vote> const &);
std::vector<std::shared_ptr<nano::vote>> find (nano::block_hash const &);
void remove (nano::block_hash const &);
@ -79,6 +81,7 @@ private:
cache;
// clang-format on
nano::network_params network_params;
nano::wallets & wallets;
friend std::unique_ptr<container_info_component> collect_container_info (votes_cache & votes_cache, const std::string & name);
};

View file

@ -1758,10 +1758,13 @@ void nano::wallets::foreach_representative (std::function<void(nano::public_key
{
auto & wallet (*i->second);
nano::lock_guard<std::recursive_mutex> store_lock (wallet.store.mutex);
nano::lock_guard<std::mutex> representatives_lock (wallet.representatives_mutex);
for (auto ii (wallet.representatives.begin ()), nn (wallet.representatives.end ()); ii != nn; ++ii)
decltype (wallet.representatives) representatives_l;
{
nano::lock_guard<std::mutex> representatives_lock (wallet.representatives_mutex);
representatives_l = wallet.representatives;
}
for (auto const & account : representatives_l)
{
nano::account account (*ii);
if (wallet.store.exists (transaction_l, account))
{
if (!node.ledger.weight (account).is_zero ())

View file

@ -132,7 +132,7 @@ nano::node_constants::node_constants (nano::network_constants & network_constant
nano::voting_constants::voting_constants (nano::network_constants & network_constants)
{
max_cache = network_constants.is_test_network () ? 2 : 4 * 1024;
max_cache = network_constants.is_test_network () ? 2 : 64 * 1024;
}
nano::portmapping_constants::portmapping_constants (nano::network_constants & network_constants)