@ -17,6 +17,7 @@
@@ -17,6 +17,7 @@
# include "txdb.h"
# include "txmempool.h"
# include "ui_interface.h"
# include "undo.h"
# include "util.h"
# include "utilmoneystr.h"
@ -1383,9 +1384,20 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
@@ -1383,9 +1384,20 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
if ( ! tx . IsCoinBase ( ) ) {
txundo . vprevout . reserve ( tx . vin . size ( ) ) ;
BOOST_FOREACH ( const CTxIn & txin , tx . vin ) {
txundo . vprevout . push_back ( CTxInUndo ( ) ) ;
bool ret = inputs . ModifyCoins ( txin . prevout . hash ) - > Spend ( txin . prevout , txundo . vprevout . back ( ) ) ;
assert ( ret ) ;
CCoinsModifier coins = inputs . ModifyCoins ( txin . prevout . hash ) ;
unsigned nPos = txin . prevout . n ;
if ( nPos > = coins - > vout . size ( ) | | coins - > vout [ nPos ] . IsNull ( ) )
assert ( false ) ;
// mark an outpoint spent, and construct undo information
txundo . vprevout . push_back ( CTxInUndo ( coins - > vout [ nPos ] ) ) ;
coins - > Spend ( nPos ) ;
if ( coins - > vout . size ( ) = = 0 ) {
CTxInUndo & undo = txundo . vprevout . back ( ) ;
undo . nHeight = coins - > nHeight ;
undo . fCoinBase = coins - > fCoinBase ;
undo . nVersion = coins - > nVersion ;
}
}
}
@ -1393,6 +1405,12 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
@@ -1393,6 +1405,12 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
inputs . ModifyCoins ( tx . GetHash ( ) ) - > FromTx ( tx , nHeight ) ;
}
void UpdateCoins ( const CTransaction & tx , CValidationState & state , CCoinsViewCache & inputs , int nHeight )
{
CTxUndo txundo ;
UpdateCoins ( tx , state , inputs , txundo , nHeight ) ;
}
bool CScriptCheck : : operator ( ) ( ) {
const CScript & scriptSig = ptxTo - > vin [ nIn ] . scriptSig ;
if ( ! VerifyScript ( scriptSig , scriptPubKey , nFlags , CachingSignatureChecker ( * ptxTo , nIn , cacheStore ) , & error ) ) {
@ -1503,7 +1521,63 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
@@ -1503,7 +1521,63 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
return true ;
}
namespace {
bool UndoWriteToDisk ( const CBlockUndo & blockundo , CDiskBlockPos & pos , const uint256 & hashBlock )
{
// Open history file to append
CAutoFile fileout ( OpenUndoFile ( pos ) , SER_DISK , CLIENT_VERSION ) ;
if ( fileout . IsNull ( ) )
return error ( " %s : OpenUndoFile failed " , __func__ ) ;
// Write index header
unsigned int nSize = fileout . GetSerializeSize ( blockundo ) ;
fileout < < FLATDATA ( Params ( ) . MessageStart ( ) ) < < nSize ;
// Write undo data
long fileOutPos = ftell ( fileout . Get ( ) ) ;
if ( fileOutPos < 0 )
return error ( " %s : ftell failed " , __func__ ) ;
pos . nPos = ( unsigned int ) fileOutPos ;
fileout < < blockundo ;
// calculate & write checksum
CHashWriter hasher ( SER_GETHASH , PROTOCOL_VERSION ) ;
hasher < < hashBlock ;
hasher < < blockundo ;
fileout < < hasher . GetHash ( ) ;
return true ;
}
bool UndoReadFromDisk ( CBlockUndo & blockundo , const CDiskBlockPos & pos , const uint256 & hashBlock )
{
// Open history file to read
CAutoFile filein ( OpenUndoFile ( pos , true ) , SER_DISK , CLIENT_VERSION ) ;
if ( filein . IsNull ( ) )
return error ( " %s : OpenBlockFile failed " , __func__ ) ;
// Read block
uint256 hashChecksum ;
try {
filein > > blockundo ;
filein > > hashChecksum ;
}
catch ( const std : : exception & e ) {
return error ( " %s : Deserialize or I/O error - %s " , __func__ , e . what ( ) ) ;
}
// Verify checksum
CHashWriter hasher ( SER_GETHASH , PROTOCOL_VERSION ) ;
hasher < < hashBlock ;
hasher < < blockundo ;
if ( hashChecksum ! = hasher . GetHash ( ) )
return error ( " %s : Checksum mismatch " , __func__ ) ;
return true ;
}
} // anon namespace
bool DisconnectBlock ( CBlock & block , CValidationState & state , CBlockIndex * pindex , CCoinsViewCache & view , bool * pfClean )
{
@ -1518,7 +1592,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
@@ -1518,7 +1592,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
CDiskBlockPos pos = pindex - > GetUndoPos ( ) ;
if ( pos . IsNull ( ) )
return error ( " DisconnectBlock() : no undo data available " ) ;
if ( ! blockUndo . ReadFromDisk ( pos , pindex - > pprev - > GetBlockHash ( ) ) )
if ( ! UndoReadFromDisk ( blockUndo , pos , pindex - > pprev - > GetBlockHash ( ) ) )
return error ( " DisconnectBlock() : failure reading undo data " ) ;
if ( blockUndo . vtxundo . size ( ) + 1 ! = block . vtx . size ( ) )
@ -1760,7 +1834,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
@@ -1760,7 +1834,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
CDiskBlockPos pos ;
if ( ! FindUndoPos ( state , pindex - > nFile , pos , : : GetSerializeSize ( blockundo , SER_DISK , CLIENT_VERSION ) + 40 ) )
return error ( " ConnectBlock() : FindUndoPos failed " ) ;
if ( ! blockundo . WriteToDisk ( pos , pindex - > pprev - > GetBlockHash ( ) ) )
if ( ! UndoWriteToDisk ( blockundo , pos , pindex - > pprev - > GetBlockHash ( ) ) )
return state . Abort ( " Failed to write undo data " ) ;
// update nUndoPos in block index
@ -2926,7 +3000,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
@@ -2926,7 +3000,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
CBlockUndo undo ;
CDiskBlockPos pos = pindex - > GetUndoPos ( ) ;
if ( ! pos . IsNull ( ) ) {
if ( ! undo . ReadFromDisk ( 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()) ;
}
}
@ -4491,61 +4565,6 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
@@ -4491,61 +4565,6 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
return true ;
}
bool CBlockUndo : : WriteToDisk ( CDiskBlockPos & pos , const uint256 & hashBlock )
{
// Open history file to append
CAutoFile fileout ( OpenUndoFile ( pos ) , SER_DISK , CLIENT_VERSION ) ;
if ( fileout . IsNull ( ) )
return error ( " CBlockUndo::WriteToDisk : OpenUndoFile failed " ) ;
// Write index header
unsigned int nSize = fileout . GetSerializeSize ( * this ) ;
fileout < < FLATDATA ( Params ( ) . MessageStart ( ) ) < < nSize ;
// Write undo data
long fileOutPos = ftell ( fileout . Get ( ) ) ;
if ( fileOutPos < 0 )
return error ( " CBlockUndo::WriteToDisk : ftell failed " ) ;
pos . nPos = ( unsigned int ) fileOutPos ;
fileout < < * this ;
// calculate & write checksum
CHashWriter hasher ( SER_GETHASH , PROTOCOL_VERSION ) ;
hasher < < hashBlock ;
hasher < < * this ;
fileout < < hasher . GetHash ( ) ;
return true ;
}
bool CBlockUndo : : ReadFromDisk ( const CDiskBlockPos & pos , const uint256 & hashBlock )
{
// Open history file to read
CAutoFile filein ( OpenUndoFile ( pos , true ) , SER_DISK , CLIENT_VERSION ) ;
if ( filein . IsNull ( ) )
return error ( " CBlockUndo::ReadFromDisk : OpenBlockFile failed " ) ;
// Read block
uint256 hashChecksum ;
try {
filein > > * this ;
filein > > hashChecksum ;
}
catch ( const std : : exception & e ) {
return error ( " %s : Deserialize or I/O error - %s " , __func__ , e . what ( ) ) ;
}
// Verify checksum
CHashWriter hasher ( SER_GETHASH , PROTOCOL_VERSION ) ;
hasher < < hashBlock ;
hasher < < * this ;
if ( hashChecksum ! = hasher . GetHash ( ) )
return error ( " CBlockUndo::ReadFromDisk : Checksum mismatch " ) ;
return true ;
}
std : : string CBlockFileInfo : : ToString ( ) const {
return strprintf ( " CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s) " , nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat( " % Y - % m - % d " , nTimeFirst), DateTimeStrFormat( " % Y - % m - % d " , nTimeLast)) ;
}