Skip to content

Commit

Permalink
Merge pull request #1704 from cyrossignol/block-v11
Browse files Browse the repository at this point in the history
Refactor claim context objects into contracts
  • Loading branch information
jamescowens committed Jun 2, 2020
2 parents 411064f + c8e54c4 commit ae4b40f
Show file tree
Hide file tree
Showing 22 changed files with 410 additions and 284 deletions.
1 change: 1 addition & 0 deletions src/contract/polls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "neuralnet/contract/contract.h"
#include "neuralnet/contract/message.h"
#include "neuralnet/quorum.h"
#include "neuralnet/superblock.h"
#include "neuralnet/tally.h"

double GetTotalBalance();
Expand Down
119 changes: 64 additions & 55 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include "block.h"
#include "miner.h"
#include "neuralnet/beacon.h"
#include "neuralnet/claim.h"
#include "neuralnet/contract/contract.h"
#include "neuralnet/project.h"
#include "neuralnet/quorum.h"
#include "neuralnet/researcher.h"
Expand Down Expand Up @@ -1127,8 +1129,8 @@ bool CTransaction::CheckTransaction() const
return DoS(10, error("CTransaction::CheckTransaction() : vin empty"));
if (vout.empty())
return DoS(10, error("CTransaction::CheckTransaction() : vout empty"));
// Size limits
if (::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
// Size limits - don't count coinbase superblocks--we check this at the block level:
if (::GetSerializeSize(*this, (SER_NETWORK & SER_SKIPSUPERBLOCK), PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
return DoS(100, error("CTransaction::CheckTransaction() : size limits failed"));

// Check for negative or overflow output values
Expand Down Expand Up @@ -2240,18 +2242,6 @@ bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex)
return true;
}



double BlockVersion(std::string v)
{
if (v.length() < 10) return 0;
std::string vIn = v.substr(1,7);
boost::replace_all(vIn, ".", "");
double ver1 = RoundFromString(vIn,0);
return ver1;
}


std::string PubKeyToAddress(const CScript& scriptPubKey)
{
//Converts a script Public Key to a Gridcoin wallet address
Expand All @@ -2270,10 +2260,53 @@ std::string PubKeyToAddress(const CScript& scriptPubKey)
return address;
}

double ClientVersionNew()
const NN::Claim& CBlock::GetClaim() const
{
if (nVersion >= 11 || !vtx[0].vContracts.empty()) {
return *vtx[0].vContracts[0].SharePayloadAs<NN::Claim>();
}

// Before block version 11, the Gridcoin reward claim context is stored
// in the hashBoinc field of the first transaction. We cache the parsed
// representation here to speed up subsequent access:
//
REF(vtx[0]).vContracts.emplace_back(NN::MakeContract<NN::Claim>(
NN::ContractAction::ADD,
NN::Claim::Parse(vtx[0].hashBoinc, nVersion)));

return *vtx[0].vContracts[0].SharePayloadAs<NN::Claim>();
}

NN::Claim CBlock::PullClaim()
{
if (nVersion >= 11 || !vtx[0].vContracts.empty()) {
return vtx[0].vContracts[0].PullPayloadAs<NN::Claim>();
}

// Before block version 11, the Gridcoin reward claim context is stored
// in the hashBoinc field of the first transaction.
//
return NN::Claim::Parse(vtx[0].hashBoinc, nVersion);
}

const NN::Superblock& CBlock::GetSuperblock() const
{
return GetClaim().m_superblock;
}

NN::Superblock CBlock::PullSuperblock()
{
double cv = BlockVersion(FormatFullVersion());
return cv;
if (nVersion >= 11 || !vtx[0].vContracts.empty()) {
auto payload = vtx[0].vContracts[0].SharePayload();
return std::move(payload.As<NN::Claim>().m_superblock);
}

// Before block version 11, the Gridcoin reward claim context is stored
// in the hashBoinc field of the first transaction.
//
NN::Claim claim = NN::Claim::Parse(vtx[0].hashBoinc, nVersion);

return std::move(claim.m_superblock);
}

//
Expand Down Expand Up @@ -2629,9 +2662,9 @@ bool TryLoadSuperblock(
const CBlockIndex* const pindex,
const NN::Claim& claim)
{
// Note: PullSuperblock() invalidates the m_claim.m_superblock field
// Note: PullSuperblock() invalidates the coinbase tx claim contract
// by moving it. This must be the last instance where we reference a
// superblock in a block's claim field:
// superblock in a block's claim contract:
//
NN::SuperblockPtr superblock = NN::SuperblockPtr::BindShared(block.PullSuperblock(), pindex);

Expand Down Expand Up @@ -3413,52 +3446,28 @@ bool CBlock::CheckBlock(std::string sCaller, int height1, int64_t Mint, bool fCh
if (vtx[i].IsCoinBase())
return DoS(100, error("CheckBlock[] : more than one coinbase"));

//Research Age
const NN::Claim& claim = GetClaim();

// Version 11+ blocks store the claim context in the block itself instead
// of the hashBoinc field of the first transaction. The hash of the claim
// is placed in the coinbase transaction instead to verify its integrity:
// Version 11+ blocks store the Gridcoin claim context as a contract in the
// coinbase transaction instead of the hashBoinc field.
//
if (nVersion >= 11) {
if (claim.m_version <= 1) {
return DoS(100, error("%s: legacy claim", __func__));
if (vtx[0].vContracts.empty()) {
return DoS(100, error("%s: missing claim contract", __func__));
}

if (!claim.WellFormed()) {
return DoS(100, error("%s: malformed claim", __func__));
if (vtx[0].vContracts.size() > 1) {
return DoS(100, error("%s: too many coinbase contracts", __func__));
}

if (claim.GetHash() != uint256S(vtx[0].hashBoinc)) {
return DoS(100, error("%s: claim hash mismatch", __func__));
if (vtx[0].vContracts[0].m_type != NN::ContractType::CLAIM) {
return DoS(100, error("%s: unexpected coinbase contract", __func__));
}
}

if(nVersion<9)
{
//For higher security, plus lets catch these bad blocks before adding them to the chain to prevent reorgs:
//Orphan Flood Attack
if (height1 > nGrandfather)
{
double blockVersion = BlockVersion(claim.m_client_version);
double cvn = ClientVersionNew();
LogPrint(BCLog::LogFlags::NOISY, "BV %f, CV %f ",blockVersion,cvn);
// Enforce Beacon Age
if (blockVersion < 3588 && height1 > 860500 && !fTestNet)
return error("CheckBlock[]: Old client spamming new blocks after mandatory upgrade ");
if (!vtx[0].vContracts[0].WellFormed()) {
return DoS(100, error("%s: malformed claim contract", __func__));
}
}

if (!fLoadingIndex && claim.HasResearchReward() && height1 > nGrandfather && BlockNeedsChecked(nTime))
{
// Full "v3" signature check is performed in ConnectBlock
if (claim.m_signature.size() < 16)
{
return DoS(20, error(
"Bad CPID or Block Signature : height %i, CPID %s, Bad Hashboinc [%s]",
height1,
claim.m_mining_id.ToString(),
vtx[0].hashBoinc));
if (vtx[0].vContracts[0].m_version <= 1 || GetClaim().m_version <= 1) {
return DoS(100, error("%s: legacy claim", __func__));
}
}

Expand Down
80 changes: 14 additions & 66 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include "arith_uint256.h"
#include "util.h"
#include "net.h"
#include "neuralnet/claim.h"
#include "neuralnet/contract/contract.h"
#include "neuralnet/cpid.h"
#include "sync.h"
Expand All @@ -30,6 +29,16 @@ class CInv;
class CNode;
class CTxMemPool;

namespace NN {
class Claim;
class Superblock;

//!
//! \brief An optional type that either contains some claim object or does not.
//!
typedef boost::optional<Claim> ClaimOption;
}

static const int LAST_POW_BLOCK = 2050;
static const int CONSENSUS_LOOKBACK = 5; //Amount of blocks to go back from best block, to avoid counting forked blocks
static const int BLOCK_GRANULARITY = 10; //Consensus block divisor
Expand Down Expand Up @@ -1168,9 +1177,6 @@ class CBlock : public CBlockHeader
// ppcoin: block signature - signed by one of the coin base txout[N]'s owner
std::vector<unsigned char> vchBlockSig;

// Gridcoin Research Reward Context
NN::Claim m_claim;

// memory only
mutable std::vector<uint256> vMerkleTree;

Expand Down Expand Up @@ -1200,22 +1206,6 @@ class CBlock : public CBlockHeader
if (!(s.GetType() & (SER_GETHASH|SER_BLOCKHEADERONLY))) {
READWRITE(vtx);
READWRITE(vchBlockSig);

// Before block version 11, the Gridcoin reward claim context is
// stored in the first transaction of the block. Versions 11 and
// above place a claim in the block to facilitate the submission
// of superblocks with a greater quantity of participant data.
//
// Because version 11+ blocks store a claim directly in a member
// field, the claim must be included as input to a block hash to
// protect its integrity. Previous versions hashed a claim along
// with the transactions. Block versions 11 and above must store
// the hash of the claim within the hashBoinc field of the first
// transaction and validation shall check that the hash matches.
//
if (nVersion >= 11) {
READWRITE(m_claim);
}
} else if (ser_action.ForRead()) {
const_cast<CBlock*>(this)->vtx.clear();
const_cast<CBlock*>(this)->vchBlockSig.clear();
Expand All @@ -1230,7 +1220,6 @@ class CBlock : public CBlockHeader
vchBlockSig.clear();
vMerkleTree.clear();
nDoS = 0;
m_claim = NN::Claim();
}

CBlockHeader GetBlockHeader() const
Expand All @@ -1245,51 +1234,10 @@ class CBlock : public CBlockHeader
return block;
}

const NN::Claim& GetClaim() const
{
if (nVersion >= 11 || m_claim.m_mining_id.Valid() || vtx.empty()) {
return m_claim;
}

// Before block version 11, the Gridcoin reward claim context is
// stored in the first transaction of the block. We'll store the
// parsed representation here to speed up subsequent access:
//
REF(m_claim) = NN::Claim::Parse(vtx[0].hashBoinc, nVersion);

return m_claim;
}

NN::Claim PullClaim()
{
if (nVersion >= 11 || m_claim.m_mining_id.Valid() || vtx.empty()) {
return std::move(m_claim);
}

// Before block version 11, the Gridcoin reward claim context is
// stored in the first transaction of the block.
//
return NN::Claim::Parse(vtx[0].hashBoinc, nVersion);
}

const NN::Superblock& GetSuperblock() const
{
return GetClaim().m_superblock;
}

NN::Superblock PullSuperblock()
{
if (nVersion >= 11 || m_claim.m_mining_id.Valid() || vtx.empty()) {
return std::move(m_claim.m_superblock);
}

// Before block version 11, the Gridcoin reward claim context is
// stored in the first transaction of the block.
//
NN::Claim claim = NN::Claim::Parse(vtx[0].hashBoinc, nVersion);

return std::move(claim.m_superblock);
}
const NN::Claim& GetClaim() const;
NN::Claim PullClaim();
const NN::Superblock& GetSuperblock() const;
NN::Superblock PullSuperblock();

// entropy bit for stake modifier if chosen by modifier
unsigned int GetStakeEntropyBit() const
Expand Down
Loading

0 comments on commit ae4b40f

Please sign in to comment.