Skip to content

Commit

Permalink
Additional changes to wire in magnitude weight factor
Browse files Browse the repository at this point in the history
  • Loading branch information
jamescowens committed Oct 23, 2024
1 parent d36dea0 commit 138ab6a
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 62 deletions.
29 changes: 27 additions & 2 deletions src/gridcoin/voting/poll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.

#include "gridcoin/protocol.h"
#include "main.h"
#include "gridcoin/support/xml.h"
#include "gridcoin/voting/poll.h"
Expand Down Expand Up @@ -92,7 +93,12 @@ Poll::Poll()
, m_weight_type(PollWeightType::UNKNOWN)
, m_response_type(PollResponseType::UNKNOWN)
, m_duration_days(0)
, m_title({})
, m_url({})
, m_question({})
, m_choices(ChoiceList())
, m_timestamp(0)
, m_magnitude_weight_factor(Fraction())
{
}

Expand All @@ -105,7 +111,8 @@ Poll::Poll(
std::string url,
std::string question,
ChoiceList choices,
int64_t timestamp)
int64_t timestamp,
Fraction magnitude_weight_factor)
: m_type(type)
, m_weight_type(weight_type)
, m_response_type(response_type)
Expand All @@ -115,6 +122,7 @@ Poll::Poll(
, m_question(std::move(question))
, m_choices(std::move(choices))
, m_timestamp(timestamp)
, m_magnitude_weight_factor(magnitude_weight_factor)
{
}

Expand All @@ -130,7 +138,8 @@ Poll Poll::Parse(const std::string& title, const std::string& contract)
ExtractXML(contract, "<URL>", "</URL>"),
ExtractXML(contract, "<QUESTION>", "</QUESTION>"),
ParseChoices(ExtractXML(contract, "<ANSWERS>", "</ANSWERS>")),
0);
0,
Params().GetConsensus().DefaultMagnitudeWeightFactor);
}

bool Poll::WellFormed() const
Expand Down Expand Up @@ -206,6 +215,22 @@ int64_t Poll::Expiration() const
return m_timestamp + (m_duration_days * 86400);
}

Fraction Poll::ResolveMagnitudeWeightFactor() const
{
Fraction magnitude_weight_factor = Params().GetConsensus().DefaultMagnitudeWeightFactor;

// Find the current protocol entry value for Magnitude Weight Factor, if it exists.
ProtocolEntryOption protocol_entry = GetProtocolRegistry().TryLastBeforeTimestamp("magnitudeweightfactor", m_timestamp);

// If their is an entry prior or equal in timestemp to the start of the poll and it is active then set the magnitude weight
// factor to that value. If the last entry is not active (i.e. deleted), then leave at the default.
if (protocol_entry != nullptr && protocol_entry->m_status == ProtocolEntryStatus::ACTIVE) {
magnitude_weight_factor = Fraction().FromString(protocol_entry->m_value);
}

return magnitude_weight_factor;
}

const Poll::ChoiceList& Poll::Choices() const
{
if (m_response_type == PollResponseType::YES_NO_ABSTAIN) {
Expand Down
53 changes: 32 additions & 21 deletions src/gridcoin/voting/poll.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "gridcoin/voting/fwd.h"
#include "serialize.h"
#include "uint256.h"
#include "util.h"

#include <string>
#include <vector>
Expand Down Expand Up @@ -398,7 +399,8 @@ class Poll
AdditionalFieldList m_additional_fields; //!< The set of additional fields for the poll.

// Memory only:
int64_t m_timestamp; //!< Time of the poll's containing transaction.
int64_t m_timestamp; //!< Time of the poll's containing transaction.
Fraction m_magnitude_weight_factor; //!< Magnitude weight factor for the poll (defined at poll start).

//!
//! \brief Initialize an empty, invalid poll instance.
Expand All @@ -408,26 +410,27 @@ class Poll
//!
//! \brief Initialize a poll instance with data from a contract.
//!
//! \param type Type of the poll.
//! \param weight_type Method used to weigh votes.
//! \param response_type Method for choosing poll answers.
//! \param duration_days Number of days the poll remains active.
//! \param title UTF-8 title of the poll.
//! \param url UTF-8 URL of the poll discussion webpage.
//! \param question UTF-8 prompt that voters shall answer.
//! \param choices The set of possible answers to the poll.
//! \param timestamp Timestamp of the poll's containing transaction.
//!
Poll(
PollType type,
PollWeightType weight_type,
PollResponseType response_type,
uint32_t duration_days,
std::string title,
std::string url,
std::string question,
ChoiceList choices,
int64_t timestamp);
//! \param type Type of the poll.
//! \param weight_type Method used to weigh votes.
//! \param response_type Method for choosing poll answers.
//! \param duration_days Number of days the poll remains active.
//! \param title UTF-8 title of the poll.
//! \param url UTF-8 URL of the poll discussion webpage.
//! \param question UTF-8 prompt that voters shall answer.
//! \param choices The set of possible answers to the poll.
//! \param timestamp Timestamp of the poll's containing transaction.
//! \param magnitude_weight_factor The magnitude weight factor for the poll, valid at poll start.
//!
Poll(PollType type,
PollWeightType weight_type,
PollResponseType response_type,
uint32_t duration_days,
std::string title,
std::string url,
std::string question,
ChoiceList choices,
int64_t timestamp,
Fraction magnitude_weight_factor);

//!
//! \brief Initialize a poll instance from a contract that contains poll
Expand Down Expand Up @@ -505,6 +508,14 @@ class Poll
//!
int64_t Expiration() const;

//!
//! \brief Fetch the applicable magnitude factor for the poll. This is the magnitude factor of the last entry in the
//! protocol registry database that has a timestamp at or before the poll start timestamp.
//!
//! \return Fraction Magnitude factor expressed as a Fraction.
//!
Fraction ResolveMagnitudeWeightFactor() const;

//!
//! \brief Get the set of possible answers to the poll.
//!
Expand Down
13 changes: 10 additions & 3 deletions src/gridcoin/voting/registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ PollReference::PollReference()
, m_timestamp(0)
, m_duration_days(0)
, m_votes({})
, m_magnitude_weight_factor(Fraction())
{
}

Expand All @@ -346,7 +347,12 @@ PollOption PollReference::TryReadFromDisk(CTxDB& txdb) const
for (auto& contract : tx.PullContracts()) {
if (contract.m_type == ContractType::POLL) {
auto payload = contract.PullPayloadAs<PollPayload>();
payload.m_poll.m_timestamp = m_timestamp;
// The time for the poll is the time of the containing transaction.
payload.m_poll.m_timestamp = tx.nTime;

// This is a critical initialization, because the magnitude weight factor is only stored
// in memory and is not serialized.
payload.m_poll.m_magnitude_weight_factor = payload.m_poll.ResolveMagnitudeWeightFactor();

return std::move(payload.m_poll);
}
Expand Down Expand Up @@ -549,8 +555,8 @@ std::optional<CAmount> PollReference::GetActiveVoteWeight(const PollResultOption
const arith_uint256 scaled_network_magnitude)
{
active_vote_weight_tally += net_weight + money_supply * (scaled_network_magnitude - scaled_pool_magnitude)
* arith_uint256(100)
/ arith_uint256(567)
* arith_uint256(m_magnitude_weight_factor.GetNumerator())
/ arith_uint256(m_magnitude_weight_factor.GetDenominator())
/ scaled_network_magnitude;

++blocks;
Expand Down Expand Up @@ -1004,6 +1010,7 @@ void PollRegistry::AddPoll(const ContractContext& ctx) EXCLUSIVE_LOCKS_REQUIRED(
poll_ref.m_type = payload->m_poll.m_type.Value();
poll_ref.m_timestamp = ctx.m_tx.nTime;
poll_ref.m_duration_days = payload->m_poll.m_duration_days;
poll_ref.m_magnitude_weight_factor = payload->m_poll.ResolveMagnitudeWeightFactor();

m_latest_poll = &poll_ref;

Expand Down
18 changes: 10 additions & 8 deletions src/gridcoin/voting/registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "gridcoin/voting/fwd.h"
#include "sync.h"
#include "uint256.h"
#include "util.h"
#include <atomic>
#include <map>

Expand Down Expand Up @@ -175,14 +176,15 @@ class PollReference
void UnlinkVote(const uint256 txid);

private:
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.
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.
int64_t m_timestamp; //!< Timestamp of the poll transaction.
uint32_t m_duration_days; //!< Number of days the poll remains active.
std::vector<uint256> m_votes; //!< Hashes of the linked vote transactions.
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.
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.
int64_t m_timestamp; //!< Timestamp of the poll transaction.
uint32_t m_duration_days; //!< Number of days the poll remains active.
std::vector<uint256> m_votes; //!< Hashes of the linked vote transactions.
Fraction m_magnitude_weight_factor; //!< Magnitude weight factor for the poll (defined at poll start).
}; // PollReference

//!
Expand Down
32 changes: 4 additions & 28 deletions src/gridcoin/voting/result.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,7 @@ class VoteCounter
//! \param supply The total network money supply as of the latest
//! block in the poll window in units of 1/100000000 GRC.
//!
void EnableMagnitudeWeight(SuperblockPtr superblock, const uint64_t supply, const Fraction magnitude_weight_factor)
void EnableMagnitudeWeight(SuperblockPtr superblock, const uint64_t supply)
{
const uint64_t total_mag = superblock->m_cpids.TotalMagnitude();

Expand All @@ -798,8 +798,8 @@ class VoteCounter

// Use integer arithmetic to avoid floating-point discrepancies:
m_magnitude_factor = supply / total_mag
* (uint64_t) magnitude_weight_factor.GetNumerator()
/ (uint64_t) magnitude_weight_factor.GetDenominator();
* (uint64_t) m_poll.m_magnitude_weight_factor.GetNumerator()
/ (uint64_t) m_poll.m_magnitude_weight_factor.GetDenominator();
m_resolver.SetSuperblock(std::move(superblock));
}

Expand Down Expand Up @@ -1137,29 +1137,6 @@ CAmount ResolveMoneySupplyForPoll(const Poll& poll)
return pindex->nMoneySupply;
}

//!
//! \brief Fetch the applicable magnitude factor for the poll. This is the magnitude factor of the last entry in the
//! protocol registry database that has a timestamp at or before the poll start timestamp.
//!
//! \param poll Poll for which to fetch the Magnitude Weight Factor.
//! \return Fraction Magnitude factor expressed as a Fraction.
//!
Fraction ResolveMagnitudeWeightFactorForPoll(const Poll& poll)
{
Fraction magnitude_weight_factor = Params().GetConsensus().DefaultMagnitudeWeightFactor;

// Find the current protocol entry value for Magnitude Weight Factor, if it exists.
ProtocolEntryOption protocol_entry = GetProtocolRegistry().TryLastBeforeTimestamp("magnitudeweightfactor", poll.m_timestamp);

// If their is an entry prior or equal in timestemp to the start of the poll and it is active then set the magnitude weight
// factor to that value. If the last entry is not active (i.e. deleted), then leave at the default.
if (protocol_entry != nullptr && protocol_entry->m_status == ProtocolEntryStatus::ACTIVE) {
magnitude_weight_factor = Fraction().FromString(protocol_entry->m_value);
}

return magnitude_weight_factor;
}

} // Anonymous namespace

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -1213,8 +1190,7 @@ PollResultOption PollResult::BuildFor(const PollReference& poll_ref)
if (result.m_poll.IncludesMagnitudeWeight()) {
counter.EnableMagnitudeWeight(
ResolveSuperblockForPoll(result.m_poll),
ResolveMoneySupplyForPoll(result.m_poll),
ResolveMagnitudeWeightFactorForPoll(result.m_poll));
ResolveMoneySupplyForPoll(result.m_poll));
}

LogPrint(BCLog::LogFlags::VOTE, "INFO: %s: number of votes = %u for poll %s",
Expand Down

0 comments on commit 138ab6a

Please sign in to comment.