Revert "Update gitian descriptors to point at stable git repo"
[novacoin.git] / src / db.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 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 "db.h"
7 #include "util.h"
8 #include "main.h"
9 #include <boost/version.hpp>
10 #include <boost/filesystem.hpp>
11 #include <boost/filesystem/fstream.hpp>
12
13 #ifndef WIN32
14 #include "sys/stat.h"
15 #endif
16
17 using namespace std;
18 using namespace boost;
19
20
21 unsigned int nWalletDBUpdated;
22
23
24
25 //
26 // CDB
27 //
28
29 CCriticalSection cs_db;
30 static bool fDbEnvInit = false;
31 bool fDetachDB = false;
32 DbEnv dbenv(0);
33 map<string, int> mapFileUseCount;
34 static map<string, Db*> mapDb;
35
36 static void EnvShutdown()
37 {
38     if (!fDbEnvInit)
39         return;
40
41     fDbEnvInit = false;
42     try
43     {
44         dbenv.close(0);
45     }
46     catch (const DbException& e)
47     {
48         printf("EnvShutdown exception: %s (%d)\n", e.what(), e.get_errno());
49     }
50     DbEnv(0).remove(GetDataDir().string().c_str(), 0);
51 }
52
53 class CDBInit
54 {
55 public:
56     CDBInit()
57     {
58     }
59     ~CDBInit()
60     {
61         EnvShutdown();
62     }
63 }
64 instance_of_cdbinit;
65
66
67 CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL)
68 {
69     int ret;
70     if (pszFile == NULL)
71         return;
72
73     fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
74     bool fCreate = strchr(pszMode, 'c');
75     unsigned int nFlags = DB_THREAD;
76     if (fCreate)
77         nFlags |= DB_CREATE;
78
79     {
80         LOCK(cs_db);
81         if (!fDbEnvInit)
82         {
83             if (fShutdown)
84                 return;
85             filesystem::path pathDataDir = GetDataDir();
86             filesystem::path pathLogDir = pathDataDir / "database";
87             filesystem::create_directory(pathLogDir);
88             filesystem::path pathErrorFile = pathDataDir / "db.log";
89             printf("dbenv.open LogDir=%s ErrorFile=%s\n", pathLogDir.string().c_str(), pathErrorFile.string().c_str());
90
91             int nDbCache = GetArg("-dbcache", 25);
92             dbenv.set_lg_dir(pathLogDir.string().c_str());
93             dbenv.set_cachesize(nDbCache / 1024, (nDbCache % 1024)*1048576, 1);
94             dbenv.set_lg_bsize(1048576);
95             dbenv.set_lg_max(10485760);
96             dbenv.set_lk_max_locks(10000);
97             dbenv.set_lk_max_objects(10000);
98             dbenv.set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug
99             dbenv.set_flags(DB_TXN_WRITE_NOSYNC, 1);
100             dbenv.set_flags(DB_AUTO_COMMIT, 1);
101             dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1);
102             ret = dbenv.open(pathDataDir.string().c_str(),
103                              DB_CREATE     |
104                              DB_INIT_LOCK  |
105                              DB_INIT_LOG   |
106                              DB_INIT_MPOOL |
107                              DB_INIT_TXN   |
108                              DB_THREAD     |
109                              DB_RECOVER,
110                              S_IRUSR | S_IWUSR);
111             if (ret > 0)
112                 throw runtime_error(strprintf("CDB() : error %d opening database environment", ret));
113             fDbEnvInit = true;
114         }
115
116         strFile = pszFile;
117         ++mapFileUseCount[strFile];
118         pdb = mapDb[strFile];
119         if (pdb == NULL)
120         {
121             pdb = new Db(&dbenv, 0);
122
123             ret = pdb->open(NULL,      // Txn pointer
124                             pszFile,   // Filename
125                             "main",    // Logical db name
126                             DB_BTREE,  // Database type
127                             nFlags,    // Flags
128                             0);
129
130             if (ret > 0)
131             {
132                 delete pdb;
133                 pdb = NULL;
134                 {
135                      LOCK(cs_db);
136                     --mapFileUseCount[strFile];
137                 }
138                 strFile = "";
139                 throw runtime_error(strprintf("CDB() : can't open database file %s, error %d", pszFile, ret));
140             }
141
142             if (fCreate && !Exists(string("version")))
143             {
144                 bool fTmp = fReadOnly;
145                 fReadOnly = false;
146                 WriteVersion(CLIENT_VERSION);
147                 fReadOnly = fTmp;
148             }
149
150             mapDb[strFile] = pdb;
151         }
152     }
153 }
154
155 void CDB::Close()
156 {
157     if (!pdb)
158         return;
159     if (!vTxn.empty())
160         vTxn.front()->abort();
161     vTxn.clear();
162     pdb = NULL;
163
164     // Flush database activity from memory pool to disk log
165     unsigned int nMinutes = 0;
166     if (fReadOnly)
167         nMinutes = 1;
168     if (strFile == "addr.dat")
169         nMinutes = 2;
170     if (strFile == "blkindex.dat")
171         nMinutes = 2;
172     if (strFile == "blkindex.dat" && IsInitialBlockDownload())
173         nMinutes = 5;
174
175     dbenv.txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100)*1024 : 0, nMinutes, 0);
176
177     {
178         LOCK(cs_db);
179         --mapFileUseCount[strFile];
180     }
181 }
182
183 void CloseDb(const string& strFile)
184 {
185     {
186         LOCK(cs_db);
187         if (mapDb[strFile] != NULL)
188         {
189             // Close the database handle
190             Db* pdb = mapDb[strFile];
191             pdb->close(0);
192             delete pdb;
193             mapDb[strFile] = NULL;
194         }
195     }
196 }
197
198 bool CDB::Rewrite(const string& strFile, const char* pszSkip)
199 {
200     while (!fShutdown)
201     {
202         {
203             LOCK(cs_db);
204             if (!mapFileUseCount.count(strFile) || mapFileUseCount[strFile] == 0)
205             {
206                 // Flush log data to the dat file
207                 CloseDb(strFile);
208                 dbenv.txn_checkpoint(0, 0, 0);
209                 dbenv.lsn_reset(strFile.c_str(), 0);
210                 mapFileUseCount.erase(strFile);
211
212                 bool fSuccess = true;
213                 printf("Rewriting %s...\n", strFile.c_str());
214                 string strFileRes = strFile + ".rewrite";
215                 { // surround usage of db with extra {}
216                     CDB db(strFile.c_str(), "r");
217                     Db* pdbCopy = new Db(&dbenv, 0);
218     
219                     int ret = pdbCopy->open(NULL,                 // Txn pointer
220                                             strFileRes.c_str(),   // Filename
221                                             "main",    // Logical db name
222                                             DB_BTREE,  // Database type
223                                             DB_CREATE,    // Flags
224                                             0);
225                     if (ret > 0)
226                     {
227                         printf("Cannot create database file %s\n", strFileRes.c_str());
228                         fSuccess = false;
229                     }
230     
231                     Dbc* pcursor = db.GetCursor();
232                     if (pcursor)
233                         while (fSuccess)
234                         {
235                             CDataStream ssKey(SER_DISK, CLIENT_VERSION);
236                             CDataStream ssValue(SER_DISK, CLIENT_VERSION);
237                             int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT);
238                             if (ret == DB_NOTFOUND)
239                             {
240                                 pcursor->close();
241                                 break;
242                             }
243                             else if (ret != 0)
244                             {
245                                 pcursor->close();
246                                 fSuccess = false;
247                                 break;
248                             }
249                             if (pszSkip &&
250                                 strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0)
251                                 continue;
252                             if (strncmp(&ssKey[0], "\x07version", 8) == 0)
253                             {
254                                 // Update version:
255                                 ssValue.clear();
256                                 ssValue << CLIENT_VERSION;
257                             }
258                             Dbt datKey(&ssKey[0], ssKey.size());
259                             Dbt datValue(&ssValue[0], ssValue.size());
260                             int ret2 = pdbCopy->put(NULL, &datKey, &datValue, DB_NOOVERWRITE);
261                             if (ret2 > 0)
262                                 fSuccess = false;
263                         }
264                     if (fSuccess)
265                     {
266                         db.Close();
267                         CloseDb(strFile);
268                         if (pdbCopy->close(0))
269                             fSuccess = false;
270                         delete pdbCopy;
271                     }
272                 }
273                 if (fSuccess)
274                 {
275                     Db dbA(&dbenv, 0);
276                     if (dbA.remove(strFile.c_str(), NULL, 0))
277                         fSuccess = false;
278                     Db dbB(&dbenv, 0);
279                     if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0))
280                         fSuccess = false;
281                 }
282                 if (!fSuccess)
283                     printf("Rewriting of %s FAILED!\n", strFileRes.c_str());
284                 return fSuccess;
285             }
286         }
287         Sleep(100);
288     }
289     return false;
290 }
291
292
293 void DBFlush(bool fShutdown)
294 {
295     // Flush log data to the actual data file
296     //  on all files that are not in use
297     printf("DBFlush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started");
298     if (!fDbEnvInit)
299         return;
300     {
301         LOCK(cs_db);
302         map<string, int>::iterator mi = mapFileUseCount.begin();
303         while (mi != mapFileUseCount.end())
304         {
305             string strFile = (*mi).first;
306             int nRefCount = (*mi).second;
307             printf("%s refcount=%d\n", strFile.c_str(), nRefCount);
308             if (nRefCount == 0)
309             {
310                 // Move log data to the dat file
311                 CloseDb(strFile);
312                 printf("%s checkpoint\n", strFile.c_str());
313                 dbenv.txn_checkpoint(0, 0, 0);
314                 if ((strFile != "blkindex.dat" && strFile != "addr.dat") || fDetachDB) {
315                     printf("%s detach\n", strFile.c_str());
316                     dbenv.lsn_reset(strFile.c_str(), 0);
317                 }
318                 printf("%s closed\n", strFile.c_str());
319                 mapFileUseCount.erase(mi++);
320             }
321             else
322                 mi++;
323         }
324         if (fShutdown)
325         {
326             char** listp;
327             if (mapFileUseCount.empty())
328             {
329                 dbenv.log_archive(&listp, DB_ARCH_REMOVE);
330                 EnvShutdown();
331             }
332         }
333     }
334 }
335
336
337
338
339
340
341 //
342 // CTxDB
343 //
344
345 bool CTxDB::ReadTxIndex(uint256 hash, CTxIndex& txindex)
346 {
347     assert(!fClient);
348     txindex.SetNull();
349     return Read(make_pair(string("tx"), hash), txindex);
350 }
351
352 bool CTxDB::UpdateTxIndex(uint256 hash, const CTxIndex& txindex)
353 {
354     assert(!fClient);
355     return Write(make_pair(string("tx"), hash), txindex);
356 }
357
358 bool CTxDB::AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight)
359 {
360     assert(!fClient);
361
362     // Add to tx index
363     uint256 hash = tx.GetHash();
364     CTxIndex txindex(pos, tx.vout.size());
365     return Write(make_pair(string("tx"), hash), txindex);
366 }
367
368 bool CTxDB::EraseTxIndex(const CTransaction& tx)
369 {
370     assert(!fClient);
371     uint256 hash = tx.GetHash();
372
373     return Erase(make_pair(string("tx"), hash));
374 }
375
376 bool CTxDB::ContainsTx(uint256 hash)
377 {
378     assert(!fClient);
379     return Exists(make_pair(string("tx"), hash));
380 }
381
382 bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>& vtx)
383 {
384     assert(!fClient);
385     vtx.clear();
386
387     // Get cursor
388     Dbc* pcursor = GetCursor();
389     if (!pcursor)
390         return false;
391
392     unsigned int fFlags = DB_SET_RANGE;
393     loop
394     {
395         // Read next record
396         CDataStream ssKey(SER_DISK, CLIENT_VERSION);
397         if (fFlags == DB_SET_RANGE)
398             ssKey << string("owner") << hash160 << CDiskTxPos(0, 0, 0);
399         CDataStream ssValue(SER_DISK, CLIENT_VERSION);
400         int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
401         fFlags = DB_NEXT;
402         if (ret == DB_NOTFOUND)
403             break;
404         else if (ret != 0)
405         {
406             pcursor->close();
407             return false;
408         }
409
410         // Unserialize
411         string strType;
412         uint160 hashItem;
413         CDiskTxPos pos;
414         int nItemHeight;
415
416         try {
417             ssKey >> strType >> hashItem >> pos;
418             ssValue >> nItemHeight;
419         }
420         catch (std::exception &e) {
421             return error("%s() : deserialize error", __PRETTY_FUNCTION__);
422         }
423
424         // Read transaction
425         if (strType != "owner" || hashItem != hash160)
426             break;
427         if (nItemHeight >= nMinHeight)
428         {
429             vtx.resize(vtx.size()+1);
430             if (!vtx.back().ReadFromDisk(pos))
431             {
432                 pcursor->close();
433                 return false;
434             }
435         }
436     }
437
438     pcursor->close();
439     return true;
440 }
441
442 bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex)
443 {
444     assert(!fClient);
445     tx.SetNull();
446     if (!ReadTxIndex(hash, txindex))
447         return false;
448     return (tx.ReadFromDisk(txindex.pos));
449 }
450
451 bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx)
452 {
453     CTxIndex txindex;
454     return ReadDiskTx(hash, tx, txindex);
455 }
456
457 bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex)
458 {
459     return ReadDiskTx(outpoint.hash, tx, txindex);
460 }
461
462 bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx)
463 {
464     CTxIndex txindex;
465     return ReadDiskTx(outpoint.hash, tx, txindex);
466 }
467
468 bool CTxDB::WriteBlockIndex(const CDiskBlockIndex& blockindex)
469 {
470     return Write(make_pair(string("blockindex"), blockindex.GetBlockHash()), blockindex);
471 }
472
473 bool CTxDB::EraseBlockIndex(uint256 hash)
474 {
475     return Erase(make_pair(string("blockindex"), hash));
476 }
477
478 bool CTxDB::ReadHashBestChain(uint256& hashBestChain)
479 {
480     return Read(string("hashBestChain"), hashBestChain);
481 }
482
483 bool CTxDB::WriteHashBestChain(uint256 hashBestChain)
484 {
485     return Write(string("hashBestChain"), hashBestChain);
486 }
487
488 bool CTxDB::ReadBestInvalidWork(CBigNum& bnBestInvalidWork)
489 {
490     return Read(string("bnBestInvalidWork"), bnBestInvalidWork);
491 }
492
493 bool CTxDB::WriteBestInvalidWork(CBigNum bnBestInvalidWork)
494 {
495     return Write(string("bnBestInvalidWork"), bnBestInvalidWork);
496 }
497
498 CBlockIndex static * InsertBlockIndex(uint256 hash)
499 {
500     if (hash == 0)
501         return NULL;
502
503     // Return existing
504     map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
505     if (mi != mapBlockIndex.end())
506         return (*mi).second;
507
508     // Create new
509     CBlockIndex* pindexNew = new CBlockIndex();
510     if (!pindexNew)
511         throw runtime_error("LoadBlockIndex() : new CBlockIndex failed");
512     mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
513     pindexNew->phashBlock = &((*mi).first);
514
515     return pindexNew;
516 }
517
518 bool CTxDB::LoadBlockIndex()
519 {
520     // Get database cursor
521     Dbc* pcursor = GetCursor();
522     if (!pcursor)
523         return false;
524
525     // Load mapBlockIndex
526     unsigned int fFlags = DB_SET_RANGE;
527     loop
528     {
529         // Read next record
530         CDataStream ssKey(SER_DISK, CLIENT_VERSION);
531         if (fFlags == DB_SET_RANGE)
532             ssKey << make_pair(string("blockindex"), uint256(0));
533         CDataStream ssValue(SER_DISK, CLIENT_VERSION);
534         int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
535         fFlags = DB_NEXT;
536         if (ret == DB_NOTFOUND)
537             break;
538         else if (ret != 0)
539             return false;
540
541         // Unserialize
542
543         try {
544         string strType;
545         ssKey >> strType;
546         if (strType == "blockindex" && !fRequestShutdown)
547         {
548             CDiskBlockIndex diskindex;
549             ssValue >> diskindex;
550
551             // Construct block index object
552             CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash());
553             pindexNew->pprev          = InsertBlockIndex(diskindex.hashPrev);
554             pindexNew->pnext          = InsertBlockIndex(diskindex.hashNext);
555             pindexNew->nFile          = diskindex.nFile;
556             pindexNew->nBlockPos      = diskindex.nBlockPos;
557             pindexNew->nHeight        = diskindex.nHeight;
558             pindexNew->nVersion       = diskindex.nVersion;
559             pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
560             pindexNew->nTime          = diskindex.nTime;
561             pindexNew->nBits          = diskindex.nBits;
562             pindexNew->nNonce         = diskindex.nNonce;
563
564             // Watch for genesis block
565             if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock)
566                 pindexGenesisBlock = pindexNew;
567
568             if (!pindexNew->CheckIndex())
569                 return error("LoadBlockIndex() : CheckIndex failed at %d", pindexNew->nHeight);
570         }
571         else
572         {
573             break; // if shutdown requested or finished loading block index
574         }
575         }    // try
576         catch (std::exception &e) {
577             return error("%s() : deserialize error", __PRETTY_FUNCTION__);
578         }
579     }
580     pcursor->close();
581
582     if (fRequestShutdown)
583         return true;
584
585     // Calculate bnChainWork
586     vector<pair<int, CBlockIndex*> > vSortedByHeight;
587     vSortedByHeight.reserve(mapBlockIndex.size());
588     BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
589     {
590         CBlockIndex* pindex = item.second;
591         vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex));
592     }
593     sort(vSortedByHeight.begin(), vSortedByHeight.end());
594     BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
595     {
596         CBlockIndex* pindex = item.second;
597         pindex->bnChainWork = (pindex->pprev ? pindex->pprev->bnChainWork : 0) + pindex->GetBlockWork();
598     }
599
600     // Load hashBestChain pointer to end of best chain
601     if (!ReadHashBestChain(hashBestChain))
602     {
603         if (pindexGenesisBlock == NULL)
604             return true;
605         return error("CTxDB::LoadBlockIndex() : hashBestChain not loaded");
606     }
607     if (!mapBlockIndex.count(hashBestChain))
608         return error("CTxDB::LoadBlockIndex() : hashBestChain not found in the block index");
609     pindexBest = mapBlockIndex[hashBestChain];
610     nBestHeight = pindexBest->nHeight;
611     bnBestChainWork = pindexBest->bnChainWork;
612     printf("LoadBlockIndex(): hashBestChain=%s  height=%d\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight);
613
614     // Load bnBestInvalidWork, OK if it doesn't exist
615     ReadBestInvalidWork(bnBestInvalidWork);
616
617     // Verify blocks in the best chain
618     int nCheckLevel = GetArg("-checklevel", 1);
619     int nCheckDepth = GetArg( "-checkblocks", 2500);
620     if (nCheckDepth == 0)
621         nCheckDepth = 1000000000; // suffices until the year 19000
622     if (nCheckDepth > nBestHeight)
623         nCheckDepth = nBestHeight;
624     printf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
625     CBlockIndex* pindexFork = NULL;
626     map<pair<unsigned int, unsigned int>, CBlockIndex*> mapBlockPos;
627     for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev)
628     {
629         if (pindex->nHeight < nBestHeight-nCheckDepth)
630             break;
631         CBlock block;
632         if (!block.ReadFromDisk(pindex))
633             return error("LoadBlockIndex() : block.ReadFromDisk failed");
634         // check level 1: verify block validity
635         if (nCheckLevel>0 && !block.CheckBlock())
636         {
637             printf("LoadBlockIndex() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
638             pindexFork = pindex->pprev;
639         }
640         // check level 2: verify transaction index validity
641         if (nCheckLevel>1)
642         {
643             pair<unsigned int, unsigned int> pos = make_pair(pindex->nFile, pindex->nBlockPos);
644             mapBlockPos[pos] = pindex;
645             BOOST_FOREACH(const CTransaction &tx, block.vtx)
646             {
647                 uint256 hashTx = tx.GetHash();
648                 CTxIndex txindex;
649                 if (ReadTxIndex(hashTx, txindex))
650                 {
651                     // check level 3: checker transaction hashes
652                     if (nCheckLevel>2 || pindex->nFile != txindex.pos.nFile || pindex->nBlockPos != txindex.pos.nBlockPos)
653                     {
654                         // either an error or a duplicate transaction
655                         CTransaction txFound;
656                         if (!txFound.ReadFromDisk(txindex.pos))
657                         {
658                             printf("LoadBlockIndex() : *** cannot read mislocated transaction %s\n", hashTx.ToString().c_str());
659                             pindexFork = pindex->pprev;
660                         }
661                         else
662                             if (txFound.GetHash() != hashTx) // not a duplicate tx
663                             {
664                                 printf("LoadBlockIndex(): *** invalid tx position for %s\n", hashTx.ToString().c_str());
665                                 pindexFork = pindex->pprev;
666                             }
667                     }
668                     // check level 4: check whether spent txouts were spent within the main chain
669                     unsigned int nOutput = 0;
670                     if (nCheckLevel>3)
671                     {
672                         BOOST_FOREACH(const CDiskTxPos &txpos, txindex.vSpent)
673                         {
674                             if (!txpos.IsNull())
675                             {
676                                 pair<unsigned int, unsigned int> posFind = make_pair(txpos.nFile, txpos.nBlockPos);
677                                 if (!mapBlockPos.count(posFind))
678                                 {
679                                     printf("LoadBlockIndex(): *** found bad spend at %d, hashBlock=%s, hashTx=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str(), hashTx.ToString().c_str());
680                                     pindexFork = pindex->pprev;
681                                 }
682                                 // check level 6: check whether spent txouts were spent by a valid transaction that consume them
683                                 if (nCheckLevel>5)
684                                 {
685                                     CTransaction txSpend;
686                                     if (!txSpend.ReadFromDisk(txpos))
687                                     {
688                                         printf("LoadBlockIndex(): *** cannot read spending transaction of %s:%i from disk\n", hashTx.ToString().c_str(), nOutput);
689                                         pindexFork = pindex->pprev;
690                                     }
691                                     else if (!txSpend.CheckTransaction())
692                                     {
693                                         printf("LoadBlockIndex(): *** spending transaction of %s:%i is invalid\n", hashTx.ToString().c_str(), nOutput);
694                                         pindexFork = pindex->pprev;
695                                     }
696                                     else
697                                     {
698                                         bool fFound = false;
699                                         BOOST_FOREACH(const CTxIn &txin, txSpend.vin)
700                                             if (txin.prevout.hash == hashTx && txin.prevout.n == nOutput)
701                                                 fFound = true;
702                                         if (!fFound)
703                                         {
704                                             printf("LoadBlockIndex(): *** spending transaction of %s:%i does not spend it\n", hashTx.ToString().c_str(), nOutput);
705                                             pindexFork = pindex->pprev;
706                                         }
707                                     }
708                                 }
709                             }
710                             nOutput++;
711                         }
712                     }
713                 }
714                 // check level 5: check whether all prevouts are marked spent
715                 if (nCheckLevel>4)
716                 {
717                      BOOST_FOREACH(const CTxIn &txin, tx.vin)
718                      {
719                           CTxIndex txindex;
720                           if (ReadTxIndex(txin.prevout.hash, txindex))
721                               if (txindex.vSpent.size()-1 < txin.prevout.n || txindex.vSpent[txin.prevout.n].IsNull())
722                               {
723                                   printf("LoadBlockIndex(): *** found unspent prevout %s:%i in %s\n", txin.prevout.hash.ToString().c_str(), txin.prevout.n, hashTx.ToString().c_str());
724                                   pindexFork = pindex->pprev;
725                               }
726                      }
727                 }
728             }
729         }
730     }
731     if (pindexFork)
732     {
733         // Reorg back to the fork
734         printf("LoadBlockIndex() : *** moving best chain pointer back to block %d\n", pindexFork->nHeight);
735         CBlock block;
736         if (!block.ReadFromDisk(pindexFork))
737             return error("LoadBlockIndex() : block.ReadFromDisk failed");
738         CTxDB txdb;
739         block.SetBestChain(txdb, pindexFork);
740     }
741
742     return true;
743 }
744
745
746
747
748
749 //
750 // CAddrDB
751 //
752
753 bool CAddrDB::WriteAddrman(const CAddrMan& addrman)
754 {
755     return Write(string("addrman"), addrman);
756 }
757
758 bool CAddrDB::LoadAddresses()
759 {
760     if (Read(string("addrman"), addrman))
761     {
762         printf("Loaded %i addresses\n", addrman.size());
763         return true;
764     }
765     
766     // Read pre-0.6 addr records
767
768     vector<CAddress> vAddr;
769     vector<vector<unsigned char> > vDelete;
770
771     // Get cursor
772     Dbc* pcursor = GetCursor();
773     if (!pcursor)
774         return false;
775
776     loop
777     {
778         // Read next record
779         CDataStream ssKey(SER_DISK, CLIENT_VERSION);
780         CDataStream ssValue(SER_DISK, CLIENT_VERSION);
781         int ret = ReadAtCursor(pcursor, ssKey, ssValue);
782         if (ret == DB_NOTFOUND)
783             break;
784         else if (ret != 0)
785             return false;
786
787         // Unserialize
788         string strType;
789         ssKey >> strType;
790         if (strType == "addr")
791         {
792             CAddress addr;
793             ssValue >> addr;
794             vAddr.push_back(addr);
795         }
796     }
797     pcursor->close();
798
799     addrman.Add(vAddr, CNetAddr("0.0.0.0"));
800     printf("Loaded %i addresses\n", addrman.size());
801
802     // Note: old records left; we ran into hangs-on-startup
803     // bugs for some users who (we think) were running after
804     // an unclean shutdown.
805
806     return true;
807 }
808
809 bool LoadAddresses()
810 {
811     return CAddrDB("cr+").LoadAddresses();
812 }
813
814