@ -1316,10 +1316,10 @@ bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex)
@@ -1316,10 +1316,10 @@ bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex)
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
if ( ! CheckBlock ( ) )
if ( ! CheckBlock ( ! fJustCheck , ! fJustCheck ) )
return false ;
// Do not allow blocks that contain transactions which 'overwrite' older transactions,
@ -1339,7 +1339,13 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
@@ -1339,7 +1339,13 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
bool fStrictPayToScriptHash = ( pindex - > nTime > = nBIP16SwitchTime ) ;
//// issue here: it doesn't know the version
unsigned int nTxPos = pindex - > nBlockPos + : : GetSerializeSize ( CBlock ( ) , SER_DISK , CLIENT_VERSION ) - 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 , CLIENT_VERSION ) - 1 + GetSizeOfCompactSize ( vtx . size ( ) ) ;
map < uint256 , CTxIndex > mapQueuedChanges ;
int64 nFees = 0 ;
@ -1362,7 +1368,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
@@ -1362,7 +1368,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
return DoS ( 100 , error ( " ConnectBlock() : too many sigops " )) ;
CDiskTxPos posThisTx ( pindex - > nFile , pindex - > nBlockPos , nTxPos ) ;
nTxPos + = : : GetSerializeSize ( tx , SER_DISK , CLIENT_VERSION ) ;
if ( ! fJustCheck )
nTxPos + = : : GetSerializeSize ( tx , SER_DISK , CLIENT_VERSION ) ;
MapPrevTx mapInputs ;
if ( ! tx . IsCoinBase ( ) )
@ -1390,6 +1397,12 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
@@ -1390,6 +1397,12 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
mapQueuedChanges [ hashTx ] = CTxIndex ( posThisTx , tx . vout . size ( ) ) ;
}
if ( vtx [ 0 ] . GetValueOut ( ) > GetBlockValue ( pindex - > nHeight , nFees ) )
return false ;
if ( fJustCheck )
return true ;
// Write queued txindex changes
for ( map < uint256 , CTxIndex > : : iterator mi = mapQueuedChanges . begin ( ) ; mi ! = mapQueuedChanges . end ( ) ; + + mi )
{
@ -1397,9 +1410,6 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
@@ -1397,9 +1410,6 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
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.
// The memory index structure will be changed after the db commits.
if ( pindex - > pprev )
@ -1703,7 +1713,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
@@ -1703,7 +1713,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
// that can be verified before saving an orphan block.
@ -1713,7 +1723,7 @@ bool CBlock::CheckBlock() const
@@ -1713,7 +1723,7 @@ bool CBlock::CheckBlock() const
return DoS ( 100 , error ( " CheckBlock() : size limits failed " )) ;
// 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 " )) ;
// Check timestamp
@ -1751,7 +1761,7 @@ bool CBlock::CheckBlock() const
@@ -1751,7 +1761,7 @@ bool CBlock::CheckBlock() const
return DoS ( 100 , error ( " CheckBlock() : out - of - bounds SigOpCount " )) ;
// Check merkleroot
if ( hashMerkleRoot ! = BuildMerkleTree ( ) )
if ( fCheckMerkleRoot & & hashMerkleRoot ! = BuildMerkleTree ( ) )
return DoS ( 100 , error ( " CheckBlock() : hashMerkleRoot mismatch " )) ;
return true ;
@ -3312,6 +3322,9 @@ public:
@@ -3312,6 +3322,9 @@ public:
uint64 nLastBlockTx = 0 ;
uint64 nLastBlockSize = 0 ;
const char * pszDummy = " \0 \0 " ;
CScript scriptDummy ( std : : vector < unsigned char > ( pszDummy , pszDummy + sizeof ( pszDummy ) ) ) ;
CBlock * CreateNewBlock ( CReserveKey & reservekey )
{
CBlockIndex * pindexPrev = pindexBest ;
@ -3469,16 +3482,22 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
@@ -3469,16 +3482,22 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
nLastBlockSize = nBlockSize ;
printf ( " CreateNewBlock(): total size %lu \n " , nBlockSize ) ;
}
pblock - > vtx [ 0 ] . vout [ 0 ] . nValue = GetBlockValue ( pindexPrev - > nHeight + 1 , nFees ) ;
// Fill in header
pblock - > hashPrevBlock = pindexPrev - > GetBlockHash ( ) ;
pblock - > hashMerkleRoot = pblock - > BuildMerkleTree ( ) ;
pblock - > UpdateTime ( pindexPrev ) ;
pblock - > nBits = GetNextWorkRequired ( pindexPrev , pblock . get ( ) ) ;
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 ( ) ;
}