mirror of
https://github.com/jwinterm/myriadcoin.git
synced 2026-10-25 05:58:42 +01:00
auxpow final fixes
This commit is contained in:
+100
-47
@@ -1135,17 +1135,6 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock
|
||||
// CBlock and CBlockIndex
|
||||
//
|
||||
|
||||
std::string CDiskBlockIndex::ToString() const
|
||||
{
|
||||
std::string str = "CDiskBlockIndex(";
|
||||
str += CBlockIndex::ToString();
|
||||
str += strprintf("\n hashBlock=%s, hashPrev=%s, hashParentBlock=%s)",
|
||||
GetBlockHash().ToString().c_str(),
|
||||
hashPrev.ToString().c_str(),
|
||||
(auxpow.get() != NULL) ? auxpow->GetParentBlockHash(GetAlgo()).ToString().substr(0,20).c_str() : "-");
|
||||
return str;
|
||||
}
|
||||
|
||||
bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos)
|
||||
{
|
||||
// Open history file to append
|
||||
@@ -1190,7 +1179,8 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos)
|
||||
}
|
||||
|
||||
// Check the header
|
||||
if (!CheckProofOfWork(block.GetPoWHash(block.GetAlgo()), block.nBits, block.GetAlgo()))
|
||||
//if (!CheckProofOfWork(block.GetPoWHash(block.GetAlgo()), block.nBits, block.GetAlgo()))
|
||||
if (!block.CheckProofOfWork(mapBlockIndex[block.GetHash()]->nHeight))
|
||||
return error("ReadBlockFromDisk : Errors in block header");
|
||||
|
||||
return true;
|
||||
@@ -1999,7 +1989,8 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
// Check it again in case a previous version let a bad block in
|
||||
if (!CheckBlock(block, state, !fJustCheck, !fJustCheck))
|
||||
//if (!CheckBlock(block, state, !fJustCheck, !fJustCheck))
|
||||
if (!CheckBlock(block, state, pindex->nHeight, !fJustCheck, !fJustCheck))
|
||||
return false;
|
||||
|
||||
// verify that the view's current state corresponds to the previous block
|
||||
@@ -2409,27 +2400,6 @@ bool ActivateBestChain(CValidationState &state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
CBlockHeader CBlockIndex::GetBlockHeader() const
|
||||
{
|
||||
CBlockHeader block;
|
||||
|
||||
if (nVersion & BLOCK_VERSION_AUXPOW) {
|
||||
CDiskBlockIndex diskblockindex;
|
||||
// auxpow is not in memory, load CDiskBlockHeader
|
||||
// from database to get it
|
||||
pblocktree->ReadDiskBlockIndex(*phashBlock, diskblockindex);
|
||||
block.auxpow = diskblockindex.auxpow;
|
||||
}
|
||||
block.nVersion = nVersion;
|
||||
if (pprev)
|
||||
block.hashPrevBlock = pprev->GetBlockHash();
|
||||
block.hashMerkleRoot = hashMerkleRoot;
|
||||
block.nTime = nTime;
|
||||
block.nBits = nBits;
|
||||
block.nNonce = nNonce;
|
||||
return block;
|
||||
}
|
||||
|
||||
bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos& pos)
|
||||
{
|
||||
// Check for duplicate
|
||||
@@ -2466,10 +2436,8 @@ bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos
|
||||
pindexNew->nStatus = BLOCK_VALID_TRANSACTIONS | BLOCK_HAVE_DATA;
|
||||
setBlockIndexValid.insert(pindexNew);
|
||||
|
||||
//if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew, block.auxpow)) || !pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew)))
|
||||
if (!pblocktree->WriteDiskBlockIndex(CDiskBlockIndex(pindexNew, block.auxpow)) || !pblocktree->WriteBlockIndex(*pindexNew))
|
||||
/* write both the immutible data (CDiskBlockIndex) and the mutable data (BlockIndex) */
|
||||
//if (!pblocktree->WriteDiskBlockIndex(CDiskBlockIndex(pindexNew, block.auxpow)) || !pblocktree->WriteBlockIndex(*pindexNew))
|
||||
if (!pblocktree->WriteDiskBlockIndex(CDiskBlockIndex(pindexNew, block.auxpow)) || !pblocktree->WriteBlockIndex(*pindexNew))
|
||||
return state.Abort(_("Failed to write block index"));
|
||||
|
||||
// New best?
|
||||
@@ -2590,26 +2558,66 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, int nHeight, bool fCheckPOW)
|
||||
{
|
||||
// Check proof of work matches claimed amount
|
||||
if (fCheckPOW && !block.CheckProofOfWork(nHeight))
|
||||
//if (fCheckPOW && !CheckProofOfWork(block.GetPoWHash(block.GetAlgo()), block.nBits, block.GetAlgo()))
|
||||
return state.DoS(50, error("CheckBlockHeader() : proof of work failed"),
|
||||
REJECT_INVALID, "high-hash");
|
||||
|
||||
bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot)
|
||||
// Check timestamp
|
||||
if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
|
||||
return state.Invalid(error("CheckBlockHeader() : block timestamp too far in the future"),
|
||||
REJECT_INVALID, "time-too-new");
|
||||
|
||||
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
|
||||
if (pcheckpoint && block.hashPrevBlock != (chainActive.Tip() ? chainActive.Tip()->GetBlockHash() : uint256(0)))
|
||||
{
|
||||
// Extra checks to prevent "fill up memory by spamming with bogus blocks"
|
||||
int64_t deltaTime = block.GetBlockTime() - pcheckpoint->nTime;
|
||||
if (deltaTime < 0)
|
||||
{
|
||||
LogPrintf("CheckBlockHeader(): Height=%d, hash=%s, BlockTime=%d, Checkpoint=%d\n", nHeight, block.GetHash().GetHex().c_str(), block.GetBlockTime(), pcheckpoint->nTime);
|
||||
return state.DoS(100, error("CheckBlockHeader() : block with timestamp before last checkpoint"),
|
||||
REJECT_CHECKPOINT, "time-too-old");
|
||||
}
|
||||
CBigNum bnNewBlock;
|
||||
bnNewBlock.SetCompact(block.nBits);
|
||||
CBigNum bnRequired;
|
||||
bnRequired.SetCompact(ComputeMinWork(pcheckpoint->nBits, deltaTime));
|
||||
if (bnNewBlock > bnRequired)
|
||||
{
|
||||
return state.DoS(100, error("CheckBlockHeader() : block with too little proof-of-work"),
|
||||
REJECT_INVALID, "bad-diffbits");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckBlock(const CBlock& block, CValidationState& state, int nHeight, bool fCheckPOW, bool fCheckMerkleRoot)
|
||||
{
|
||||
// These are checks that are independent of context
|
||||
// that can be verified before saving an orphan block.
|
||||
|
||||
if (!CheckBlockHeader(block, state, nHeight, fCheckPOW))
|
||||
return false;
|
||||
|
||||
// Size limits
|
||||
if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
|
||||
return state.DoS(100, error("CheckBlock() : size limits failed"),
|
||||
REJECT_INVALID, "bad-blk-length");
|
||||
|
||||
// Check proof of work matches claimed amount
|
||||
if (fCheckPOW && !CheckProofOfWork(block.GetPoWHash(block.GetAlgo()), block.nBits, block.GetAlgo()))
|
||||
return state.DoS(50, error("CheckBlock() : proof of work failed"),
|
||||
REJECT_INVALID, "high-hash");
|
||||
// if (fCheckPOW && !CheckProofOfWork(block.GetPoWHash(block.GetAlgo()), block.nBits, block.GetAlgo()))
|
||||
// return state.DoS(50, error("CheckBlock() : proof of work failed"),
|
||||
// REJECT_INVALID, "high-hash");
|
||||
|
||||
// Check timestamp
|
||||
if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
|
||||
return state.Invalid(error("CheckBlock() : block timestamp too far in the future"),
|
||||
REJECT_INVALID, "time-too-new");
|
||||
// if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
|
||||
// return state.Invalid(error("CheckBlock() : block timestamp too far in the future"),
|
||||
// REJECT_INVALID, "time-too-new");
|
||||
|
||||
// First transaction must be coinbase, the rest must not be
|
||||
if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
|
||||
@@ -2812,6 +2820,48 @@ int64_t CBlockIndex::GetMedianTime() const
|
||||
return pindex->GetMedianTimePast();
|
||||
}
|
||||
|
||||
std::string CBlockIndex::ToString() const
|
||||
{
|
||||
return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)",
|
||||
pprev, nHeight,
|
||||
hashMerkleRoot.ToString().substr(0,10).c_str(),
|
||||
GetBlockHash().ToString().c_str());
|
||||
}
|
||||
|
||||
std::string CDiskBlockIndex::ToString() const
|
||||
{
|
||||
std::string str = "CDiskBlockIndex(";
|
||||
str += CBlockIndex::ToString();
|
||||
str += strprintf("\n hashBlock=%s, hashPrev=%s, hashParentBlock=%s)",
|
||||
GetBlockHash().ToString().c_str(),
|
||||
hashPrev.ToString().c_str(),
|
||||
(auxpow.get() != NULL) ? auxpow->GetParentBlockHash(GetAlgo()).ToString().substr(0,20).c_str() : "-");
|
||||
return str;
|
||||
}
|
||||
|
||||
CBlockHeader CBlockIndex::GetBlockHeader() const
|
||||
{
|
||||
CBlockHeader block;
|
||||
|
||||
if (nVersion & BLOCK_VERSION_AUXPOW) {
|
||||
CDiskBlockIndex diskblockindex;
|
||||
// auxpow is not in memory, load CDiskBlockHeader
|
||||
// from database to get it
|
||||
|
||||
pblocktree->ReadDiskBlockIndex(*phashBlock, diskblockindex);
|
||||
block.auxpow = diskblockindex.auxpow;
|
||||
}
|
||||
|
||||
block.nVersion = nVersion;
|
||||
if (pprev)
|
||||
block.hashPrevBlock = pprev->GetBlockHash();
|
||||
block.hashMerkleRoot = hashMerkleRoot;
|
||||
block.nTime = nTime;
|
||||
block.nBits = nBits;
|
||||
block.nNonce = nNonce;
|
||||
return block;
|
||||
}
|
||||
|
||||
void PushGetBlocks(CNode* pnode, CBlockIndex* pindexBegin, uint256 hashEnd)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
@@ -2835,9 +2885,12 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
|
||||
if (mapOrphanBlocks.count(hash))
|
||||
return state.Invalid(error("ProcessBlock() : already have block (orphan) %s", hash.ToString()), 0, "duplicate");
|
||||
|
||||
// Preliminary checks
|
||||
if (!CheckBlock(*pblock, state))
|
||||
if (!CheckBlock(*pblock, state, INT_MAX))
|
||||
{
|
||||
if (state.CorruptionPossible())
|
||||
mapAlreadyAskedFor.erase(CInv(MSG_BLOCK, hash));
|
||||
return error("ProcessBlock() : CheckBlock FAILED");
|
||||
}
|
||||
|
||||
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
|
||||
if (pcheckpoint && pblock->hashPrevBlock != (chainActive.Tip() ? chainActive.Tip()->GetBlockHash() : uint256(0)))
|
||||
@@ -3235,7 +3288,7 @@ bool VerifyDB(int nCheckLevel, int nCheckDepth)
|
||||
if (!ReadBlockFromDisk(block, pindex))
|
||||
return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
|
||||
// check level 1: verify block validity
|
||||
if (nCheckLevel >= 1 && !CheckBlock(block, state))
|
||||
if (nCheckLevel >= 1 && !CheckBlock(block, state, pindex->nHeight))
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user