| 29 | } |
| 30 | |
| 31 | bool CBlockIndexDB::LoadBlockIndexes() { |
| 32 | leveldb::Iterator *pCursor = NewIterator(); |
| 33 | const std::string &prefix = dbk::GetKeyPrefix(dbk::BLOCK_INDEX); |
| 34 | |
| 35 | pCursor->Seek(prefix); |
| 36 | |
| 37 | // Load mapBlockIndex |
| 38 | while (pCursor->Valid()) { |
| 39 | boost::this_thread::interruption_point(); |
| 40 | try { |
| 41 | leveldb::Slice slKey = pCursor->key(); |
| 42 | if (slKey.starts_with(prefix)) { |
| 43 | leveldb::Slice slValue = pCursor->value(); |
| 44 | CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION); |
| 45 | CDiskBlockIndex diskIndex; |
| 46 | ssValue >> diskIndex; |
| 47 | |
| 48 | // Construct block index object |
| 49 | CBlockIndex *pIndexNew = InsertBlockIndex(diskIndex.GetBlockHash()); |
| 50 | pIndexNew->pprev = InsertBlockIndex(diskIndex.hashPrev); |
| 51 | pIndexNew->height = diskIndex.height; |
| 52 | pIndexNew->nFile = diskIndex.nFile; |
| 53 | pIndexNew->nDataPos = diskIndex.nDataPos; |
| 54 | pIndexNew->nUndoPos = diskIndex.nUndoPos; |
| 55 | pIndexNew->nVersion = diskIndex.nVersion; |
| 56 | pIndexNew->nTime = diskIndex.nTime; |
| 57 | pIndexNew->nStatus = diskIndex.nStatus; |
| 58 | pIndexNew->nFuelFee = diskIndex.nFuelFee; |
| 59 | pIndexNew->nFuelRate = diskIndex.nFuelRate; |
| 60 | |
| 61 | if (!pIndexNew->CheckIndex()) |
| 62 | return ERRORMSG("LoadBlockIndex() : CheckIndex failed: %s", pIndexNew->ToString()); |
| 63 | |
| 64 | pCursor->Next(); |
| 65 | } else { |
| 66 | break; // if shutdown requested or finished loading block index |
| 67 | } |
| 68 | } catch (std::exception &e) { |
| 69 | return ERRORMSG("Deserialize or I/O error - %s", e.what()); |
| 70 | } |
| 71 | } |
| 72 | delete pCursor; |
| 73 | |
| 74 | return true; |
| 75 | } |
| 76 | |
| 77 | bool CBlockIndexDB::WriteBlockFileInfo(int32_t nFile, const CBlockFileInfo &info) { |
| 78 | return Write(dbk::GenDbKey(dbk::BLOCKFILE_NUM_INFO, nFile), info); |
no test coverage detected