When the Bitcoin client loads up, it only checks that the last 2500 blocks in the chain that it has are valid. Beyond that, you can change anything you want in the previous blocks without effecting what the client thinks the block hash is. Remember, the data on disk is assumed to have already been checked by your client, so there is no reason to check it on every startup. If it did, it would take
hours to start your client.
That said, I have to thank you. I just discovered an undocumented command line option:
-checkblocks. If you use that, you
will be safe if you download an untrusted blockchain and put it in your data directory.
for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev)
{
if (pindex->nHeight < nBestHeight-2500 && !mapArgs.count("-checkblocks"))
break;
CBlock block;
if (!block.ReadFromDisk(pindex))
return error("LoadBlockIndex() : block.ReadFromDisk failed");
if (!block.CheckBlock())
{
printf("LoadBlockIndex() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
pindexFork = pindex->pprev;
}
}
Line 474 in
src/db.cppSo a potential attack might go like this:
- Create corrupt blockchain, showing that you have 100,000 BTC at a particular address from a transaction back in block 100,000.
- Get more than 50% of miners to download said blockchain (impossible, given that major pools make up far more than 50% of hashing power, and they already have the blockchain)
- Send those 100,000 BTC to another real address. The miners with the corrupted blockchain would accept the transaction.
- Spend, spend away!
What other concerns might this present?