@ -45,7 +45,6 @@ CConditionVariable cvBlockChange;
int nScriptCheckThreads = 0 ;
int nScriptCheckThreads = 0 ;
bool fImporting = false ;
bool fImporting = false ;
bool fReindex = false ;
bool fReindex = false ;
bool fBenchmark = false ;
bool fTxIndex = false ;
bool fTxIndex = false ;
bool fIsBareMultisigStd = true ;
bool fIsBareMultisigStd = true ;
unsigned int nCoinCacheSize = 5000 ;
unsigned int nCoinCacheSize = 5000 ;
@ -1680,6 +1679,12 @@ void ThreadScriptCheck() {
scriptcheckqueue . Thread ( ) ;
scriptcheckqueue . Thread ( ) ;
}
}
static int64_t nTimeVerify = 0 ;
static int64_t nTimeConnect = 0 ;
static int64_t nTimeIndex = 0 ;
static int64_t nTimeCallbacks = 0 ;
static int64_t nTimeTotal = 0 ;
bool ConnectBlock ( CBlock & block , CValidationState & state , CBlockIndex * pindex , CCoinsViewCache & view , bool fJustCheck )
bool ConnectBlock ( CBlock & block , CValidationState & state , CBlockIndex * pindex , CCoinsViewCache & view , bool fJustCheck )
{
{
AssertLockHeld ( cs_main ) ;
AssertLockHeld ( cs_main ) ;
@ -1735,7 +1740,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
CCheckQueueControl < CScriptCheck > control ( fScriptChecks & & nScriptCheckThreads ? & scriptcheckqueue : NULL ) ;
CCheckQueueControl < CScriptCheck > control ( fScriptChecks & & nScriptCheckThreads ? & scriptcheckqueue : NULL ) ;
int64_t nStart = GetTimeMicros ( ) ;
int64_t nTime Start = GetTimeMicros ( ) ;
int64_t nFees = 0 ;
int64_t nFees = 0 ;
int nInputs = 0 ;
int nInputs = 0 ;
unsigned int nSigOps = 0 ;
unsigned int nSigOps = 0 ;
@ -1785,9 +1790,8 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
vPos . push_back ( std : : make_pair ( tx . GetHash ( ) , pos ) ) ;
vPos . push_back ( std : : make_pair ( tx . GetHash ( ) , pos ) ) ;
pos . nTxOffset + = : : GetSerializeSize ( tx , SER_DISK , CLIENT_VERSION ) ;
pos . nTxOffset + = : : GetSerializeSize ( tx , SER_DISK , CLIENT_VERSION ) ;
}
}
int64_t nTime = GetTimeMicros ( ) - nStart ;
int64_t nTime1 = GetTimeMicros ( ) ; nTimeConnect + = nTime1 - nTimeStart ;
if ( fBenchmark )
LogPrint ( " bench " , " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs] \n " , ( unsigned ) block . vtx . size ( ) , 0.001 * ( nTime1 - nTimeStart ) , 0.001 * ( nTime1 - nTimeStart ) / block . vtx . size ( ) , nInputs < = 1 ? 0 : 0.001 * ( nTime1 - nTimeStart ) / ( nInputs - 1 ) , nTimeConnect * 0.000001 ) ;
LogPrintf ( " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) \n " , ( unsigned ) block . vtx . size ( ) , 0.001 * nTime , 0.001 * nTime / block . vtx . size ( ) , nInputs < = 1 ? 0 : 0.001 * nTime / ( nInputs - 1 ) ) ;
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 ,
@ -1797,9 +1801,8 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
if ( ! control . Wait ( ) )
if ( ! control . Wait ( ) )
return state . DoS ( 100 , false ) ;
return state . DoS ( 100 , false ) ;
int64_t nTime2 = GetTimeMicros ( ) - nStart ;
int64_t nTime2 = GetTimeMicros ( ) ; nTimeVerify + = nTime2 - nTimeStart ;
if ( fBenchmark )
LogPrint ( " bench " , " - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs] \n " , nInputs - 1 , 0.001 * ( nTime2 - nTimeStart ) , nInputs < = 1 ? 0 : 0.001 * ( nTime2 - nTimeStart ) / ( nInputs - 1 ) , nTimeVerify * 0.000001 ) ;
LogPrintf ( " - Verify %u txins: %.2fms (%.3fms/txin) \n " , nInputs - 1 , 0.001 * nTime2 , nInputs < = 1 ? 0 : 0.001 * nTime2 / ( nInputs - 1 ) ) ;
if ( fJustCheck )
if ( fJustCheck )
return true ;
return true ;
@ -1840,6 +1843,9 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
ret = view . SetBestBlock ( pindex - > GetBlockHash ( ) ) ;
ret = view . SetBestBlock ( pindex - > GetBlockHash ( ) ) ;
assert ( ret ) ;
assert ( ret ) ;
int64_t nTime3 = GetTimeMicros ( ) ; nTimeIndex + = nTime3 - nTime2 ;
LogPrint ( " bench " , " - Index writing: %.2fms [%.2fs] \n " , 0.001 * ( nTime3 - nTime2 ) , nTimeIndex * 0.000001 ) ;
// Watch for transactions paying to me
// Watch for transactions paying to me
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
g_signals . SyncTransaction ( tx , & block ) ;
g_signals . SyncTransaction ( tx , & block ) ;
@ -1849,6 +1855,9 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
g_signals . UpdatedTransaction ( hashPrevBestCoinBase ) ;
g_signals . UpdatedTransaction ( hashPrevBestCoinBase ) ;
hashPrevBestCoinBase = block . vtx [ 0 ] . GetHash ( ) ;
hashPrevBestCoinBase = block . vtx [ 0 ] . GetHash ( ) ;
int64_t nTime4 = GetTimeMicros ( ) ; nTimeCallbacks + = nTime4 - nTime3 ;
LogPrint ( " bench " , " - Callbacks: %.2fms [%.2fs] \n " , 0.001 * ( nTime4 - nTime3 ) , nTimeCallbacks * 0.000001 ) ;
return true ;
return true ;
}
}
@ -1928,8 +1937,7 @@ bool static DisconnectTip(CValidationState &state) {
return error ( " DisconnectTip() : DisconnectBlock % s failed " , pindexDelete->GetBlockHash().ToString()) ;
return error ( " DisconnectTip() : DisconnectBlock % s failed " , pindexDelete->GetBlockHash().ToString()) ;
assert ( view . Flush ( ) ) ;
assert ( view . Flush ( ) ) ;
}
}
if ( fBenchmark )
LogPrint ( " bench " , " - Disconnect block: %.2fms \n " , ( GetTimeMicros ( ) - nStart ) * 0.001 ) ;
LogPrintf ( " - Disconnect: %.2fms \n " , ( GetTimeMicros ( ) - nStart ) * 0.001 ) ;
// Write the chain state to disk, if necessary.
// Write the chain state to disk, if necessary.
if ( ! WriteChainState ( state ) )
if ( ! WriteChainState ( state ) )
return false ;
return false ;
@ -1953,16 +1961,25 @@ bool static DisconnectTip(CValidationState &state) {
return true ;
return true ;
}
}
static int64_t nTimeReadFromDisk = 0 ;
static int64_t nTimeConnectTotal = 0 ;
static int64_t nTimeFlush = 0 ;
static int64_t nTimeChainState = 0 ;
static int64_t nTimePostConnect = 0 ;
// Connect a new block to chainActive.
// Connect a new block to chainActive.
bool static ConnectTip ( CValidationState & state , CBlockIndex * pindexNew ) {
bool static ConnectTip ( CValidationState & state , CBlockIndex * pindexNew ) {
assert ( pindexNew - > pprev = = chainActive . Tip ( ) ) ;
assert ( pindexNew - > pprev = = chainActive . Tip ( ) ) ;
mempool . check ( pcoinsTip ) ;
mempool . check ( pcoinsTip ) ;
// Read block from disk.
// Read block from disk.
int64_t nTime1 = GetTimeMicros ( ) ;
CBlock block ;
CBlock block ;
if ( ! ReadBlockFromDisk ( block , pindexNew ) )
if ( ! ReadBlockFromDisk ( block , pindexNew ) )
return state . Abort ( _ ( " Failed to read block " ) ) ;
return state . Abort ( _ ( " Failed to read block " ) ) ;
// Apply the block atomically to the chain state.
// Apply the block atomically to the chain state.
int64_t nStart = GetTimeMicros ( ) ;
int64_t nTime2 = GetTimeMicros ( ) ; nTimeReadFromDisk + = nTime2 - nTime1 ;
int64_t nTime3 ;
LogPrint ( " bench " , " - Load block from disk: %.2fms [%.2fs] \n " , ( nTime2 - nTime1 ) * 0.001 , nTimeReadFromDisk * 0.000001 ) ;
{
{
CCoinsViewCache view ( * pcoinsTip , true ) ;
CCoinsViewCache view ( * pcoinsTip , true ) ;
CInv inv ( MSG_BLOCK , pindexNew - > GetBlockHash ( ) ) ;
CInv inv ( MSG_BLOCK , pindexNew - > GetBlockHash ( ) ) ;
@ -1972,13 +1989,17 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew) {
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 ;
LogPrint ( " bench " , " - Connect total: %.2fms [%.2fs] \n " , ( nTime3 - nTime2 ) * 0.001 , nTimeConnectTotal * 0.000001 ) ;
assert ( view . Flush ( ) ) ;
assert ( view . Flush ( ) ) ;
}
}
if ( fBenchmark )
int64_t nTime4 = GetTimeMicros ( ) ; nTimeFlush + = nTime4 - nTime3 ;
LogPrintf ( " - Connect: %.2fms \n " , ( GetTimeMicros ( ) - nStart ) * 0.001 ) ;
LogPrint ( " bench " , " - Flush: %.2fms [%.2fs] \n " , ( nTime4 - nTime3 ) * 0.001 , nTimeFlush * 0.000 001 ) ;
// Write the chain state to disk, if necessary.
// Write the chain state to disk, if necessary.
if ( ! WriteChainState ( state ) )
if ( ! WriteChainState ( state ) )
return false ;
return false ;
int64_t nTime5 = GetTimeMicros ( ) ; nTimeChainState + = nTime5 - nTime4 ;
LogPrint ( " bench " , " - Writing chainstate: %.2fms [%.2fs] \n " , ( nTime5 - nTime4 ) * 0.001 , nTimeChainState * 0.000001 ) ;
// Remove conflicting transactions from the mempool.
// Remove conflicting transactions from the mempool.
list < CTransaction > txConflicted ;
list < CTransaction > txConflicted ;
mempool . removeForBlock ( block . vtx , pindexNew - > nHeight , txConflicted ) ;
mempool . removeForBlock ( block . vtx , pindexNew - > nHeight , txConflicted ) ;
@ -1994,6 +2015,9 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew) {
BOOST_FOREACH ( const CTransaction & tx , block . vtx ) {
BOOST_FOREACH ( const CTransaction & tx , block . vtx ) {
SyncWithWallets ( tx , & block ) ;
SyncWithWallets ( tx , & block ) ;
}
}
int64_t nTime6 = GetTimeMicros ( ) ; nTimePostConnect + = nTime6 - nTime5 ; nTimeTotal + = nTime6 - nTime1 ;
LogPrint ( " bench " , " - Connect postprocess: %.2fms [%.2fs] \n " , ( nTime6 - nTime5 ) * 0.001 , nTimePostConnect * 0.000001 ) ;
LogPrint ( " bench " , " - Connect block: %.2fms [%.2fs] \n " , ( nTime6 - nTime1 ) * 0.001 , nTimeTotal * 0.000001 ) ;
return true ;
return true ;
}
}