|
|
|
|
@@ -2583,9 +2583,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|
|
|
|
}
|
|
|
|
|
auto verifier = libzcash::ProofVerifier::Strict();
|
|
|
|
|
auto disabledVerifier = libzcash::ProofVerifier::Disabled();
|
|
|
|
|
|
|
|
|
|
int32_t futureblock;
|
|
|
|
|
// Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
|
|
|
|
|
if (!CheckBlock(pindex->nHeight,pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck))
|
|
|
|
|
if (!CheckBlock(&futureblock,pindex->nHeight,pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck))
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr,"checkblock failure in connectblock\n");
|
|
|
|
|
return false;
|
|
|
|
|
@@ -3740,7 +3740,7 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CheckBlockHeader(int32_t height,CBlockIndex *pindex, const CBlockHeader& blockhdr, CValidationState& state, bool fCheckPOW)
|
|
|
|
|
bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, const CBlockHeader& blockhdr, CValidationState& state, bool fCheckPOW)
|
|
|
|
|
{
|
|
|
|
|
// Check timestamp
|
|
|
|
|
if ( 0 )
|
|
|
|
|
@@ -3758,11 +3758,12 @@ bool CheckBlockHeader(int32_t height,CBlockIndex *pindex, const CBlockHeader& bl
|
|
|
|
|
fprintf(stderr," <- chainTip\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*futureblockp = 0;
|
|
|
|
|
if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60)
|
|
|
|
|
{
|
|
|
|
|
CBlockIndex *tipindex;
|
|
|
|
|
//fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime());
|
|
|
|
|
if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetAdjustedTime() + 60*2 )
|
|
|
|
|
fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime());
|
|
|
|
|
if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetAdjustedTime() + 60 + 5 )
|
|
|
|
|
{
|
|
|
|
|
//fprintf(stderr,"it is the next block, let's wait for %d seconds\n",GetAdjustedTime() + 60 - blockhdr.GetBlockTime());
|
|
|
|
|
while ( blockhdr.GetBlockTime() > GetAdjustedTime() + 60 )
|
|
|
|
|
@@ -3771,6 +3772,8 @@ bool CheckBlockHeader(int32_t height,CBlockIndex *pindex, const CBlockHeader& bl
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (blockhdr.GetBlockTime() < GetAdjustedTime() + 600)
|
|
|
|
|
*futureblockp = 1;
|
|
|
|
|
return false; //state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -3799,7 +3802,7 @@ bool CheckBlockHeader(int32_t height,CBlockIndex *pindex, const CBlockHeader& bl
|
|
|
|
|
int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime);
|
|
|
|
|
int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height);
|
|
|
|
|
|
|
|
|
|
bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
|
|
|
|
|
bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
|
|
|
|
|
libzcash::ProofVerifier& verifier,
|
|
|
|
|
bool fCheckPOW, bool fCheckMerkleRoot)
|
|
|
|
|
{
|
|
|
|
|
@@ -3809,7 +3812,7 @@ bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidat
|
|
|
|
|
|
|
|
|
|
// Check that the header is valid (particularly PoW). This is mostly
|
|
|
|
|
// redundant with the call in AcceptBlockHeader.
|
|
|
|
|
if (!CheckBlockHeader(height,pindex,block,state,fCheckPOW))
|
|
|
|
|
if (!CheckBlockHeader(futureblockp,height,pindex,block,state,fCheckPOW))
|
|
|
|
|
{
|
|
|
|
|
//fprintf(stderr,"checkblockheader error PoW.%d\n",fCheckPOW);
|
|
|
|
|
return false;
|
|
|
|
|
@@ -3991,11 +3994,12 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
|
|
|
|
|
//static uint256 komodo_requestedhash;
|
|
|
|
|
//static int32_t komodo_requestedcount;
|
|
|
|
|
|
|
|
|
|
bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
|
|
|
|
|
bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
|
|
|
|
|
{
|
|
|
|
|
static uint256 zero;
|
|
|
|
|
const CChainParams& chainparams = Params();
|
|
|
|
|
AssertLockHeld(cs_main);
|
|
|
|
|
|
|
|
|
|
// Check for duplicate
|
|
|
|
|
uint256 hash = block.GetHash();
|
|
|
|
|
BlockMap::iterator miSelf = mapBlockIndex.find(hash);
|
|
|
|
|
@@ -4018,7 +4022,7 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
|
|
|
|
|
// fprintf(stderr,"accepthdr %s already known but no pindex\n",hash.ToString().c_str());
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (!CheckBlockHeader(*ppindex!=0?(*ppindex)->nHeight:0,*ppindex, block, state,0))
|
|
|
|
|
if (!CheckBlockHeader(futureblockp,*ppindex!=0?(*ppindex)->nHeight:0,*ppindex, block, state,0))
|
|
|
|
|
{
|
|
|
|
|
//fprintf(stderr,"AcceptBlockHeader: CheckBlockHeader failed\n");
|
|
|
|
|
return false;
|
|
|
|
|
@@ -4030,7 +4034,7 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
|
|
|
|
|
BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
|
|
|
|
|
if (mi == mapBlockIndex.end())
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr,"AcceptBlockHeader hashPrevBlock %s not found\n",block.hashPrevBlock.ToString().c_str());
|
|
|
|
|
//fprintf(stderr,"AcceptBlockHeader hashPrevBlock %s not found\n",block.hashPrevBlock.ToString().c_str());
|
|
|
|
|
/*if ( komodo_requestedhash == zero )
|
|
|
|
|
{
|
|
|
|
|
komodo_requestedhash = block.hashPrevBlock;
|
|
|
|
|
@@ -4042,8 +4046,8 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
|
|
|
|
|
pindexPrev = (*mi).second;
|
|
|
|
|
if (pindexPrev == 0 )
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr,"AcceptBlockHeader failed no pindexPrev %s\n",block.hashPrevBlock.ToString().c_str());
|
|
|
|
|
/*if ( komodo_requestedhash == zero )
|
|
|
|
|
/*fprintf(stderr,"AcceptBlockHeader failed no pindexPrev %s\n",block.hashPrevBlock.ToString().c_str());
|
|
|
|
|
if ( komodo_requestedhash == zero )
|
|
|
|
|
{
|
|
|
|
|
komodo_requestedhash = block.hashPrevBlock;
|
|
|
|
|
komodo_requestedcount = 0;
|
|
|
|
|
@@ -4076,13 +4080,13 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
|
|
|
|
|
bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
|
|
|
|
|
{
|
|
|
|
|
const CChainParams& chainparams = Params();
|
|
|
|
|
AssertLockHeld(cs_main);
|
|
|
|
|
|
|
|
|
|
CBlockIndex *&pindex = *ppindex;
|
|
|
|
|
if (!AcceptBlockHeader(block, state, &pindex))
|
|
|
|
|
if (!AcceptBlockHeader(futureblockp,block, state, &pindex))
|
|
|
|
|
{
|
|
|
|
|
//fprintf(stderr,"AcceptBlockHeader rejected\n");
|
|
|
|
|
return false;
|
|
|
|
|
@@ -4117,9 +4121,9 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
|
|
|
|
|
|
|
|
|
|
// See method docstring for why this is always disabled
|
|
|
|
|
auto verifier = libzcash::ProofVerifier::Disabled();
|
|
|
|
|
if ((!CheckBlock(pindex->nHeight,pindex,block, state, verifier,0)) || !ContextualCheckBlock(block, state, pindex->pprev))
|
|
|
|
|
if ((!CheckBlock(futureblockp,pindex->nHeight,pindex,block, state, verifier,0)) || !ContextualCheckBlock(block, state, pindex->pprev))
|
|
|
|
|
{
|
|
|
|
|
if (state.IsInvalid() && !state.CorruptionPossible()) {
|
|
|
|
|
if (*futureblockp == 0 && state.IsInvalid() && !state.CorruptionPossible()) {
|
|
|
|
|
pindex->nStatus |= BLOCK_FAILED_VALID;
|
|
|
|
|
setDirtyBlockIndex.insert(pindex);
|
|
|
|
|
}
|
|
|
|
|
@@ -4192,13 +4196,13 @@ CBlockIndex *komodo_ensure(CBlock *pblock,uint256 hash)
|
|
|
|
|
bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
|
|
|
|
|
{
|
|
|
|
|
// Preliminary checks
|
|
|
|
|
bool checked; uint256 hash;
|
|
|
|
|
bool checked; uint256 hash; int32_t futureblock=0;
|
|
|
|
|
auto verifier = libzcash::ProofVerifier::Disabled();
|
|
|
|
|
hash = pblock->GetHash();
|
|
|
|
|
//fprintf(stderr,"process newblock %s\n",hash.ToString().c_str());
|
|
|
|
|
if ( chainActive.Tip() != 0 )
|
|
|
|
|
komodo_currentheight_set(chainActive.Tip()->nHeight);
|
|
|
|
|
checked = CheckBlock(height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
|
|
|
|
|
checked = CheckBlock(&futureblock,height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
|
|
|
|
|
{
|
|
|
|
|
LOCK(cs_main);
|
|
|
|
|
bool fRequested = MarkBlockAsReceived(hash);
|
|
|
|
|
@@ -4208,7 +4212,7 @@ bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNo
|
|
|
|
|
checked = 0;
|
|
|
|
|
fprintf(stderr,"passed checkblock but failed checkPOW.%d\n",from_miner && ASSETCHAINS_STAKED == 0);
|
|
|
|
|
}
|
|
|
|
|
if (!checked)
|
|
|
|
|
if (!checked && futureblock == 0)
|
|
|
|
|
{
|
|
|
|
|
if ( pfrom != 0 )
|
|
|
|
|
{
|
|
|
|
|
@@ -4222,17 +4226,17 @@ bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNo
|
|
|
|
|
// without the komodo_ensure call, it is quite possible to get a non-error but null pindex returned from AcceptBlockHeader. In a 2 node network, it will be a long time before that block is reprocessed. Even though restarting makes it rescan, it seems much better to keep the nodes in sync
|
|
|
|
|
komodo_ensure(pblock,hash);
|
|
|
|
|
}
|
|
|
|
|
bool ret = AcceptBlock(*pblock, state, &pindex, fRequested, dbp);
|
|
|
|
|
bool ret = AcceptBlock(&futureblock,*pblock, state, &pindex, fRequested, dbp);
|
|
|
|
|
if (pindex && pfrom) {
|
|
|
|
|
mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
|
|
|
|
|
}
|
|
|
|
|
CheckBlockIndex();
|
|
|
|
|
if (!ret)
|
|
|
|
|
if (!ret && futureblock == 0)
|
|
|
|
|
return error("%s: AcceptBlock FAILED", __func__);
|
|
|
|
|
//else fprintf(stderr,"added block %s %p\n",pindex->GetBlockHash().ToString().c_str(),pindex->pprev);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ActivateBestChain(state, pblock))
|
|
|
|
|
if (futureblock == 0 && !ActivateBestChain(state, pblock))
|
|
|
|
|
return error("%s: ActivateBestChain failed", __func__);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
@@ -4255,7 +4259,8 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex
|
|
|
|
|
//fprintf(stderr,"TestBlockValidity failure A checkPOW.%d\n",fCheckPOW);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (!CheckBlock(indexDummy.nHeight,0,block, state, verifier, fCheckPOW, fCheckMerkleRoot))
|
|
|
|
|
int32_t futureblock;
|
|
|
|
|
if (!CheckBlock(&futureblock,indexDummy.nHeight,0,block, state, verifier, fCheckPOW, fCheckMerkleRoot))
|
|
|
|
|
{
|
|
|
|
|
//fprintf(stderr,"TestBlockValidity failure B checkPOW.%d\n",fCheckPOW);
|
|
|
|
|
return false;
|
|
|
|
|
@@ -4665,7 +4670,8 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
|
|
|
|
|
if (!ReadBlockFromDisk(block, pindex,0))
|
|
|
|
|
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
|
|
|
|
|
// check level 1: verify block validity
|
|
|
|
|
if (nCheckLevel >= 1 && !CheckBlock(pindex->nHeight,pindex,block, state, verifier,0))
|
|
|
|
|
int32_t futureblock;
|
|
|
|
|
if (nCheckLevel >= 1 && !CheckBlock(&futureblock,pindex->nHeight,pindex,block, state, verifier,0))
|
|
|
|
|
return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
|
|
|
|
|
// check level 2: verify undo validity
|
|
|
|
|
if (nCheckLevel >= 2 && pindex) {
|
|
|
|
|
@@ -6074,12 +6080,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|
|
|
|
Misbehaving(pfrom->GetId(), 20);
|
|
|
|
|
return error("non-continuous headers sequence");
|
|
|
|
|
}
|
|
|
|
|
int32_t futureblock;
|
|
|
|
|
//fprintf(stderr,"headers msg nCount.%d\n",(int32_t)nCount);
|
|
|
|
|
if (!AcceptBlockHeader(header, state, &pindexLast)) {
|
|
|
|
|
if (!AcceptBlockHeader(&futureblock,header, state, &pindexLast)) {
|
|
|
|
|
int nDoS;
|
|
|
|
|
if (state.IsInvalid(nDoS))
|
|
|
|
|
{
|
|
|
|
|
if (nDoS > 0)
|
|
|
|
|
if (nDoS > 0 && futureblock == 0)
|
|
|
|
|
Misbehaving(pfrom->GetId(), nDoS/nDoS);
|
|
|
|
|
return error("invalid header received");
|
|
|
|
|
}
|
|
|
|
|
|