Advertisement
Guest User

Untitled

a guest
Feb 9th, 2014
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.52 KB | None | 0 0
  1. // Copyright (c) 2009-2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2013 The Bitcoin developers
  3. // Distributed under the MIT/X11 software license, see the accompanying
  4. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5.  
  6. #include "txdb.h"
  7.  
  8. #include "core.h"
  9. #include "uint256.h"
  10.  
  11. #include <stdint.h>
  12.  
  13. using namespace std;
  14.  
  15. void static BatchWriteCoins(CLevelDBBatch &batch, const uint256 &hash, const CCoins &coins) {
  16. if (coins.IsPruned())
  17. batch.Erase(make_pair('c', hash));
  18. else
  19. batch.Write(make_pair('c', hash), coins);
  20. }
  21.  
  22. void static BatchWriteHashBestChain(CLevelDBBatch &batch, const uint256 &hash) {
  23. batch.Write('B', hash);
  24. }
  25.  
  26. CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) {
  27. }
  28.  
  29. bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) {
  30. return db.Read(make_pair('c', txid), coins);
  31. }
  32.  
  33. bool CCoinsViewDB::SetCoins(const uint256 &txid, const CCoins &coins) {
  34. CLevelDBBatch batch;
  35. BatchWriteCoins(batch, txid, coins);
  36. return db.WriteBatch(batch);
  37. }
  38.  
  39. bool CCoinsViewDB::HaveCoins(const uint256 &txid) {
  40. return db.Exists(make_pair('c', txid));
  41. }
  42.  
  43. uint256 CCoinsViewDB::GetBestBlock() {
  44. uint256 hashBestChain;
  45. if (!db.Read('B', hashBestChain))
  46. return uint256(0);
  47. return hashBestChain;
  48. }
  49.  
  50. bool CCoinsViewDB::SetBestBlock(const uint256 &hashBlock) {
  51. CLevelDBBatch batch;
  52. BatchWriteHashBestChain(batch, hashBlock);
  53. return db.WriteBatch(batch);
  54. }
  55.  
  56. bool CCoinsViewDB::BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock) {
  57. LogPrint("coindb", "Committing %u changed transactions to coin database...\n", (unsigned int)mapCoins.size());
  58.  
  59. CLevelDBBatch batch;
  60. for (std::map<uint256, CCoins>::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
  61. BatchWriteCoins(batch, it->first, it->second);
  62. if (hashBlock != uint256(0))
  63. BatchWriteHashBestChain(batch, hashBlock);
  64.  
  65. return db.WriteBatch(batch);
  66. }
  67.  
  68. CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CLevelDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) {
  69. if (!Read('S', salt)) {
  70. salt = GetRandHash();
  71. Write('S', salt);
  72. }
  73. }
  74.  
  75. bool CBlockTreeDB::WriteBlockIndex(const CDiskBlockIndex& blockindex)
  76. {
  77. return Write(make_pair('b', blockindex.GetBlockHash()), blockindex);
  78. }
  79.  
  80. bool CBlockTreeDB::WriteBestInvalidWork(const CBigNum& bnBestInvalidWork)
  81. {
  82. // Obsolete; only written for backward compatibility.
  83. return Write('I', bnBestInvalidWork);
  84. }
  85.  
  86. bool CBlockTreeDB::WriteBlockFileInfo(int nFile, const CBlockFileInfo &info) {
  87. return Write(make_pair('f', nFile), info);
  88. }
  89.  
  90. bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) {
  91. return Read(make_pair('f', nFile), info);
  92. }
  93.  
  94. bool CBlockTreeDB::WriteLastBlockFile(int nFile) {
  95. return Write('l', nFile);
  96. }
  97.  
  98. bool CBlockTreeDB::WriteReindexing(bool fReindexing) {
  99. if (fReindexing)
  100. return Write('R', '1');
  101. else
  102. return Erase('R');
  103. }
  104.  
  105. bool CBlockTreeDB::ReadReindexing(bool &fReindexing) {
  106. fReindexing = Exists('R');
  107. return true;
  108. }
  109.  
  110. bool CBlockTreeDB::ReadLastBlockFile(int &nFile) {
  111. return Read('l', nFile);
  112. }
  113.  
  114. bool CCoinsViewDB::GetStats(CCoinsStats &stats) {
  115. CLevelDBIterator *pcursor = db.NewIterator();
  116. pcursor->Seek('c');
  117.  
  118. CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
  119. stats.hashBlock = GetBestBlock();
  120. ss << stats.hashBlock;
  121. int64_t nTotalAmount = 0;
  122. while (pcursor->Valid()) {
  123. boost::this_thread::interruption_point();
  124. <<<<<<< HEAD
  125. std::pair<char, uint256> key;
  126. CCoins coins;
  127. if (pcursor->GetKey(key) && key.first == 'c') {
  128. if (pcursor->GetValue(coins)) {
  129. =======
  130. try {
  131. leveldb::Slice slKey = pcursor->key();
  132. CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION);
  133. char chType;
  134. ssKey >> chType;
  135. if (chType == 'c') {
  136. leveldb::Slice slValue = pcursor->value();
  137. CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
  138. CCoins coins;
  139. ssValue >> coins;
  140. uint256 txhash;
  141. ssKey >> txhash;
  142. ss << txhash;
  143. ss << VARINT(coins.nVersion);
  144. ss << (coins.fCoinBase ? 'c' : 'n');
  145. ss << VARINT(coins.nHeight);
  146. >>>>>>> master
  147. stats.nTransactions++;
  148. for (unsigned int i=0; i<coins.vout.size(); i++) {
  149. const CTxOut &out = coins.vout[i];
  150. if (!out.IsNull()) {
  151. stats.nTransactionOutputs++;
  152. ss << VARINT(i+1);
  153. ss << out;
  154. nTotalAmount += out.nValue;
  155. }
  156. }
  157. stats.nSerializedSize += 32 + pcursor->GetKeySize();
  158. ss << VARINT(0);
  159. } else {
  160. return error("CCoinsViewDB::GetStats() : unable to read value");
  161. }
  162. <<<<<<< HEAD
  163. } else {
  164. break;
  165. =======
  166. pcursor->Next();
  167. } catch (std::exception &e) {
  168. return error("%s : Deserialize or I/O error - %s", __PRETTY_FUNCTION__, e.what());
  169. >>>>>>> master
  170. }
  171. pcursor->Next();
  172. }
  173. delete pcursor;
  174. stats.nHeight = mapBlockIndex.find(GetBestBlock())->second->nHeight;
  175. stats.hashSerialized = ss.GetHash();
  176. stats.nTotalAmount = nTotalAmount;
  177. return true;
  178. }
  179.  
  180. bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) {
  181. return Read(make_pair('t', txid), pos);
  182. }
  183.  
  184. bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> >&vect) {
  185. CLevelDBBatch batch;
  186. for (std::vector<std::pair<uint256,CDiskTxPos> >::const_iterator it=vect.begin(); it!=vect.end(); it++)
  187. batch.Write(make_pair('t', it->first), it->second);
  188. return WriteBatch(batch);
  189. }
  190.  
  191. bool CBlockTreeDB::ReadAddrIndex(uint160 addrid, std::vector<CExtDiskTxPos> &list) {
  192. CLevelDBIterator *iter = NewIterator();
  193. uint64_t lookupid;
  194. {
  195. CHashWriter ss(SER_GETHASH, 0);
  196. ss << salt;
  197. ss << addrid;
  198. lookupid = ss.GetHash().Get64(0);
  199. }
  200. iter->Seek(make_pair('a', lookupid));
  201. while (iter->Valid()) {
  202. std::pair<std::pair<char, uint64_t>, CExtDiskTxPos> key;
  203. if (iter->GetKey(key) && key.first.first == 'a' && key.first.second == lookupid) {
  204. list.push_back(key.second);
  205. } else {
  206. break;
  207. }
  208. iter->Next();
  209. }
  210. return true;
  211. }
  212.  
  213. bool CBlockTreeDB::AddAddrIndex(const std::vector<std::pair<uint160, CExtDiskTxPos> > &list) {
  214. unsigned char foo[0];
  215. CLevelDBBatch batch;
  216. for (std::vector<std::pair<uint160, CExtDiskTxPos> >::const_iterator it=list.begin(); it!=list.end(); it++) {
  217. CHashWriter ss(SER_GETHASH, 0);
  218. ss << salt;
  219. ss << it->first;
  220. batch.Write(make_pair(make_pair('a', ss.GetHash().Get64(0)), it->second), FLATDATA(foo));
  221. }
  222. return WriteBatch(batch);
  223. }
  224.  
  225. bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) {
  226. return Write(std::make_pair('F', name), fValue ? '1' : '0');
  227. }
  228.  
  229. bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) {
  230. char ch;
  231. if (!Read(std::make_pair('F', name), ch))
  232. return false;
  233. fValue = ch == '1';
  234. return true;
  235. }
  236.  
  237. bool CBlockTreeDB::LoadBlockIndexGuts()
  238. {
  239. CLevelDBIterator *pcursor = NewIterator();
  240.  
  241. pcursor->Seek(make_pair('b', uint256(0)));
  242.  
  243. // Load mapBlockIndex
  244. while (pcursor->Valid()) {
  245. boost::this_thread::interruption_point();
  246. std::pair<char, uint256> key;
  247. if (pcursor->GetKey(key) && key.first == 'b') {
  248. CDiskBlockIndex diskindex;
  249. if (pcursor->GetValue(diskindex)) {
  250. // Construct block index object
  251. CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash());
  252. pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev);
  253. pindexNew->nHeight = diskindex.nHeight;
  254. pindexNew->nFile = diskindex.nFile;
  255. pindexNew->nDataPos = diskindex.nDataPos;
  256. pindexNew->nUndoPos = diskindex.nUndoPos;
  257. pindexNew->nVersion = diskindex.nVersion;
  258. pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
  259. pindexNew->nTime = diskindex.nTime;
  260. pindexNew->nBits = diskindex.nBits;
  261. pindexNew->nNonce = diskindex.nNonce;
  262. pindexNew->nStatus = diskindex.nStatus;
  263. pindexNew->nTx = diskindex.nTx;
  264.  
  265. if (!pindexNew->CheckIndex())
  266. return error("LoadBlockIndex() : CheckIndex failed: %s", pindexNew->ToString());
  267.  
  268. pcursor->Next();
  269. } else {
  270. return error("LoadBlockIndex() : failed to read value");
  271. }
  272. <<<<<<< HEAD
  273. } else {
  274. break;
  275. =======
  276. } catch (std::exception &e) {
  277. return error("%s : Deserialize or I/O error - %s", __PRETTY_FUNCTION__, e.what());
  278. >>>>>>> master
  279. }
  280. }
  281. delete pcursor;
  282.  
  283. return true;
  284. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement