|
|
@ -270,6 +270,7 @@ bool CCoinsViewMemPool::HaveCoins(uint256 txid) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
CCoinsViewCache *pcoinsTip = NULL; |
|
|
|
CCoinsViewCache *pcoinsTip = NULL; |
|
|
|
|
|
|
|
CBlockTreeDB *pblocktree = NULL; |
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
//
|
|
|
@ -1143,7 +1144,7 @@ void static InvalidChainFound(CBlockIndex* pindexNew) |
|
|
|
if (pindexNew->bnChainWork > bnBestInvalidWork) |
|
|
|
if (pindexNew->bnChainWork > bnBestInvalidWork) |
|
|
|
{ |
|
|
|
{ |
|
|
|
bnBestInvalidWork = pindexNew->bnChainWork; |
|
|
|
bnBestInvalidWork = pindexNew->bnChainWork; |
|
|
|
CChainDB().WriteBestInvalidWork(bnBestInvalidWork); |
|
|
|
pblocktree->WriteBestInvalidWork(bnBestInvalidWork); |
|
|
|
uiInterface.NotifyBlocksChanged(); |
|
|
|
uiInterface.NotifyBlocksChanged(); |
|
|
|
} |
|
|
|
} |
|
|
|
printf("InvalidChainFound: invalid block=%s height=%d work=%s date=%s\n", |
|
|
|
printf("InvalidChainFound: invalid block=%s height=%d work=%s date=%s\n", |
|
|
@ -1159,7 +1160,7 @@ void static InvalidChainFound(CBlockIndex* pindexNew) |
|
|
|
|
|
|
|
|
|
|
|
void static InvalidBlockFound(CBlockIndex *pindex) { |
|
|
|
void static InvalidBlockFound(CBlockIndex *pindex) { |
|
|
|
pindex->nStatus |= BLOCK_FAILED_VALID; |
|
|
|
pindex->nStatus |= BLOCK_FAILED_VALID; |
|
|
|
CChainDB().WriteBlockIndex(CDiskBlockIndex(pindex)); |
|
|
|
pblocktree->WriteBlockIndex(CDiskBlockIndex(pindex)); |
|
|
|
setBlockIndexValid.erase(pindex); |
|
|
|
setBlockIndexValid.erase(pindex); |
|
|
|
InvalidChainFound(pindex); |
|
|
|
InvalidChainFound(pindex); |
|
|
|
if (pindex->pnext) |
|
|
|
if (pindex->pnext) |
|
|
@ -1186,12 +1187,11 @@ bool ConnectBestBlock() { |
|
|
|
do { |
|
|
|
do { |
|
|
|
if (pindexTest->nStatus & BLOCK_FAILED_MASK) { |
|
|
|
if (pindexTest->nStatus & BLOCK_FAILED_MASK) { |
|
|
|
// mark descendants failed
|
|
|
|
// mark descendants failed
|
|
|
|
CChainDB chaindb; |
|
|
|
|
|
|
|
CBlockIndex *pindexFailed = pindexNewBest; |
|
|
|
CBlockIndex *pindexFailed = pindexNewBest; |
|
|
|
while (pindexTest != pindexFailed) { |
|
|
|
while (pindexTest != pindexFailed) { |
|
|
|
pindexFailed->nStatus |= BLOCK_FAILED_CHILD; |
|
|
|
pindexFailed->nStatus |= BLOCK_FAILED_CHILD; |
|
|
|
setBlockIndexValid.erase(pindexFailed); |
|
|
|
setBlockIndexValid.erase(pindexFailed); |
|
|
|
chaindb.WriteBlockIndex(CDiskBlockIndex(pindexFailed)); |
|
|
|
pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexFailed)); |
|
|
|
pindexFailed = pindexFailed->pprev; |
|
|
|
pindexFailed = pindexFailed->pprev; |
|
|
|
} |
|
|
|
} |
|
|
|
InvalidChainFound(pindexNewBest); |
|
|
|
InvalidChainFound(pindexNewBest); |
|
|
@ -1498,7 +1498,7 @@ bool CBlock::DisconnectBlock(CBlockIndex *pindex, CCoinsViewCache &view) |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool FindUndoPos(CChainDB &chaindb, int nFile, CDiskBlockPos &pos, unsigned int nAddSize); |
|
|
|
bool FindUndoPos(int nFile, CDiskBlockPos &pos, unsigned int nAddSize); |
|
|
|
|
|
|
|
|
|
|
|
bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJustCheck) |
|
|
|
bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJustCheck) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -1581,11 +1581,9 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJust |
|
|
|
// Write undo information to disk
|
|
|
|
// Write undo information to disk
|
|
|
|
if (pindex->GetUndoPos().IsNull() || (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) |
|
|
|
if (pindex->GetUndoPos().IsNull() || (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) |
|
|
|
{ |
|
|
|
{ |
|
|
|
CChainDB chaindb; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (pindex->GetUndoPos().IsNull()) { |
|
|
|
if (pindex->GetUndoPos().IsNull()) { |
|
|
|
CDiskBlockPos pos; |
|
|
|
CDiskBlockPos pos; |
|
|
|
if (!FindUndoPos(chaindb, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 8)) |
|
|
|
if (!FindUndoPos(pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 8)) |
|
|
|
return error("ConnectBlock() : FindUndoPos failed"); |
|
|
|
return error("ConnectBlock() : FindUndoPos failed"); |
|
|
|
if (!blockundo.WriteToDisk(pos)) |
|
|
|
if (!blockundo.WriteToDisk(pos)) |
|
|
|
return error("ConnectBlock() : CBlockUndo::WriteToDisk failed"); |
|
|
|
return error("ConnectBlock() : CBlockUndo::WriteToDisk failed"); |
|
|
@ -1598,7 +1596,7 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJust |
|
|
|
pindex->nStatus = (pindex->nStatus & ~BLOCK_VALID_MASK) | BLOCK_VALID_SCRIPTS; |
|
|
|
pindex->nStatus = (pindex->nStatus & ~BLOCK_VALID_MASK) | BLOCK_VALID_SCRIPTS; |
|
|
|
|
|
|
|
|
|
|
|
CDiskBlockIndex blockindex(pindex); |
|
|
|
CDiskBlockIndex blockindex(pindex); |
|
|
|
if (!chaindb.WriteBlockIndex(blockindex)) |
|
|
|
if (!pblocktree->WriteBlockIndex(blockindex)) |
|
|
|
return error("ConnectBlock() : WriteBlockIndex failed"); |
|
|
|
return error("ConnectBlock() : WriteBlockIndex failed"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1804,12 +1802,7 @@ bool CBlock::AddToBlockIndex(const CDiskBlockPos &pos) |
|
|
|
pindexNew->nStatus = BLOCK_VALID_TRANSACTIONS | BLOCK_HAVE_DATA; |
|
|
|
pindexNew->nStatus = BLOCK_VALID_TRANSACTIONS | BLOCK_HAVE_DATA; |
|
|
|
setBlockIndexValid.insert(pindexNew); |
|
|
|
setBlockIndexValid.insert(pindexNew); |
|
|
|
|
|
|
|
|
|
|
|
CChainDB chaindb; |
|
|
|
pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew)); |
|
|
|
if (!chaindb.TxnBegin()) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
chaindb.WriteBlockIndex(CDiskBlockIndex(pindexNew)); |
|
|
|
|
|
|
|
if (!chaindb.TxnCommit()) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// New best?
|
|
|
|
// New best?
|
|
|
|
if (!ConnectBestBlock()) |
|
|
|
if (!ConnectBestBlock()) |
|
|
@ -1823,13 +1816,15 @@ bool CBlock::AddToBlockIndex(const CDiskBlockPos &pos) |
|
|
|
hashPrevBestCoinBase = GetTxHash(0); |
|
|
|
hashPrevBestCoinBase = GetTxHash(0); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pblocktree->Flush(); |
|
|
|
|
|
|
|
|
|
|
|
uiInterface.NotifyBlocksChanged(); |
|
|
|
uiInterface.NotifyBlocksChanged(); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool FindBlockPos(CChainDB &chaindb, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64 nTime) |
|
|
|
bool FindBlockPos(CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64 nTime) |
|
|
|
{ |
|
|
|
{ |
|
|
|
bool fUpdatedLast = false; |
|
|
|
bool fUpdatedLast = false; |
|
|
|
|
|
|
|
|
|
|
@ -1845,7 +1840,7 @@ bool FindBlockPos(CChainDB &chaindb, CDiskBlockPos &pos, unsigned int nAddSize, |
|
|
|
fclose(file); |
|
|
|
fclose(file); |
|
|
|
nLastBlockFile++; |
|
|
|
nLastBlockFile++; |
|
|
|
infoLastBlockFile.SetNull(); |
|
|
|
infoLastBlockFile.SetNull(); |
|
|
|
chaindb.ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile); // check whether data for the new file somehow already exist; can fail just fine
|
|
|
|
pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile); // check whether data for the new file somehow already exist; can fail just fine
|
|
|
|
fUpdatedLast = true; |
|
|
|
fUpdatedLast = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1865,15 +1860,15 @@ bool FindBlockPos(CChainDB &chaindb, CDiskBlockPos &pos, unsigned int nAddSize, |
|
|
|
fclose(file); |
|
|
|
fclose(file); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!chaindb.WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile)) |
|
|
|
if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile)) |
|
|
|
return error("FindBlockPos() : cannot write updated block info"); |
|
|
|
return error("FindBlockPos() : cannot write updated block info"); |
|
|
|
if (fUpdatedLast) |
|
|
|
if (fUpdatedLast) |
|
|
|
chaindb.WriteLastBlockFile(nLastBlockFile); |
|
|
|
pblocktree->WriteLastBlockFile(nLastBlockFile); |
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool FindUndoPos(CChainDB &chaindb, int nFile, CDiskBlockPos &pos, unsigned int nAddSize) |
|
|
|
bool FindUndoPos(int nFile, CDiskBlockPos &pos, unsigned int nAddSize) |
|
|
|
{ |
|
|
|
{ |
|
|
|
pos.nFile = nFile; |
|
|
|
pos.nFile = nFile; |
|
|
|
|
|
|
|
|
|
|
@ -1883,15 +1878,15 @@ bool FindUndoPos(CChainDB &chaindb, int nFile, CDiskBlockPos &pos, unsigned int |
|
|
|
if (nFile == nLastBlockFile) { |
|
|
|
if (nFile == nLastBlockFile) { |
|
|
|
pos.nPos = infoLastBlockFile.nUndoSize; |
|
|
|
pos.nPos = infoLastBlockFile.nUndoSize; |
|
|
|
nNewSize = (infoLastBlockFile.nUndoSize += nAddSize); |
|
|
|
nNewSize = (infoLastBlockFile.nUndoSize += nAddSize); |
|
|
|
if (!chaindb.WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile)) |
|
|
|
if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile)) |
|
|
|
return error("FindUndoPos() : cannot write updated block info"); |
|
|
|
return error("FindUndoPos() : cannot write updated block info"); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
CBlockFileInfo info; |
|
|
|
CBlockFileInfo info; |
|
|
|
if (!chaindb.ReadBlockFileInfo(nFile, info)) |
|
|
|
if (!pblocktree->ReadBlockFileInfo(nFile, info)) |
|
|
|
return error("FindUndoPos() : cannot read block info"); |
|
|
|
return error("FindUndoPos() : cannot read block info"); |
|
|
|
pos.nPos = info.nUndoSize; |
|
|
|
pos.nPos = info.nUndoSize; |
|
|
|
nNewSize = (info.nUndoSize += nAddSize); |
|
|
|
nNewSize = (info.nUndoSize += nAddSize); |
|
|
|
if (!chaindb.WriteBlockFileInfo(nFile, info)) |
|
|
|
if (!pblocktree->WriteBlockFileInfo(nFile, info)) |
|
|
|
return error("FindUndoPos() : cannot write updated block info"); |
|
|
|
return error("FindUndoPos() : cannot write updated block info"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2022,11 +2017,8 @@ bool CBlock::AcceptBlock() |
|
|
|
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"); |
|
|
|
CDiskBlockPos blockPos; |
|
|
|
CDiskBlockPos blockPos; |
|
|
|
{ |
|
|
|
if (!FindBlockPos(blockPos, nBlockSize+8, nHeight, nTime)) |
|
|
|
CChainDB chaindb; |
|
|
|
return error("AcceptBlock() : FindBlockPos failed"); |
|
|
|
if (!FindBlockPos(chaindb, blockPos, nBlockSize+8, nHeight, nTime)) |
|
|
|
|
|
|
|
return error("AcceptBlock() : FindBlockPos failed"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (!WriteToDisk(blockPos)) |
|
|
|
if (!WriteToDisk(blockPos)) |
|
|
|
return error("AcceptBlock() : WriteToDisk failed"); |
|
|
|
return error("AcceptBlock() : WriteToDisk failed"); |
|
|
|
if (!AddToBlockIndex(blockPos)) |
|
|
|
if (!AddToBlockIndex(blockPos)) |
|
|
@ -2210,12 +2202,10 @@ bool LoadBlockIndex(bool fAllowNew) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Load block index
|
|
|
|
// Load block index from databases
|
|
|
|
//
|
|
|
|
//
|
|
|
|
CChainDB chaindb("cr"); |
|
|
|
if (!LoadBlockIndexDB()) |
|
|
|
if (!LoadBlockIndex(chaindb)) |
|
|
|
|
|
|
|
return false; |
|
|
|
return false; |
|
|
|
chaindb.Close(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Init with genesis block
|
|
|
|
// Init with genesis block
|
|
|
@ -2267,11 +2257,8 @@ bool LoadBlockIndex(bool fAllowNew) |
|
|
|
// Start new block file
|
|
|
|
// Start new block file
|
|
|
|
unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); |
|
|
|
unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); |
|
|
|
CDiskBlockPos blockPos; |
|
|
|
CDiskBlockPos blockPos; |
|
|
|
{ |
|
|
|
if (!FindBlockPos(blockPos, nBlockSize+8, 0, block.nTime)) |
|
|
|
CChainDB chaindb; |
|
|
|
return error("AcceptBlock() : FindBlockPos failed"); |
|
|
|
if (!FindBlockPos(chaindb, blockPos, nBlockSize+8, 0, block.nTime)) |
|
|
|
|
|
|
|
return error("AcceptBlock() : FindBlockPos failed"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (!block.WriteToDisk(blockPos)) |
|
|
|
if (!block.WriteToDisk(blockPos)) |
|
|
|
return error("LoadBlockIndex() : writing genesis block to disk failed"); |
|
|
|
return error("LoadBlockIndex() : writing genesis block to disk failed"); |
|
|
|
if (!block.AddToBlockIndex(blockPos)) |
|
|
|
if (!block.AddToBlockIndex(blockPos)) |
|
|
|