15 #include <boost/thread.hpp>
17 static const char DB_COINS =
'c';
18 static const char DB_BLOCK_FILES =
'f';
19 static const char DB_TXINDEX =
't';
20 static const char DB_BLOCK_INDEX =
'b';
22 static const char DB_BEST_BLOCK =
'B';
23 static const char DB_FLAG =
'F';
24 static const char DB_REINDEX_FLAG =
'R';
25 static const char DB_LAST_BLOCK =
'l';
33 return db.
Read(std::make_pair(DB_COINS, txid), coins);
37 return db.
Exists(std::make_pair(DB_COINS, txid));
42 if (!
db.
Read(DB_BEST_BLOCK, hashBestChain))
51 for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
53 if (it->second.coins.IsPruned())
54 batch.
Erase(std::make_pair(DB_COINS, it->first));
56 batch.
Write(std::make_pair(DB_COINS, it->first), it->second.coins);
60 CCoinsMap::iterator itOld = it++;
61 mapCoins.erase(itOld);
64 batch.
Write(DB_BEST_BLOCK, hashBlock);
66 LogPrint(
"coindb",
"Committing %u changed transactions (out of %u) to coin database...\n", (
unsigned int)changed, (
unsigned int)count);
74 return Read(std::make_pair(DB_BLOCK_FILES, nFile), info);
79 return Write(DB_REINDEX_FLAG,
'1');
81 return Erase(DB_REINDEX_FLAG);
85 fReindexing =
Exists(DB_REINDEX_FLAG);
90 return Read(DB_LAST_BLOCK, nFile);
112 if (
keyTmp.first == DB_COINS) {
121 return pcursor->GetValue(coins);
126 return pcursor->GetValueSize();
131 return keyTmp.first == DB_COINS;
141 bool CBlockTreeDB::WriteBatchSync(
const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo,
int nLastFile,
const std::vector<const CBlockIndex*>& blockinfo) {
143 for (std::vector<std::pair<int, const CBlockFileInfo*> >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) {
144 batch.
Write(std::make_pair(DB_BLOCK_FILES, it->first), *it->second);
146 batch.
Write(DB_LAST_BLOCK, nLastFile);
147 for (std::vector<const CBlockIndex*>::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) {
154 return Read(std::make_pair(DB_TXINDEX, txid), pos);
159 for (std::vector<std::pair<uint256,CDiskTxPos> >::const_iterator it=vect.begin(); it!=vect.end(); it++)
160 batch.
Write(std::make_pair(DB_TXINDEX, it->first), it->second);
165 return Write(std::make_pair(DB_FLAG, name), fValue ?
'1' :
'0');
170 if (!
Read(std::make_pair(DB_FLAG, name), ch))
178 std::unique_ptr<CDBIterator> pcursor(
NewIterator());
180 pcursor->Seek(std::make_pair(DB_BLOCK_INDEX,
uint256()));
183 while (pcursor->Valid()) {
184 boost::this_thread::interruption_point();
185 std::pair<char, uint256> key;
186 if (pcursor->GetKey(key) && key.first == DB_BLOCK_INDEX) {
188 if (pcursor->GetValue(diskindex)) {
202 pindexNew->
nTx = diskindex.
nTx;
211 return error(
"LoadBlockIndex() : failed to read value");
The block chain is a tree shaped structure starting with the genesis block at the root,...
CBlockIndex * pprev
pointer to the index of the predecessor of this block
int nFile
Which # file this block is stored in (blk?????.dat)
unsigned int nUndoPos
Byte offset within rev?????.dat where this block's undo data is stored.
unsigned int nStatus
Verification status of this block. See enum BlockStatus.
unsigned int nTx
Number of transactions in this block.
int nHeight
height of the entry in the chain. The genesis block has height 0
unsigned int nDataPos
Byte offset within blk?????.dat where this block's data is stored.
bool ReadReindexing(bool &fReindex)
bool WriteTxIndex(const std::vector< std::pair< uint256, CDiskTxPos > > &list)
CBlockTreeDB(size_t nCacheSize, bool fMemory=false, bool fWipe=false)
bool ReadBlockFileInfo(int nFile, CBlockFileInfo &fileinfo)
bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos)
bool LoadBlockIndexGuts(boost::function< CBlockIndex *(const uint256 &)> insertBlockIndex)
bool WriteReindexing(bool fReindex)
bool WriteBatchSync(const std::vector< std::pair< int, const CBlockFileInfo * > > &fileInfo, int nLastFile, const std::vector< const CBlockIndex * > &blockinfo)
bool ReadFlag(const std::string &name, bool &fValue)
bool ReadLastBlockFile(int &nFile)
bool WriteFlag(const std::string &name, bool fValue)
Pruned version of CTransaction: only retains metadata and unspent transaction outputs.
Cursor for iterating over CoinsView state.
Specialization of CCoinsViewCursor to iterate over a CCoinsViewDB.
std::unique_ptr< CDBIterator > pcursor
bool GetValue(CCoins &coins) const
bool GetKey(uint256 &key) const
unsigned int GetValueSize() const
std::pair< char, uint256 > keyTmp
CCoinsViewDB(size_t nCacheSize, bool fMemory=false, bool fWipe=false)
CCoinsViewCursor * Cursor() const
Get a cursor to iterate over the whole state.
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock)
Do a bulk modification (multiple CCoins changes + BestBlock change).
bool GetCoins(const uint256 &txid, CCoins &coins) const
Retrieve the CCoins (unspent transaction outputs) for a given txid.
uint256 GetBestBlock() const
Retrieve the block hash whose state this CCoinsView currently represents.
bool HaveCoins(const uint256 &txid) const
Just check whether we have data for a given txid.
Batch of changes queued to be written to a CDBWrapper.
void Write(const K &key, const V &value)
CDBIterator * NewIterator()
bool WriteBatch(CDBBatch &batch, bool fSync=false)
bool Read(const K &key, V &value) const
bool Erase(const K &key, bool fSync=false)
bool Write(const K &key, const V &value, bool fSync=false)
bool Exists(const K &key) const
Used to marshal pointers into hashes for db storage.
uint256 GetBlockHash() const
boost::unordered_map< uint256, CCoinsCacheEntry, SaltedTxidHasher > CCoinsMap
const boost::filesystem::path & GetDataDir(bool fNetSpecific)
#define LogPrint(category,...)
bool error(const char *fmt, const Args &... args)