Skip to content

Commit

Permalink
Delete reps with weight 0 from rep_weight table and cache
Browse files Browse the repository at this point in the history
  • Loading branch information
simpago committed Mar 12, 2024
1 parent 2bc5a89 commit f016d62
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 24 deletions.
22 changes: 22 additions & 0 deletions nano/core_test/ledger.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include "nano/lib/numbers.hpp"

#include <nano/lib/blocks.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/stats.hpp>
Expand Down Expand Up @@ -684,6 +686,26 @@ TEST (ledger, representation_changes)
ASSERT_EQ (2, rep_weights.representation_get (key1.pub));
}

TEST (ledger, delete_rep_weight_of_zero)
{
auto store{ nano::make_store () };
nano::rep_weights rep_weights{ store->rep_weight };
auto txn{ store->tx_begin_write () };
rep_weights.representation_add (txn, 1, 100);
rep_weights.representation_add_dual (txn, 2, 100, 3, 100);
ASSERT_EQ (3, rep_weights.size ());
ASSERT_EQ (3, store->rep_weight.count (txn));

// set rep weights to 0
rep_weights.representation_add (txn, 1, std::numeric_limits<nano::uint128_t>::max () - 99);
ASSERT_EQ (2, rep_weights.size ());
ASSERT_EQ (2, store->rep_weight.count (txn));

rep_weights.representation_add_dual (txn, 2, std::numeric_limits<nano::uint128_t>::max () - 99, 3, std::numeric_limits<nano::uint128_t>::max () - 99);
ASSERT_EQ (0, rep_weights.size ());
ASSERT_EQ (0, store->rep_weight.count (txn));
}

TEST (ledger, representation)
{
auto ctx = nano::test::context::ledger_empty ();
Expand Down
77 changes: 54 additions & 23 deletions nano/secure/rep_weights.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,39 @@ nano::rep_weights::rep_weights (nano::store::rep_weight & rep_weight_store_a) :
{
}

void nano::rep_weights::representation_add (store::write_transaction const & txn_a, nano::account const & source_rep_a, nano::uint128_t const & amount_a)
void nano::rep_weights::representation_add (store::write_transaction const & txn_a, nano::account const & rep_a, nano::uint128_t const & amount_a)
{
auto weight{ rep_weight_store.get (txn_a, source_rep_a) };
weight += amount_a;
auto previous_weight{ rep_weight_store.get (txn_a, rep_a) };
auto new_weight = previous_weight + amount_a;
put_store (txn_a, rep_a, previous_weight, new_weight);
nano::lock_guard<nano::mutex> guard (mutex);
rep_weight_store.put (txn_a, source_rep_a, weight);
put (source_rep_a, weight);
put_cache (rep_a, new_weight);
}

void nano::rep_weights::representation_add_dual (store::write_transaction const & txn_a, nano::account const & source_rep_1, nano::uint128_t const & amount_1, nano::account const & source_rep_2, nano::uint128_t const & amount_2)
void nano::rep_weights::representation_add_dual (store::write_transaction const & txn_a, nano::account const & rep_1, nano::uint128_t const & amount_1, nano::account const & rep_2, nano::uint128_t const & amount_2)
{
if (source_rep_1 != source_rep_2)
if (rep_1 != rep_2)
{
auto rep_1_weight{ rep_weight_store.get (txn_a, source_rep_1) };
auto rep_2_weight{ rep_weight_store.get (txn_a, source_rep_2) };
rep_1_weight += amount_1;
rep_2_weight += amount_2;
rep_weight_store.put (txn_a, source_rep_1, rep_1_weight);
rep_weight_store.put (txn_a, source_rep_2, rep_2_weight);
auto previous_weight_1{ rep_weight_store.get (txn_a, rep_1) };
auto previous_weight_2{ rep_weight_store.get (txn_a, rep_2) };
auto new_weight_1 = previous_weight_1 + amount_1;
auto new_weight_2 = previous_weight_2 + amount_2;
put_store (txn_a, rep_1, previous_weight_1, new_weight_1);
put_store (txn_a, rep_2, previous_weight_2, new_weight_2);
nano::lock_guard<nano::mutex> guard (mutex);
put (source_rep_1, rep_1_weight);
put (source_rep_2, rep_2_weight);
put_cache (rep_1, new_weight_1);
put_cache (rep_2, new_weight_2);
}
else
{
representation_add (txn_a, source_rep_1, amount_1 + amount_2);
representation_add (txn_a, rep_1, amount_1 + amount_2);
}
}

void nano::rep_weights::representation_put (nano::account const & account_a, nano::uint128_t const & representation_a)
{
nano::lock_guard<nano::mutex> guard (mutex);
put (account_a, representation_a);
put_cache (account_a, representation_a);
}

nano::uint128_t nano::rep_weights::representation_get (nano::account const & account_a) const
Expand All @@ -62,21 +62,46 @@ void nano::rep_weights::copy_from (nano::rep_weights & other_a)
for (auto const & entry : other_a.rep_amounts)
{
auto prev_amount (get (entry.first));
put (entry.first, prev_amount + entry.second);
put_cache (entry.first, prev_amount + entry.second);
}
}

void nano::rep_weights::put (nano::account const & account_a, nano::uint128_union const & representation_a)
void nano::rep_weights::put_cache (nano::account const & account_a, nano::uint128_union const & representation_a)
{
auto it = rep_amounts.find (account_a);
auto amount = representation_a.number ();
if (it != rep_amounts.end ())
if (representation_a.is_zero ())
{
it->second = amount;
if (it != rep_amounts.end ())
{
rep_amounts.erase (it);
}
}
else
{
rep_amounts.emplace (account_a, amount);
auto amount = representation_a.number ();
if (it != rep_amounts.end ())
{
it->second = amount;
}
else
{
rep_amounts.emplace (account_a, amount);
}
}
}

void nano::rep_weights::put_store (store::write_transaction const & txn_a, nano::account const & rep_a, nano::uint128_t const & previous_weight_a, nano::uint128_t const & new_weight_a)
{
if (new_weight_a.is_zero ())
{
if (!previous_weight_a.is_zero ())
{
rep_weight_store.del (txn_a, rep_a);
}
}
else
{
rep_weight_store.put (txn_a, rep_a, new_weight_a);
}
}

Expand All @@ -93,6 +118,12 @@ nano::uint128_t nano::rep_weights::get (nano::account const & account_a) const
}
}

std::size_t nano::rep_weights::size () const
{
nano::lock_guard<nano::mutex> guard (mutex);
return rep_amounts.size ();
}

std::unique_ptr<nano::container_info_component> nano::collect_container_info (nano::rep_weights const & rep_weights, std::string const & name)
{
size_t rep_amounts_count;
Expand Down
5 changes: 4 additions & 1 deletion nano/secure/rep_weights.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@ class rep_weights
/* Only use this method when loading rep weights from the database table */
void representation_put (nano::account const & account_a, nano::uint128_t const & representation_a);
std::unordered_map<nano::account, nano::uint128_t> get_rep_amounts () const;
/* Only use this method when loading rep weights from the database table */
void copy_from (rep_weights & other_a);
size_t size () const;

private:
mutable nano::mutex mutex;
std::unordered_map<nano::account, nano::uint128_t> rep_amounts;
nano::store::rep_weight & rep_weight_store;
void put (nano::account const & account_a, nano::uint128_union const & representation_a);
void put_cache (nano::account const & account_a, nano::uint128_union const & representation_a);
void put_store (store::write_transaction const & txn_a, nano::account const & rep_a, nano::uint128_t const & previous_weight_a, nano::uint128_t const & new_weight_a);
nano::uint128_t get (nano::account const & account_a) const;

friend std::unique_ptr<container_info_component> collect_container_info (rep_weights const &, std::string const &);
Expand Down

0 comments on commit f016d62

Please sign in to comment.