@ -25,6 +25,7 @@ const uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6
CBlockIndex * pindexGenesisBlock = NULL ;
CBlockIndex * pindexGenesisBlock = NULL ;
int nBestHeight = - 1 ;
int nBestHeight = - 1 ;
CBigNum bnBestChainWork = 0 ;
CBigNum bnBestChainWork = 0 ;
CBigNum bnBestInvalidWork = 0 ;
uint256 hashBestChain = 0 ;
uint256 hashBestChain = 0 ;
CBlockIndex * pindexBest = NULL ;
CBlockIndex * pindexBest = NULL ;
int64 nTimeBestReceived = 0 ;
int64 nTimeBestReceived = 0 ;
@ -794,12 +795,12 @@ uint256 GetOrphanRoot(const CBlock* pblock)
return pblock - > GetHash ( ) ;
return pblock - > GetHash ( ) ;
}
}
int64 CBlock : : GetBlockValue ( int64 nFees ) const
int64 CBlock : : GetBlockValue ( int nHeight , int64 nFees ) const
{
{
int64 nSubsidy = 50 * COIN ;
int64 nSubsidy = 50 * COIN ;
// Subsidy is cut in half every 4 years
// Subsidy is cut in half every 4 years
nSubsidy > > = ( nBest Height / 210000 ) ;
nSubsidy > > = ( nHeight / 210000 ) ;
return nSubsidy + nFees ;
return nSubsidy + nFees ;
}
}
@ -865,6 +866,28 @@ bool IsInitialBlockDownload()
pindexBest - > nTime < GetTime ( ) - 24 * 60 * 60 ) ;
pindexBest - > nTime < GetTime ( ) - 24 * 60 * 60 ) ;
}
}
bool IsLockdown ( )
{
if ( ! pindexBest )
return false ;
return ( bnBestInvalidWork > bnBestChainWork + pindexBest - > GetBlockWork ( ) * 6 ) ;
}
void Lockdown ( CBlockIndex * pindexNew )
{
if ( pindexNew - > bnChainWork > bnBestInvalidWork )
{
bnBestInvalidWork = pindexNew - > bnChainWork ;
CTxDB ( ) . WriteBestInvalidWork ( bnBestInvalidWork ) ;
MainFrameRepaint ( ) ;
}
printf ( " Lockdown: invalid block=%s height=%d work=%s \n " , pindexNew - > GetBlockHash ( ) . ToString ( ) . substr ( 0 , 22 ) . c_str ( ) , pindexNew - > nHeight , pindexNew - > bnChainWork . ToString ( ) . c_str ( ) ) ;
printf ( " Lockdown: current best=%s height=%d work=%s \n " , hashBestChain . ToString ( ) . substr ( 0 , 22 ) . c_str ( ) , nBestHeight , bnBestChainWork . ToString ( ) . c_str ( ) ) ;
printf ( " Lockdown: IsLockdown()=%d \n " , ( IsLockdown ( ) ? 1 : 0 ) ) ;
if ( IsLockdown ( ) )
printf ( " Lockdown: WARNING: Displayed transactions may not be correct! You may need to upgrade. \n " ) ;
}
@ -1086,7 +1109,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
return false ;
return false ;
}
}
if ( vtx [ 0 ] . GetValueOut ( ) > GetBlockValue ( nFees ) )
if ( vtx [ 0 ] . GetValueOut ( ) > GetBlockValue ( pindex - > nHeight , nFees ) )
return false ;
return false ;
// Update block index on disk without changing it in memory.
// Update block index on disk without changing it in memory.
@ -1116,11 +1139,13 @@ bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
CBlockIndex * plonger = pindexNew ;
CBlockIndex * plonger = pindexNew ;
while ( pfork ! = plonger )
while ( pfork ! = plonger )
{
{
if ( ! ( pfork = pfork - > pprev ) )
return error ( " Reorganize() : pfork - > pprev is null " ) ;
while ( plonger - > nHeight > pfork - > nHeight )
while ( plonger - > nHeight > pfork - > nHeight )
if ( ! ( plonger = plonger - > pprev ) )
if ( ! ( plonger = plonger - > pprev ) )
return error ( " Reorganize() : plonger - > pprev is null " ) ;
return error ( " Reorganize() : plonger - > pprev is null " ) ;
if ( pfork = = plonger )
break ;
if ( ! ( pfork = pfork - > pprev ) )
return error ( " Reorganize() : pfork - > pprev is null " ) ;
}
}
// List of what to disconnect
// List of what to disconnect
@ -1160,16 +1185,8 @@ bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
return error ( " Reorganize() : ReadFromDisk for connect failed " ) ;
return error ( " Reorganize() : ReadFromDisk for connect failed " ) ;
if ( ! block . ConnectBlock ( txdb , pindex ) )
if ( ! block . ConnectBlock ( txdb , pindex ) )
{
{
// Invalid block, delete the rest of this branch
// Invalid block
txdb . TxnAbort ( ) ;
txdb . TxnAbort ( ) ;
for ( int j = i ; j < vConnect . size ( ) ; j + + )
{
CBlockIndex * pindex = vConnect [ j ] ;
pindex - > EraseBlockFromDisk ( ) ;
txdb . EraseBlockIndex ( pindex - > GetBlockHash ( ) ) ;
mapBlockIndex . erase ( pindex - > GetBlockHash ( ) ) ;
delete pindex ;
}
return error ( " Reorganize() : ConnectBlock failed " ) ;
return error ( " Reorganize() : ConnectBlock failed " ) ;
}
}
@ -1227,12 +1244,12 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
pindexNew - > bnChainWork = ( pindexNew - > pprev ? pindexNew - > pprev - > bnChainWork : 0 ) + pindexNew - > GetBlockWork ( ) ;
pindexNew - > bnChainWork = ( pindexNew - > pprev ? pindexNew - > pprev - > bnChainWork : 0 ) + pindexNew - > GetBlockWork ( ) ;
CTxDB txdb ;
CTxDB txdb ;
txdb . TxnBegin ( ) ;
txdb . WriteBlockIndex ( CDiskBlockIndex ( pindexNew ) ) ;
txdb . WriteBlockIndex ( CDiskBlockIndex ( pindexNew ) ) ;
// New best
// New best
if ( pindexNew - > bnChainWork > bnBestChainWork )
if ( pindexNew - > bnChainWork > bnBestChainWork )
{
{
txdb . TxnBegin ( ) ;
if ( pindexGenesisBlock = = NULL & & hash = = hashGenesisBlock )
if ( pindexGenesisBlock = = NULL & & hash = = hashGenesisBlock )
{
{
pindexGenesisBlock = pindexNew ;
pindexGenesisBlock = pindexNew ;
@ -1244,9 +1261,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
if ( ! ConnectBlock ( txdb , pindexNew ) | | ! txdb . WriteHashBestChain ( hash ) )
if ( ! ConnectBlock ( txdb , pindexNew ) | | ! txdb . WriteHashBestChain ( hash ) )
{
{
txdb . TxnAbort ( ) ;
txdb . TxnAbort ( ) ;
pindexNew - > EraseBlockFromDisk ( ) ;
Lockdown ( pindexNew ) ;
mapBlockIndex . erase ( pindexNew - > GetBlockHash ( ) ) ;
delete pindexNew ;
return error ( " AddToBlockIndex() : ConnectBlock failed " ) ;
return error ( " AddToBlockIndex() : ConnectBlock failed " ) ;
}
}
txdb . TxnCommit ( ) ;
txdb . TxnCommit ( ) ;
@ -1262,9 +1277,11 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
if ( ! Reorganize ( txdb , pindexNew ) )
if ( ! Reorganize ( txdb , pindexNew ) )
{
{
txdb . TxnAbort ( ) ;
txdb . TxnAbort ( ) ;
Lockdown ( pindexNew ) ;
return error ( " AddToBlockIndex() : Reorganize failed " ) ;
return error ( " AddToBlockIndex() : Reorganize failed " ) ;
}
}
}
}
txdb . TxnCommit ( ) ;
// New best block
// New best block
hashBestChain = hash ;
hashBestChain = hash ;
@ -1273,10 +1290,9 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
bnBestChainWork = pindexNew - > bnChainWork ;
bnBestChainWork = pindexNew - > bnChainWork ;
nTimeBestReceived = GetTime ( ) ;
nTimeBestReceived = GetTime ( ) ;
nTransactionsUpdated + + ;
nTransactionsUpdated + + ;
printf ( " AddToBlockIndex: new best=%s height=%d \n " , hashBestChain . ToString ( ) . substr ( 0 , 16 ) . c_str ( ) , nBestHeight ) ;
printf ( " AddToBlockIndex: new best=%s height=%d work=%s \n " , hashBestChain . ToString ( ) . substr ( 0 , 22 ) . c_str ( ) , nBestHeight , bnBestChainWork . ToString ( ) . c_str ( ) ) ;
}
}
txdb . TxnCommit ( ) ;
txdb . Close ( ) ;
txdb . Close ( ) ;
if ( pindexNew = = pindexBest )
if ( pindexNew = = pindexBest )
@ -1352,7 +1368,7 @@ bool CBlock::AcceptBlock()
// Check that all transactions are finalized
// Check that all transactions are finalized
foreach ( const CTransaction & tx , vtx )
foreach ( const CTransaction & tx , vtx )
if ( ! tx . IsFinal ( nTime ) )
if ( ! tx . IsFinal ( pindexPrev - > nHeight + 1 , nTime ) )
return error ( " AcceptBlock() : contains a non - final transaction " ) ;
return error ( " AcceptBlock() : contains a non - final transaction " ) ;
// Check proof of work
// Check proof of work
@ -2648,7 +2664,7 @@ void BitcoinMiner()
}
}
}
}
pblock - > nBits = nBits ;
pblock - > nBits = nBits ;
pblock - > vtx [ 0 ] . vout [ 0 ] . nValue = pblock - > GetBlockValue ( nFees ) ;
pblock - > vtx [ 0 ] . vout [ 0 ] . nValue = pblock - > GetBlockValue ( pindexPrev - > nHeight + 1 , nFees ) ;
printf ( " Running BitcoinMiner with %d transactions in block \n " , pblock - > vtx . size ( ) ) ;
printf ( " Running BitcoinMiner with %d transactions in block \n " , pblock - > vtx . size ( ) ) ;