Orphan block fill-up-memory attack prevention

This commit is contained in:
Gavin Andresen
2011-09-08 12:51:43 -04:00
parent eb5fff9e16
commit 10fd7f6689
5 changed files with 132 additions and 8 deletions

View File

@@ -659,11 +659,32 @@ int64 static GetBlockValue(int nHeight, int64 nFees)
return nSubsidy + nFees;
}
static const int64 nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
static const int64 nTargetSpacing = 10 * 60;
static const int64 nInterval = nTargetTimespan / nTargetSpacing;
//
// minimum amount of work that could possibly be required nTime after
// minimum work required was nBase
//
unsigned int ComputeMinWork(unsigned int nBase, int64 nTime)
{
CBigNum bnResult;
bnResult.SetCompact(nBase);
while (nTime > 0 && bnResult < bnProofOfWorkLimit)
{
// Maximum 400% adjustment...
bnResult *= 4;
// ... in best-case exactly 4-times-normal target time
nTime -= nTargetTimespan*4;
}
if (bnResult > bnProofOfWorkLimit)
bnResult = bnProofOfWorkLimit;
return bnResult.GetCompact();
}
unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast)
{
const int64 nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
const int64 nTargetSpacing = 10 * 60;
const int64 nInterval = nTargetTimespan / nTargetSpacing;
// Genesis block
if (pindexLast == NULL)
@@ -1340,6 +1361,28 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock)
if (!pblock->CheckBlock())
return error("ProcessBlock() : CheckBlock FAILED");
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
if (pcheckpoint && pblock->hashPrevBlock != hashBestChain)
{
// Extra checks to prevent "fill up memory by spamming with bogus blocks"
int64 deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime;
if (deltaTime < 0)
{
pfrom->Misbehaving(100);
return error("ProcessBlock() : block with timestamp before last checkpoint");
}
CBigNum bnNewBlock;
bnNewBlock.SetCompact(pblock->nBits);
CBigNum bnRequired;
bnRequired.SetCompact(ComputeMinWork(pcheckpoint->nBits, deltaTime));
if (bnNewBlock > bnRequired)
{
pfrom->Misbehaving(100);
return error("ProcessBlock() : block with too little proof-of-work");
}
}
// If don't already have its previous block, shunt it off to holding area until we get it
if (!mapBlockIndex.count(pblock->hashPrevBlock))
{