From e7de7021351a8ceda96c7b0fb90ebce8cf48054b Mon Sep 17 00:00:00 2001 From: "James C. Owens" Date: Sun, 27 Oct 2024 13:46:04 -0400 Subject: [PATCH] Ensure GetActiveNetworkWeight behavior is correct for all poll weight types --- src/gridcoin/voting/registry.cpp | 33 ++++++++++++++++++++++++++++++-- src/gridcoin/voting/registry.h | 1 + 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/gridcoin/voting/registry.cpp b/src/gridcoin/voting/registry.cpp index 66cf3a3336..d6e745486b 100644 --- a/src/gridcoin/voting/registry.cpp +++ b/src/gridcoin/voting/registry.cpp @@ -355,6 +355,7 @@ PollOption PollReference::TryReadFromDisk(CTxDB& txdb) const // in memory and is not serialized. payload.m_poll.m_magnitude_weight_factor = payload.m_poll.ResolveMagnitudeWeightFactor(GetStartingBlockIndexPtr()); m_magnitude_weight_factor = payload.m_poll.m_magnitude_weight_factor; + m_weight_type = payload.m_poll.m_weight_type.Value(); LogPrint(BCLog::LogFlags::VOTE, "INFO: %s: reference.m_timestamp = %" PRId64 " , poll.m_timestamp = %" PRId64 " , " "poll.m_magnitude_weight_factor = %s", @@ -527,6 +528,36 @@ std::optional PollReference::GetActiveVoteWeight(const PollResultOption __func__, pindex_end->nHeight); } + arith_uint256 active_vote_weight_tally = 0; + unsigned int blocks = 0; + + // If poll weight type is balance only, then simply sum up the netweights over the block range of the poll. + if (m_weight_type == PollWeightType::BALANCE) { + for (CBlockIndex* pindex = pindex_start; pindex ; pindex = pindex->pnext) { + + arith_uint256 net_weight = GetAvgNetworkWeight(pindex); + + active_vote_weight_tally += net_weight; + ++blocks; + + if (pindex == pindex_end) { + break; + } + } + + if (!blocks) { + return std::nullopt; + } + + return (active_vote_weight_tally / blocks).GetLow64(); + + // If it is not balance only (handled by above), and is not BALANCE_AND_MAGNITUDE (everything else) then return nullopt. + // In reality all weight types other than BALANCE and BALANCE_AND_MAGNITUDE are deprecated in Fern onwards, so this + // only applies for legacy polls. + } else if (m_weight_type != PollWeightType::BALANCE_AND_MAGNITUDE) { + return std::nullopt; + } + // determine the pools that did NOT vote in the poll (via the result passed in). Only pools that did not // vote contribute to the magnitude correction for pools. std::vector pools_not_voting; @@ -556,10 +587,8 @@ std::optional PollReference::GetActiveVoteWeight(const PollResultOption // Note we must use bignums here, because the second term of the active_vote_weight_tally will overflow // otherwise. We are also avoiding floating point calculations, because avw will be used in consensus rules in // the future. - arith_uint256 active_vote_weight_tally = 0; arith_uint256 scaled_pool_magnitude = 0; arith_uint256 scaled_network_magnitude = 0; - unsigned int blocks = 0; // Lambda for active_vote_weight tally. const auto tally_active_vote_weight = [&]( diff --git a/src/gridcoin/voting/registry.h b/src/gridcoin/voting/registry.h index 5102c742ff..dff16f2d68 100644 --- a/src/gridcoin/voting/registry.h +++ b/src/gridcoin/voting/registry.h @@ -186,6 +186,7 @@ class PollReference uint256 m_txid; //!< Hash of the poll transaction. uint32_t m_payload_version; //!< Version of the poll (payload). PollType m_type; //!< Type of the poll. + mutable PollWeightType m_weight_type; //!< Weight type of the poll. const std::string* m_ptitle; //!< Title of the poll for indexing/mapping purposes. std::string m_title; //!< Original title of the poll for display purposes. mutable int64_t m_timestamp; //!< Timestamp of the poll transaction.