Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
a603801
Add poll_type to PollToJson output
jamescowens May 31, 2022
1ca4db2
Implement PollV3Height protocol parameter
jamescowens May 31, 2022
49f3449
Change CURRENT_VERSION of poll payload to 3
jamescowens May 31, 2022
13959f7
Add additional poll types to voting fwd.h to correspond with UI poll …
jamescowens May 31, 2022
fb24f8e
Poll type validation rules
jamescowens Jun 1, 2022
9154198
Align Qt poll type enum to core
jamescowens Jun 3, 2022
0e7a9d3
Add poll type functionality to addpoll RPC command
jamescowens Jun 3, 2022
a460dd4
Have GUI use all PollTypes properly for v3+ and use SURVEY only for v2
jamescowens Jun 4, 2022
8b6f52a
Tweak PollToJson
jamescowens Jun 4, 2022
aacaa1f
Add VOTE category logging to improve information for troubleshooting
jamescowens Jun 4, 2022
86163bd
Refactor AVW calculations into the poll Result class
jamescowens Jun 5, 2022
f70a180
Implement AVW validation
jamescowens Jun 5, 2022
09eac0f
Implement BlockFinder::FindByMinTimeFromGivenIndex
jamescowens Jun 5, 2022
56d2157
For switch statement break to assert on out of bound
jamescowens Jun 10, 2022
ff4d9e6
Correct use of optional on m_poll_results_validated to update m_valid…
jamescowens Jun 10, 2022
1b3e3a4
Use cast PollWeightType enums instead of fixed values for balanceLabe…
jamescowens Jun 10, 2022
8a5ec79
Use cast enums for PollWeightType for magnitudeLabel->hide() rather t…
jamescowens Jun 10, 2022
fc3d4b7
Make post-review changes to PollPayload, PollType(s), and POLL_TYPE_R…
jamescowens Jun 10, 2022
4713756
Implement BlockValidate in contract validation
jamescowens Jun 10, 2022
d516d00
Change miner to use BlockContractValidate in CreateRestOfTheBlock
jamescowens Jun 11, 2022
f230304
Add invalid poll status tag and also correct display logic
jamescowens Jun 11, 2022
63922b1
Little correction to POLL_TYPE_RULES comment (to be squashed)
jamescowens Jun 11, 2022
e7cf0ee
Add v3 poll rule to require balance+magnitude for poll types with AVW…
jamescowens Jun 11, 2022
d1d0a01
Missing include for builders.h (to eliminate IDE complaints)
jamescowens Jun 12, 2022
f63af03
Correct GetValidPollTypes call in rpc addpoll
jamescowens Jun 12, 2022
533fb39
Correct BlockValidate function
jamescowens Jun 12, 2022
bd09acf
Add VOTE contract exception in PollRegistry::BlockValidate
jamescowens Jun 12, 2022
961e5bf
Correct PollBuilder and associated sendcontract for payload version
jamescowens Jun 12, 2022
aaba9f0
Implement poll type lable in poll display
jamescowens Jun 12, 2022
a8190bf
Add capability for additional fields for polls
jamescowens Jun 12, 2022
ed6ad37
Add AdditionalFields functionality to PollBuilder
jamescowens Jun 13, 2022
ef4ec55
Enhance rpc addpoll to properly handle (required) additional fields
jamescowens Jun 13, 2022
aaaa527
Move extern nBestHeight from payloads.h to votingmodel.cpp
jamescowens Jun 24, 2022
04b0ef8
Add cross verification of AdditionalFields m_required bool with rules…
jamescowens Jun 24, 2022
14090da
Add AdditionalFieldList::WellFormed() check to PollBuilder::AddAdditi…
jamescowens Jun 24, 2022
84e1b83
Streamline output from PollAdditionalFieldsToJson
jamescowens Jun 25, 2022
71a8af9
Set PollV3Height to 1944820 for testnet hardfork
jamescowens Jun 26, 2022
b4637fc
Add additional field WellFormed() check and POLL_MAX_ADDITIONAL_FIELD…
jamescowens Jun 26, 2022
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
2 changes: 2 additions & 0 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class CMainParams : public CChainParams {
consensus.BlockV10Height = 1420000;
consensus.BlockV11Height = 2053000;
consensus.BlockV12Height = std::numeric_limits<int>::max();
consensus.PollV3Height = std::numeric_limits<int>::max();
// Immediately post zero payment interval fees 40% for mainnet
consensus.InitialMRCFeeFractionPostZeroInterval = Fraction(2, 5);
// Zero day interval is 14 days on mainnet
Expand Down Expand Up @@ -160,6 +161,7 @@ class CTestNetParams : public CChainParams {
consensus.BlockV10Height = 629409;
consensus.BlockV11Height = 1301500;
consensus.BlockV12Height = 1871830;
consensus.PollV3Height = 1944820;
// Immediately post zero payment interval fees 40% for testnet, the same as mainnet
consensus.InitialMRCFeeFractionPostZeroInterval = Fraction(2, 5);
// Zero day interval is 10 minutes on testnet. The very short interval facilitates testing.
Expand Down
8 changes: 8 additions & 0 deletions src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,14 @@ inline bool IsV12Enabled(int nHeight)
return nHeight >= BlockV12Height;
}

inline bool IsPollV3Enabled(int nHeight)
{
// Temporary override for testing. Cf. Corresponding code in init.cpp
int PollV3Height = gArgs.GetArg("-pollv3height", Params().GetConsensus().PollV3Height);

return nHeight >= PollV3Height;
}

inline int GetSuperblockAgeSpacing(int nHeight)
{
return (fTestNet ? 86400 : (nHeight > 364500) ? 86400 : 43200);
Expand Down
2 changes: 2 additions & 0 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ struct Params {
int BlockV11Height;
/** Block height at which v12 blocks are created */
int BlockV12Height;
/** Block height at which poll v3 contract payloads are valid */
int PollV3Height;
/** The fraction of rewards taken as fees in an MRC after the zero payment interval. Only consesnus critical
* at BlockV12Height or above.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/gridcoin/beacon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,11 @@ bool BeaconRegistry::Validate(const Contract& contract, const CTransaction& tx,
return true;
}

bool BeaconRegistry::BlockValidate(const ContractContext& ctx, int& DoS) const
{
return Validate(ctx.m_contract, ctx.m_tx, DoS);
}

void BeaconRegistry::ActivatePending(
const std::vector<uint160>& beacon_ids,
const int64_t superblock_time, const uint256& block_hash, const int& height)
Expand Down
11 changes: 11 additions & 0 deletions src/gridcoin/beacon.h
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,17 @@ class BeaconRegistry : public IContractHandler
//!
bool Validate(const Contract& contract, const CTransaction& tx, int &DoS) const override;

//!
//! \brief Determine whether a beacon contract is valid including block context. This is used
//! in ConnectBlock.
//!
//! \param ctx ContractContext containing the beacon data to validate.
//! \param DoS Misbehavior score out.
//!
//! \return \c false If the contract fails validation.
//!
bool BlockValidate(const ContractContext& ctx, int& DoS) const override;

//!
//! \brief Register a beacon from contract data.
//!
Expand Down
49 changes: 48 additions & 1 deletion src/gridcoin/contract/contract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ class AppCacheContractHandler : public IContractHandler
return true; // No contextual validation needed yet
}

bool BlockValidate(const ContractContext& ctx, int& DoS) const override
{
return true; // No contextual validation needed yet
}

void Add(const ContractContext& ctx) override
{
const auto payload = ctx->SharePayloadAs<LegacyPayload>();
Expand Down Expand Up @@ -200,6 +205,11 @@ class UnknownContractHandler : public IContractHandler
return true; // No contextual validation needed yet
}

bool BlockValidate(const ContractContext& ctx, int& DoS) const override
{
return true; // No contextual validation needed yet
}

//!
//! \brief Handle a contract addition.
//!
Expand Down Expand Up @@ -288,6 +298,28 @@ class Dispatcher
return GetHandler(contract.m_type.Value()).Validate(contract, tx, DoS);
}

//!
//! \brief Perform contextual validation for the provided contract including block context. This is used
//! in ConnectBlock.
//!
//! \param ctx ContractContext to validate.
//! \param DoS Misbehavior score out.
//!
//! \return \c false If the contract fails validation.
//!
bool BlockValidate(const ContractContext& ctx, int& DoS)
{
if (!GetHandler(ctx.m_contract.m_type.Value()).BlockValidate(ctx, DoS)) {
error("%s: Contract of type %s failed validation.",
__func__,
ctx.m_contract.m_type.ToString());

return false;
}

return true;
}

//!
//! \brief Revert a previously-applied contract from a transaction message
//! by passing it to the appropriate contract handler.
Expand Down Expand Up @@ -604,6 +636,17 @@ bool GRC::ValidateContracts(const CTransaction& tx, int& DoS)
return true;
}

bool GRC::BlockValidateContracts(const CBlockIndex* const pindex, const CTransaction& tx, int& DoS)
{
for (const auto& contract: tx.GetContracts()) {
if (!g_dispatcher.BlockValidate({ contract, tx, pindex }, DoS)) {
return false;
}
}

return true;
}

void GRC::RevertContracts(const CTransaction& tx, const CBlockIndex* const pindex)
{
// Reverse the contracts. Reorganize will load any previous versions:
Expand Down Expand Up @@ -896,7 +939,11 @@ void Contract::Body::ResetType(const ContractType type)
m_payload.Reset(new TxMessage());
break;
case ContractType::POLL:
m_payload.Reset(new PollPayload());
// Note that the contract code expects cs_main to already be taken which
// means that the access to nBestHeight is safe.
// TODO: This ternary should be removed at the next mandatory after
// Kermit's Mom.
m_payload.Reset(new PollPayload(IsPollV3Enabled(nBestHeight) ? 3 : 2));
break;
case ContractType::PROJECT:
m_payload.Reset(new Project());
Expand Down
13 changes: 13 additions & 0 deletions src/gridcoin/contract/contract.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define GRIDCOIN_CONTRACT_CONTRACT_H

#include "amount.h"
#include "gridcoin/contract/handler.h"
#include "gridcoin/contract/payload.h"
#include "gridcoin/support/enumbytes.h"
#include "serialize.h"
Expand Down Expand Up @@ -520,6 +521,18 @@ void ApplyContracts(
//!
bool ValidateContracts(const CTransaction& tx, int& DoS);

//!
//! \brief Perform contextual validation for the contracts in a transaction including block context. This is used
//! in ConnectBlock.
//!
//! \param pindex The CBlockIndex of the block context of the transaction.
//! \param tx The transaction to validate contracts for.
//! \param DoS Misbehavior score out.
//!
//! \return \c false If the contract fails validation.
//!
bool BlockValidateContracts(const CBlockIndex* const pindex, const CTransaction& tx, int& DoS);

//!
//! \brief Revert previously-applied contracts from a transaction by passing
//! them to the appropriate contract handlers.
Expand Down
11 changes: 11 additions & 0 deletions src/gridcoin/contract/handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,17 @@ struct IContractHandler
//!
virtual bool Validate(const Contract& contract, const CTransaction& tx, int& DoS) const = 0;

//!
//! \brief Perform contextual validation for the provided contract including block context. This is used
//! in ConnectBlock.
//!
//! \param ctx ContractContext to validate.
//! \param DoS Misbehavior score out.
//!
//! \return \c false If the contract fails validation.
//!
virtual bool BlockValidate(const ContractContext& ctx, int& DoS) const = 0;

//!
//! \brief Destroy the contract handler state to prepare for historical
//! contract replay.
Expand Down
5 changes: 5 additions & 0 deletions src/gridcoin/mrc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,11 @@ bool GRC::MRCContractHandler::Validate(const Contract& contract, const CTransact
return ValidateMRC(contract, tx, DoS);
}

bool GRC::MRCContractHandler::BlockValidate(const ContractContext& ctx, int& DoS) const
{
return Validate(ctx.m_contract, ctx.m_tx, DoS);
}

namespace {
//!
//! \brief Sign the mrc.
Expand Down
20 changes: 20 additions & 0 deletions src/gridcoin/mrc.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,28 @@ class MRCContractHandler : public IContractHandler
// Reset is a noop for MRC's here.
void Reset() override {}

//!
//! \brief Perform contextual validation for the provided contract.
//!
//! \param contract Contract to validate.
//! \param tx Transaction that contains the contract.
//! \param DoS Misbehavior score out.
//!
//! \return \c false If the contract fails validation.
//!
bool Validate(const Contract& contract, const CTransaction& tx, int& DoS) const override;

//!
//! \brief Perform contextual validation for the provided contract including block context. This is used
//! in ConnectBlock.
//!
//! \param ctx ContractContext to validate.
//! \param DoS Misbehavior score out.
//!
//! \return \c false If the contract fails validation.
//!
bool BlockValidate(const ContractContext& ctx, int& DoS) const override;

// Add is a noop here, because this is handled at the block level by the staker (in the miner) as with the claim.
void Add(const ContractContext& ctx) override {}

Expand Down
14 changes: 14 additions & 0 deletions src/gridcoin/project.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,20 @@ class Whitelist : public IContractHandler
return true; // No contextual validation needed yet
}

//!
//! \brief Perform contextual validation for the provided contract including block context. This is used
//! in ConnectBlock.
//!
//! \param ctx ContractContext to validate.
//! \param DoS Misbehavior score out.
//!
//! \return \c false If the contract fails validation.
//!
bool BlockValidate(const ContractContext& ctx, int& DoS) const override
{
return true; // No contextual validation needed yet
}

//!
//! \brief Add a project to the whitelist from contract data.
//!
Expand Down
30 changes: 25 additions & 5 deletions src/gridcoin/support/block_finder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ CBlockIndex* BlockFinder::FindByHeight(int height)
if(index != nullptr)
{
// Traverse towards the tail.
while (index && index->pprev && index->nHeight > height)
while (index && index->pprev && index->nHeight > height) {
index = index->pprev;
}

// Traverse towards the head.
while (index && index->pnext && index->nHeight < height)
while (index && index->pnext && index->nHeight < height) {
index = index->pnext;
}
}

return index;
Expand All @@ -38,15 +40,33 @@ CBlockIndex* BlockFinder::FindByMinTime(int64_t time)
? pindexBest
: pindexGenesisBlock;

if(index != nullptr)
if (index != nullptr)
{
// Move back until the previous block is no longer younger than "time".
while(index && index->pprev && index->pprev->nTime > time)
while (index && index->pprev && index->pprev->nTime > time) {
index = index->pprev;
}

// Move forward until the current block is younger than "time".
while(index && index->pnext && index->nTime < time)
while (index && index->pnext && index->nTime < time) {
index = index->pnext;
}
}

return index;
}

// The arguments are passed by value on purpose.
CBlockIndex* BlockFinder::FindByMinTimeFromGivenIndex(int64_t time, CBlockIndex* index)
{
// If no starting index is provided (i.e. second parameter is omitted or nullptr is passed in,
// then start at the Genesis Block. This is in general expensive and should be avoided.
if (!index) {
index = pindexGenesisBlock;
}

while (index && index->pnext && index->nTime < time) {
index = index->pnext;
}

return index;
Expand Down
11 changes: 11 additions & 0 deletions src/gridcoin/support/block_finder.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#ifndef GRIDCOIN_SUPPORT_BLOCK_FINDER_H
#define GRIDCOIN_SUPPORT_BLOCK_FINDER_H

#include <cstdint>

class CBlockIndex;

namespace GRC {
Expand Down Expand Up @@ -38,6 +40,15 @@ class BlockFinder
//! head of the chain if it is older than \p time.
//!
static CBlockIndex* FindByMinTime(int64_t time);

//!
//! \brief Find block by time going forward from given index.
//! \param time
//! \param CBlockIndex from where to start
//! \return CBlockIndex pointing to the youngest block which is not older than \p time, or
//! the head of the chain if it is older than \p time.
//!
static CBlockIndex* FindByMinTimeFromGivenIndex(int64_t time, CBlockIndex* index = nullptr);
};
} // namespace GRC

Expand Down
Loading