Improve votes cache usage (#1678)
* Improve votes cache usage Serch block in cache before dist search * Fix code * Add wallets.reps_count * Count resp for deterministic_insert () & insert_ahdoc () * Use ++reps_count instead of reps_count++
This commit is contained in:
parent
daa3754bac
commit
f716f82067
8 changed files with 67 additions and 43 deletions
|
@ -334,6 +334,22 @@ void nano::network::confirm_hashes (nano::transaction const & transaction_a, nan
|
|||
}
|
||||
}
|
||||
|
||||
bool nano::network::send_votes_cache (nano::block_hash const & hash_a, nano::endpoint const & peer_a)
|
||||
{
|
||||
// Search in cache
|
||||
auto votes (node.votes_cache.find (hash_a));
|
||||
// Send from cache
|
||||
for (auto & vote : votes)
|
||||
{
|
||||
nano::confirm_ack confirm (vote);
|
||||
auto vote_bytes = confirm.to_bytes ();
|
||||
confirm_send (confirm, vote_bytes, peer_a);
|
||||
}
|
||||
// Returns true if votes were sent
|
||||
bool result (!votes.empty ());
|
||||
return result;
|
||||
}
|
||||
|
||||
void nano::network::republish_block (std::shared_ptr<nano::block> block)
|
||||
{
|
||||
auto hash (block->hash ());
|
||||
|
@ -650,41 +666,31 @@ public:
|
|||
node.stats.inc (nano::stat::type::message, nano::stat::detail::confirm_req, nano::stat::dir::in);
|
||||
node.peers.contacted (sender, message_a.header.version_using);
|
||||
// Don't load nodes with disabled voting
|
||||
if (node.config.enable_voting)
|
||||
if (node.config.enable_voting && node.wallets.reps_count)
|
||||
{
|
||||
auto transaction (node.store.tx_begin_read ());
|
||||
if (message_a.block != nullptr)
|
||||
{
|
||||
auto successor (node.ledger.successor (transaction, nano::uint512_union (message_a.block->previous (), message_a.block->root ())));
|
||||
if (successor != nullptr)
|
||||
auto hash (message_a.block->hash ());
|
||||
if (!node.network.send_votes_cache (hash, sender))
|
||||
{
|
||||
auto same_block (successor->hash () == message_a.block->hash ());
|
||||
confirm_block (transaction, node, sender, std::move (successor), !same_block);
|
||||
auto transaction (node.store.tx_begin_read ());
|
||||
auto successor (node.ledger.successor (transaction, nano::uint512_union (message_a.block->previous (), message_a.block->root ())));
|
||||
if (successor != nullptr)
|
||||
{
|
||||
auto same_block (successor->hash () == hash);
|
||||
confirm_block (transaction, node, sender, std::move (successor), !same_block);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!message_a.roots_hashes.empty ())
|
||||
{
|
||||
auto transaction (node.store.tx_begin_read ());
|
||||
std::vector<nano::block_hash> blocks_bundle;
|
||||
for (auto & root_hash : message_a.roots_hashes)
|
||||
{
|
||||
if (node.store.block_exists (transaction, root_hash.first))
|
||||
if (!node.network.send_votes_cache (root_hash.first, sender) && node.store.block_exists (transaction, root_hash.first))
|
||||
{
|
||||
// Search in cache
|
||||
auto votes (node.votes_cache.find (root_hash.first));
|
||||
if (votes.empty ())
|
||||
{
|
||||
blocks_bundle.push_back (root_hash.first);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send from cache
|
||||
for (auto & vote : votes)
|
||||
{
|
||||
nano::confirm_ack confirm (vote);
|
||||
auto vote_bytes = confirm.to_bytes ();
|
||||
node.network.confirm_send (confirm, vote_bytes, sender);
|
||||
}
|
||||
}
|
||||
blocks_bundle.push_back (root_hash.first);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -701,22 +707,10 @@ public:
|
|||
}
|
||||
if (!successor.is_zero ())
|
||||
{
|
||||
// Search in cache
|
||||
auto votes (node.votes_cache.find (successor));
|
||||
if (votes.empty ())
|
||||
if (!node.network.send_votes_cache (successor, sender))
|
||||
{
|
||||
blocks_bundle.push_back (successor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send from cache
|
||||
for (auto & vote : votes)
|
||||
{
|
||||
nano::confirm_ack confirm (vote);
|
||||
auto vote_bytes = confirm.to_bytes ();
|
||||
node.network.confirm_send (confirm, vote_bytes, sender);
|
||||
}
|
||||
}
|
||||
auto successor_block (node.store.block_get (transaction, successor));
|
||||
assert (successor_block != nullptr);
|
||||
node.network.republish_block (std::move (successor_block), sender);
|
||||
|
@ -1811,7 +1805,9 @@ void nano::block_processor::process_batch (std::unique_lock<std::mutex> & lock_a
|
|||
{
|
||||
// Replace our block with the winner and roll back any dependent blocks
|
||||
BOOST_LOG (node.log) << boost::str (boost::format ("Rolling back %1% and replacing with %2%") % successor->hash ().to_string () % hash.to_string ());
|
||||
node.ledger.rollback (transaction, successor->hash ());
|
||||
std::vector<nano::block_hash> rollback_list;
|
||||
node.ledger.rollback (transaction, successor->hash (), rollback_list);
|
||||
BOOST_LOG (node.log) << boost::str (boost::format ("%1% blocks rolled back") % rollback_list.size ());
|
||||
lock_a.lock ();
|
||||
// Prevent rolled back blocks second insertion
|
||||
auto inserted (rolled_back.insert (nano::rolled_hash{ std::chrono::steady_clock::now (), successor->hash () }));
|
||||
|
@ -1826,6 +1822,11 @@ void nano::block_processor::process_batch (std::unique_lock<std::mutex> & lock_a
|
|||
}
|
||||
}
|
||||
lock_a.unlock ();
|
||||
// Deleting from votes cache
|
||||
for (auto & i : rollback_list)
|
||||
{
|
||||
node.votes_cache.remove (i);
|
||||
}
|
||||
}
|
||||
}
|
||||
number_of_blocks_processed++;
|
||||
|
|
|
@ -334,6 +334,7 @@ public:
|
|||
void send_confirm_req (nano::endpoint const &, std::shared_ptr<nano::block>);
|
||||
void send_confirm_req_hashes (nano::endpoint const &, std::vector<std::pair<nano::block_hash, nano::block_hash>> const &);
|
||||
void confirm_hashes (nano::transaction const &, nano::endpoint const &, std::vector<nano::block_hash>);
|
||||
bool send_votes_cache (nano::block_hash const &, nano::endpoint const &);
|
||||
void send_buffer (uint8_t const *, size_t, nano::endpoint const &, std::function<void(boost::system::error_code const &, size_t)>);
|
||||
nano::endpoint endpoint ();
|
||||
nano::udp_buffer buffer_container;
|
||||
|
|
|
@ -141,6 +141,12 @@ std::vector<std::shared_ptr<nano::vote>> nano::votes_cache::find (nano::block_ha
|
|||
return result;
|
||||
}
|
||||
|
||||
void nano::votes_cache::remove (nano::block_hash const & hash_a)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (cache_mutex);
|
||||
cache.get<1> ().erase (hash_a);
|
||||
}
|
||||
|
||||
namespace nano
|
||||
{
|
||||
std::unique_ptr<seq_con_info_component> collect_seq_con_info (vote_generator & vote_generator, const std::string & name)
|
||||
|
|
|
@ -53,6 +53,7 @@ class votes_cache
|
|||
public:
|
||||
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 &);
|
||||
|
||||
private:
|
||||
std::mutex cache_mutex;
|
||||
|
|
|
@ -805,6 +805,7 @@ nano::public_key nano::wallet::deterministic_insert (nano::transaction const & t
|
|||
{
|
||||
std::lock_guard<std::mutex> lock (representatives_mutex);
|
||||
representatives.insert (key);
|
||||
++wallets.reps_count;
|
||||
}
|
||||
}
|
||||
return key;
|
||||
|
@ -847,6 +848,7 @@ nano::public_key nano::wallet::insert_adhoc (nano::transaction const & transacti
|
|||
{
|
||||
std::lock_guard<std::mutex> lock (representatives_mutex);
|
||||
representatives.insert (key);
|
||||
++wallets.reps_count;
|
||||
}
|
||||
}
|
||||
return key;
|
||||
|
@ -1605,6 +1607,7 @@ void nano::wallets::clear_send_ids (nano::transaction const & transaction_a)
|
|||
void nano::wallets::compute_reps ()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
reps_count = 0;
|
||||
auto ledger_transaction (node.store.tx_begin_read ());
|
||||
auto transaction (tx_begin_read ());
|
||||
for (auto i (items.begin ()), n (items.end ()); i != n; ++i)
|
||||
|
@ -1617,6 +1620,7 @@ void nano::wallets::compute_reps ()
|
|||
if (node.ledger.weight (ledger_transaction, account) >= node.config.vote_minimum.number ())
|
||||
{
|
||||
representatives_l.insert (account);
|
||||
++reps_count;
|
||||
}
|
||||
}
|
||||
std::lock_guard<std::mutex> representatives_lock (wallet.representatives_mutex);
|
||||
|
|
|
@ -200,6 +200,7 @@ public:
|
|||
boost::thread thread;
|
||||
static nano::uint128_t const generate_priority;
|
||||
static nano::uint128_t const high_priority;
|
||||
std::atomic<uint64_t> reps_count{ 0 };
|
||||
|
||||
/** Start read-write transaction */
|
||||
nano::transaction tx_begin_write ();
|
||||
|
|
|
@ -11,9 +11,10 @@ namespace
|
|||
class rollback_visitor : public nano::block_visitor
|
||||
{
|
||||
public:
|
||||
rollback_visitor (nano::transaction const & transaction_a, nano::ledger & ledger_a) :
|
||||
rollback_visitor (nano::transaction const & transaction_a, nano::ledger & ledger_a, std::vector<nano::block_hash> & list_a) :
|
||||
transaction (transaction_a),
|
||||
ledger (ledger_a)
|
||||
ledger (ledger_a),
|
||||
list (list_a)
|
||||
{
|
||||
}
|
||||
virtual ~rollback_visitor () = default;
|
||||
|
@ -24,7 +25,7 @@ public:
|
|||
nano::pending_key key (block_a.hashables.destination, hash);
|
||||
while (ledger.store.pending_get (transaction, key, pending))
|
||||
{
|
||||
ledger.rollback (transaction, ledger.latest (transaction, block_a.hashables.destination));
|
||||
ledger.rollback (transaction, ledger.latest (transaction, block_a.hashables.destination), list);
|
||||
}
|
||||
nano::account_info info;
|
||||
auto error (ledger.store.account_get (transaction, pending.source, info));
|
||||
|
@ -114,7 +115,7 @@ public:
|
|||
nano::pending_key key (block_a.hashables.link, hash);
|
||||
while (!ledger.store.pending_exists (transaction, key))
|
||||
{
|
||||
ledger.rollback (transaction, ledger.latest (transaction, block_a.hashables.link));
|
||||
ledger.rollback (transaction, ledger.latest (transaction, block_a.hashables.link), list);
|
||||
}
|
||||
ledger.store.pending_del (transaction, key);
|
||||
ledger.stats.inc (nano::stat::type::rollback, nano::stat::detail::send);
|
||||
|
@ -148,6 +149,7 @@ public:
|
|||
}
|
||||
nano::transaction const & transaction;
|
||||
nano::ledger & ledger;
|
||||
std::vector<nano::block_hash> & list;
|
||||
};
|
||||
|
||||
class ledger_processor : public nano::block_visitor
|
||||
|
@ -824,21 +826,28 @@ nano::uint128_t nano::ledger::weight (nano::transaction const & transaction_a, n
|
|||
}
|
||||
|
||||
// Rollback blocks until `block_a' doesn't exist
|
||||
void nano::ledger::rollback (nano::transaction const & transaction_a, nano::block_hash const & block_a)
|
||||
void nano::ledger::rollback (nano::transaction const & transaction_a, nano::block_hash const & block_a, std::vector<nano::block_hash> & list_a)
|
||||
{
|
||||
assert (store.block_exists (transaction_a, block_a));
|
||||
auto account_l (account (transaction_a, block_a));
|
||||
rollback_visitor rollback (transaction_a, *this);
|
||||
rollback_visitor rollback (transaction_a, *this, list_a);
|
||||
nano::account_info info;
|
||||
while (store.block_exists (transaction_a, block_a))
|
||||
{
|
||||
auto latest_error (store.account_get (transaction_a, account_l, info));
|
||||
assert (!latest_error);
|
||||
auto block (store.block_get (transaction_a, info.head));
|
||||
list_a.push_back (info.head);
|
||||
block->visit (rollback);
|
||||
}
|
||||
}
|
||||
|
||||
void nano::ledger::rollback (nano::transaction const & transaction_a, nano::block_hash const & block_a)
|
||||
{
|
||||
std::vector<nano::block_hash> rollback_list;
|
||||
rollback (transaction_a, block_a, rollback_list);
|
||||
}
|
||||
|
||||
// Return account containing hash
|
||||
nano::account nano::ledger::account (nano::transaction const & transaction_a, nano::block_hash const & hash_a)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
nano::block_hash block_destination (nano::transaction const &, nano::block const &);
|
||||
nano::block_hash block_source (nano::transaction const &, nano::block const &);
|
||||
nano::process_return process (nano::transaction const &, nano::block const &, nano::signature_verification = nano::signature_verification::unknown);
|
||||
void rollback (nano::transaction const &, nano::block_hash const &, std::vector<nano::block_hash> &);
|
||||
void rollback (nano::transaction const &, nano::block_hash const &);
|
||||
void change_latest (nano::transaction const &, nano::account const &, nano::block_hash const &, nano::account const &, nano::uint128_union const &, uint64_t, bool = false, nano::epoch = nano::epoch::epoch_0);
|
||||
void dump_account_chain (nano::account const &);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue