@ -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)