@ -45,6 +45,7 @@ int nScriptCheckThreads = 0;
bool fImporting = false ;
bool fImporting = false ;
bool fReindex = false ;
bool fReindex = false ;
bool fBenchmark = false ;
bool fBenchmark = false ;
bool fTxIndex = false ;
unsigned int nCoinCacheSize = 5000 ;
unsigned int nCoinCacheSize = 5000 ;
CMedianFilter < int > cPeerBlockCounts ( 8 , 0 ) ; // Amount of blocks that other nodes claim to have
CMedianFilter < int > cPeerBlockCounts ( 8 , 0 ) ; // Amount of blocks that other nodes claim to have
@ -949,6 +950,25 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock
}
}
}
}
if ( fTxIndex ) {
CDiskTxPos postx ;
if ( pblocktree - > ReadTxIndex ( hash , postx ) ) {
CAutoFile file ( OpenBlockFile ( postx , true ) , SER_DISK , CLIENT_VERSION ) ;
CBlockHeader header ;
try {
file > > header ;
fseek ( file , postx . nTxOffset , SEEK_CUR ) ;
file > > txOut ;
} catch ( std : : exception & e ) {
return error ( " %s() : deserialize or I / O error " , __PRETTY_FUNCTION__) ;
}
hashBlock = header . GetHash ( ) ;
if ( txOut . GetHash ( ) ! = hash )
return error ( " %s() : txid mismatch " , __PRETTY_FUNCTION__) ;
return true ;
}
}
if ( fAllowSlow ) { // use coin database to locate block that contains transaction, and scan it
if ( fAllowSlow ) { // use coin database to locate block that contains transaction, and scan it
int nHeight = - 1 ;
int nHeight = - 1 ;
{
{
@ -1632,6 +1652,9 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJust
int64 nFees = 0 ;
int64 nFees = 0 ;
int nInputs = 0 ;
int nInputs = 0 ;
unsigned int nSigOps = 0 ;
unsigned int nSigOps = 0 ;
CDiskTxPos pos ( pindex - > GetBlockPos ( ) , GetSizeOfCompactSize ( vtx . size ( ) ) ) ;
std : : vector < std : : pair < uint256 , CDiskTxPos > > vPos ;
vPos . reserve ( vtx . size ( ) ) ;
for ( unsigned int i = 0 ; i < vtx . size ( ) ; i + + )
for ( unsigned int i = 0 ; i < vtx . size ( ) ; i + + )
{
{
@ -1671,6 +1694,8 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJust
if ( ! tx . IsCoinBase ( ) )
if ( ! tx . IsCoinBase ( ) )
blockundo . vtxundo . push_back ( txundo ) ;
blockundo . vtxundo . push_back ( txundo ) ;
vPos . push_back ( std : : make_pair ( GetTxHash ( i ) , pos ) ) ;
pos . nTxOffset + = : : GetSerializeSize ( tx , SER_DISK , CLIENT_VERSION ) ;
}
}
int64 nTime = GetTimeMicros ( ) - nStart ;
int64 nTime = GetTimeMicros ( ) - nStart ;
if ( fBenchmark )
if ( fBenchmark )
@ -1710,6 +1735,9 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJust
return error ( " ConnectBlock() : WriteBlockIndex failed " ) ;
return error ( " ConnectBlock() : WriteBlockIndex failed " ) ;
}
}
if ( fTxIndex )
pblocktree - > WriteTxIndex ( vPos ) ;
// add this block to the view's block chain
// add this block to the view's block chain
if ( ! view . SetBestBlock ( pindex ) )
if ( ! view . SetBestBlock ( pindex ) )
return false ;
return false ;
@ -2554,6 +2582,10 @@ bool static LoadBlockIndexDB()
pblocktree - > ReadReindexing ( fReindexing ) ;
pblocktree - > ReadReindexing ( fReindexing ) ;
fReindex | = fReindexing ;
fReindex | = fReindexing ;
// Check whether we have a transaction index
pblocktree - > ReadFlag ( " txindex " , fTxIndex ) ;
printf ( " LoadBlockIndex(): transaction index %s \n " , fTxIndex ? " enabled " : " disabled " ) ;
// Load hashBestChain pointer to end of best chain
// Load hashBestChain pointer to end of best chain
pindexBest = pcoinsTip - > GetBestBlock ( ) ;
pindexBest = pcoinsTip - > GetBestBlock ( ) ;
if ( pindexBest = = NULL )
if ( pindexBest = = NULL )
@ -2658,13 +2690,10 @@ bool LoadBlockIndex()
hashGenesisBlock = uint256 ( " 000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943 " ) ;
hashGenesisBlock = uint256 ( " 000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943 " ) ;
}
}
if ( fReindex )
return true ;
//
//
// Load block index from databases
// Load block index from databases
//
//
if ( ! LoadBlockIndexDB ( ) )
if ( ! fReindex & & ! LoadBlockIndexDB ( ) )
return false ;
return false ;
//
//
@ -2672,6 +2701,13 @@ bool LoadBlockIndex()
//
//
if ( mapBlockIndex . empty ( ) )
if ( mapBlockIndex . empty ( ) )
{
{
fTxIndex = GetBoolArg ( " -txindex " , false ) ;
pblocktree - > WriteFlag ( " txindex " , fTxIndex ) ;
printf ( " Initializing databases... \n " ) ;
if ( fReindex )
return true ;
// Genesis Block:
// Genesis Block:
// CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
// CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
// CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
// CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)