Skip to content

Commit

Permalink
Merge pull request #95 from Stamek/master
Browse files Browse the repository at this point in the history
Fix staking, remove IsSuperMajority and some improvements
  • Loading branch information
akcryptoguy committed Aug 23, 2020
2 parents 9a3217c + 2b42962 commit 2e57ca8
Show file tree
Hide file tree
Showing 19 changed files with 109 additions and 184 deletions.
9 changes: 1 addition & 8 deletions src/chain.h
Expand Up @@ -80,7 +80,7 @@ enum BlockStatus {
*/
BLOCK_VALID_TRANSACTIONS = 3,

//! Outputs do not overspend inputs, no double spends, coinbase output ok, immature coinbase spends, BIP30.
//! Outputs do not overspend inputs, no double spends, coinbase output ok, immature coinbase spends.
//! Implies all parents are also at least CHAIN.
BLOCK_VALID_CHAIN = 4,

Expand Down Expand Up @@ -385,13 +385,6 @@ class CBlockIndex
nFlags |= BLOCK_STAKE_MODIFIER;
}

/**
* Returns true if there are nRequired or more blocks of minVersion or above
* in the last Params().ToCheckBlockUpgradeMajority() blocks, starting at pstart
* and going backwards.
*/
static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired);

std::string ToString() const
{
return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)",
Expand Down
21 changes: 6 additions & 15 deletions src/chainparams.cpp
Expand Up @@ -60,12 +60,13 @@ static Checkpoints::MapCheckpoints mapCheckpoints =
(32848, uint256("352431d65a69b3425ce508cfbbff077c8fdc2833a84e6e239f0ba8e7300e9744"))
(31562, uint256("7738a178f95139b2cd6b2120b19584cc17a2a28a00962b5d28978cd199427821"))
(126438, uint256("7f0c69501d91e4a4ed413bf9942972cf489e79034a0af4a6440fa513c037140d"))
(862000, uint256("18f02da3b76f9d66474a890438344b0587a2f2b2272e845fa940e4e2cf83ca3c"));
(862000, uint256("18f02da3b76f9d66474a890438344b0587a2f2b2272e845fa940e4e2cf83ca3c"))
(1011360, uint256("a3b68cc2be16360617c1fb6d672ad16f66e8f2c1cae5441c198a8c8121249a6c"));

static const Checkpoints::CCheckpointData data = {
&mapCheckpoints,
1588866189, // * UNIX timestamp of last checkpoint block
1790696, // * total number of transactions between genesis and last checkpoint
1597873950, // * UNIX timestamp of last checkpoint block
2133199, // * total number of transactions between genesis and last checkpoint
// (the tx=... number in the SetBestChain debug.log lines)
2000 // * estimated number of transactions per day after checkpoint
};
Expand Down Expand Up @@ -138,9 +139,6 @@ class CMainParams : public CChainParams
bnProofOfWorkLimit = ~uint256(0) >> 20; // sQuorum starting difficulty is 1 / 2^12
nSubsidyHalvingInterval = 210240;
nMaxReorganizationDepth = 100;
nEnforceBlockUpgradeMajority = 8100; // 75%
nRejectBlockOutdatedMajority = 10260; // 95%
nToCheckBlockUpgradeMajority = 10800; // Approximate expected amount of blocks in 7 days (1440*7.5)
nMinerThreads = 0;
nTargetSpacing = 1 * 60; // 1 minute
nMaturity = 100;
Expand Down Expand Up @@ -169,6 +167,7 @@ class CMainParams : public CChainParams
nEnforceNewSporkKey = 1537963200; // (PIVX: 1525158000) //!> Sporks signed after (GMT): Wednesday, September 26,2018 12:00 PM must use the new spork key
nRejectOldSporkKey = 1537966800; // (PIVX: 1527811200) //!> Fully reject old spork key after (GMT): Wednesday, September 26,2018 12:00 PM
nBlockStakeModifierlV2 = 1130000;
nBIP65ActivationHeight = 1000000;
// Public coin spend enforcement
nPublicZCSpends = 999999999;

Expand Down Expand Up @@ -271,9 +270,6 @@ class CTestNetParams : public CMainParams
pchMessageStart[3] = 0x0e;
vAlertPubKey = ParseHex("");
nDefaultPort = 19009;
nEnforceBlockUpgradeMajority = 4320; // 75%
nRejectBlockOutdatedMajority = 5472; // 95%
nToCheckBlockUpgradeMajority = 5760; // 4 days
nMinerThreads = 0;
nTargetSpacing = 1 * 60; // sQuorum: 1 minute
nLastPOWBlock = 400;
Expand All @@ -294,6 +290,7 @@ class CTestNetParams : public CMainParams
nEnforceNewSporkKey = 1537963200; // (PIVX: 1525158000) //!> Sporks signed after (GMT): Wednesday, September 26,2018 12:00 PM must use the new spork key
nRejectOldSporkKey = 1537966800; // (PIVX: 1527811200) //!> Fully reject old spork key after (GMT): Wednesday, September 26,2018 12:00 PM
nBlockStakeModifierlV2 = 1000;
nBIP65ActivationHeight = 1000;
// Public coin spend enforcement
nPublicZCSpends = 999999999;

Expand Down Expand Up @@ -368,9 +365,6 @@ class CRegTestParams : public CTestNetParams
pchMessageStart[3] = 0x0e;
nDefaultPort = 19004;
nSubsidyHalvingInterval = 150;
nEnforceBlockUpgradeMajority = 750;
nRejectBlockOutdatedMajority = 950;
nToCheckBlockUpgradeMajority = 1000;
nMinerThreads = 1;
nTargetSpacing = 1 * 60; // sQuorum: 1 minutes
bnProofOfWorkLimit = ~uint256(0) >> 1;
Expand Down Expand Up @@ -451,9 +445,6 @@ class CUnitTestParams : public CMainParams, public CModifiableParams

//! Published setters to allow changing values in unit test cases
virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) { nSubsidyHalvingInterval = anSubsidyHalvingInterval; }
virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority) { nEnforceBlockUpgradeMajority = anEnforceBlockUpgradeMajority; }
virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority) { nRejectBlockOutdatedMajority = anRejectBlockOutdatedMajority; }
virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority) { nToCheckBlockUpgradeMajority = anToCheckBlockUpgradeMajority; }
virtual void setDefaultConsistencyChecks(bool afDefaultConsistencyChecks) { fDefaultConsistencyChecks = afDefaultConsistencyChecks; }
virtual void setAllowMinDifficultyBlocks(bool afAllowMinDifficultyBlocks) { fAllowMinDifficultyBlocks = afAllowMinDifficultyBlocks; }
virtual void setSkipProofOfWorkCheck(bool afSkipProofOfWorkCheck) { fSkipProofOfWorkCheck = afSkipProofOfWorkCheck; }
Expand Down
11 changes: 2 additions & 9 deletions src/chainparams.h
Expand Up @@ -56,9 +56,6 @@ class CChainParams
const uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; }
int SubsidyHalvingInterval() const { return nSubsidyHalvingInterval; }
/** Used to check majorities for block version upgrade */
int EnforceBlockUpgradeMajority() const { return nEnforceBlockUpgradeMajority; }
int RejectBlockOutdatedMajority() const { return nRejectBlockOutdatedMajority; }
int ToCheckBlockUpgradeMajority() const { return nToCheckBlockUpgradeMajority; }
int MaxReorganizationDepth() const { return nMaxReorganizationDepth; }

/** Used if GenerateBitcoins is called with a negative number of threads */
Expand Down Expand Up @@ -144,6 +141,7 @@ class CChainParams
// int Block_Enforce_Invalid() const { return nBlockEnforceInvalidUTXO; }
int Zerocoin_Block_V2_Start() const { return nBlockZerocoinV2; }
bool IsStakeModifierV2(const int nHeight) const { return nHeight >= nBlockStakeModifierlV2; }
int BIP65ActivationHeight() const { return nBIP65ActivationHeight; }

int Zerocoin_Block_Public_Spend_Enabled() const { return nPublicZCSpends; }

Expand All @@ -158,9 +156,6 @@ class CChainParams
uint256 bnProofOfWorkLimit;
int nMaxReorganizationDepth;
int nSubsidyHalvingInterval;
int nEnforceBlockUpgradeMajority;
int nRejectBlockOutdatedMajority;
int nToCheckBlockUpgradeMajority;
int64_t nTargetSpacing;
int nLastPOWBlock;
int64_t nsQuorumBadBlockTime;
Expand Down Expand Up @@ -210,6 +205,7 @@ class CChainParams
int nZerocoinStartTime;
int nZerocoinRequiredStakeDepth;
int64_t nProposalEstablishmentTime;
int nBIP65ActivationHeight;

// // int nBlockEnforceSerialRange;
int nBlockRecalculateAccumulators;
Expand All @@ -233,9 +229,6 @@ class CModifiableParams
public:
//! Published setters to allow changing values in unit test cases
virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) = 0;
virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority) = 0;
virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority) = 0;
virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority) = 0;
virtual void setDefaultConsistencyChecks(bool aDefaultConsistencyChecks) = 0;
virtual void setAllowMinDifficultyBlocks(bool aAllowMinDifficultyBlocks) = 0;
virtual void setSkipProofOfWorkCheck(bool aSkipProofOfWorkCheck) = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/init.cpp
Expand Up @@ -1722,8 +1722,8 @@ bool AppInit2()

//Load zerocoin mint hashes to memory
pwalletMain->zsqrTracker->Init();
zwalletMain->LoadMintPoolFromDB();
zwalletMain->SyncWithChain();
//zwalletMain->LoadMintPoolFromDB();
//zwalletMain->SyncWithChain();
} // (!fDisableWallet)
#else // ENABLE_WALLET
LogPrintf("No wallet compiled in!\n");
Expand Down
4 changes: 2 additions & 2 deletions src/kernel.cpp
Expand Up @@ -368,11 +368,11 @@ bool Stake(const CBlockIndex* pindexPrev, CStakeInput* stakeInput, unsigned int

// iterate the hashing
bool fSuccess = false;
const unsigned int nHashDrift = 60;
const unsigned int nHashDrift = 30;
unsigned int nTryTime = nTimeTx - 1;
// iterate from nTimeTx up to nTimeTx + nHashDrift
// but not after the max allowed future blocktime drift (3 minutes for PoS)
const unsigned int maxTime = std::min(nTimeTx + nHashDrift, Params().MaxFutureBlockTime(GetAdjustedTime(), true));
const unsigned int maxTime = std::min(nTimeTx + nHashDrift, Params().MaxFutureBlockTime(GetAdjustedTime(), true) - 30);

while (nTryTime < maxTime)
{
Expand Down
82 changes: 26 additions & 56 deletions src/main.cpp
Expand Up @@ -1575,12 +1575,12 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa
nFees, ::minRelayTxFee.GetFee(nSize) * 10000);
}

bool fCLTVHasMajority = CBlockIndex::IsSuperMajority(5, chainActive.Tip(), Params().EnforceBlockUpgradeMajority());
bool fCLTVIsActivated = chainActive.Tip()->nHeight >= Params().BIP65ActivationHeight();

// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
int flags = STANDARD_SCRIPT_VERIFY_FLAGS;
if (fCLTVHasMajority)
if (fCLTVIsActivated)
flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
if (!CheckInputs(tx, state, view, true, flags, true)) {
return error("AcceptToMemoryPool: : ConnectInputs failed %s", hash.ToString());
Expand All @@ -1596,7 +1596,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa
// invalid blocks, however allowing such transactions into the mempool
// can be exploited as a DoS attack.
flags = MANDATORY_SCRIPT_VERIFY_FLAGS;
if (fCLTVHasMajority)
if (fCLTVIsActivated)
flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
if (!CheckInputs(tx, state, view, true, flags, true)) {
return error("AcceptToMemoryPool: : BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
Expand Down Expand Up @@ -1785,12 +1785,12 @@ bool AcceptableInputs(CTxMemPool& pool, CValidationState& state, const CTransact
hash.ToString(),
nFees, ::minRelayTxFee.GetFee(nSize) * 10000);

bool fCLTVHasMajority = CBlockIndex::IsSuperMajority(5, chainActive.Tip(), Params().EnforceBlockUpgradeMajority());
bool fCLTVIsActivated = chainActive.Tip()->nHeight >= Params().BIP65ActivationHeight();

// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
int flags = STANDARD_SCRIPT_VERIFY_FLAGS;
if (fCLTVHasMajority)
if (fCLTVIsActivated)
flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
if (!CheckInputs(tx, state, view, false, flags, true)) {
return error("AcceptableInputs: : ConnectInputs failed %s", hash.ToString());
Expand Down Expand Up @@ -2906,28 +2906,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
bool fScriptChecks = pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate();

// If scripts won't be checked anyways, don't bother seeing if CLTV is activated
bool fCLTVHasMajority = false;
bool fCLTVIsActivated = false;
if (fScriptChecks && pindex->pprev) {
fCLTVHasMajority = CBlockIndex::IsSuperMajority(5, pindex->pprev, Params().EnforceBlockUpgradeMajority());
}

// Do not allow blocks that contain transactions which 'overwrite' older transactions,
// unless those are already completely spent.
// If such overwrites are allowed, coinbases and transactions depending upon those
// can be duplicated to remove the ability to spend the first instance -- even after
// being sent to another address.
// See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information.
// This logic is not necessary for memory pool transactions, as AcceptToMemoryPool
// already refuses previously-known transaction ids entirely.
// This rule was originally applied all blocks whose timestamp was after March 15, 2012, 0:00 UTC.
// Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the
// two in the chain that violate it. This prevents exploiting the issue against nodes in their
// initial block download.
for (const CTransaction& tx : block.vtx) {
const CCoins* coins = view.AccessCoins(tx.GetHash());
if (coins && !coins->IsPruned())
return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction"),
REJECT_INVALID, "bad-txns-BIP30");
fCLTVIsActivated = pindex->pprev->nHeight >= Params().BIP65ActivationHeight();
}

CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
Expand Down Expand Up @@ -3068,7 +3049,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin

std::vector<CScriptCheck> vChecks;
unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG;
if (fCLTVHasMajority)
if (fCLTVIsActivated)
flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;

if (!CheckInputs(tx, state, view, fScriptChecks, flags, false, nScriptCheckThreads ? &vChecks : NULL))
Expand Down Expand Up @@ -3197,11 +3178,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
}

// Flush spend/mint info to disk
if (!zerocoinDB->WriteCoinSpendBatch(vSpends)) return state.Abort(("Failed to record coin serials to database"));
if (!zerocoinDB->WriteCoinMintBatch(vMints)) return state.Abort(("Failed to record new mints to database"));
//if (!zerocoinDB->WriteCoinSpendBatch(vSpends)) return state.Abort(("Failed to record coin serials to database"));
//if (!zerocoinDB->WriteCoinMintBatch(vMints)) return state.Abort(("Failed to record new mints to database"));

//Record accumulator checksums
DatabaseChecksums(mapAccumulators);
//DatabaseChecksums(mapAccumulators);

if (fTxIndex)
if (!pblocktree->WriteTxIndex(vPos))
Expand Down Expand Up @@ -4290,11 +4271,13 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
if (pcheckpoint && nHeight < pcheckpoint->nHeight)
return state.DoS(0, error("%s : forked chain older than last checkpoint (height %d)", __func__, nHeight));

// Reject block.nVersion=1, ..., CURRENT_VERSION-1 blocks when 95% (75% on testnet) of the network has upgraded:
for (int version = 2; version <= CBlockHeader::CURRENT_VERSION; version++) {
if (block.nVersion < version && CBlockIndex::IsSuperMajority(version, pindexPrev, Params().RejectBlockOutdatedMajority())) {
return state.Invalid(error("%s : rejected nVersion=%d block", __func__, block.nVersion), REJECT_OBSOLETE, "bad-version");
}
// Reject outdated version blocks
if ((block.nVersion < 4 && nHeight >= 1) ||
(block.nVersion < 5 && nHeight >= Params().BIP65ActivationHeight()) ||
(block.nVersion < 6 && Params().IsStakeModifierV2(nHeight)))
{
std::string stringErr = strprintf("rejected block version %d at height %d", block.nVersion, nHeight);
return state.Invalid(error("%s : %s", __func__, stringErr), REJECT_OBSOLETE, stringErr);
}

return true;
Expand Down Expand Up @@ -4337,13 +4320,12 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
}

// Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
// if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet):
if (block.nVersion >= 2 &&
CBlockIndex::IsSuperMajority(2, pindexPrev, Params().EnforceBlockUpgradeMajority())) {
if (pindexPrev) { // pindexPrev is only null on the first block which is a version 1 block.
CScript expect = CScript() << nHeight;
if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
!std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) {
return state.DoS(100, error("%s : block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height");
return state.DoS(100, error("%s : block height mismatch in coinbase", __func__), REJECT_INVALID,
"bad-cb-height");
}
}
LogPrint("debug", "ContextualCheckBlock returning true");
Expand Down Expand Up @@ -4706,18 +4688,6 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
return true;
}

bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired)
{
unsigned int nToCheck = Params().ToCheckBlockUpgradeMajority();
unsigned int nFound = 0;
for (unsigned int i = 0; i < nToCheck && nFound < nRequired && pstart != NULL; i++) {
if (pstart->nVersion >= minVersion)
++nFound;
pstart = pstart->pprev;
}
return (nFound >= nRequired);
}

/** Turn the lowest '1' bit in the binary representation of a number into a '0'. */
int static inline InvertLowestOne(int n) { return n & (n - 1); }

Expand Down Expand Up @@ -6784,13 +6754,13 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
int ActiveProtocol()
{
// SPORK_14 is used for 71030 (v1.0+)
if (IsSporkActive(SPORK_14_NEW_PROTOCOL_ENFORCEMENT))
return MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT;

// SPORK_15 was used for 71020 (v0.15+), commented out now.
//if (IsSporkActive(SPORK_15_NEW_PROTOCOL_ENFORCEMENT_2))
//if (IsSporkActive(SPORK_14_NEW_PROTOCOL_ENFORCEMENT))
// return MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT;

// SPORK_15 is used for 71031
if (IsSporkActive(SPORK_15_NEW_PROTOCOL_ENFORCEMENT_2))
return MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT;

return MIN_PEER_PROTO_VERSION_BEFORE_ENFORCEMENT;
}

Expand Down
9 changes: 5 additions & 4 deletions src/miner.cpp
Expand Up @@ -143,7 +143,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,
if (fZerocoinActive)
pblock->nVersion = 5;
else
pblock->nVersion = 3;
pblock->nVersion = 4;

pblock->nVersion = GetArg("-blockversion", pblock->nVersion);
}
Expand Down Expand Up @@ -641,7 +641,7 @@ int nMintableLastCheck = 0;
void BitcoinMiner(CWallet* pwallet, bool fProofOfStake)
{
LogPrintf("sQuorumMiner started\n");
SetThreadPriority(THREAD_PRIORITY_LOWEST);
//SetThreadPriority(THREAD_PRIORITY_LOWEST);
RenameThread("squorum-miner");

// Each thread has its own key and counter
Expand Down Expand Up @@ -712,12 +712,12 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake)

//Stake miner main
if (fProofOfStake) {
SetThreadPriority(THREAD_PRIORITY_NORMAL);
//SetThreadPriority(THREAD_PRIORITY_NORMAL);
if (!ProcessBlockFound(pblock, *pwallet)) {
fLastLoopOrphan = true;
continue;
}
SetThreadPriority(THREAD_PRIORITY_LOWEST);
//SetThreadPriority(THREAD_PRIORITY_LOWEST);

continue;
}
Expand Down Expand Up @@ -807,6 +807,7 @@ void static ThreadBitcoinMiner(void* parg)
{
boost::this_thread::interruption_point();
CWallet* pwallet = (CWallet*)parg;
SetThreadPriority(THREAD_PRIORITY_LOWEST);
try {
BitcoinMiner(pwallet, false);
boost::this_thread::interruption_point();
Expand Down

0 comments on commit 2e57ca8

Please sign in to comment.