Untitled diff

Created Diff never expires
1 removal
83 lines
4 additions
86 lines
bool CBlock::AcceptBlock()
bool CBlock::AcceptBlock()
{
{
// Check for duplicate
// Check for duplicate
uint256 hash = GetHash();
uint256 hash = GetHash();
if (mapBlockIndex.count(hash))
if (mapBlockIndex.count(hash))
return error("AcceptBlock() : block already in mapBlockIndex");
return error("AcceptBlock() : block already in mapBlockIndex");


// Get prev block index
// Get prev block index
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock);
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock);
if (mi == mapBlockIndex.end())
if (mi == mapBlockIndex.end())
return DoS(10, error("AcceptBlock() : prev block not found"));
return DoS(10, error("AcceptBlock() : prev block not found"));
CBlockIndex* pindexPrev = (*mi).second;
CBlockIndex* pindexPrev = (*mi).second;
int nHeight = pindexPrev->nHeight+1;
int nHeight = pindexPrev->nHeight+1;


if (IsProofOfWork() && nHeight > LAST_POW_BLOCK)
return DoS(100, error("AcceptBlock() : reject proof-of-work at height %d", nHeight));

// Check proof-of-work or proof-of-stake
// Check proof-of-work or proof-of-stake
if (nBits != GetNextTargetRequired(pindexPrev, IsProofOfStake()))
if (nBits != GetNextTargetRequired(pindexPrev, IsProofOfStake()))
return DoS(100, error("AcceptBlock() : incorrect %s", IsProofOfWork() ? "proof-of-work" : "proof-of-stake"));
return DoS(100, error("AcceptBlock() : incorrect %s", IsProofOfWork() ? "proof-of-work" : "proof-of-stake"));


// Check timestamp against prev
// Check timestamp against prev
if (GetBlockTime() <= pindexPrev->GetPastTimeLimit() || FutureDrift(GetBlockTime()) < pindexPrev->GetBlockTime())
if (GetBlockTime() <= pindexPrev->GetPastTimeLimit() || FutureDrift(GetBlockTime()) < pindexPrev->GetBlockTime())
return error("AcceptBlock() : block's timestamp is too early");
return error("AcceptBlock() : block's timestamp is too early");


// Check that all transactions are finalized
// Check that all transactions are finalized
BOOST_FOREACH(const CTransaction& tx, vtx)
BOOST_FOREACH(const CTransaction& tx, vtx)
if (!tx.IsFinal(nHeight, GetBlockTime()))
if (!tx.IsFinal(nHeight, GetBlockTime()))
return DoS(10, error("AcceptBlock() : contains a non-final transaction"));
return DoS(10, error("AcceptBlock() : contains a non-final transaction"));


// Check that the block chain matches the known block chain up to a checkpoint
// Check that the block chain matches the known block chain up to a checkpoint
if (!Checkpoints::CheckHardened(nHeight, hash))
if (!Checkpoints::CheckHardened(nHeight, hash))
return DoS(100, error("AcceptBlock() : rejected by hardened checkpoint lock-in at %d", nHeight));
return DoS(100, error("AcceptBlock() : rejected by hardened checkpoint lock-in at %d", nHeight));


// Verify hash target and signature of coinstake tx
// Verify hash target and signature of coinstake tx
uint256 hashProofOfStake = 0, targetProofOfStake = 0;
uint256 hashProofOfStake = 0, targetProofOfStake = 0;
if (IsProofOfStake())
if (IsProofOfStake())
{
{
if (!CheckProofOfStake(vtx[1], nBits, hashProofOfStake, targetProofOfStake))
if (!CheckProofOfStake(vtx[1], nBits, hashProofOfStake, targetProofOfStake))
{
{
printf("WARNING: ProcessBlock(): check proof-of-stake failed for block %s\n", hash.ToString().c_str());
printf("WARNING: ProcessBlock(): check proof-of-stake failed for block %s\n", hash.ToString().c_str());
return false; // do not error here as we expect this during initial block download
return false; // do not error here as we expect this during initial block download
}
}
}
}


bool cpSatisfies = Checkpoints::CheckSync(hash, pindexPrev);
bool cpSatisfies = Checkpoints::CheckSync(hash, pindexPrev);


// Check that the block satisfies synchronized checkpoint
// Check that the block satisfies synchronized checkpoint
if (CheckpointsMode == Checkpoints::STRICT && !cpSatisfies)
if (CheckpointsMode == Checkpoints::STRICT && !cpSatisfies)
return error("AcceptBlock() : rejected by synchronized checkpoint");
return error("AcceptBlock() : rejected by synchronized checkpoint");


if (CheckpointsMode == Checkpoints::ADVISORY && !cpSatisfies)
if (CheckpointsMode == Checkpoints::ADVISORY && !cpSatisfies)
strMiscWarning = _("WARNING: syncronized checkpoint violation detected, but skipped!");
strMiscWarning = _("WARNING: syncronized checkpoint violation detected, but skipped!");


// Enforce rule that the coinbase starts with serialized block height
// Enforce rule that the coinbase starts with serialized block height
CScript expect = CScript() << nHeight;
CScript expect = CScript() << nHeight;
if (vtx[0].vin[0].scriptSig.size() < expect.size() ||
if (vtx[0].vin[0].scriptSig.size() < expect.size() ||
!std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin()))
!std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin()))
return DoS(100, error("AcceptBlock() : block height mismatch in coinbase"));
return DoS(100, error("AcceptBlock() : block height mismatch in coinbase"));


// Write block to history file
// Write block to history file
if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION)))
if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION)))
return error("AcceptBlock() : out of disk space");
return error("AcceptBlock() : out of disk space");
unsigned int nFile = -1;
unsigned int nFile = -1;
unsigned int nBlockPos = 0;
unsigned int nBlockPos = 0;
if (!WriteToDisk(nFile, nBlockPos))
if (!WriteToDisk(nFile, nBlockPos))
return error("AcceptBlock() : WriteToDisk failed");
return error("AcceptBlock() : WriteToDisk failed");
if (!AddToBlockIndex(nFile, nBlockPos, hashProofOfStake))
if (!AddToBlockIndex(nFile, nBlockPos, hashProofOfStake))
return error("AcceptBlock() : AddToBlockIndex failed");
return error("AcceptBlock() : AddToBlockIndex failed");


// Relay inventory, but don't relay old inventory during initial block download
// Relay inventory, but don't relay old inventory during initial block download
int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
if (hashBestChain == hash)
if (hashBestChain == hash)
{
{
LOCK(cs_vNodes);
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
BOOST_FOREACH(CNode* pnode, vNodes)
if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
pnode->PushInventory(CInv(MSG_BLOCK, hash));
pnode->PushInventory(CInv(MSG_BLOCK, hash));
}
}


// ppcoin: check pending sync-checkpoint
// nebuchadnezzar: check pending sync-checkpoint
Checkpoints::AcceptPendingSyncCheckpoint();
Checkpoints::AcceptPendingSyncCheckpoint();


return true;
return true;
}
}