Skip to content

Commit

Permalink
Convert vote_uniquer to use generic implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
pwojcikdev committed Nov 7, 2023
1 parent 363cc43 commit 1377d51
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 98 deletions.
21 changes: 7 additions & 14 deletions nano/core_test/conflicts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,13 @@ TEST (conflicts, add_two)

TEST (vote_uniquer, null)
{
nano::block_uniquer block_uniquer;
nano::vote_uniquer uniquer (block_uniquer);
nano::vote_uniquer uniquer;
ASSERT_EQ (nullptr, uniquer.unique (nullptr));
}

TEST (vote_uniquer, vbh_one)
{
nano::block_uniquer block_uniquer;
nano::vote_uniquer uniquer (block_uniquer);
nano::vote_uniquer uniquer;
nano::keypair key;
nano::block_builder builder;
auto block = builder
Expand All @@ -210,8 +208,7 @@ TEST (vote_uniquer, vbh_one)

TEST (vote_uniquer, vbh_two)
{
nano::block_uniquer block_uniquer;
nano::vote_uniquer uniquer (block_uniquer);
nano::vote_uniquer uniquer;
nano::keypair key;
nano::block_builder builder;
auto block1 = builder
Expand Down Expand Up @@ -246,8 +243,7 @@ TEST (vote_uniquer, vbh_two)

TEST (vote_uniquer, cleanup)
{
nano::block_uniquer block_uniquer;
nano::vote_uniquer uniquer (block_uniquer);
nano::vote_uniquer uniquer;
nano::keypair key;
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 } });
Expand All @@ -256,10 +252,7 @@ TEST (vote_uniquer, cleanup)
vote2.reset ();
vote4.reset ();
ASSERT_EQ (2, uniquer.size ());
auto iterations (0);
while (uniquer.size () == 2)
{
auto vote5 (uniquer.unique (vote1));
ASSERT_LT (iterations++, 200);
}
std::this_thread::sleep_for (nano::block_uniquer::cleanup_cutoff);
auto vote5 = uniquer.unique (vote1);
ASSERT_EQ (1, uniquer.size ());
}
2 changes: 1 addition & 1 deletion nano/core_test/message_deserializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ auto message_deserializer_success_checker (message_type & message_original) -> v
// Dependencies for the message deserializer.
nano::network_filter filter (1);
nano::block_uniquer block_uniquer;
nano::vote_uniquer vote_uniquer (block_uniquer);
nano::vote_uniquer vote_uniquer;

// Data used to simulate the incoming buffer to be deserialized, the offset tracks how much has been read from the input_source
// as the read function is called first to read the header, then called again to read the payload.
Expand Down
4 changes: 2 additions & 2 deletions nano/node/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons
block_processor (*this, write_database_queue),
online_reps (ledger, config),
history{ config.network_params.voting },
vote_uniquer (block_uniquer),
vote_uniquer{},
confirmation_height_processor (ledger, write_database_queue, config.conf_height_processor_batch_min_time, config.logging, logger, node_initialized_latch, flags.confirmation_height_processor_mode),
vote_cache{ config.vote_cache, stats },
generator{ config, ledger, wallets, vote_processor, history, network, stats, /* non-final */ false },
Expand Down Expand Up @@ -565,8 +565,8 @@ std::unique_ptr<nano::container_info_component> nano::collect_container_info (no
composite->add_component (collect_container_info (node.block_arrival, "block_arrival"));
composite->add_component (collect_container_info (node.online_reps, "online_reps"));
composite->add_component (collect_container_info (node.history, "history"));
composite->add_component (collect_container_info (node.vote_uniquer, "vote_uniquer"));
composite->add_component (node.block_uniquer.collect_container_info ("block_uniquer"));
composite->add_component (node.vote_uniquer.collect_container_info ("vote_uniquer"));
composite->add_component (collect_container_info (node.confirmation_height_processor, "confirmation_height_processor"));
composite->add_component (collect_container_info (node.distributed_work, "distributed_work"));
composite->add_component (collect_container_info (node.aggregator, "request_aggregator"));
Expand Down
66 changes: 4 additions & 62 deletions nano/secure/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -610,72 +610,14 @@ bool nano::vote::is_final_timestamp (uint64_t timestamp)
return timestamp == std::numeric_limits<uint64_t>::max ();
}

nano::block_hash nano::iterate_vote_blocks_as_hash::operator() (nano::block_hash const & item) const
{
return item;
}

nano::vote_uniquer::vote_uniquer (nano::block_uniquer & uniquer_a) :
uniquer (uniquer_a)
nano::block_hash nano::full_hash (const nano::vote & vote)
{
return vote.full_hash ();
}

std::shared_ptr<nano::vote> nano::vote_uniquer::unique (std::shared_ptr<nano::vote> const & vote_a)
{
auto result = vote_a;
if (result != nullptr)
{
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;
}
else
{
existing = vote_a;
}

release_assert (std::numeric_limits<CryptoPP::word32>::max () > votes.size ());
for (auto i (0); i < cleanup_count && !votes.empty (); ++i)
{
auto random_offset = nano::random_pool::generate_word32 (0, static_cast<CryptoPP::word32> (votes.size () - 1));

auto existing (std::next (votes.begin (), random_offset));
if (existing == votes.end ())
{
existing = votes.begin ();
}
if (existing != votes.end ())
{
if (auto block_l = existing->second.lock ())
{
// Still live
}
else
{
votes.erase (existing);
}
}
}
}
return result;
}

size_t nano::vote_uniquer::size ()
{
nano::lock_guard<nano::mutex> lock{ mutex };
return votes.size ();
}

std::unique_ptr<nano::container_info_component> nano::collect_container_info (vote_uniquer & vote_uniquer, std::string const & name)
nano::block_hash nano::iterate_vote_blocks_as_hash::operator() (nano::block_hash const & item) const
{
auto count = vote_uniquer.size ();
auto sizeof_element = sizeof (vote_uniquer::value_type);
auto composite = std::make_unique<container_info_composite> (name);
composite->add_component (std::make_unique<container_info_leaf> (container_info{ "votes", count, sizeof_element }));
return composite;
return item;
}

nano::wallet_id nano::random_wallet_id ()
Expand Down
22 changes: 3 additions & 19 deletions nano/secure/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <nano/lib/rep_weights.hpp>
#include <nano/lib/stats.hpp>
#include <nano/lib/timer.hpp>
#include <nano/lib/uniquer.hpp>
#include <nano/lib/utility.hpp>

#include <boost/iterator/transform_iterator.hpp>
Expand Down Expand Up @@ -301,26 +302,9 @@ class vote final
private:
uint64_t packed_timestamp (uint64_t timestamp, uint8_t duration) const;
};
/**
* This class serves to find and return unique variants of a vote in order to minimize memory usage
*/
class vote_uniquer final
{
public:
using value_type = std::pair<nano::block_hash const, std::weak_ptr<nano::vote>>;

vote_uniquer (nano::block_uniquer &);
std::shared_ptr<nano::vote> unique (std::shared_ptr<nano::vote> const &);
size_t size ();

private:
nano::block_uniquer & uniquer;
nano::mutex mutex{ mutex_identifier (mutexes::vote_uniquer) };
std::unordered_map<std::remove_const_t<value_type::first_type>, value_type::second_type> votes;
static unsigned constexpr cleanup_count = 2;
};

std::unique_ptr<container_info_component> collect_container_info (vote_uniquer & vote_uniquer, std::string const & name);
nano::block_hash full_hash (nano::vote const &);
using vote_uniquer = nano::uniquer<nano::block_hash, nano::vote>;

enum class vote_code
{
Expand Down

0 comments on commit 1377d51

Please sign in to comment.