@ -820,14 +820,14 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
{
{
// Basic checks that don't depend on any context
// Basic checks that don't depend on any context
if ( tx . vin . empty ( ) )
if ( tx . vin . empty ( ) )
return state . DoS ( 10 , error ( " CheckTransaction() : vin empty " ) ,
return state . DoS ( 10 , error ( " CheckTransaction(): vin empty " ) ,
REJECT_INVALID , " bad-txns-vin-empty " ) ;
REJECT_INVALID , " bad-txns-vin-empty " ) ;
if ( tx . vout . empty ( ) )
if ( tx . vout . empty ( ) )
return state . DoS ( 10 , error ( " CheckTransaction() : vout empty " ) ,
return state . DoS ( 10 , error ( " CheckTransaction(): vout empty " ) ,
REJECT_INVALID , " bad-txns-vout-empty " ) ;
REJECT_INVALID , " bad-txns-vout-empty " ) ;
// Size limits
// Size limits
if ( : : GetSerializeSize ( tx , SER_NETWORK , PROTOCOL_VERSION ) > MAX_BLOCK_SIZE )
if ( : : GetSerializeSize ( tx , SER_NETWORK , PROTOCOL_VERSION ) > MAX_BLOCK_SIZE )
return state . DoS ( 100 , error ( " CheckTransaction() : size limits failed " ) ,
return state . DoS ( 100 , error ( " CheckTransaction(): size limits failed " ) ,
REJECT_INVALID , " bad-txns-oversize " ) ;
REJECT_INVALID , " bad-txns-oversize " ) ;
// Check for negative or overflow output values
// Check for negative or overflow output values
@ -835,14 +835,14 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
BOOST_FOREACH ( const CTxOut & txout , tx . vout )
BOOST_FOREACH ( const CTxOut & txout , tx . vout )
{
{
if ( txout . nValue < 0 )
if ( txout . nValue < 0 )
return state . DoS ( 100 , error ( " CheckTransaction() : txout.nValue negative " ) ,
return state . DoS ( 100 , error ( " CheckTransaction(): txout.nValue negative " ) ,
REJECT_INVALID , " bad-txns-vout-negative " ) ;
REJECT_INVALID , " bad-txns-vout-negative " ) ;
if ( txout . nValue > MAX_MONEY )
if ( txout . nValue > MAX_MONEY )
return state . DoS ( 100 , error ( " CheckTransaction() : txout.nValue too high " ) ,
return state . DoS ( 100 , error ( " CheckTransaction(): txout.nValue too high " ) ,
REJECT_INVALID , " bad-txns-vout-toolarge " ) ;
REJECT_INVALID , " bad-txns-vout-toolarge " ) ;
nValueOut + = txout . nValue ;
nValueOut + = txout . nValue ;
if ( ! MoneyRange ( nValueOut ) )
if ( ! MoneyRange ( nValueOut ) )
return state . DoS ( 100 , error ( " CheckTransaction() : txout total out of range " ) ,
return state . DoS ( 100 , error ( " CheckTransaction(): txout total out of range " ) ,
REJECT_INVALID , " bad-txns-txouttotal-toolarge " ) ;
REJECT_INVALID , " bad-txns-txouttotal-toolarge " ) ;
}
}
@ -851,7 +851,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
{
{
if ( vInOutPoints . count ( txin . prevout ) )
if ( vInOutPoints . count ( txin . prevout ) )
return state . DoS ( 100 , error ( " CheckTransaction() : duplicate inputs " ) ,
return state . DoS ( 100 , error ( " CheckTransaction(): duplicate inputs " ) ,
REJECT_INVALID , " bad-txns-inputs-duplicate " ) ;
REJECT_INVALID , " bad-txns-inputs-duplicate " ) ;
vInOutPoints . insert ( txin . prevout ) ;
vInOutPoints . insert ( txin . prevout ) ;
}
}
@ -859,14 +859,14 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
if ( tx . IsCoinBase ( ) )
if ( tx . IsCoinBase ( ) )
{
{
if ( tx . vin [ 0 ] . scriptSig . size ( ) < 2 | | tx . vin [ 0 ] . scriptSig . size ( ) > 100 )
if ( tx . vin [ 0 ] . scriptSig . size ( ) < 2 | | tx . vin [ 0 ] . scriptSig . size ( ) > 100 )
return state . DoS ( 100 , error ( " CheckTransaction() : coinbase script size " ) ,
return state . DoS ( 100 , error ( " CheckTransaction(): coinbase script size " ) ,
REJECT_INVALID , " bad-cb-length " ) ;
REJECT_INVALID , " bad-cb-length " ) ;
}
}
else
else
{
{
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
if ( txin . prevout . IsNull ( ) )
if ( txin . prevout . IsNull ( ) )
return state . DoS ( 10 , error ( " CheckTransaction() : prevout is null " ) ,
return state . DoS ( 10 , error ( " CheckTransaction(): prevout is null " ) ,
REJECT_INVALID , " bad-txns-prevout-null " ) ;
REJECT_INVALID , " bad-txns-prevout-null " ) ;
}
}
@ -922,7 +922,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
string reason ;
string reason ;
if ( Params ( ) . RequireStandard ( ) & & ! IsStandardTx ( tx , reason ) )
if ( Params ( ) . RequireStandard ( ) & & ! IsStandardTx ( tx , reason ) )
return state . DoS ( 0 ,
return state . DoS ( 0 ,
error ( " AcceptToMemoryPool : nonstandard transaction: %s " , reason ) ,
error ( " AcceptToMemoryPool: nonstandard transaction: %s " , reason ) ,
REJECT_NONSTANDARD , reason ) ;
REJECT_NONSTANDARD , reason ) ;
// Only accept nLockTime-using transactions that can be mined in the next
// Only accept nLockTime-using transactions that can be mined in the next
@ -942,7 +942,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// timestamp applications where it matters.
// timestamp applications where it matters.
if ( ! IsFinalTx ( tx , chainActive . Height ( ) + 1 ) )
if ( ! IsFinalTx ( tx , chainActive . Height ( ) + 1 ) )
return state . DoS ( 0 ,
return state . DoS ( 0 ,
error ( " AcceptToMemoryPool : non-final " ) ,
error ( " AcceptToMemoryPool: non-final " ) ,
REJECT_NONSTANDARD , " non-final " ) ;
REJECT_NONSTANDARD , " non-final " ) ;
// is it already in the memory pool?
// is it already in the memory pool?
@ -991,7 +991,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// are the actual inputs available?
// are the actual inputs available?
if ( ! view . HaveInputs ( tx ) )
if ( ! view . HaveInputs ( tx ) )
return state . Invalid ( error ( " AcceptToMemoryPool : inputs already spent " ) ,
return state . Invalid ( error ( " AcceptToMemoryPool: inputs already spent " ) ,
REJECT_DUPLICATE , " bad-txns-inputs-spent " ) ;
REJECT_DUPLICATE , " bad-txns-inputs-spent " ) ;
// Bring the best block into scope
// Bring the best block into scope
@ -1016,7 +1016,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
nSigOps + = GetP2SHSigOpCount ( tx , view ) ;
nSigOps + = GetP2SHSigOpCount ( tx , view ) ;
if ( nSigOps > MAX_STANDARD_TX_SIGOPS )
if ( nSigOps > MAX_STANDARD_TX_SIGOPS )
return state . DoS ( 0 ,
return state . DoS ( 0 ,
error ( " AcceptToMemoryPool : too many sigops %s, %d > %d " ,
error ( " AcceptToMemoryPool: too many sigops %s, %d > %d " ,
hash . ToString ( ) , nSigOps , MAX_STANDARD_TX_SIGOPS ) ,
hash . ToString ( ) , nSigOps , MAX_STANDARD_TX_SIGOPS ) ,
REJECT_NONSTANDARD , " bad-txns-too-many-sigops " ) ;
REJECT_NONSTANDARD , " bad-txns-too-many-sigops " ) ;
@ -1030,7 +1030,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Don't accept it if it can't get into a block
// Don't accept it if it can't get into a block
CAmount txMinFee = GetMinRelayFee ( tx , nSize , true ) ;
CAmount txMinFee = GetMinRelayFee ( tx , nSize , true ) ;
if ( fLimitFree & & nFees < txMinFee )
if ( fLimitFree & & nFees < txMinFee )
return state . DoS ( 0 , error ( " AcceptToMemoryPool : not enough fees %s, %d < %d " ,
return state . DoS ( 0 , error ( " AcceptToMemoryPool: not enough fees %s, %d < %d " ,
hash . ToString ( ) , nFees , txMinFee ) ,
hash . ToString ( ) , nFees , txMinFee ) ,
REJECT_INSUFFICIENTFEE , " insufficient fee " ) ;
REJECT_INSUFFICIENTFEE , " insufficient fee " ) ;
@ -1057,7 +1057,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// -limitfreerelay unit is thousand-bytes-per-minute
// -limitfreerelay unit is thousand-bytes-per-minute
// At default rate it would take over a month to fill 1GB
// At default rate it would take over a month to fill 1GB
if ( dFreeCount > = GetArg ( " -limitfreerelay " , 15 ) * 10 * 1000 )
if ( dFreeCount > = GetArg ( " -limitfreerelay " , 15 ) * 10 * 1000 )
return state . DoS ( 0 , error ( " AcceptToMemoryPool : free transaction rejected by rate limiter " ) ,
return state . DoS ( 0 , error ( " AcceptToMemoryPool: free transaction rejected by rate limiter " ) ,
REJECT_INSUFFICIENTFEE , " rate limited free transaction " ) ;
REJECT_INSUFFICIENTFEE , " rate limited free transaction " ) ;
LogPrint ( " mempool " , " Rate limit dFreeCount: %g => %g \n " , dFreeCount , dFreeCount + nSize ) ;
LogPrint ( " mempool " , " Rate limit dFreeCount: %g => %g \n " , dFreeCount , dFreeCount + nSize ) ;
dFreeCount + = nSize ;
dFreeCount + = nSize ;
@ -1123,11 +1123,11 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock
fseek ( file . Get ( ) , postx . nTxOffset , SEEK_CUR ) ;
fseek ( file . Get ( ) , postx . nTxOffset , SEEK_CUR ) ;
file > > txOut ;
file > > txOut ;
} catch ( const std : : exception & e ) {
} catch ( const std : : exception & e ) {
return error ( " %s : Deserialize or I/O error - %s " , __func__ , e . what ( ) ) ;
return error ( " %s: Deserialize or I/O error - %s " , __func__ , e . what ( ) ) ;
}
}
hashBlock = header . GetHash ( ) ;
hashBlock = header . GetHash ( ) ;
if ( txOut . GetHash ( ) ! = hash )
if ( txOut . GetHash ( ) ! = hash )
return error ( " %s : txid mismatch " , __func__ ) ;
return error ( " %s: txid mismatch " , __func__ ) ;
return true ;
return true ;
}
}
}
}
@ -1176,7 +1176,7 @@ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos)
// Open history file to append
// Open history file to append
CAutoFile fileout ( OpenBlockFile ( pos ) , SER_DISK , CLIENT_VERSION ) ;
CAutoFile fileout ( OpenBlockFile ( pos ) , SER_DISK , CLIENT_VERSION ) ;
if ( fileout . IsNull ( ) )
if ( fileout . IsNull ( ) )
return error ( " WriteBlockToDisk : OpenBlockFile failed " ) ;
return error ( " WriteBlockToDisk: OpenBlockFile failed " ) ;
// Write index header
// Write index header
unsigned int nSize = fileout . GetSerializeSize ( block ) ;
unsigned int nSize = fileout . GetSerializeSize ( block ) ;
@ -1185,7 +1185,7 @@ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos)
// Write block
// Write block
long fileOutPos = ftell ( fileout . Get ( ) ) ;
long fileOutPos = ftell ( fileout . Get ( ) ) ;
if ( fileOutPos < 0 )
if ( fileOutPos < 0 )
return error ( " WriteBlockToDisk : ftell failed " ) ;
return error ( " WriteBlockToDisk: ftell failed " ) ;
pos . nPos = ( unsigned int ) fileOutPos ;
pos . nPos = ( unsigned int ) fileOutPos ;
fileout < < block ;
fileout < < block ;
@ -1199,19 +1199,19 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos)
// Open history file to read
// Open history file to read
CAutoFile filein ( OpenBlockFile ( pos , true ) , SER_DISK , CLIENT_VERSION ) ;
CAutoFile filein ( OpenBlockFile ( pos , true ) , SER_DISK , CLIENT_VERSION ) ;
if ( filein . IsNull ( ) )
if ( filein . IsNull ( ) )
return error ( " ReadBlockFromDisk : OpenBlockFile failed " ) ;
return error ( " ReadBlockFromDisk: OpenBlockFile failed " ) ;
// Read block
// Read block
try {
try {
filein > > block ;
filein > > block ;
}
}
catch ( const std : : exception & e ) {
catch ( const std : : exception & e ) {
return error ( " %s : Deserialize or I/O error - %s " , __func__ , e . what ( ) ) ;
return error ( " %s: Deserialize or I/O error - %s " , __func__ , e . what ( ) ) ;
}
}
// Check the header
// Check the header
if ( ! CheckProofOfWork ( block . GetHash ( ) , block . nBits ) )
if ( ! CheckProofOfWork ( block . GetHash ( ) , block . nBits ) )
return error ( " ReadBlockFromDisk : Errors in block header " ) ;
return error ( " ReadBlockFromDisk: Errors in block header " ) ;
return true ;
return true ;
}
}
@ -1221,7 +1221,7 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex)
if ( ! ReadBlockFromDisk ( block , pindex - > GetBlockPos ( ) ) )
if ( ! ReadBlockFromDisk ( block , pindex - > GetBlockPos ( ) ) )
return false ;
return false ;
if ( block . GetHash ( ) ! = pindex - > GetBlockHash ( ) )
if ( block . GetHash ( ) ! = pindex - > GetBlockHash ( ) )
return error ( " ReadBlockFromDisk(CBlock&, CBlockIndex*) : GetHash ( ) doesn ' t match index " ) ;
return error ( " ReadBlockFromDisk(CBlock&, CBlockIndex*) : GetHash ( ) doesn ' t match index " ) ;
return true ;
return true ;
}
}
@ -1423,7 +1423,7 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
bool CScriptCheck : : operator ( ) ( ) {
bool CScriptCheck : : operator ( ) ( ) {
const CScript & scriptSig = ptxTo - > vin [ nIn ] . scriptSig ;
const CScript & scriptSig = ptxTo - > vin [ nIn ] . scriptSig ;
if ( ! VerifyScript ( scriptSig , scriptPubKey , nFlags , CachingSignatureChecker ( * ptxTo , nIn , cacheStore ) , & error ) ) {
if ( ! VerifyScript ( scriptSig , scriptPubKey , nFlags , CachingSignatureChecker ( * ptxTo , nIn , cacheStore ) , & error ) ) {
return : : error ( " CScriptCheck() : %s:%d VerifySignature failed: %s " , ptxTo - > GetHash ( ) . ToString ( ) , nIn , ScriptErrorString ( error ) ) ;
return : : error ( " CScriptCheck(): %s:%d VerifySignature failed: %s " , ptxTo - > GetHash ( ) . ToString ( ) , nIn , ScriptErrorString ( error ) ) ;
}
}
return true ;
return true ;
}
}
@ -1438,7 +1438,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
// This doesn't trigger the DoS code on purpose; if it did, it would make it easier
// This doesn't trigger the DoS code on purpose; if it did, it would make it easier
// for an attacker to attempt to split the network.
// for an attacker to attempt to split the network.
if ( ! inputs . HaveInputs ( tx ) )
if ( ! inputs . HaveInputs ( tx ) )
return state . Invalid ( error ( " CheckInputs() : %s inputs unavailable " , tx . GetHash ( ) . ToString ( ) ) ) ;
return state . Invalid ( error ( " CheckInputs(): %s inputs unavailable " , tx . GetHash ( ) . ToString ( ) ) ) ;
// While checking, GetBestBlock() refers to the parent block.
// While checking, GetBestBlock() refers to the parent block.
// This is also true for mempool checks.
// This is also true for mempool checks.
@ -1456,31 +1456,31 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
if ( coins - > IsCoinBase ( ) ) {
if ( coins - > IsCoinBase ( ) ) {
if ( nSpendHeight - coins - > nHeight < COINBASE_MATURITY )
if ( nSpendHeight - coins - > nHeight < COINBASE_MATURITY )
return state . Invalid (
return state . Invalid (
error ( " CheckInputs() : tried to spend coinbase at depth %d " , nSpendHeight - coins - > nHeight ) ,
error ( " CheckInputs(): tried to spend coinbase at depth %d " , nSpendHeight - coins - > nHeight ) ,
REJECT_INVALID , " bad-txns-premature-spend-of-coinbase " ) ;
REJECT_INVALID , " bad-txns-premature-spend-of-coinbase " ) ;
}
}
// Check for negative or overflow input values
// Check for negative or overflow input values
nValueIn + = coins - > vout [ prevout . n ] . nValue ;
nValueIn + = coins - > vout [ prevout . n ] . nValue ;
if ( ! MoneyRange ( coins - > vout [ prevout . n ] . nValue ) | | ! MoneyRange ( nValueIn ) )
if ( ! MoneyRange ( coins - > vout [ prevout . n ] . nValue ) | | ! MoneyRange ( nValueIn ) )
return state . DoS ( 100 , error ( " CheckInputs() : txin values out of range " ) ,
return state . DoS ( 100 , error ( " CheckInputs(): txin values out of range " ) ,
REJECT_INVALID , " bad-txns-inputvalues-outofrange " ) ;
REJECT_INVALID , " bad-txns-inputvalues-outofrange " ) ;
}
}
if ( nValueIn < tx . GetValueOut ( ) )
if ( nValueIn < tx . GetValueOut ( ) )
return state . DoS ( 100 , error ( " CheckInputs() : %s value in (%s) < value out (%s) " ,
return state . DoS ( 100 , error ( " CheckInputs(): %s value in (%s) < value out (%s) " ,
tx . GetHash ( ) . ToString ( ) , FormatMoney ( nValueIn ) , FormatMoney ( tx . GetValueOut ( ) ) ) ,
tx . GetHash ( ) . ToString ( ) , FormatMoney ( nValueIn ) , FormatMoney ( tx . GetValueOut ( ) ) ) ,
REJECT_INVALID , " bad-txns-in-belowout " ) ;
REJECT_INVALID , " bad-txns-in-belowout " ) ;
// Tally transaction fees
// Tally transaction fees
CAmount nTxFee = nValueIn - tx . GetValueOut ( ) ;
CAmount nTxFee = nValueIn - tx . GetValueOut ( ) ;
if ( nTxFee < 0 )
if ( nTxFee < 0 )
return state . DoS ( 100 , error ( " CheckInputs() : %s nTxFee < 0 " , tx . GetHash ( ) . ToString ( ) ) ,
return state . DoS ( 100 , error ( " CheckInputs(): %s nTxFee < 0 " , tx . GetHash ( ) . ToString ( ) ) ,
REJECT_INVALID , " bad-txns-fee-negative " ) ;
REJECT_INVALID , " bad-txns-fee-negative " ) ;
nFees + = nTxFee ;
nFees + = nTxFee ;
if ( ! MoneyRange ( nFees ) )
if ( ! MoneyRange ( nFees ) )
return state . DoS ( 100 , error ( " CheckInputs() : nFees out of range " ) ,
return state . DoS ( 100 , error ( " CheckInputs(): nFees out of range " ) ,
REJECT_INVALID , " bad-txns-fee-outofrange " ) ;
REJECT_INVALID , " bad-txns-fee-outofrange " ) ;
// The first loop above does all the inexpensive checks.
// The first loop above does all the inexpensive checks.
@ -1537,7 +1537,7 @@ bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint
// Open history file to append
// Open history file to append
CAutoFile fileout ( OpenUndoFile ( pos ) , SER_DISK , CLIENT_VERSION ) ;
CAutoFile fileout ( OpenUndoFile ( pos ) , SER_DISK , CLIENT_VERSION ) ;
if ( fileout . IsNull ( ) )
if ( fileout . IsNull ( ) )
return error ( " %s : OpenUndoFile failed " , __func__ ) ;
return error ( " %s: OpenUndoFile failed " , __func__ ) ;
// Write index header
// Write index header
unsigned int nSize = fileout . GetSerializeSize ( blockundo ) ;
unsigned int nSize = fileout . GetSerializeSize ( blockundo ) ;
@ -1546,7 +1546,7 @@ bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint
// Write undo data
// Write undo data
long fileOutPos = ftell ( fileout . Get ( ) ) ;
long fileOutPos = ftell ( fileout . Get ( ) ) ;
if ( fileOutPos < 0 )
if ( fileOutPos < 0 )
return error ( " %s : ftell failed " , __func__ ) ;
return error ( " %s: ftell failed " , __func__ ) ;
pos . nPos = ( unsigned int ) fileOutPos ;
pos . nPos = ( unsigned int ) fileOutPos ;
fileout < < blockundo ;
fileout < < blockundo ;
@ -1564,7 +1564,7 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin
// Open history file to read
// Open history file to read
CAutoFile filein ( OpenUndoFile ( pos , true ) , SER_DISK , CLIENT_VERSION ) ;
CAutoFile filein ( OpenUndoFile ( pos , true ) , SER_DISK , CLIENT_VERSION ) ;
if ( filein . IsNull ( ) )
if ( filein . IsNull ( ) )
return error ( " %s : OpenBlockFile failed " , __func__ ) ;
return error ( " %s: OpenBlockFile failed " , __func__ ) ;
// Read block
// Read block
uint256 hashChecksum ;
uint256 hashChecksum ;
@ -1573,7 +1573,7 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin
filein > > hashChecksum ;
filein > > hashChecksum ;
}
}
catch ( const std : : exception & e ) {
catch ( const std : : exception & e ) {
return error ( " %s : Deserialize or I/O error - %s " , __func__ , e . what ( ) ) ;
return error ( " %s: Deserialize or I/O error - %s " , __func__ , e . what ( ) ) ;
}
}
// Verify checksum
// Verify checksum
@ -1581,7 +1581,7 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin
hasher < < hashBlock ;
hasher < < hashBlock ;
hasher < < blockundo ;
hasher < < blockundo ;
if ( hashChecksum ! = hasher . GetHash ( ) )
if ( hashChecksum ! = hasher . GetHash ( ) )
return error ( " %s : Checksum mismatch " , __func__ ) ;
return error ( " %s: Checksum mismatch " , __func__ ) ;
return true ;
return true ;
}
}
@ -1600,12 +1600,12 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
CBlockUndo blockUndo ;
CBlockUndo blockUndo ;
CDiskBlockPos pos = pindex - > GetUndoPos ( ) ;
CDiskBlockPos pos = pindex - > GetUndoPos ( ) ;
if ( pos . IsNull ( ) )
if ( pos . IsNull ( ) )
return error ( " DisconnectBlock() : no undo data available " ) ;
return error ( " DisconnectBlock() : no undo data available " ) ;
if ( ! UndoReadFromDisk ( blockUndo , pos , pindex - > pprev - > GetBlockHash ( ) ) )
if ( ! UndoReadFromDisk ( blockUndo , pos , pindex - > pprev - > GetBlockHash ( ) ) )
return error ( " DisconnectBlock() : failure reading undo data " ) ;
return error ( " DisconnectBlock() : failure reading undo data " ) ;
if ( blockUndo . vtxundo . size ( ) + 1 ! = block . vtx . size ( ) )
if ( blockUndo . vtxundo . size ( ) + 1 ! = block . vtx . size ( ) )
return error ( " DisconnectBlock() : block and undo data inconsistent " ) ;
return error ( " DisconnectBlock() : block and undo data inconsistent " ) ;
// undo transactions in reverse order
// undo transactions in reverse order
for ( int i = block . vtx . size ( ) - 1 ; i > = 0 ; i - - ) {
for ( int i = block . vtx . size ( ) - 1 ; i > = 0 ; i - - ) {
@ -1628,7 +1628,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
if ( outsBlock . nVersion < 0 )
if ( outsBlock . nVersion < 0 )
outs - > nVersion = outsBlock . nVersion ;
outs - > nVersion = outsBlock . nVersion ;
if ( * outs ! = outsBlock )
if ( * outs ! = outsBlock )
fClean = fClean & & error ( " DisconnectBlock() : added transaction mismatch? database corrupted " ) ;
fClean = fClean & & error ( " DisconnectBlock(): added transaction mismatch? database corrupted " ) ;
// remove outputs
// remove outputs
outs - > Clear ( ) ;
outs - > Clear ( ) ;
@ -1638,7 +1638,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
if ( i > 0 ) { // not coinbases
if ( i > 0 ) { // not coinbases
const CTxUndo & txundo = blockUndo . vtxundo [ i - 1 ] ;
const CTxUndo & txundo = blockUndo . vtxundo [ i - 1 ] ;
if ( txundo . vprevout . size ( ) ! = tx . vin . size ( ) )
if ( txundo . vprevout . size ( ) ! = tx . vin . size ( ) )
return error ( " DisconnectBlock() : transaction and undo data inconsistent " ) ;
return error ( " DisconnectBlock() : transaction and undo data inconsistent " ) ;
for ( unsigned int j = tx . vin . size ( ) ; j - - > 0 ; ) {
for ( unsigned int j = tx . vin . size ( ) ; j - - > 0 ; ) {
const COutPoint & out = tx . vin [ j ] . prevout ;
const COutPoint & out = tx . vin [ j ] . prevout ;
const CTxInUndo & undo = txundo . vprevout [ j ] ;
const CTxInUndo & undo = txundo . vprevout [ j ] ;
@ -1646,17 +1646,17 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
if ( undo . nHeight ! = 0 ) {
if ( undo . nHeight ! = 0 ) {
// undo data contains height: this is the last output of the prevout tx being spent
// undo data contains height: this is the last output of the prevout tx being spent
if ( ! coins - > IsPruned ( ) )
if ( ! coins - > IsPruned ( ) )
fClean = fClean & & error ( " DisconnectBlock() : undo data overwriting existing transaction " ) ;
fClean = fClean & & error ( " DisconnectBlock(): undo data overwriting existing transaction " ) ;
coins - > Clear ( ) ;
coins - > Clear ( ) ;
coins - > fCoinBase = undo . fCoinBase ;
coins - > fCoinBase = undo . fCoinBase ;
coins - > nHeight = undo . nHeight ;
coins - > nHeight = undo . nHeight ;
coins - > nVersion = undo . nVersion ;
coins - > nVersion = undo . nVersion ;
} else {
} else {
if ( coins - > IsPruned ( ) )
if ( coins - > IsPruned ( ) )
fClean = fClean & & error ( " DisconnectBlock() : undo data adding output to missing transaction " ) ;
fClean = fClean & & error ( " DisconnectBlock(): undo data adding output to missing transaction " ) ;
}
}
if ( coins - > IsAvailable ( out . n ) )
if ( coins - > IsAvailable ( out . n ) )
fClean = fClean & & error ( " DisconnectBlock() : undo data overwriting existing output " ) ;
fClean = fClean & & error ( " DisconnectBlock(): undo data overwriting existing output " ) ;
if ( coins - > vout . size ( ) < out . n + 1 )
if ( coins - > vout . size ( ) < out . n + 1 )
coins - > vout . resize ( out . n + 1 ) ;
coins - > vout . resize ( out . n + 1 ) ;
coins - > vout [ out . n ] = undo . txout ;
coins - > vout [ out . n ] = undo . txout ;
@ -1753,7 +1753,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
BOOST_FOREACH ( const CTransaction & tx , block . vtx ) {
BOOST_FOREACH ( const CTransaction & tx , block . vtx ) {
const CCoins * coins = view . AccessCoins ( tx . GetHash ( ) ) ;
const CCoins * coins = view . AccessCoins ( tx . GetHash ( ) ) ;
if ( coins & & ! coins - > IsPruned ( ) )
if ( coins & & ! coins - > IsPruned ( ) )
return state . DoS ( 100 , error ( " ConnectBlock() : tried to overwrite transaction " ) ,
return state . DoS ( 100 , error ( " ConnectBlock(): tried to overwrite transaction " ) ,
REJECT_INVALID , " bad-txns-BIP30 " ) ;
REJECT_INVALID , " bad-txns-BIP30 " ) ;
}
}
}
}
@ -1783,13 +1783,13 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
nInputs + = tx . vin . size ( ) ;
nInputs + = tx . vin . size ( ) ;
nSigOps + = GetLegacySigOpCount ( tx ) ;
nSigOps + = GetLegacySigOpCount ( tx ) ;
if ( nSigOps > MAX_BLOCK_SIGOPS )
if ( nSigOps > MAX_BLOCK_SIGOPS )
return state . DoS ( 100 , error ( " ConnectBlock() : too many sigops " ) ,
return state . DoS ( 100 , error ( " ConnectBlock(): too many sigops " ) ,
REJECT_INVALID , " bad-blk-sigops " ) ;
REJECT_INVALID , " bad-blk-sigops " ) ;
if ( ! tx . IsCoinBase ( ) )
if ( ! tx . IsCoinBase ( ) )
{
{
if ( ! view . HaveInputs ( tx ) )
if ( ! view . HaveInputs ( tx ) )
return state . DoS ( 100 , error ( " ConnectBlock() : inputs missing/spent " ) ,
return state . DoS ( 100 , error ( " ConnectBlock(): inputs missing/spent " ) ,
REJECT_INVALID , " bad-txns-inputs-missingorspent " ) ;
REJECT_INVALID , " bad-txns-inputs-missingorspent " ) ;
if ( fStrictPayToScriptHash )
if ( fStrictPayToScriptHash )
@ -1799,7 +1799,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
// an incredibly-expensive-to-validate block.
// an incredibly-expensive-to-validate block.
nSigOps + = GetP2SHSigOpCount ( tx , view ) ;
nSigOps + = GetP2SHSigOpCount ( tx , view ) ;
if ( nSigOps > MAX_BLOCK_SIGOPS )
if ( nSigOps > MAX_BLOCK_SIGOPS )
return state . DoS ( 100 , error ( " ConnectBlock() : too many sigops " ) ,
return state . DoS ( 100 , error ( " ConnectBlock(): too many sigops " ) ,
REJECT_INVALID , " bad-blk-sigops " ) ;
REJECT_INVALID , " bad-blk-sigops " ) ;
}
}
@ -1825,7 +1825,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
if ( block . vtx [ 0 ] . GetValueOut ( ) > GetBlockValue ( pindex - > nHeight , nFees ) )
if ( block . vtx [ 0 ] . GetValueOut ( ) > GetBlockValue ( pindex - > nHeight , nFees ) )
return state . DoS ( 100 ,
return state . DoS ( 100 ,
error ( " ConnectBlock() : coinbase pays too much (actual=%d vs limit=%d) " ,
error ( " ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d) " ,
block . vtx [ 0 ] . GetValueOut ( ) , GetBlockValue ( pindex - > nHeight , nFees ) ) ,
block . vtx [ 0 ] . GetValueOut ( ) , GetBlockValue ( pindex - > nHeight , nFees ) ) ,
REJECT_INVALID , " bad-cb-amount " ) ;
REJECT_INVALID , " bad-cb-amount " ) ;
@ -1843,7 +1843,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
if ( pindex - > GetUndoPos ( ) . IsNull ( ) ) {
if ( pindex - > GetUndoPos ( ) . IsNull ( ) ) {
CDiskBlockPos pos ;
CDiskBlockPos pos ;
if ( ! FindUndoPos ( state , pindex - > nFile , pos , : : GetSerializeSize ( blockundo , SER_DISK , CLIENT_VERSION ) + 40 ) )
if ( ! FindUndoPos ( state , pindex - > nFile , pos , : : GetSerializeSize ( blockundo , SER_DISK , CLIENT_VERSION ) + 40 ) )
return error ( " ConnectBlock() : FindUndoPos failed " ) ;
return error ( " ConnectBlock() : FindUndoPos failed " ) ;
if ( ! UndoWriteToDisk ( blockundo , pos , pindex - > pprev - > GetBlockHash ( ) ) )
if ( ! UndoWriteToDisk ( blockundo , pos , pindex - > pprev - > GetBlockHash ( ) ) )
return state . Abort ( " Failed to write undo data " ) ;
return state . Abort ( " Failed to write undo data " ) ;
@ -1995,7 +1995,7 @@ bool static DisconnectTip(CValidationState &state) {
{
{
CCoinsViewCache view ( pcoinsTip ) ;
CCoinsViewCache view ( pcoinsTip ) ;
if ( ! DisconnectBlock ( block , state , pindexDelete , view ) )
if ( ! DisconnectBlock ( block , state , pindexDelete , view ) )
return error ( " DisconnectTip() : DisconnectBlock % s failed " , pindexDelete->GetBlockHash().ToString()) ;
return error ( " DisconnectTip() : DisconnectBlock % s failed " , pindexDelete->GetBlockHash().ToString()) ;
assert ( view . Flush ( ) ) ;
assert ( view . Flush ( ) ) ;
}
}
LogPrint ( " bench " , " - Disconnect block: %.2fms \n " , ( GetTimeMicros ( ) - nStart ) * 0.001 ) ;
LogPrint ( " bench " , " - Disconnect block: %.2fms \n " , ( GetTimeMicros ( ) - nStart ) * 0.001 ) ;
@ -2055,7 +2055,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
if ( ! rv ) {
if ( ! rv ) {
if ( state . IsInvalid ( ) )
if ( state . IsInvalid ( ) )
InvalidBlockFound ( pindexNew , state ) ;
InvalidBlockFound ( pindexNew , state ) ;
return error ( " ConnectTip() : ConnectBlock % s failed " , pindexNew->GetBlockHash().ToString()) ;
return error ( " ConnectTip() : ConnectBlock % s failed " , pindexNew->GetBlockHash().ToString()) ;
}
}
mapBlockSource . erase ( inv . hash ) ;
mapBlockSource . erase ( inv . hash ) ;
nTime3 = GetTimeMicros ( ) ; nTimeConnectTotal + = nTime3 - nTime2 ;
nTime3 = GetTimeMicros ( ) ; nTimeConnectTotal + = nTime3 - nTime2 ;
@ -2492,12 +2492,12 @@ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool f
{
{
// Check proof of work matches claimed amount
// Check proof of work matches claimed amount
if ( fCheckPOW & & ! CheckProofOfWork ( block . GetHash ( ) , block . nBits ) )
if ( fCheckPOW & & ! CheckProofOfWork ( block . GetHash ( ) , block . nBits ) )
return state . DoS ( 50 , error ( " CheckBlockHeader() : proof of work failed " ) ,
return state . DoS ( 50 , error ( " CheckBlockHeader(): proof of work failed " ) ,
REJECT_INVALID , " high-hash " ) ;
REJECT_INVALID , " high-hash " ) ;
// Check timestamp
// Check timestamp
if ( block . GetBlockTime ( ) > GetAdjustedTime ( ) + 2 * 60 * 60 )
if ( block . GetBlockTime ( ) > GetAdjustedTime ( ) + 2 * 60 * 60 )
return state . Invalid ( error ( " CheckBlockHeader() : block timestamp too far in the future " ) ,
return state . Invalid ( error ( " CheckBlockHeader(): block timestamp too far in the future " ) ,
REJECT_INVALID , " time-too-new " ) ;
REJECT_INVALID , " time-too-new " ) ;
return true ;
return true ;
@ -2517,14 +2517,14 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
bool mutated ;
bool mutated ;
uint256 hashMerkleRoot2 = block . BuildMerkleTree ( & mutated ) ;
uint256 hashMerkleRoot2 = block . BuildMerkleTree ( & mutated ) ;
if ( block . hashMerkleRoot ! = hashMerkleRoot2 )
if ( block . hashMerkleRoot ! = hashMerkleRoot2 )
return state . DoS ( 100 , error ( " CheckBlock() : hashMerkleRoot mismatch " ) ,
return state . DoS ( 100 , error ( " CheckBlock(): hashMerkleRoot mismatch " ) ,
REJECT_INVALID , " bad-txnmrklroot " , true ) ;
REJECT_INVALID , " bad-txnmrklroot " , true ) ;
// Check for merkle tree malleability (CVE-2012-2459): repeating sequences
// Check for merkle tree malleability (CVE-2012-2459): repeating sequences
// of transactions in a block without affecting the merkle root of a block,
// of transactions in a block without affecting the merkle root of a block,
// while still invalidating it.
// while still invalidating it.
if ( mutated )
if ( mutated )
return state . DoS ( 100 , error ( " CheckBlock() : duplicate transaction " ) ,
return state . DoS ( 100 , error ( " CheckBlock(): duplicate transaction " ) ,
REJECT_INVALID , " bad-txns-duplicate " , true ) ;
REJECT_INVALID , " bad-txns-duplicate " , true ) ;
}
}
@ -2534,22 +2534,22 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
// Size limits
// Size limits
if ( block . vtx . empty ( ) | | block . vtx . size ( ) > MAX_BLOCK_SIZE | | : : GetSerializeSize ( block , SER_NETWORK , PROTOCOL_VERSION ) > MAX_BLOCK_SIZE )
if ( block . vtx . empty ( ) | | block . vtx . size ( ) > MAX_BLOCK_SIZE | | : : GetSerializeSize ( block , SER_NETWORK , PROTOCOL_VERSION ) > MAX_BLOCK_SIZE )
return state . DoS ( 100 , error ( " CheckBlock() : size limits failed " ) ,
return state . DoS ( 100 , error ( " CheckBlock(): size limits failed " ) ,
REJECT_INVALID , " bad-blk-length " ) ;
REJECT_INVALID , " bad-blk-length " ) ;
// First transaction must be coinbase, the rest must not be
// First transaction must be coinbase, the rest must not be
if ( block . vtx . empty ( ) | | ! block . vtx [ 0 ] . IsCoinBase ( ) )
if ( block . vtx . empty ( ) | | ! block . vtx [ 0 ] . IsCoinBase ( ) )
return state . DoS ( 100 , error ( " CheckBlock() : first tx is not coinbase " ) ,
return state . DoS ( 100 , error ( " CheckBlock(): first tx is not coinbase " ) ,
REJECT_INVALID , " bad-cb-missing " ) ;
REJECT_INVALID , " bad-cb-missing " ) ;
for ( unsigned int i = 1 ; i < block . vtx . size ( ) ; i + + )
for ( unsigned int i = 1 ; i < block . vtx . size ( ) ; i + + )
if ( block . vtx [ i ] . IsCoinBase ( ) )
if ( block . vtx [ i ] . IsCoinBase ( ) )
return state . DoS ( 100 , error ( " CheckBlock() : more than one coinbase " ) ,
return state . DoS ( 100 , error ( " CheckBlock(): more than one coinbase " ) ,
REJECT_INVALID , " bad-cb-multiple " ) ;
REJECT_INVALID , " bad-cb-multiple " ) ;
// Check transactions
// Check transactions
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
if ( ! CheckTransaction ( tx , state ) )
if ( ! CheckTransaction ( tx , state ) )
return error ( " CheckBlock() : CheckTransaction failed " ) ;
return error ( " CheckBlock() : CheckTransaction failed " ) ;
unsigned int nSigOps = 0 ;
unsigned int nSigOps = 0 ;
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
@ -2557,7 +2557,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
nSigOps + = GetLegacySigOpCount ( tx ) ;
nSigOps + = GetLegacySigOpCount ( tx ) ;
}
}
if ( nSigOps > MAX_BLOCK_SIGOPS )
if ( nSigOps > MAX_BLOCK_SIGOPS )
return state . DoS ( 100 , error ( " CheckBlock() : out-of-bounds SigOpCount " ) ,
return state . DoS ( 100 , error ( " CheckBlock(): out-of-bounds SigOpCount " ) ,
REJECT_INVALID , " bad-blk-sigops " , true ) ;
REJECT_INVALID , " bad-blk-sigops " , true ) ;
return true ;
return true ;
@ -2576,28 +2576,28 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
// Check proof of work
// Check proof of work
if ( ( ! Params ( ) . SkipProofOfWorkCheck ( ) ) & &
if ( ( ! Params ( ) . SkipProofOfWorkCheck ( ) ) & &
( block . nBits ! = GetNextWorkRequired ( pindexPrev , & block ) ) )
( block . nBits ! = GetNextWorkRequired ( pindexPrev , & block ) ) )
return state . DoS ( 100 , error ( " %s : incorrect proof of work " , __func__ ) ,
return state . DoS ( 100 , error ( " %s: incorrect proof of work " , __func__ ) ,
REJECT_INVALID , " bad-diffbits " ) ;
REJECT_INVALID , " bad-diffbits " ) ;
// Check timestamp against prev
// Check timestamp against prev
if ( block . GetBlockTime ( ) < = pindexPrev - > GetMedianTimePast ( ) )
if ( block . GetBlockTime ( ) < = pindexPrev - > GetMedianTimePast ( ) )
return state . Invalid ( error ( " %s : block's timestamp is too early " , __func__ ) ,
return state . Invalid ( error ( " %s: block's timestamp is too early " , __func__ ) ,
REJECT_INVALID , " time-too-old " ) ;
REJECT_INVALID , " time-too-old " ) ;
// 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
if ( ! Checkpoints : : CheckBlock ( nHeight , hash ) )
if ( ! Checkpoints : : CheckBlock ( nHeight , hash ) )
return state . DoS ( 100 , error ( " %s : rejected by checkpoint lock-in at %d " , __func__ , nHeight ) ,
return state . DoS ( 100 , error ( " %s: rejected by checkpoint lock-in at %d " , __func__ , nHeight ) ,
REJECT_CHECKPOINT , " checkpoint mismatch " ) ;
REJECT_CHECKPOINT , " checkpoint mismatch " ) ;
// Don't accept any forks from the main chain prior to last checkpoint
// Don't accept any forks from the main chain prior to last checkpoint
CBlockIndex * pcheckpoint = Checkpoints : : GetLastCheckpoint ( ) ;
CBlockIndex * pcheckpoint = Checkpoints : : GetLastCheckpoint ( ) ;
if ( pcheckpoint & & nHeight < pcheckpoint - > nHeight )
if ( pcheckpoint & & nHeight < pcheckpoint - > nHeight )
return state . DoS ( 100 , error ( " %s : forked chain older than last checkpoint (height %d) " , __func__ , nHeight ) ) ;
return state . DoS ( 100 , error ( " %s: forked chain older than last checkpoint (height %d) " , __func__ , 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 ( block . nVersion < 2 & & IsSuperMajority ( 2 , pindexPrev , Params ( ) . RejectBlockOutdatedMajority ( ) ) )
if ( block . nVersion < 2 & & IsSuperMajority ( 2 , pindexPrev , Params ( ) . RejectBlockOutdatedMajority ( ) ) )
{
{
return state . Invalid ( error ( " %s : rejected nVersion=1 block " , __func__ ) ,
return state . Invalid ( error ( " %s: rejected nVersion=1 block " , __func__ ) ,
REJECT_OBSOLETE , " bad-version " ) ;
REJECT_OBSOLETE , " bad-version " ) ;
}
}
@ -2611,7 +2611,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
// Check that all transactions are finalized
// Check that all transactions are finalized
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
if ( ! IsFinalTx ( tx , nHeight , block . GetBlockTime ( ) ) ) {
if ( ! IsFinalTx ( tx , nHeight , block . GetBlockTime ( ) ) ) {
return state . DoS ( 10 , error ( " %s : contains a non-final transaction " , __func__ ) , REJECT_INVALID , " bad-txns-nonfinal " ) ;
return state . DoS ( 10 , error ( " %s: contains a non-final transaction " , __func__ ) , REJECT_INVALID , " bad-txns-nonfinal " ) ;
}
}
// 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
@ -2621,7 +2621,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
CScript expect = CScript ( ) < < nHeight ;
CScript expect = CScript ( ) < < nHeight ;
if ( block . vtx [ 0 ] . vin [ 0 ] . scriptSig . size ( ) < expect . size ( ) | |
if ( block . vtx [ 0 ] . vin [ 0 ] . scriptSig . size ( ) < expect . size ( ) | |
! std : : equal ( expect . begin ( ) , expect . end ( ) , block . vtx [ 0 ] . vin [ 0 ] . scriptSig . begin ( ) ) ) {
! std : : equal ( expect . begin ( ) , expect . end ( ) , block . vtx [ 0 ] . vin [ 0 ] . scriptSig . begin ( ) ) ) {
return state . DoS ( 100 , error ( " %s : block height mismatch in coinbase " , __func__ ) , REJECT_INVALID , " bad-cb-height " ) ;
return state . DoS ( 100 , error ( " %s: block height mismatch in coinbase " , __func__ ) , REJECT_INVALID , " bad-cb-height " ) ;
}
}
}
}
@ -2641,7 +2641,7 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
if ( ppindex )
if ( ppindex )
* ppindex = pindex ;
* ppindex = pindex ;
if ( pindex - > nStatus & BLOCK_FAILED_MASK )
if ( pindex - > nStatus & BLOCK_FAILED_MASK )
return state . Invalid ( error ( " %s : block is marked invalid " , __func__ ) , 0 , " duplicate " ) ;
return state . Invalid ( error ( " %s: block is marked invalid " , __func__ ) , 0 , " duplicate " ) ;
return true ;
return true ;
}
}
@ -2653,10 +2653,10 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
if ( hash ! = Params ( ) . HashGenesisBlock ( ) ) {
if ( hash ! = Params ( ) . HashGenesisBlock ( ) ) {
BlockMap : : iterator mi = mapBlockIndex . find ( block . hashPrevBlock ) ;
BlockMap : : iterator mi = mapBlockIndex . find ( block . hashPrevBlock ) ;
if ( mi = = mapBlockIndex . end ( ) )
if ( mi = = mapBlockIndex . end ( ) )
return state . DoS ( 10 , error ( " %s : prev block not found " , __func__ ) , 0 , " bad-prevblk " ) ;
return state . DoS ( 10 , error ( " %s: prev block not found " , __func__ ) , 0 , " bad-prevblk " ) ;
pindexPrev = ( * mi ) . second ;
pindexPrev = ( * mi ) . second ;
if ( pindexPrev - > nStatus & BLOCK_FAILED_MASK )
if ( pindexPrev - > nStatus & BLOCK_FAILED_MASK )
return state . DoS ( 100 , error ( " %s : prev block invalid " , __func__ ) , REJECT_INVALID , " bad-prevblk " ) ;
return state . DoS ( 100 , error ( " %s: prev block invalid " , __func__ ) , REJECT_INVALID , " bad-prevblk " ) ;
}
}
if ( ! ContextualCheckBlockHeader ( block , state , pindexPrev ) )
if ( ! ContextualCheckBlockHeader ( block , state , pindexPrev ) )
@ -2682,7 +2682,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
if ( pindex - > nStatus & BLOCK_HAVE_DATA ) {
if ( pindex - > nStatus & BLOCK_HAVE_DATA ) {
// TODO: deal better with duplicate blocks.
// TODO: deal better with duplicate blocks.
// return state.DoS(20, error("AcceptBlock() : already have block %d %s", pindex->nHeight, pindex->GetBlockHash().ToString()), REJECT_DUPLICATE, "duplicate");
// return state.DoS(20, error("AcceptBlock(): already have block %d %s", pindex->nHeight, pindex->GetBlockHash().ToString()), REJECT_DUPLICATE, "duplicate");
return true ;
return true ;
}
}
@ -2703,12 +2703,12 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
if ( dbp ! = NULL )
if ( dbp ! = NULL )
blockPos = * dbp ;
blockPos = * dbp ;
if ( ! FindBlockPos ( state , blockPos , nBlockSize + 8 , nHeight , block . GetBlockTime ( ) , dbp ! = NULL ) )
if ( ! FindBlockPos ( state , blockPos , nBlockSize + 8 , nHeight , block . GetBlockTime ( ) , dbp ! = NULL ) )
return error ( " AcceptBlock() : FindBlockPos failed " ) ;
return error ( " AcceptBlock() : FindBlockPos failed " ) ;
if ( dbp = = NULL )
if ( dbp = = NULL )
if ( ! WriteBlockToDisk ( block , blockPos ) )
if ( ! WriteBlockToDisk ( block , blockPos ) )
return state . Abort ( " Failed to write block " ) ;
return state . Abort ( " Failed to write block " ) ;
if ( ! ReceivedBlockTransactions ( block , state , pindex , blockPos ) )
if ( ! ReceivedBlockTransactions ( block , state , pindex , blockPos ) )
return error ( " AcceptBlock() : ReceivedBlockTransactions failed " ) ;
return error ( " AcceptBlock() : ReceivedBlockTransactions failed " ) ;
} catch ( const std : : runtime_error & e ) {
} catch ( const std : : runtime_error & e ) {
return state . Abort ( std : : string ( " System error: " ) + e . what ( ) ) ;
return state . Abort ( std : : string ( " System error: " ) + e . what ( ) ) ;
}
}
@ -2739,7 +2739,7 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis
LOCK ( cs_main ) ;
LOCK ( cs_main ) ;
MarkBlockAsReceived ( pblock - > GetHash ( ) ) ;
MarkBlockAsReceived ( pblock - > GetHash ( ) ) ;
if ( ! checked ) {
if ( ! checked ) {
return error ( " %s : CheckBlock FAILED " , __func__ ) ;
return error ( " %s: CheckBlock FAILED " , __func__ ) ;
}
}
// Store to disk
// Store to disk
@ -2749,11 +2749,11 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis
mapBlockSource [ pindex - > GetBlockHash ( ) ] = pfrom - > GetId ( ) ;
mapBlockSource [ pindex - > GetBlockHash ( ) ] = pfrom - > GetId ( ) ;
}
}
if ( ! ret )
if ( ! ret )
return error ( " %s : AcceptBlock FAILED " , __func__ ) ;
return error ( " %s: AcceptBlock FAILED " , __func__ ) ;
}
}
if ( ! ActivateBestChain ( state , pblock ) )
if ( ! ActivateBestChain ( state , pblock ) )
return error ( " %s : ActivateBestChain failed " , __func__ ) ;
return error ( " %s: ActivateBestChain failed " , __func__ ) ;
return true ;
return true ;
}
}
@ -2859,7 +2859,7 @@ CBlockIndex * InsertBlockIndex(uint256 hash)
// Create new
// Create new
CBlockIndex * pindexNew = new CBlockIndex ( ) ;
CBlockIndex * pindexNew = new CBlockIndex ( ) ;
if ( ! pindexNew )
if ( ! pindexNew )
throw runtime_error ( " LoadBlockIndex() : new CBlockIndex failed " ) ;
throw runtime_error ( " LoadBlockIndex() : new CBlockIndex failed " ) ;
mi = mapBlockIndex . insert ( make_pair ( hash , pindexNew ) ) . first ;
mi = mapBlockIndex . insert ( make_pair ( hash , pindexNew ) ) . first ;
pindexNew - > phashBlock = & ( ( * mi ) . first ) ;
pindexNew - > phashBlock = & ( ( * mi ) . first ) ;
@ -3005,24 +3005,24 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
CBlock block ;
CBlock block ;
// check level 0: read from disk
// check level 0: read from disk
if ( ! ReadBlockFromDisk ( block , pindex ) )
if ( ! ReadBlockFromDisk ( block , pindex ) )
return error ( " VerifyDB() : * * * ReadBlockFromDisk failed at % d , hash = % s " , pindex->nHeight, pindex->GetBlockHash().ToString()) ;
return error ( " VerifyDB() : * * * ReadBlockFromDisk failed at % d , hash = % s " , pindex->nHeight, pindex->GetBlockHash().ToString()) ;
// check level 1: verify block validity
// check level 1: verify block validity
if ( nCheckLevel > = 1 & & ! CheckBlock ( block , state ) )
if ( nCheckLevel > = 1 & & ! CheckBlock ( block , state ) )
return error ( " VerifyDB() : * * * found bad block at % d , hash = % s \ n " , pindex->nHeight, pindex->GetBlockHash().ToString()) ;
return error ( " VerifyDB() : * * * found bad block at % d , hash = % s \ n " , pindex->nHeight, pindex->GetBlockHash().ToString()) ;
// check level 2: verify undo validity
// check level 2: verify undo validity
if ( nCheckLevel > = 2 & & pindex ) {
if ( nCheckLevel > = 2 & & pindex ) {
CBlockUndo undo ;
CBlockUndo undo ;
CDiskBlockPos pos = pindex - > GetUndoPos ( ) ;
CDiskBlockPos pos = pindex - > GetUndoPos ( ) ;
if ( ! pos . IsNull ( ) ) {
if ( ! pos . IsNull ( ) ) {
if ( ! UndoReadFromDisk ( undo , pos , pindex - > pprev - > GetBlockHash ( ) ) )
if ( ! UndoReadFromDisk ( undo , pos , pindex - > pprev - > GetBlockHash ( ) ) )
return error ( " VerifyDB() : * * * found bad undo data at % d , hash = % s \ n " , pindex->nHeight, pindex->GetBlockHash().ToString()) ;
return error ( " VerifyDB() : * * * found bad undo data at % d , hash = % s \ n " , pindex->nHeight, pindex->GetBlockHash().ToString()) ;
}
}
}
}
// check level 3: check for inconsistencies during memory-only disconnect of tip blocks
// check level 3: check for inconsistencies during memory-only disconnect of tip blocks
if ( nCheckLevel > = 3 & & pindex = = pindexState & & ( coins . GetCacheSize ( ) + pcoinsTip - > GetCacheSize ( ) ) < = nCoinCacheSize ) {
if ( nCheckLevel > = 3 & & pindex = = pindexState & & ( coins . GetCacheSize ( ) + pcoinsTip - > GetCacheSize ( ) ) < = nCoinCacheSize ) {
bool fClean = true ;
bool fClean = true ;
if ( ! DisconnectBlock ( block , state , pindex , coins , & fClean ) )
if ( ! DisconnectBlock ( block , state , pindex , coins , & fClean ) )
return error ( " VerifyDB() : * * * irrecoverable inconsistency in block data at % d , hash = % s " , pindex->nHeight, pindex->GetBlockHash().ToString()) ;
return error ( " VerifyDB() : * * * irrecoverable inconsistency in block data at % d , hash = % s " , pindex->nHeight, pindex->GetBlockHash().ToString()) ;
pindexState = pindex - > pprev ;
pindexState = pindex - > pprev ;
if ( ! fClean ) {
if ( ! fClean ) {
nGoodTransactions = 0 ;
nGoodTransactions = 0 ;
@ -3034,7 +3034,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
return true ;
return true ;
}
}
if ( pindexFailure )
if ( pindexFailure )
return error ( " VerifyDB() : * * * coin database inconsistencies found ( last % i blocks , % i good transactions before that ) \ n " , chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions) ;
return error ( " VerifyDB() : * * * coin database inconsistencies found ( last % i blocks , % i good transactions before that ) \ n " , chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions) ;
// check level 4: try reconnecting blocks
// check level 4: try reconnecting blocks
if ( nCheckLevel > = 4 ) {
if ( nCheckLevel > = 4 ) {
@ -3045,9 +3045,9 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
pindex = chainActive . Next ( pindex ) ;
pindex = chainActive . Next ( pindex ) ;
CBlock block ;
CBlock block ;
if ( ! ReadBlockFromDisk ( block , pindex ) )
if ( ! ReadBlockFromDisk ( block , pindex ) )
return error ( " VerifyDB() : * * * ReadBlockFromDisk failed at % d , hash = % s " , pindex->nHeight, pindex->GetBlockHash().ToString()) ;
return error ( " VerifyDB() : * * * ReadBlockFromDisk failed at % d , hash = % s " , pindex->nHeight, pindex->GetBlockHash().ToString()) ;
if ( ! ConnectBlock ( block , state , pindex , coins ) )
if ( ! ConnectBlock ( block , state , pindex , coins ) )
return error ( " VerifyDB() : * * * found unconnectable block at % d , hash = % s " , pindex->nHeight, pindex->GetBlockHash().ToString()) ;
return error ( " VerifyDB() : * * * found unconnectable block at % d , hash = % s " , pindex->nHeight, pindex->GetBlockHash().ToString()) ;
}
}
}
}
@ -3093,18 +3093,18 @@ bool InitBlockIndex() {
CDiskBlockPos blockPos ;
CDiskBlockPos blockPos ;
CValidationState state ;
CValidationState state ;
if ( ! FindBlockPos ( state , blockPos , nBlockSize + 8 , 0 , block . GetBlockTime ( ) ) )
if ( ! FindBlockPos ( state , blockPos , nBlockSize + 8 , 0 , block . GetBlockTime ( ) ) )
return error ( " LoadBlockIndex() : FindBlockPos failed " ) ;
return error ( " LoadBlockIndex() : FindBlockPos failed " ) ;
if ( ! WriteBlockToDisk ( block , blockPos ) )
if ( ! WriteBlockToDisk ( block , blockPos ) )
return error ( " LoadBlockIndex() : writing genesis block to disk failed " ) ;
return error ( " LoadBlockIndex() : writing genesis block to disk failed " ) ;
CBlockIndex * pindex = AddToBlockIndex ( block ) ;
CBlockIndex * pindex = AddToBlockIndex ( block ) ;
if ( ! ReceivedBlockTransactions ( block , state , pindex , blockPos ) )
if ( ! ReceivedBlockTransactions ( block , state , pindex , blockPos ) )
return error ( " LoadBlockIndex() : genesis block not accepted " ) ;
return error ( " LoadBlockIndex() : genesis block not accepted " ) ;
if ( ! ActivateBestChain ( state , & block ) )
if ( ! ActivateBestChain ( state , & block ) )
return error ( " LoadBlockIndex() : genesis block cannot be activated " ) ;
return error ( " LoadBlockIndex() : genesis block cannot be activated " ) ;
// Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
// Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
return FlushStateToDisk ( state , FLUSH_STATE_ALWAYS ) ;
return FlushStateToDisk ( state , FLUSH_STATE_ALWAYS ) ;
} catch ( const std : : runtime_error & e ) {
} catch ( const std : : runtime_error & e ) {
return error ( " LoadBlockIndex() : failed to initialize block database : % s " , e.what()) ;
return error ( " LoadBlockIndex() : failed to initialize block database : % s " , e.what()) ;
}
}
}
}
@ -3204,7 +3204,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
}
}
}
}
} catch ( const std : : exception & e ) {
} catch ( const std : : exception & e ) {
LogPrintf ( " %s : Deserialize or I/O error - %s " , __func__ , e . what ( ) ) ;
LogPrintf ( " %s: Deserialize or I/O error - %s " , __func__ , e . what ( ) ) ;
}
}
}
}
} catch ( const std : : runtime_error & e ) {
} catch ( const std : : runtime_error & e ) {
@ -3268,7 +3268,7 @@ string GetWarnings(string strFor)
return strStatusBar ;
return strStatusBar ;
else if ( strFor = = " rpc " )
else if ( strFor = = " rpc " )
return strRPC ;
return strRPC ;
assert ( ! " GetWarnings() : invalid parameter " ) ;
assert ( ! " GetWarnings(): invalid parameter " ) ;
return " error " ;
return " error " ;
}
}
@ -3835,7 +3835,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
vWorkQueue . push_back ( inv . hash ) ;
vWorkQueue . push_back ( inv . hash ) ;
vEraseQueue . push_back ( inv . hash ) ;
vEraseQueue . push_back ( inv . hash ) ;
LogPrint ( " mempool " , " AcceptToMemoryPool: peer=%d %s : accepted %s (poolsz %u) \n " ,
LogPrint ( " mempool " , " AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u) \n " ,
pfrom - > id , pfrom - > cleanSubVer ,
pfrom - > id , pfrom - > cleanSubVer ,
tx . GetHash ( ) . ToString ( ) ,
tx . GetHash ( ) . ToString ( ) ,
mempool . mapTx . size ( ) ) ;
mempool . mapTx . size ( ) ) ;
@ -4297,7 +4297,7 @@ bool ProcessMessages(CNode* pfrom)
memcpy ( & nChecksum , & hash , sizeof ( nChecksum ) ) ;
memcpy ( & nChecksum , & hash , sizeof ( nChecksum ) ) ;
if ( nChecksum ! = hdr . nChecksum )
if ( nChecksum ! = hdr . nChecksum )
{
{
LogPrintf ( " ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x \n " ,
LogPrintf ( " ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x \n " ,
strCommand , nMessageSize , nChecksum , hdr . nChecksum ) ;
strCommand , nMessageSize , nChecksum , hdr . nChecksum ) ;
continue ;
continue ;
}
}
@ -4315,12 +4315,12 @@ bool ProcessMessages(CNode* pfrom)
if ( strstr ( e . what ( ) , " end of data " ) )
if ( strstr ( e . what ( ) , " end of data " ) )
{
{
// Allow exceptions from under-length message on vRecv
// Allow exceptions from under-length message on vRecv
LogPrintf ( " ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length \n " , strCommand , nMessageSize , e . what ( ) ) ;
LogPrintf ( " ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length \n " , strCommand , nMessageSize , e . what ( ) ) ;
}
}
else if ( strstr ( e . what ( ) , " size too large " ) )
else if ( strstr ( e . what ( ) , " size too large " ) )
{
{
// Allow exceptions from over-long size
// Allow exceptions from over-long size
LogPrintf ( " ProcessMessages(%s, %u bytes) : Exception '%s' caught \n " , strCommand , nMessageSize , e . what ( ) ) ;
LogPrintf ( " ProcessMessages(%s, %u bytes): Exception '%s' caught \n " , strCommand , nMessageSize , e . what ( ) ) ;
}
}
else
else
{
{