@ -2246,10 +2246,10 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
return true ;
return true ;
}
}
bool CBlock : : AcceptBlock ( CValidationState & state , CDiskBlockPos * dbp )
bool AcceptBlock ( CBlock & block , CValidationState & state , CDiskBlockPos * dbp )
{
{
// Check for duplicate
// Check for duplicate
uint256 hash = GetHash ( ) ;
uint256 hash = block . GetHash ( ) ;
if ( mapBlockIndex . count ( hash ) )
if ( mapBlockIndex . count ( hash ) )
return state . Invalid ( error ( " AcceptBlock() : block already in mapBlockIndex " ) ) ;
return state . Invalid ( error ( " AcceptBlock() : block already in mapBlockIndex " ) ) ;
@ -2257,23 +2257,23 @@ bool CBlock::AcceptBlock(CValidationState &state, CDiskBlockPos *dbp)
CBlockIndex * pindexPrev = NULL ;
CBlockIndex * pindexPrev = NULL ;
int nHeight = 0 ;
int nHeight = 0 ;
if ( hash ! = Params ( ) . HashGenesisBlock ( ) ) {
if ( hash ! = Params ( ) . HashGenesisBlock ( ) ) {
map < uint256 , CBlockIndex * > : : iterator mi = mapBlockIndex . find ( hashPrevBlock ) ;
map < uint256 , CBlockIndex * > : : iterator mi = mapBlockIndex . find ( block . hashPrevBlock ) ;
if ( mi = = mapBlockIndex . end ( ) )
if ( mi = = mapBlockIndex . end ( ) )
return state . DoS ( 10 , error ( " AcceptBlock() : prev block not found " ) ) ;
return state . DoS ( 10 , error ( " AcceptBlock() : prev block not found " ) ) ;
pindexPrev = ( * mi ) . second ;
pindexPrev = ( * mi ) . second ;
nHeight = pindexPrev - > nHeight + 1 ;
nHeight = pindexPrev - > nHeight + 1 ;
// Check proof of work
// Check proof of work
if ( nBits ! = GetNextWorkRequired ( pindexPrev , this ) )
if ( block . nBits ! = GetNextWorkRequired ( pindexPrev , & block ) )
return state . DoS ( 100 , error ( " AcceptBlock() : incorrect proof of work " ) ) ;
return state . DoS ( 100 , error ( " AcceptBlock() : incorrect proof of work " ) ) ;
// Check timestamp against prev
// Check timestamp against prev
if ( GetBlockTime ( ) < = pindexPrev - > GetMedianTimePast ( ) )
if ( block . GetBlockTime ( ) < = pindexPrev - > GetMedianTimePast ( ) )
return state . Invalid ( error ( " AcceptBlock() : block's timestamp is too early " ) ) ;
return state . Invalid ( error ( " AcceptBlock() : block's timestamp is too early " ) ) ;
// Check that all transactions are finalized
// Check that all transactions are finalized
BOOST_FOREACH ( const CTransaction & tx , vtx )
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
if ( ! IsFinalTx ( tx , nHeight , GetBlockTime ( ) ) )
if ( ! IsFinalTx ( tx , nHeight , block . GetBlockTime ( ) ) )
return state . DoS ( 10 , error ( " AcceptBlock() : contains a non-final transaction " ) ) ;
return state . DoS ( 10 , error ( " AcceptBlock() : contains a non-final transaction " ) ) ;
// Check that the block chain matches the known block chain up to a checkpoint
// Check that the block chain matches the known block chain up to a checkpoint
@ -2281,7 +2281,7 @@ bool CBlock::AcceptBlock(CValidationState &state, CDiskBlockPos *dbp)
return state . DoS ( 100 , error ( " AcceptBlock() : rejected by checkpoint lock-in at %d " , nHeight ) ) ;
return state . DoS ( 100 , error ( " AcceptBlock() : rejected by checkpoint lock-in at %d " , nHeight ) ) ;
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
if ( nVersion < 2 )
if ( block . nVersion < 2 )
{
{
if ( ( ! TestNet ( ) & & CBlockIndex : : IsSuperMajority ( 2 , pindexPrev , 950 , 1000 ) ) | |
if ( ( ! TestNet ( ) & & CBlockIndex : : IsSuperMajority ( 2 , pindexPrev , 950 , 1000 ) ) | |
( TestNet ( ) & & CBlockIndex : : IsSuperMajority ( 2 , pindexPrev , 75 , 100 ) ) )
( TestNet ( ) & & CBlockIndex : : IsSuperMajority ( 2 , pindexPrev , 75 , 100 ) ) )
@ -2290,14 +2290,14 @@ bool CBlock::AcceptBlock(CValidationState &state, CDiskBlockPos *dbp)
}
}
}
}
// Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
// Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
if ( nVersion > = 2 )
if ( block . nVersion > = 2 )
{
{
// if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet):
// if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet):
if ( ( ! TestNet ( ) & & CBlockIndex : : IsSuperMajority ( 2 , pindexPrev , 750 , 1000 ) ) | |
if ( ( ! TestNet ( ) & & CBlockIndex : : IsSuperMajority ( 2 , pindexPrev , 750 , 1000 ) ) | |
( TestNet ( ) & & CBlockIndex : : IsSuperMajority ( 2 , pindexPrev , 51 , 100 ) ) )
( TestNet ( ) & & CBlockIndex : : IsSuperMajority ( 2 , pindexPrev , 51 , 100 ) ) )
{
{
CScript expect = CScript ( ) < < nHeight ;
CScript expect = CScript ( ) < < nHeight ;
if ( ! std : : equal ( expect . begin ( ) , expect . end ( ) , vtx [ 0 ] . vin [ 0 ] . scriptSig . begin ( ) ) )
if ( ! std : : equal ( expect . begin ( ) , expect . end ( ) , block . vtx [ 0 ] . vin [ 0 ] . scriptSig . begin ( ) ) )
return state . DoS ( 100 , error ( " AcceptBlock() : block height mismatch in coinbase " ) ) ;
return state . DoS ( 100 , error ( " AcceptBlock() : block height mismatch in coinbase " ) ) ;
}
}
}
}
@ -2305,16 +2305,16 @@ bool CBlock::AcceptBlock(CValidationState &state, CDiskBlockPos *dbp)
// Write block to history file
// Write block to history file
try {
try {
unsigned int nBlockSize = : : GetSerializeSize ( * this , SER_DISK , CLIENT_VERSION ) ;
unsigned int nBlockSize = : : GetSerializeSize ( block , SER_DISK , CLIENT_VERSION ) ;
CDiskBlockPos blockPos ;
CDiskBlockPos blockPos ;
if ( dbp ! = NULL )
if ( dbp ! = NULL )
blockPos = * dbp ;
blockPos = * dbp ;
if ( ! FindBlockPos ( state , blockPos , nBlockSize + 8 , nHeight , nTime , dbp ! = NULL ) )
if ( ! FindBlockPos ( state , blockPos , nBlockSize + 8 , nHeight , block . nTime , dbp ! = NULL ) )
return error ( " AcceptBlock() : FindBlockPos failed " ) ;
return error ( " AcceptBlock() : FindBlockPos failed " ) ;
if ( dbp = = NULL )
if ( dbp = = NULL )
if ( ! WriteBlockToDisk ( * this , blockPos ) )
if ( ! WriteBlockToDisk ( block , blockPos ) )
return state . Abort ( _ ( " Failed to write block " ) ) ;
return state . Abort ( _ ( " Failed to write block " ) ) ;
if ( ! AddToBlockIndex ( * this , state , blockPos ) )
if ( ! AddToBlockIndex ( block , state , blockPos ) )
return error ( " AcceptBlock() : AddToBlockIndex failed " ) ;
return error ( " AcceptBlock() : AddToBlockIndex failed " ) ;
} catch ( std : : runtime_error & e ) {
} catch ( std : : runtime_error & e ) {
return state . Abort ( _ ( " System error: " ) + e . what ( ) ) ;
return state . Abort ( _ ( " System error: " ) + e . what ( ) ) ;
@ -2407,7 +2407,7 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
}
}
// Store to disk
// Store to disk
if ( ! pblock - > AcceptBlock ( state , dbp ) )
if ( ! AcceptBlock ( * pblock , state , dbp ) )
return error ( " ProcessBlock() : AcceptBlock FAILED " ) ;
return error ( " ProcessBlock() : AcceptBlock FAILED " ) ;
// Recursively process any orphan blocks that depended on this one
// Recursively process any orphan blocks that depended on this one
@ -2423,7 +2423,7 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
CBlock * pblockOrphan = ( * mi ) . second ;
CBlock * pblockOrphan = ( * mi ) . second ;
// Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan resolution (that is, feeding people an invalid block based on LegitBlockX in order to get anyone relaying LegitBlockX banned)
// Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan resolution (that is, feeding people an invalid block based on LegitBlockX in order to get anyone relaying LegitBlockX banned)
CValidationState stateDummy ;
CValidationState stateDummy ;
if ( pblockOrphan - > AcceptBlock ( stateDummy ) )
if ( AcceptBlock ( * pblockOrphan , stateDummy ) )
vWorkQueue . push_back ( pblockOrphan - > GetHash ( ) ) ;
vWorkQueue . push_back ( pblockOrphan - > GetHash ( ) ) ;
mapOrphanBlocks . erase ( pblockOrphan - > GetHash ( ) ) ;
mapOrphanBlocks . erase ( pblockOrphan - > GetHash ( ) ) ;
delete pblockOrphan ;
delete pblockOrphan ;