diff --git a/nano/lib/rep_weights.cpp b/nano/lib/rep_weights.cpp index 24167ae7..7a011c2d 100644 --- a/nano/lib/rep_weights.cpp +++ b/nano/lib/rep_weights.cpp @@ -1,11 +1,27 @@ #include #include -void nano::rep_weights::representation_add (nano::account const & source_rep, nano::uint128_t const & amount_a) +void nano::rep_weights::representation_add (nano::account const & source_rep_a, nano::uint128_t const & amount_a) { nano::lock_guard guard (mutex); - auto source_previous (get (source_rep)); - put (source_rep, source_previous + amount_a); + auto source_previous (get (source_rep_a)); + put (source_rep_a, source_previous + amount_a); +} + +void nano::rep_weights::representation_add_dual (nano::account const & source_rep_1, nano::uint128_t const & amount_1, nano::account const & source_rep_2, nano::uint128_t const & amount_2) +{ + if (source_rep_1 != source_rep_2) + { + nano::lock_guard guard (mutex); + auto source_previous_1 (get (source_rep_1)); + put (source_rep_1, source_previous_1 + amount_1); + auto source_previous_2 (get (source_rep_2)); + put (source_rep_2, source_previous_2 + amount_2); + } + else + { + representation_add (source_rep_1, amount_1 + amount_2); + } } void nano::rep_weights::representation_put (nano::account const & account_a, nano::uint128_union const & representation_a) diff --git a/nano/lib/rep_weights.hpp b/nano/lib/rep_weights.hpp index 818c5f4e..73e5753d 100644 --- a/nano/lib/rep_weights.hpp +++ b/nano/lib/rep_weights.hpp @@ -15,7 +15,8 @@ class transaction; class rep_weights { public: - void representation_add (nano::account const & source_a, nano::uint128_t const & amount_a); + void representation_add (nano::account const & source_rep_a, nano::uint128_t const & amount_a); + void representation_add_dual (nano::account const & source_rep_1, nano::uint128_t const & amount_1, nano::account const & source_rep_2, nano::uint128_t const & amount_2); nano::uint128_t representation_get (nano::account const & account_a); void representation_put (nano::account const & account_a, nano::uint128_union const & representation_a); std::unordered_map get_rep_amounts (); diff --git a/nano/secure/ledger.cpp b/nano/secure/ledger.cpp index da80730b..344acda3 100644 --- a/nano/secure/ledger.cpp +++ b/nano/secure/ledger.cpp @@ -94,8 +94,7 @@ public: auto block = ledger.store.block_get (transaction, rep_block); release_assert (block != nullptr); auto representative = block->representative (); - ledger.cache.rep_weights.representation_add (block_a.representative (), 0 - balance); - ledger.cache.rep_weights.representation_add (representative, balance); + ledger.cache.rep_weights.representation_add_dual (block_a.representative (), 0 - balance, representative, balance); ledger.store.block_del (transaction, hash); nano::account_info new_info (block_a.hashables.previous, representative, info.open_block, info.balance, nano::seconds_since_epoch (), info.block_count - 1, nano::epoch::epoch_0); ledger.change_latest (transaction, account, info, new_info); @@ -114,16 +113,19 @@ public: } auto balance (ledger.balance (transaction, block_a.hashables.previous)); auto is_send (block_a.hashables.balance < balance); - // Add in amount delta - ledger.cache.rep_weights.representation_add (block_a.representative (), 0 - block_a.hashables.balance.number ()); nano::account representative{ 0 }; if (!rep_block_hash.is_zero ()) { - // Move existing representation + // Move existing representation & add in amount delta auto block (ledger.store.block_get (transaction, rep_block_hash)); debug_assert (block != nullptr); representative = block->representative (); - ledger.cache.rep_weights.representation_add (representative, balance); + ledger.cache.rep_weights.representation_add_dual (representative, balance, block_a.representative (), 0 - block_a.hashables.balance.number ()); + } + else + { + // Add in amount delta only + ledger.cache.rep_weights.representation_add (block_a.representative (), 0 - block_a.hashables.balance.number ()); } nano::account_info info; @@ -347,11 +349,14 @@ void ledger_processor::state_block_impl (nano::state_block & block_a) if (!info.head.is_zero ()) { - // Move existing representation - ledger.cache.rep_weights.representation_add (info.representative, 0 - info.balance.number ()); + // Move existing representation & add in amount delta + ledger.cache.rep_weights.representation_add_dual (info.representative, 0 - info.balance.number (), block_a.representative (), block_a.hashables.balance.number ()); + } + else + { + // Add in amount delta only + ledger.cache.rep_weights.representation_add (block_a.representative (), block_a.hashables.balance.number ()); } - // Add in amount delta - ledger.cache.rep_weights.representation_add (block_a.representative (), block_a.hashables.balance.number ()); if (is_send) { @@ -506,8 +511,7 @@ void ledger_processor::change_block (nano::change_block & block_a) block_a.sideband_set (nano::block_sideband (account, 0, info.balance, info.block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */)); ledger.store.block_put (transaction, hash, block_a); auto balance (ledger.balance (transaction, block_a.hashables.previous)); - ledger.cache.rep_weights.representation_add (block_a.representative (), balance); - ledger.cache.rep_weights.representation_add (info.representative, 0 - balance); + ledger.cache.rep_weights.representation_add_dual (block_a.representative (), balance, info.representative, 0 - balance); nano::account_info new_info (hash, block_a.representative (), info.open_block, info.balance, nano::seconds_since_epoch (), info.block_count + 1, nano::epoch::epoch_0); ledger.change_latest (transaction, account, info, new_info); ledger.store.frontier_del (transaction, block_a.hashables.previous);