You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

txdb.cpp 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. // Copyright (c) 2009-2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2016 The Starwels developers
  3. // Distributed under the MIT software license, see the accompanying
  4. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5. #include "txdb.h"
  6. #include "chainparams.h"
  7. #include "hash.h"
  8. #include "random.h"
  9. #include "pow.h"
  10. #include "uint256.h"
  11. #include "util.h"
  12. #include "ui_interface.h"
  13. #include "init.h"
  14. #include <stdint.h>
  15. #include <boost/thread.hpp>
  16. static const char DB_COIN = 'C';
  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';
  21. static const char DB_BEST_BLOCK = 'B';
  22. static const char DB_HEAD_BLOCKS = 'H';
  23. static const char DB_FLAG = 'F';
  24. static const char DB_REINDEX_FLAG = 'R';
  25. static const char DB_LAST_BLOCK = 'l';
  26. namespace {
  27. struct CoinEntry {
  28. COutPoint* outpoint;
  29. char key;
  30. CoinEntry(const COutPoint* ptr) : outpoint(const_cast<COutPoint*>(ptr)), key(DB_COIN) {}
  31. template<typename Stream>
  32. void Serialize(Stream &s) const {
  33. s << key;
  34. s << outpoint->hash;
  35. s << VARINT(outpoint->n);
  36. }
  37. template<typename Stream>
  38. void Unserialize(Stream& s) {
  39. s >> key;
  40. s >> outpoint->hash;
  41. s >> VARINT(outpoint->n);
  42. }
  43. };
  44. }
  45. CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe, true)
  46. {
  47. }
  48. bool CCoinsViewDB::GetCoin(const COutPoint &outpoint, Coin &coin) const {
  49. return db.Read(CoinEntry(&outpoint), coin);
  50. }
  51. bool CCoinsViewDB::HaveCoin(const COutPoint &outpoint) const {
  52. return db.Exists(CoinEntry(&outpoint));
  53. }
  54. uint256 CCoinsViewDB::GetBestBlock() const {
  55. uint256 hashBestChain;
  56. if (!db.Read(DB_BEST_BLOCK, hashBestChain))
  57. return uint256();
  58. return hashBestChain;
  59. }
  60. std::vector<uint256> CCoinsViewDB::GetHeadBlocks() const {
  61. std::vector<uint256> vhashHeadBlocks;
  62. if (!db.Read(DB_HEAD_BLOCKS, vhashHeadBlocks)) {
  63. return std::vector<uint256>();
  64. }
  65. return vhashHeadBlocks;
  66. }
  67. bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) {
  68. CDBBatch batch(db);
  69. size_t count = 0;
  70. size_t changed = 0;
  71. size_t batch_size = (size_t)gArgs.GetArg("-dbbatchsize", nDefaultDbBatchSize);
  72. int crash_simulate = gArgs.GetArg("-dbcrashratio", 0);
  73. assert(!hashBlock.IsNull());
  74. uint256 old_tip = GetBestBlock();
  75. if (old_tip.IsNull()) {
  76. // We may be in the middle of replaying.
  77. std::vector<uint256> old_heads = GetHeadBlocks();
  78. if (old_heads.size() == 2) {
  79. assert(old_heads[0] == hashBlock);
  80. old_tip = old_heads[1];
  81. }
  82. }
  83. // In the first batch, mark the database as being in the middle of a
  84. // transition from old_tip to hashBlock.
  85. // A vector is used for future extensibility, as we may want to support
  86. // interrupting after partial writes from multiple independent reorgs.
  87. batch.Erase(DB_BEST_BLOCK);
  88. batch.Write(DB_HEAD_BLOCKS, std::vector<uint256>{hashBlock, old_tip});
  89. for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
  90. if (it->second.flags & CCoinsCacheEntry::DIRTY) {
  91. CoinEntry entry(&it->first);
  92. if (it->second.coin.IsSpent())
  93. batch.Erase(entry);
  94. else
  95. batch.Write(entry, it->second.coin);
  96. changed++;
  97. }
  98. count++;
  99. CCoinsMap::iterator itOld = it++;
  100. mapCoins.erase(itOld);
  101. if (batch.SizeEstimate() > batch_size) {
  102. LogPrint(BCLog::COINDB, "Writing partial batch of %.2f MiB\n", batch.SizeEstimate() * (1.0 / 1048576.0));
  103. db.WriteBatch(batch);
  104. batch.Clear();
  105. if (crash_simulate) {
  106. static FastRandomContext rng;
  107. if (rng.randrange(crash_simulate) == 0) {
  108. LogPrintf("Simulating a crash. Goodbye.\n");
  109. _Exit(0);
  110. }
  111. }
  112. }
  113. }
  114. // In the last batch, mark the database as consistent with hashBlock again.
  115. batch.Erase(DB_HEAD_BLOCKS);
  116. batch.Write(DB_BEST_BLOCK, hashBlock);
  117. LogPrint(BCLog::COINDB, "Writing final batch of %.2f MiB\n", batch.SizeEstimate() * (1.0 / 1048576.0));
  118. bool ret = db.WriteBatch(batch);
  119. LogPrint(BCLog::COINDB, "Committed %u changed transaction outputs (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count);
  120. return ret;
  121. }
  122. size_t CCoinsViewDB::EstimateSize() const
  123. {
  124. return db.EstimateSize(DB_COIN, (char)(DB_COIN+1));
  125. }
  126. CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) {
  127. }
  128. bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) {
  129. return Read(std::make_pair(DB_BLOCK_FILES, nFile), info);
  130. }
  131. bool CBlockTreeDB::WriteReindexing(bool fReindexing) {
  132. if (fReindexing)
  133. return Write(DB_REINDEX_FLAG, '1');
  134. else
  135. return Erase(DB_REINDEX_FLAG);
  136. }
  137. bool CBlockTreeDB::ReadReindexing(bool &fReindexing) {
  138. fReindexing = Exists(DB_REINDEX_FLAG);
  139. return true;
  140. }
  141. bool CBlockTreeDB::ReadLastBlockFile(int &nFile) {
  142. return Read(DB_LAST_BLOCK, nFile);
  143. }
  144. CCoinsViewCursor *CCoinsViewDB::Cursor() const
  145. {
  146. CCoinsViewDBCursor *i = new CCoinsViewDBCursor(const_cast<CDBWrapper&>(db).NewIterator(), GetBestBlock());
  147. /* It seems that there are no "const iterators" for LevelDB. Since we
  148. only need read operations on it, use a const-cast to get around
  149. that restriction. */
  150. i->pcursor->Seek(DB_COIN);
  151. // Cache key of first record
  152. if (i->pcursor->Valid()) {
  153. CoinEntry entry(&i->keyTmp.second);
  154. i->pcursor->GetKey(entry);
  155. i->keyTmp.first = entry.key;
  156. } else {
  157. i->keyTmp.first = 0; // Make sure Valid() and GetKey() return false
  158. }
  159. return i;
  160. }
  161. bool CCoinsViewDBCursor::GetKey(COutPoint &key) const
  162. {
  163. // Return cached key
  164. if (keyTmp.first == DB_COIN) {
  165. key = keyTmp.second;
  166. return true;
  167. }
  168. return false;
  169. }
  170. bool CCoinsViewDBCursor::GetValue(Coin &coin) const
  171. {
  172. return pcursor->GetValue(coin);
  173. }
  174. unsigned int CCoinsViewDBCursor::GetValueSize() const
  175. {
  176. return pcursor->GetValueSize();
  177. }
  178. bool CCoinsViewDBCursor::Valid() const
  179. {
  180. return keyTmp.first == DB_COIN;
  181. }
  182. void CCoinsViewDBCursor::Next()
  183. {
  184. pcursor->Next();
  185. CoinEntry entry(&keyTmp.second);
  186. if (!pcursor->Valid() || !pcursor->GetKey(entry)) {
  187. keyTmp.first = 0; // Invalidate cached key after last record so that Valid() and GetKey() return false
  188. } else {
  189. keyTmp.first = entry.key;
  190. }
  191. }
  192. bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo) {
  193. CDBBatch batch(*this);
  194. for (std::vector<std::pair<int, const CBlockFileInfo*> >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) {
  195. batch.Write(std::make_pair(DB_BLOCK_FILES, it->first), *it->second);
  196. }
  197. batch.Write(DB_LAST_BLOCK, nLastFile);
  198. for (std::vector<const CBlockIndex*>::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) {
  199. batch.Write(std::make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()), CDiskBlockIndex(*it));
  200. }
  201. return WriteBatch(batch, true);
  202. }
  203. bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) {
  204. return Read(std::make_pair(DB_TXINDEX, txid), pos);
  205. }
  206. bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> >&vect) {
  207. CDBBatch batch(*this);
  208. for (std::vector<std::pair<uint256,CDiskTxPos> >::const_iterator it=vect.begin(); it!=vect.end(); it++)
  209. batch.Write(std::make_pair(DB_TXINDEX, it->first), it->second);
  210. return WriteBatch(batch);
  211. }
  212. bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) {
  213. return Write(std::make_pair(DB_FLAG, name), fValue ? '1' : '0');
  214. }
  215. bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) {
  216. char ch;
  217. if (!Read(std::make_pair(DB_FLAG, name), ch))
  218. return false;
  219. fValue = ch == '1';
  220. return true;
  221. }
  222. bool CBlockTreeDB::LoadBlockIndexGuts(const Consensus::Params& consensusParams, std::function<CBlockIndex*(const uint256&)> insertBlockIndex)
  223. {
  224. std::unique_ptr<CDBIterator> pcursor(NewIterator());
  225. pcursor->Seek(std::make_pair(DB_BLOCK_INDEX, uint256()));
  226. // Load mapBlockIndex
  227. while (pcursor->Valid()) {
  228. boost::this_thread::interruption_point();
  229. std::pair<char, uint256> key;
  230. if (pcursor->GetKey(key) && key.first == DB_BLOCK_INDEX) {
  231. CDiskBlockIndex diskindex;
  232. if (pcursor->GetValue(diskindex)) {
  233. // Construct block index object
  234. CBlockIndex* pindexNew = insertBlockIndex(diskindex.GetBlockHash());
  235. pindexNew->pprev = insertBlockIndex(diskindex.hashPrev);
  236. pindexNew->nHeight = diskindex.nHeight;
  237. pindexNew->nFile = diskindex.nFile;
  238. pindexNew->nDataPos = diskindex.nDataPos;
  239. pindexNew->nUndoPos = diskindex.nUndoPos;
  240. pindexNew->nVersion = diskindex.nVersion;
  241. pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
  242. pindexNew->nTime = diskindex.nTime;
  243. pindexNew->nBits = diskindex.nBits;
  244. pindexNew->nNonce = diskindex.nNonce;
  245. pindexNew->nStatus = diskindex.nStatus;
  246. pindexNew->nTx = diskindex.nTx;
  247. if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits, consensusParams))
  248. return error("%s: CheckProofOfWork failed: %s", __func__, pindexNew->ToString());
  249. pcursor->Next();
  250. } else {
  251. return error("%s: failed to read value", __func__);
  252. }
  253. } else {
  254. break;
  255. }
  256. }
  257. return true;
  258. }
  259. namespace {
  260. //! Legacy class to deserialize pre-pertxout database entries without reindex.
  261. class CCoins
  262. {
  263. public:
  264. //! whether transaction is a coinbase
  265. bool fCoinBase;
  266. //! unspent transaction outputs; spent outputs are .IsNull(); spent outputs at the end of the array are dropped
  267. std::vector<CTxOut> vout;
  268. //! at which height this transaction was included in the active block chain
  269. int nHeight;
  270. //! empty constructor
  271. CCoins() : fCoinBase(false), vout(0), nHeight(0) { }
  272. template<typename Stream>
  273. void Unserialize(Stream &s) {
  274. unsigned int nCode = 0;
  275. // version
  276. int nVersionDummy;
  277. ::Unserialize(s, VARINT(nVersionDummy));
  278. // header code
  279. ::Unserialize(s, VARINT(nCode));
  280. fCoinBase = nCode & 1;
  281. std::vector<bool> vAvail(2, false);
  282. vAvail[0] = (nCode & 2) != 0;
  283. vAvail[1] = (nCode & 4) != 0;
  284. unsigned int nMaskCode = (nCode / 8) + ((nCode & 6) != 0 ? 0 : 1);
  285. // spentness bitmask
  286. while (nMaskCode > 0) {
  287. unsigned char chAvail = 0;
  288. ::Unserialize(s, chAvail);
  289. for (unsigned int p = 0; p < 8; p++) {
  290. bool f = (chAvail & (1 << p)) != 0;
  291. vAvail.push_back(f);
  292. }
  293. if (chAvail != 0)
  294. nMaskCode--;
  295. }
  296. // txouts themself
  297. vout.assign(vAvail.size(), CTxOut());
  298. for (unsigned int i = 0; i < vAvail.size(); i++) {
  299. if (vAvail[i])
  300. ::Unserialize(s, REF(CTxOutCompressor(vout[i])));
  301. }
  302. // coinbase height
  303. ::Unserialize(s, VARINT(nHeight));
  304. }
  305. };
  306. }
  307. /** Upgrade the database from older formats.
  308. *
  309. * Currently implemented: from the per-tx utxo model (0.8..0.14.x) to per-txout.
  310. */
  311. bool CCoinsViewDB::Upgrade() {
  312. std::unique_ptr<CDBIterator> pcursor(db.NewIterator());
  313. pcursor->Seek(std::make_pair(DB_COINS, uint256()));
  314. if (!pcursor->Valid()) {
  315. return true;
  316. }
  317. int64_t count = 0;
  318. LogPrintf("Upgrading utxo-set database...\n");
  319. LogPrintf("[0%%]...");
  320. size_t batch_size = 1 << 24;
  321. CDBBatch batch(db);
  322. uiInterface.SetProgressBreakAction(StartShutdown);
  323. int reportDone = 0;
  324. std::pair<unsigned char, uint256> key;
  325. std::pair<unsigned char, uint256> prev_key = {DB_COINS, uint256()};
  326. while (pcursor->Valid()) {
  327. boost::this_thread::interruption_point();
  328. if (ShutdownRequested()) {
  329. break;
  330. }
  331. if (pcursor->GetKey(key) && key.first == DB_COINS) {
  332. if (count++ % 256 == 0) {
  333. uint32_t high = 0x100 * *key.second.begin() + *(key.second.begin() + 1);
  334. int percentageDone = (int)(high * 100.0 / 65536.0 + 0.5);
  335. uiInterface.ShowProgress(_("Upgrading UTXO database") + "\n"+ _("(press q to shutdown and continue later)") + "\n", percentageDone);
  336. if (reportDone < percentageDone/10) {
  337. // report max. every 10% step
  338. LogPrintf("[%d%%]...", percentageDone);
  339. reportDone = percentageDone/10;
  340. }
  341. }
  342. CCoins old_coins;
  343. if (!pcursor->GetValue(old_coins)) {
  344. return error("%s: cannot parse CCoins record", __func__);
  345. }
  346. COutPoint outpoint(key.second, 0);
  347. for (size_t i = 0; i < old_coins.vout.size(); ++i) {
  348. if (!old_coins.vout[i].IsNull() && !old_coins.vout[i].scriptPubKey.IsUnspendable()) {
  349. Coin newcoin(std::move(old_coins.vout[i]), old_coins.nHeight, old_coins.fCoinBase);
  350. outpoint.n = i;
  351. CoinEntry entry(&outpoint);
  352. batch.Write(entry, newcoin);
  353. }
  354. }
  355. batch.Erase(key);
  356. if (batch.SizeEstimate() > batch_size) {
  357. db.WriteBatch(batch);
  358. batch.Clear();
  359. db.CompactRange(prev_key, key);
  360. prev_key = key;
  361. }
  362. pcursor->Next();
  363. } else {
  364. break;
  365. }
  366. }
  367. db.WriteBatch(batch);
  368. db.CompactRange({DB_COINS, uint256()}, key);
  369. uiInterface.SetProgressBreakAction(std::function<void(void)>());
  370. LogPrintf("[%s].\n", ShutdownRequested() ? "CANCELLED" : "DONE");
  371. return !ShutdownRequested();
  372. }