#include "util.h"
#include "main.h"
#include "kernel.h"
-#include <boost/version.hpp>
+#include "ui_interface.h"
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
dbenv.set_cachesize(nDbCache / 1024, (nDbCache % 1024)*1048576, 1);
dbenv.set_lg_bsize(1048576);
dbenv.set_lg_max(10485760);
- dbenv.set_lk_max_locks(10000);
+
+ // Bugfix: Bump lk_max_locks default to 537000, to safely handle reorgs with up to 5 blocks reversed
+ // dbenv.set_lk_max_locks(10000);
+ dbenv.set_lk_max_locks(537000);
+
dbenv.set_lk_max_objects(10000);
dbenv.set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug
dbenv.set_flags(DB_AUTO_COMMIT, 1);
dbenv.set_flags(DB_TXN_WRITE_NOSYNC, 1);
-// dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1);
+#ifdef DB_LOG_AUTO_REMOVE
+ dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1);
+#endif
int ret = dbenv.open(strPath.c_str(),
DB_CREATE |
DB_INIT_LOCK |
fDbEnvInit = true;
fMockDb = false;
+
+ // Check that the number of locks is sufficient (to prevent chain fork possibility, read http://bitcoin.org/may15 for more info)
+ u_int32_t nMaxLocks;
+ if (!dbenv.get_lk_max_locks(&nMaxLocks))
+ {
+ int nBlocks, nDeepReorg;
+ std::string strMessage;
+
+ nBlocks = nMaxLocks / 48768;
+ nDeepReorg = (nBlocks - 1) / 2;
+
+ printf("Final lk_max_locks is %lu, sufficient for (worst case) %d block%s in a single transaction (up to a %d-deep reorganization)\n", (unsigned long)nMaxLocks, nBlocks, (nBlocks == 1) ? "" : "s", nDeepReorg);
+ if (nDeepReorg < 3)
+ {
+ if (nBlocks < 1)
+ strMessage = strprintf(_("Warning: DB_CONFIG has set_lk_max_locks %lu, which may be too low for a single block. If this limit is reached, NovaCoin may stop working."), (unsigned long)nMaxLocks);
+ else
+ strMessage = strprintf(_("Warning: DB_CONFIG has set_lk_max_locks %lu, which may be too low for a common blockchain reorganization. If this limit is reached, NovaCoin may stop working."), (unsigned long)nMaxLocks);
+
+ strMiscWarning = strMessage;
+ printf("*** %s\n", strMessage.c_str());
+ }
+ }
+
return true;
}
dbenv.set_lk_max_locks(10000);
dbenv.set_lk_max_objects(10000);
dbenv.set_flags(DB_AUTO_COMMIT, 1);
-// dbenv.log_set_config(DB_LOG_IN_MEMORY, 1);
+#ifdef DB_LOG_IN_MEMORY
+ dbenv.log_set_config(DB_LOG_IN_MEMORY, 1);
+#endif
int ret = dbenv.open(NULL,
DB_CREATE |
DB_INIT_LOCK |
if (fRequestShutdown)
return true;
- // Calculate bnChainTrust
+ // Calculate nChainTrust
vector<pair<int, CBlockIndex*> > vSortedByHeight;
vSortedByHeight.reserve(mapBlockIndex.size());
BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
{
CBlockIndex* pindex = item.second;
- pindex->bnChainTrust = (pindex->pprev ? pindex->pprev->bnChainTrust : 0) + pindex->GetBlockTrust();
+ pindex->nChainTrust = (pindex->pprev ? pindex->pprev->nChainTrust : 0) + pindex->GetBlockTrust();
// ppcoin: calculate stake modifier checksum
pindex->nStakeModifierChecksum = GetStakeModifierChecksum(pindex);
if (!CheckStakeModifierCheckpoints(pindex->nHeight, pindex->nStakeModifierChecksum))
return error("CTxDB::LoadBlockIndex() : hashBestChain not found in the block index");
pindexBest = mapBlockIndex[hashBestChain];
nBestHeight = pindexBest->nHeight;
- bnBestChainTrust = pindexBest->bnChainTrust;
+ nBestChainTrust = pindexBest->nChainTrust;
printf("LoadBlockIndex(): hashBestChain=%s height=%d trust=%s date=%s\n",
- hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainTrust.ToString().c_str(),
+ hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, CBigNum(nBestChainTrust).ToString().c_str(),
DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str());
// ppcoin: load hashSyncCheckpoint
printf("LoadBlockIndex(): synchronized checkpoint %s\n", Checkpoints::hashSyncCheckpoint.ToString().c_str());
// Load bnBestInvalidTrust, OK if it doesn't exist
+ CBigNum bnBestInvalidTrust;
ReadBestInvalidTrust(bnBestInvalidTrust);
+ nBestInvalidTrust = bnBestInvalidTrust.getuint256();
// Verify blocks in the best chain
int nCheckLevel = GetArg("-checklevel", 1);
if (!block.ReadFromDisk(pindex))
return error("LoadBlockIndex() : block.ReadFromDisk failed");
// check level 1: verify block validity
- if (nCheckLevel>0 && !block.CheckBlock())
+ // check level 7: verify block signature too
+ if (nCheckLevel>0 && !block.CheckBlock(true, true, (nCheckLevel>6)))
{
printf("LoadBlockIndex() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
pindexFork = pindex->pprev;
// Load mapBlockIndex
unsigned int fFlags = DB_SET_RANGE;
- loop
+ while (true)
{
// Read next record
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
// use file size to size memory buffer
int fileSize = GetFilesize(filein);
int dataSize = fileSize - sizeof(uint256);
+ //Don't try to resize to a negative number if file is small
+ if ( dataSize < 0 ) dataSize = 0;
vector<unsigned char> vchData;
vchData.resize(dataSize);
uint256 hashIn;