From 278b9b829aba941aa67776e0036c028a05097f6b Mon Sep 17 00:00:00 2001 From: jamescowens Date: Sat, 16 Apr 2022 19:42:40 -0400 Subject: [PATCH] Enhance PollResult and AVW to handle pools better --- src/gridcoin/voting/registry.cpp | 29 ++++++++++++++++++++++++++--- src/gridcoin/voting/registry.h | 2 +- src/gridcoin/voting/result.cpp | 27 ++++++++++++++++++++++++++- src/gridcoin/voting/result.h | 9 +++++---- src/qt/voting/votingmodel.cpp | 2 +- src/rpc/voting.cpp | 2 +- 6 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/gridcoin/voting/registry.cpp b/src/gridcoin/voting/registry.cpp index b524da4521..6fdfc75488 100644 --- a/src/gridcoin/voting/registry.cpp +++ b/src/gridcoin/voting/registry.cpp @@ -12,6 +12,7 @@ #include "gridcoin/voting/payloads.h" #include "gridcoin/voting/registry.h" #include "gridcoin/voting/vote.h" +#include "gridcoin/voting/result.h" #include "gridcoin/support/block_finder.h" #include "node/blockstorage.h" #include "txdb.h" @@ -366,7 +367,7 @@ std::optional PollReference::GetEndingHeight() const return std::nullopt; } -std::optional PollReference::GetActiveVoteWeight() const +std::optional PollReference::GetActiveVoteWeight(const PollResultOption& result) const { // Instrument this so we can log real time performance. g_timer.InitTimer(__func__, LogInstance().WillLogCategory(BCLog::LogFlags::VOTE)); @@ -392,6 +393,28 @@ std::optional PollReference::GetActiveVoteWeight() const __func__, pindex_end->nHeight); } + // 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; + const std::vector& mining_pools = g_mining_pools.GetMiningPools(); + + LogPrint(BCLog::LogFlags::VOTE, "INFO: %s: %u out of %u pool cpids voted.", + __func__, + result->m_pools_voted.size(), + mining_pools.size()); + + for (const auto& pool : mining_pools) { + if (result && std::find(result->m_pools_voted.begin(), result->m_pools_voted.end(), + pool.m_cpid) == result->m_pools_voted.end()) { + LogPrint(BCLog::LogFlags::VOTE, "INFO: %s: pool with cpid %s did not vote and will be removed from magnitude " + "in the AVW calculation.", + __func__, + pool.m_cpid.ToString()); + + pools_not_voting.push_back(pool); + } + } + // Since this calculation by its very nature is going to be heavyweight, we are going to // dispense with using the heavyweight averaging functions, and instead accumulate the necessary // values directly in a for loop that traverses the index. This will do it all in a single index @@ -437,7 +460,7 @@ std::optional PollReference::GetActiveVoteWeight() const superblock_well_formed = superblock.WellFormed(); - for (const auto& pool : g_mining_pools.GetMiningPools()) { + for (const auto& pool : pools_not_voting) { scaled_pool_magnitude += superblock.m_cpids.MagnitudeOf(pool.m_cpid).Scaled(); } @@ -487,7 +510,7 @@ std::optional PollReference::GetActiveVoteWeight() const if (claim && claim->ContainsSuperblock()) { const GRC::Superblock& superblock = *claim->m_superblock; - for (const auto& pool : g_mining_pools.GetMiningPools()) { + for (const auto& pool : pools_not_voting) { scaled_pool_magnitude += superblock.m_cpids.MagnitudeOf(pool.m_cpid).Scaled(); } diff --git a/src/gridcoin/voting/registry.h b/src/gridcoin/voting/registry.h index b3a04635a6..8bea4cc4f7 100644 --- a/src/gridcoin/voting/registry.h +++ b/src/gridcoin/voting/registry.h @@ -127,7 +127,7 @@ class PollReference //! std::optional GetEndingHeight() const; - std::optional GetActiveVoteWeight() const; + std::optional GetActiveVoteWeight(const PollResultOption &result) const; //! //! \brief Record a transaction that contains a response to the poll. diff --git a/src/gridcoin/voting/result.cpp b/src/gridcoin/voting/result.cpp index 4d308a4704..e260efccb9 100644 --- a/src/gridcoin/voting/result.cpp +++ b/src/gridcoin/voting/result.cpp @@ -10,6 +10,7 @@ #include "gridcoin/voting/result.h" #include "gridcoin/voting/poll.h" #include "gridcoin/voting/vote.h" +#include "gridcoin/researcher.h" #include "txdb.h" #include "util/reverse_iterator.h" @@ -23,6 +24,8 @@ using ResponseDetail = PollResult::ResponseDetail; using VoteDetail = PollResult::VoteDetail; using Weight = PollResult::Weight; +extern MiningPools g_mining_pools; + namespace { //! //! \brief Used for mapping legacy vote answer labels to poll choice offsets. @@ -803,12 +806,15 @@ class VoteCounter for (auto& vote : m_votes) { result.TallyVote(std::move(vote)); } + + result.m_pools_voted = m_pools_voted; } private: CTxDB& m_txdb; const Poll& m_poll; std::vector m_votes; + std::vector m_pools_voted; Weight m_magnitude_factor; VoteResolver m_resolver; LegacyVoteCounterContext m_legacy; @@ -912,6 +918,24 @@ class VoteCounter CalculateWeight(detail, m_magnitude_factor); + const std::vector& mining_pools = g_mining_pools.GetMiningPools(); + + // Record if a pool votes + if (detail.m_mining_id.TryCpid()) { + for (const auto& pool : mining_pools) { + if (detail.m_mining_id == pool.m_cpid) { + LogPrint(BCLog::LogFlags::VOTE, "INFO: %s: Pool with CPID %s voted on poll %s.", + __func__, + detail.m_mining_id.TryCpid()->ToString(), + m_poll.m_title); + + m_pools_voted.push_back(*detail.m_mining_id.TryCpid()); + + break; + } + } + } + m_votes.emplace_back(std::move(detail)); } @@ -1083,7 +1107,8 @@ PollResult::PollResult(Poll poll) : m_poll(std::move(poll)) , m_total_weight(0) , m_invalid_votes(0) - , m_finished(poll.Expired(GetAdjustedTime())) + , m_pools_voted({}) + , m_finished(m_poll.Expired(GetAdjustedTime())) { m_responses.resize(m_poll.Choices().size()); } diff --git a/src/gridcoin/voting/result.h b/src/gridcoin/voting/result.h index f1786f437e..f65e7de362 100644 --- a/src/gridcoin/voting/result.h +++ b/src/gridcoin/voting/result.h @@ -77,10 +77,11 @@ class PollResult bool Empty() const; }; - const Poll m_poll; //!< The poll associated with the result. - Weight m_total_weight; //!< Aggregate weight of all the votes submitted. - size_t m_invalid_votes; //!< Number of votes that failed validation. - bool m_finished; //!< Whether the poll finished as of this result. + const Poll m_poll; //!< The poll associated with the result. + Weight m_total_weight; //!< Aggregate weight of all the votes submitted. + size_t m_invalid_votes; //!< Number of votes that failed validation. + std::vector m_pools_voted; //!< Cpids of pools that actually voted + bool m_finished; //!< Whether the poll finished as of this result. //! //! \brief The aggregated voting weight tallied for each poll choice. diff --git a/src/qt/voting/votingmodel.cpp b/src/qt/voting/votingmodel.cpp index 7b2102386f..e4af144a03 100644 --- a/src/qt/voting/votingmodel.cpp +++ b/src/qt/voting/votingmodel.cpp @@ -61,7 +61,7 @@ std::optional BuildPollItem(const PollRegistry::Sequence::Iterator& it item.m_total_votes = result->m_votes.size(); item.m_total_weight = result->m_total_weight / COIN; - if (auto active_vote_weight = ref.GetActiveVoteWeight()) { + if (auto active_vote_weight = ref.GetActiveVoteWeight(result)) { item.m_active_weight = *active_vote_weight / COIN; } else { item.m_active_weight = 0; diff --git a/src/rpc/voting.cpp b/src/rpc/voting.cpp index 202a65bb69..10e1b47847 100644 --- a/src/rpc/voting.cpp +++ b/src/rpc/voting.cpp @@ -98,7 +98,7 @@ UniValue PollResultToJson(const PollResult& result, const PollReference& poll_re json.pushKV("invalid_votes", (uint64_t)result.m_invalid_votes); json.pushKV("total_weight", ValueFromAmount(result.m_total_weight)); - if (auto active_vote_weight = poll_ref.GetActiveVoteWeight()) { + if (auto active_vote_weight = poll_ref.GetActiveVoteWeight(result)) { json.pushKV("active_vote_weight", ValueFromAmount(*active_vote_weight)); json.pushKV("vote_percent_avw", (double) result.m_total_weight / (double) *active_vote_weight * 100.0); }