Skip to content

Commit

Permalink
Document overflow analysis for magnitude weight factor as fraction
Browse files Browse the repository at this point in the history
  • Loading branch information
jamescowens committed Oct 25, 2024
1 parent dae229a commit 1b7cbfb
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/gridcoin/voting/registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,11 @@ std::optional<CAmount> PollReference::GetActiveVoteWeight(const PollResultOption
const arith_uint256 scaled_pool_magnitude,
const arith_uint256 scaled_network_magnitude)
{
// Unlike the complementary calculation in EnableMagnitudeWeight for vote weights, this calculation is not
// subject to overflow because it uses 256 bit integers. In the end it the RESULT is cast to a 64 bit integer, but
// by then all of the multiplication and division are done. m_magnitude_weight_factor as a fraction something that is
// not expected to stray any farther than the interval [1/10, 1/1], where the current default value of 100 / 567 is
// in that interval. So we should never have an overflow problem here.
active_vote_weight_tally += net_weight + money_supply * (scaled_network_magnitude - scaled_pool_magnitude)
* arith_uint256(m_magnitude_weight_factor.GetNumerator())
/ arith_uint256(m_magnitude_weight_factor.GetDenominator())
Expand Down
13 changes: 13 additions & 0 deletions src/gridcoin/voting/result.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,19 @@ class VoteCounter
}

// Use integer arithmetic to avoid floating-point discrepancies:

// Overflow analysis:
//
// Current supply as of block 3404576 = 493424753.
// network magnitude = 115000
// max value for uint64_t = 2^64 - 1
//
// 2^64 - 1 >= (493424753 / 115000) * mwf numerator
//
// This means mwf numerator <= (2^64 - 1) * (115000 / 493424753)
// ~<= 4.3E15
// Even if money supply is approximately doubled we can safely handle 2E15, which means 15 decimal
// places in the fraction numerator
m_magnitude_factor = supply / total_mag
* (uint64_t) m_poll.m_magnitude_weight_factor.GetNumerator()
/ (uint64_t) m_poll.m_magnitude_weight_factor.GetDenominator();
Expand Down

0 comments on commit 1b7cbfb

Please sign in to comment.