Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

voting, gui, rpc: Enhance PollResult and AVW calculation to improve pool handling #2489

Merged
merged 1 commit into from
Apr 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions src/gridcoin/voting/registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -366,7 +367,7 @@ std::optional<int> PollReference::GetEndingHeight() const
return std::nullopt;
}

std::optional<CAmount> PollReference::GetActiveVoteWeight() const
std::optional<CAmount> PollReference::GetActiveVoteWeight(const PollResultOption& result) const
{
// Instrument this so we can log real time performance.
g_timer.InitTimer(__func__, LogInstance().WillLogCategory(BCLog::LogFlags::VOTE));
Expand All @@ -392,6 +393,28 @@ std::optional<CAmount> 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<MiningPool> pools_not_voting;
const std::vector<MiningPool>& 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
Expand Down Expand Up @@ -437,7 +460,7 @@ std::optional<CAmount> 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();
}

Expand Down Expand Up @@ -487,7 +510,7 @@ std::optional<CAmount> 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();
}

Expand Down
2 changes: 1 addition & 1 deletion src/gridcoin/voting/registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class PollReference
//!
std::optional<int> GetEndingHeight() const;

std::optional<CAmount> GetActiveVoteWeight() const;
std::optional<CAmount> GetActiveVoteWeight(const PollResultOption &result) const;

//!
//! \brief Record a transaction that contains a response to the poll.
Expand Down
27 changes: 26 additions & 1 deletion src/gridcoin/voting/result.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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.
Expand Down Expand Up @@ -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<VoteDetail> m_votes;
std::vector<Cpid> m_pools_voted;
Weight m_magnitude_factor;
VoteResolver m_resolver;
LegacyVoteCounterContext m_legacy;
Expand Down Expand Up @@ -912,6 +918,24 @@ class VoteCounter

CalculateWeight(detail, m_magnitude_factor);

const std::vector<MiningPool>& 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));
}

Expand Down Expand Up @@ -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());
}
Expand Down
9 changes: 5 additions & 4 deletions src/gridcoin/voting/result.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<Cpid> 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.
Expand Down
2 changes: 1 addition & 1 deletion src/qt/voting/votingmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ std::optional<PollItem> 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;
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/voting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down