Browse Source

Merge pull request #930 from sipa/minireorg

Limit the impact of reorganisations on the database (fix #925)
miguelfreitas
Gregory Maxwell 13 years ago
parent
commit
89cccc83f8
  1. 72
      src/main.cpp
  2. 3
      src/main.h

72
src/main.cpp

@ -1457,26 +1457,18 @@ runCommand(std::string strCommand) @@ -1457,26 +1457,18 @@ runCommand(std::string strCommand)
printf("runCommand error: system(%s) returned %d\n", strCommand.c_str(), nErr);
}
bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
bool CBlock::SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew)
{
assert(pindexNew->pprev == pindexBest);
uint256 hash = GetHash();
txdb.TxnBegin();
if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
{
txdb.WriteHashBestChain(hash);
if (!txdb.TxnCommit())
return error("SetBestChain() : TxnCommit failed");
pindexGenesisBlock = pindexNew;
}
else if (hashPrevBlock == hashBestChain)
{
// Adding to current best branch
if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash))
{
txdb.TxnAbort();
InvalidChainFound(pindexNew);
return error("SetBestChain() : ConnectBlock failed");
return false;
}
if (!txdb.TxnCommit())
return error("SetBestChain() : TxnCommit failed");
@ -1487,16 +1479,68 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) @@ -1487,16 +1479,68 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
// Delete redundant memory transactions
BOOST_FOREACH(CTransaction& tx, vtx)
tx.RemoveFromMemoryPool();
return true;
}
bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
{
uint256 hash = GetHash();
txdb.TxnBegin();
if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
{
txdb.WriteHashBestChain(hash);
if (!txdb.TxnCommit())
return error("SetBestChain() : TxnCommit failed");
pindexGenesisBlock = pindexNew;
}
else if (hashPrevBlock == hashBestChain)
{
if (!SetBestChainInner(txdb, pindexNew))
return error("SetBestChain() : SetBestChainInner failed");
}
else
{
// New best branch
if (!Reorganize(txdb, pindexNew))
// the first block in the new chain that will cause it to become the new best chain
CBlockIndex *pindexIntermediate = pindexNew;
// list of blocks that need to be connected afterwards
std::vector<CBlockIndex*> vpindexSecondary;
// Reorganize is costly in terms of db load, as it works in a single db transaction.
// Try to limit how much needs to be done inside
while (pindexIntermediate->pprev && pindexIntermediate->pprev->bnChainWork > pindexBest->bnChainWork)
{
vpindexSecondary.push_back(pindexIntermediate);
pindexIntermediate = pindexIntermediate->pprev;
}
if (!vpindexSecondary.empty())
printf("Postponing %i reconnects\n", vpindexSecondary.size());
// Switch to new best branch
if (!Reorganize(txdb, pindexIntermediate))
{
txdb.TxnAbort();
InvalidChainFound(pindexNew);
return error("SetBestChain() : Reorganize failed");
}
// Connect futher blocks
BOOST_REVERSE_FOREACH(CBlockIndex *pindex, vpindexSecondary)
{
CBlock block;
if (!block.ReadFromDisk(pindex))
{
printf("SetBestChain() : ReadFromDisk failed\n");
break;
}
txdb.TxnBegin();
// errors now are not fatal, we still did a reorganisation to a new chain in a valid way
if (!block.SetBestChainInner(txdb, pindex))
break;
}
}
// Update best block in wallet (so we can detect restored wallets)

3
src/main.h

@ -1030,6 +1030,9 @@ public: @@ -1030,6 +1030,9 @@ public:
bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
bool CheckBlock() const;
bool AcceptBlock();
private:
bool SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew);
};

Loading…
Cancel
Save