Skip to content

Commit

Permalink
Readblockfromdisk error (#28)
Browse files Browse the repository at this point in the history
* Remove doubleup of checks in kernel.cpp
* Resolve readblockfromdisk error; left tracing enabled just in case
  • Loading branch information
barrystyle authored and barrystyle committed Nov 15, 2019
1 parent bfed33b commit fa149a9
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 105 deletions.
2 changes: 1 addition & 1 deletion src/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ class CBlockIndex
SetNull();
}

CBlockIndex(const CBlock& block)
explicit CBlockIndex(const CBlock& block)
{
SetNull();

Expand Down
14 changes: 2 additions & 12 deletions src/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,6 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned
bnTargetPerCoinDay.SetCompact(nBits);
CAmount nValueIn = txPrev->vout[prevout.n].nValue;

// discard stakes generated from inputs of less than 10000 PAC
if (nValueIn < Params().GetConsensus().nMinimumStakeValue)
return error("CheckStakeKernelHash() : min amount violation");

// v0.3 protocol kernel hash weight starts from 0 at the 30-day min age
// this change increases active coins participating the hash and helps
// to secure the network when proof-of-stake difficulty is low
Expand Down Expand Up @@ -366,11 +362,6 @@ bool CheckProofOfStake(const CBlock &block, uint256& hashProofOfStake)

CTxOut prevTxOut = txPrev->vout[txin.prevout.n];

// Enforce minimum amount for stake input
if (prevTxOut.nValue < Params().GetConsensus().nMinimumStakeValue)
return error("CheckProofOfStake() : INFO: stakeinput value less than minimum required (%llu < %llu), blockhash %s\n",
prevTxOut.nValue, Params().GetConsensus().nMinimumStakeValue, hashBlock.ToString().c_str());

CBlockIndex* pindex = NULL;
BlockMap::iterator it = mapBlockIndex.find(hashBlock);
if (it != mapBlockIndex.end())
Expand All @@ -386,9 +377,8 @@ bool CheckProofOfStake(const CBlock &block, uint256& hashProofOfStake)
if(!CheckKernelScript(prevTxOut.scriptPubKey, tx->vout[1].scriptPubKey))
return error("CheckProofOfStake() : INFO: check kernel script failed on coinstake %s, hashProof=%s \n", tx->GetHash().ToString().c_str(), hashProofOfStake.ToString().c_str());

unsigned int nTime = block.nTime;
if (!CheckStakeKernelHash(block.nBits, blockprev, sizeof(CBlock), txPrev, txin.prevout, nTime, hashProofOfStake, false, true))
return error("CheckProofOfStake() : INFO: check kernel failed on coinstake %s, hashProof=%s \n", tx->GetHash().ToString().c_str(), hashProofOfStake.ToString().c_str()); // may occur during initial download or if behind on block chain sync
if (!CheckStakeKernelHash(block.nBits, blockprev, sizeof(CBlock), txPrev, txin.prevout, block.nTime, hashProofOfStake, false, true))
return error("CheckProofOfStake() : INFO: check kernel failed on coinstake %s, hashProof=%s \n", tx->GetHash().ToString().c_str(), hashProofOfStake.ToString().c_str());

return true;
}
Expand Down
109 changes: 17 additions & 92 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ std::atomic<bool> fDIP0001ActiveAtTip{false};
std::atomic<bool> fDIP0003ActiveAtTip{false};

uint256 hashAssumeValid;
std::map<COutPoint, int> mapStakeSpent;

CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;

Expand Down Expand Up @@ -1095,8 +1094,12 @@ bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHea
return true;
}

bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams)
{
#if __APPLE__
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams) {
#else
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams, const char* str) {
LogPrintf("ReadBlockFromDisk(CDiskBlockPos)::called by %s\n", str);
#endif
LOCK(cs_main);
block.SetNull();

Expand All @@ -1120,8 +1123,12 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus:
return true;
}

bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams)
{
#if __APPLE__
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams) {
#else
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams, const char* str) {
LogPrintf("ReadBlockFromDisk(CBlockIndex)::called by %s\n", str);
#endif
CDiskBlockPos blockPos;
{
LOCK(cs_main);
Expand Down Expand Up @@ -1744,9 +1751,6 @@ static DisconnectResult DisconnectBlock(const CBlock& block, CValidationState& s
if (res == DISCONNECT_FAILED) return DISCONNECT_FAILED;
fClean = fClean && res != DISCONNECT_UNCLEAN;

// erase the spent input
mapStakeSpent.erase(out);

const CTxIn input = tx.vin[j];

if (fSpentIndex) {
Expand Down Expand Up @@ -2370,30 +2374,6 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd
if (!pblocktree->WriteTxIndex(vPos))
return AbortNode(state, "Failed to write transaction index");

if (pindex->nHeight > Params().GetConsensus().nLastPoWBlock)
{
// add new entries
for (const CTransactionRef ptx: block.vtx) {
const CTransaction& tx = *ptx;
if (tx.IsCoinBase())
continue;
for (const CTxIn in: tx.vin) {
LogPrintf("mapStakeSpent: Insert %s | %u\n", in.prevout.ToString(), pindex->nHeight);
mapStakeSpent.insert(std::make_pair(in.prevout, pindex->nHeight));
}
}

// delete old entries
for (auto it = mapStakeSpent.begin(); it != mapStakeSpent.end();) {
if (it->second < pindex->nHeight - Params().MaxReorganizationDepth()) {
LogPrintf("mapStakeSpent: Erase %s | %u\n", it->first.ToString(), it->second);
it = mapStakeSpent.erase(it);
}else {
it++;
}
}
}

if (fAddressIndex) {
if (!pblocktree->WriteAddressIndex(addressIndex)) {
return AbortNode(state, "Failed to write address index");
Expand Down Expand Up @@ -3681,6 +3661,7 @@ static bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidation

CBlockIndex *pindexDummy = NULL;
CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;

if (!AcceptBlockHeader(block, state, chainparams, &pindex))
return false;

Expand Down Expand Up @@ -3725,68 +3706,12 @@ static bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidation
if (!IsInitialBlockDownload() && chainActive.Tip() == pindex->pprev)
GetMainSignals().NewPoWValidBlock(pindex, pblock);

int nHeight = pindex->nHeight;

if (block.IsProofOfStake()) {
LOCK(cs_main);

CCoinsViewCache coins(pcoinsTip);

const CTransaction& tx = *block.vtx[1];
if (!coins.HaveInputs(tx)) {
// the inputs are spent at the chain tip so we should look at the recently spent outputs

for (CTxIn in : tx.vin) {
auto it = mapStakeSpent.find(in.prevout);
if (it == mapStakeSpent.end()) {
return false;
}
if (it->second < pindex->pprev->nHeight) {
return false;
}
}
}

// if this is on fork
if (!chainActive.Contains(pindex->pprev) && pindex->pprev != nullptr) {
// start at the block we're adding on to
CBlockIndex *last = pindex->pprev;

// while that block is not on the main chain
while (!chainActive.Contains(last) && last != NULL) {
CBlock bl;
ReadBlockFromDisk(bl, last, Params().GetConsensus());
// loop through every spent input from said block

for (CTransactionRef tRef : bl.vtx) {
const CTransaction& t = *tRef;
for (CTxIn in : t.vin) {
// loop through every spent input in the staking transaction of the new block

const CTransaction& tx = *block.vtx[1];
for (CTxIn stakeIn : tx.vin) {

// if they spent the same input
if (stakeIn.prevout == in.prevout) {
// reject the block
return false;
}
}
}
}

// go to the parent block
last = last->pprev;
}
}
}

// test if hashproofofstake matches
//// hashproof test
uint256 hashProofOfStake = uint256();
if (block.IsProofOfStake())
{
if(block.GetHash() == hashProofOfStake)
return state.DoS(100, error("CheckBlock(): invalid proof of stake block\n"));
if(block.GetHash() == hashProofOfStake)
return state.DoS(100, error("CheckBlock(): invalid proof of stake block\n"));

if(!CheckProofOfStake(block, hashProofOfStake))
return state.DoS(100, error("CheckBlock(): check proof-of-stake failed for block %s\n", hashProofOfStake.ToString().c_str()));
Expand All @@ -3805,7 +3730,7 @@ static bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidation
CDiskBlockPos blockPos;
if (dbp != NULL)
blockPos = *dbp;
if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
if (!FindBlockPos(state, blockPos, nBlockSize+8, pindex->nHeight, block.GetBlockTime(), dbp != NULL))
return error("AcceptBlock(): FindBlockPos failed");
if (dbp == NULL)
if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
Expand Down
7 changes: 7 additions & 0 deletions src/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,8 +486,15 @@ bool GetAddressUnspent(uint160 addressHash, int type,

/** Functions for disk access for blocks */
bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart);

// note - clang doesnt like __builtin_FUNCTION()
#if __APPLE__
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams);
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams);
#else
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams, const char* str = __builtin_FUNCTION());
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams, const char* str = __builtin_FUNCTION());
#endif

/** Functions for validating blocks and updating the block tree */

Expand Down

0 comments on commit fa149a9

Please sign in to comment.