@ -1252,10 +1252,10 @@ bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex)
return true ;
return true ;
}
}
bool CBlock : : ConnectBlock ( CTxDB & txdb , CBlockIndex * pindex )
bool CBlock : : ConnectBlock ( CTxDB & txdb , CBlockIndex * pindex , bool fJustCheck )
{
{
// Check it again in case a previous version let a bad block in
// Check it again in case a previous version let a bad block in
if ( ! CheckBlock ( ) )
if ( ! CheckBlock ( ! fJustCheck , ! fJustCheck ) )
return false ;
return false ;
// Do not allow blocks that contain transactions which 'overwrite' older transactions,
// Do not allow blocks that contain transactions which 'overwrite' older transactions,
@ -1283,7 +1283,13 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
bool fStrictPayToScriptHash = ( pindex - > nTime > = nBIP16SwitchTime ) ;
bool fStrictPayToScriptHash = ( pindex - > nTime > = nBIP16SwitchTime ) ;
//// issue here: it doesn't know the version
//// issue here: it doesn't know the version
unsigned int nTxPos = pindex - > nBlockPos + : : GetSerializeSize ( CBlock ( ) , SER_DISK ) - 1 + GetSizeOfCompactSize ( vtx . size ( ) ) ;
unsigned int nTxPos ;
if ( fJustCheck )
// FetchInputs treats CDiskTxPos(1,1,1) as a special "refer to memorypool" indicator
// Since we're just checking the block and not actually connecting it, it might not (and probably shouldn't) be on the disk to get the transaction from
nTxPos = 1 ;
else
nTxPos = pindex - > nBlockPos + : : GetSerializeSize ( CBlock ( ) , SER_DISK ) - 1 + GetSizeOfCompactSize ( vtx . size ( ) ) ;
map < uint256 , CTxIndex > mapQueuedChanges ;
map < uint256 , CTxIndex > mapQueuedChanges ;
int64 nFees = 0 ;
int64 nFees = 0 ;
@ -1295,6 +1301,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
return DoS ( 100 , error ( " ConnectBlock() : too many sigops " )) ;
return DoS ( 100 , error ( " ConnectBlock() : too many sigops " )) ;
CDiskTxPos posThisTx ( pindex - > nFile , pindex - > nBlockPos , nTxPos ) ;
CDiskTxPos posThisTx ( pindex - > nFile , pindex - > nBlockPos , nTxPos ) ;
if ( ! fJustCheck )
nTxPos + = : : GetSerializeSize ( tx , SER_DISK ) ;
nTxPos + = : : GetSerializeSize ( tx , SER_DISK ) ;
MapPrevTx mapInputs ;
MapPrevTx mapInputs ;
@ -1323,6 +1330,12 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
mapQueuedChanges [ tx . GetHash ( ) ] = CTxIndex ( posThisTx , tx . vout . size ( ) ) ;
mapQueuedChanges [ tx . GetHash ( ) ] = CTxIndex ( posThisTx , tx . vout . size ( ) ) ;
}
}
if ( vtx [ 0 ] . GetValueOut ( ) > GetBlockValue ( pindex - > nHeight , nFees ) )
return false ;
if ( fJustCheck )
return true ;
// Write queued txindex changes
// Write queued txindex changes
for ( map < uint256 , CTxIndex > : : iterator mi = mapQueuedChanges . begin ( ) ; mi ! = mapQueuedChanges . end ( ) ; + + mi )
for ( map < uint256 , CTxIndex > : : iterator mi = mapQueuedChanges . begin ( ) ; mi ! = mapQueuedChanges . end ( ) ; + + mi )
{
{
@ -1330,9 +1343,6 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
return error ( " ConnectBlock() : UpdateTxIndex failed " ) ;
return error ( " ConnectBlock() : UpdateTxIndex failed " ) ;
}
}
if ( vtx [ 0 ] . GetValueOut ( ) > GetBlockValue ( pindex - > nHeight , nFees ) )
return false ;
// Update block index on disk without changing it in memory.
// Update block index on disk without changing it in memory.
// The memory index structure will be changed after the db commits.
// The memory index structure will be changed after the db commits.
if ( pindex - > pprev )
if ( pindex - > pprev )
@ -1619,7 +1629,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
bool CBlock : : CheckBlock ( ) const
bool CBlock : : CheckBlock ( bool fCheckPOW , bool fCheckMerkleRoot ) const
{
{
// These are checks that are independent of context
// These are checks that are independent of context
// that can be verified before saving an orphan block.
// that can be verified before saving an orphan block.
@ -1629,7 +1639,7 @@ bool CBlock::CheckBlock() const
return DoS ( 100 , error ( " CheckBlock() : size limits failed " )) ;
return DoS ( 100 , error ( " CheckBlock() : size limits failed " )) ;
// Check proof of work matches claimed amount
// Check proof of work matches claimed amount
if ( ! CheckProofOfWork ( GetHash ( ) , nBits ) )
if ( fCheckPOW & & ! CheckProofOfWork ( GetHash ( ) , nBits ) )
return DoS ( 50 , error ( " CheckBlock() : proof of work failed " )) ;
return DoS ( 50 , error ( " CheckBlock() : proof of work failed " )) ;
// Check timestamp
// Check timestamp
@ -1657,7 +1667,7 @@ bool CBlock::CheckBlock() const
return DoS ( 100 , error ( " CheckBlock() : out - of - bounds SigOpCount " )) ;
return DoS ( 100 , error ( " CheckBlock() : out - of - bounds SigOpCount " )) ;
// Check merkleroot
// Check merkleroot
if ( hashMerkleRoot ! = BuildMerkleTree ( ) )
if ( fCheckMerkleRoot & & hashMerkleRoot ! = BuildMerkleTree ( ) )
return DoS ( 100 , error ( " CheckBlock() : hashMerkleRoot mismatch " )) ;
return DoS ( 100 , error ( " CheckBlock() : hashMerkleRoot mismatch " )) ;
return true ;
return true ;
@ -3066,6 +3076,9 @@ public:
uint64 nLastBlockTx = 0 ;
uint64 nLastBlockTx = 0 ;
uint64 nLastBlockSize = 0 ;
uint64 nLastBlockSize = 0 ;
const char * pszDummy = " \0 \0 " ;
CScript scriptDummy ( std : : vector < unsigned char > ( pszDummy , pszDummy + sizeof ( pszDummy ) ) ) ;
CBlock * CreateNewBlock ( CReserveKey & reservekey )
CBlock * CreateNewBlock ( CReserveKey & reservekey )
{
{
CBlockIndex * pindexPrev = pindexBest ;
CBlockIndex * pindexPrev = pindexBest ;
@ -3224,16 +3237,22 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
nLastBlockSize = nBlockSize ;
nLastBlockSize = nBlockSize ;
printf ( " CreateNewBlock(): total size %lu \n " , nBlockSize ) ;
printf ( " CreateNewBlock(): total size %lu \n " , nBlockSize ) ;
}
pblock - > vtx [ 0 ] . vout [ 0 ] . nValue = GetBlockValue ( pindexPrev - > nHeight + 1 , nFees ) ;
pblock - > vtx [ 0 ] . vout [ 0 ] . nValue = GetBlockValue ( pindexPrev - > nHeight + 1 , nFees ) ;
// Fill in header
// Fill in header
pblock - > hashPrevBlock = pindexPrev - > GetBlockHash ( ) ;
pblock - > hashPrevBlock = pindexPrev - > GetBlockHash ( ) ;
pblock - > hashMerkleRoot = pblock - > BuildMerkleTree ( ) ;
pblock - > UpdateTime ( pindexPrev ) ;
pblock - > UpdateTime ( pindexPrev ) ;
pblock - > nBits = GetNextWorkRequired ( pindexPrev , pblock . get ( ) ) ;
pblock - > nBits = GetNextWorkRequired ( pindexPrev , pblock . get ( ) ) ;
pblock - > nNonce = 0 ;
pblock - > nNonce = 0 ;
pblock - > vtx [ 0 ] . vin [ 0 ] . scriptSig = scriptDummy ;
CBlockIndex indexDummy ( 1 , 1 , * pblock ) ;
indexDummy . pprev = pindexPrev ;
indexDummy . nHeight = pindexPrev - > nHeight + 1 ;
if ( ! pblock - > ConnectBlock ( txdb , & indexDummy , true ) )
throw std : : runtime_error ( " CreateNewBlock() : ConnectBlock failed " ) ;
}
return pblock . release ( ) ;
return pblock . release ( ) ;
}
}