Skip to content

Commit

Permalink
[Refactoring] Move ContextualCheckZerocoinStake() to kernel.cpp
Browse files Browse the repository at this point in the history
And call it in CheckProofOfStake() which is called by AcceptBlock()
instead of calling it directly from AcceptBlock().
  • Loading branch information
Warrows committed Jun 17, 2019
1 parent 988b33d commit 2621b7f
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 30 deletions.
30 changes: 29 additions & 1 deletion src/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,33 @@ bool Stake(CStakeInput* stakeInput, unsigned int nBits, unsigned int nTimeBlockF
return fSuccess;
}

bool ContextualCheckZerocoinStake(int nPreviousBlockHeight, CStakeInput* stake)
{
if (nPreviousBlockHeight < Params().Zerocoin_Block_V2_Start())
return error("%s: zPIV stake block is less than allowed start height", __func__);

if (CZPivStake* zPIV = dynamic_cast<CZPivStake*>(stake)) {
CBlockIndex* pindexFrom = zPIV->GetIndexFrom();
if (!pindexFrom)
return error("%s: failed to get index associated with zPIV stake checksum", __func__);

if (chainActive.Height() - pindexFrom->nHeight < Params().Zerocoin_RequiredStakeDepth())
return error("%s: zPIV stake does not have required confirmation depth. Current height %d, stakeInput height %d.", __func__, chainActive.Height(), pindexFrom->nHeight);

//The checksum needs to be the exact checksum from 200 blocks ago
uint256 nCheckpoint200 = chainActive[nPreviousBlockHeight - Params().Zerocoin_RequiredStakeDepth()]->nAccumulatorCheckpoint;
uint32_t nChecksum200 = ParseChecksum(nCheckpoint200, libzerocoin::AmountToZerocoinDenomination(zPIV->GetValue()));
if (nChecksum200 != zPIV->GetChecksum())
return error("%s: accumulator checksum is different than the block 200 blocks previous. stake=%d block200=%d", __func__, zPIV->GetChecksum(), nChecksum200);
} else {
return error("%s: dynamic_cast of stake ptr failed", __func__);
}

return true;
}

// Check kernel hash target and coinstake signature
bool CheckProofOfStake(const CBlock block, uint256& hashProofOfStake, std::unique_ptr<CStakeInput>& stake)
bool CheckProofOfStake(const CBlock block, uint256& hashProofOfStake, std::unique_ptr<CStakeInput>& stake, int nPreviousBlockHeight)
{
const CTransaction tx = block.vtx[1];
if (!tx.IsCoinStake())
Expand All @@ -367,6 +392,9 @@ bool CheckProofOfStake(const CBlock block, uint256& hashProofOfStake, std::uniqu
return error("%s: spend is using the wrong SpendType (%d)", __func__, (int)spend.getSpendType());

stake = std::unique_ptr<CStakeInput>(new CZPivStake(spend));

if (!ContextualCheckZerocoinStake(nPreviousBlockHeight, stake.get()))
return error("%s: staked zPIV fails context checks", __func__);
} else {
// First try finding the previous transaction in database
uint256 hashBlock;
Expand Down
2 changes: 2 additions & 0 deletions src/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,6 @@ bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierCheck
// Get time weight using supplied timestamps
int64_t GetWeight(int64_t nIntervalBeginning, int64_t nIntervalEnd);

bool ContextualCheckZerocoinStake(int nPreviousBlockHeight, CStakeInput* stake);

#endif // BITCOIN_KERNEL_H
30 changes: 1 addition & 29 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4691,31 +4691,6 @@ bool AcceptBlockHeader(const CBlock& block, CValidationState& state, CBlockIndex
return true;
}

bool ContextualCheckZerocoinStake(int nHeight, CStakeInput* stake)
{
if (nHeight < Params().Zerocoin_Block_V2_Start())
return error("%s: zPIV stake block is less than allowed start height", __func__);

if (CZPivStake* zPIV = dynamic_cast<CZPivStake*>(stake)) {
CBlockIndex* pindexFrom = zPIV->GetIndexFrom();
if (!pindexFrom)
return error("%s: failed to get index associated with zPIV stake checksum", __func__);

if (chainActive.Height() - pindexFrom->nHeight < Params().Zerocoin_RequiredStakeDepth())
return error("%s: zPIV stake does not have required confirmation depth. Current height %d, stakeInput height %d.", __func__, chainActive.Height(), pindexFrom->nHeight);

//The checksum needs to be the exact checksum from 200 blocks ago
uint256 nCheckpoint200 = chainActive[nHeight - Params().Zerocoin_RequiredStakeDepth()]->nAccumulatorCheckpoint;
uint32_t nChecksum200 = ParseChecksum(nCheckpoint200, libzerocoin::AmountToZerocoinDenomination(zPIV->GetValue()));
if (nChecksum200 != zPIV->GetChecksum())
return error("%s: accumulator checksum is different than the block 200 blocks previous. stake=%d block200=%d", __func__, zPIV->GetChecksum(), nChecksum200);
} else {
return error("%s: dynamic_cast of stake ptr failed", __func__);
}

return true;
}

bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, CDiskBlockPos* dbp, bool fAlreadyCheckedBlock)
{
AssertLockHeld(cs_main);
Expand Down Expand Up @@ -4754,15 +4729,12 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
uint256 hashProofOfStake = 0;
unique_ptr<CStakeInput> stake;

if (!CheckProofOfStake(block, hashProofOfStake, stake))
if (!CheckProofOfStake(block, hashProofOfStake, stake, pindexPrev->nHeight))
return state.DoS(100, error("%s: proof of stake check failed", __func__));

if (!stake)
return error("%s: null stake ptr", __func__);

if (stake->IsZPIV() && !ContextualCheckZerocoinStake(pindexPrev->nHeight, stake.get()))
return state.DoS(100, error("%s: staked zPIV fails context checks", __func__));

uint256 hash = block.GetHash();
if(!mapProofOfStake.count(hash)) // add to mapProofOfStake
mapProofOfStake.insert(make_pair(hash, hashProofOfStake));
Expand Down

0 comments on commit 2621b7f

Please sign in to comment.