From d8f8063eda45b8dec864b28bb98839a2dd3a8170 Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 15 Jan 2014 00:18:47 +0400 Subject: [PATCH] Second pre-release update * Use maximum timeweight as a split/combine threshold (instead of age); * Remove BDB transactions index support, include some basic optimizations of leveldb wrapper; * --- novacoin-qt.pro | 54 ++---- src/checkpoints.cpp | 16 -- src/db.cpp | 25 --- src/init.cpp | 3 + src/kernel.cpp | 26 ++-- src/kernel.h | 3 + src/main.cpp | 37 ++--- src/makefile.bsd | 36 +---- src/makefile.linux-mingw | 23 +--- src/makefile.mingw | 25 +--- src/makefile.osx | 38 +---- src/makefile.unix | 35 +---- src/miner.cpp | 8 +- src/txdb-bdb.cpp | 426 ---------------------------------------------- src/txdb-bdb.h | 42 ----- src/txdb-leveldb.cpp | 37 ++--- src/txdb-leveldb.h | 2 + src/txdb.h | 13 -- src/version.h | 5 + src/wallet.cpp | 36 ++-- 20 files changed, 107 insertions(+), 783 deletions(-) delete mode 100644 src/txdb-bdb.cpp delete mode 100644 src/txdb-bdb.h diff --git a/novacoin-qt.pro b/novacoin-qt.pro index 386d1fd..a59787a 100644 --- a/novacoin-qt.pro +++ b/novacoin-qt.pro @@ -91,34 +91,26 @@ contains(BITCOIN_NEED_QT_PLUGINS, 1) { QTPLUGIN += qcncodecs qjpcodecs qtwcodecs qkrcodecs qtaccessiblewidgets } -contains(USE_LEVELDB, -) { - message(Building without LevelDB) - SOURCES += src/txdb-bdb.cpp +INCLUDEPATH += src/leveldb/include src/leveldb/helpers +LIBS += $$PWD/src/leveldb/libleveldb.a $$PWD/src/leveldb/libmemenv.a +SOURCES += src/txdb-leveldb.cpp +!win32 { + # we use QMAKE_CXXFLAGS_RELEASE even without RELEASE=1 because we use RELEASE to indicate linking preferences not -O preferences + genleveldb.commands = cd $$PWD/src/leveldb && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) OPT=\"$$QMAKE_CXXFLAGS $$QMAKE_CXXFLAGS_RELEASE\" libleveldb.a libmemenv.a } else { - message(Building with LevelDB) - DEFINES += USE_LEVELDB - - INCLUDEPATH += src/leveldb/include src/leveldb/helpers - LIBS += $$PWD/src/leveldb/libleveldb.a $$PWD/src/leveldb/libmemenv.a - SOURCES += src/txdb-leveldb.cpp - !win32 { - # we use QMAKE_CXXFLAGS_RELEASE even without RELEASE=1 because we use RELEASE to indicate linking preferences not -O preferences - genleveldb.commands = cd $$PWD/src/leveldb && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) OPT=\"$$QMAKE_CXXFLAGS $$QMAKE_CXXFLAGS_RELEASE\" libleveldb.a libmemenv.a - } else { - # make an educated guess about what the ranlib command is called - isEmpty(QMAKE_RANLIB) { - QMAKE_RANLIB = $$replace(QMAKE_STRIP, strip, ranlib) - } - LIBS += -lshlwapi - genleveldb.commands = cd $$PWD/src/leveldb && CC=$$QMAKE_CC CXX=$$QMAKE_CXX TARGET_OS=OS_WINDOWS_CROSSCOMPILE $(MAKE) OPT=\"$$QMAKE_CXXFLAGS $$QMAKE_CXXFLAGS_RELEASE\" libleveldb.a libmemenv.a && $$QMAKE_RANLIB $$PWD/src/leveldb/libleveldb.a && $$QMAKE_RANLIB $$PWD/src/leveldb/libmemenv.a + # make an educated guess about what the ranlib command is called + isEmpty(QMAKE_RANLIB) { + QMAKE_RANLIB = $$replace(QMAKE_STRIP, strip, ranlib) } - genleveldb.target = $$PWD/src/leveldb/libleveldb.a - genleveldb.depends = FORCE - PRE_TARGETDEPS += $$PWD/src/leveldb/libleveldb.a - QMAKE_EXTRA_TARGETS += genleveldb - # Gross ugly hack that depends on qmake internals, unfortunately there is no other way to do it. - QMAKE_CLEAN += $$PWD/src/leveldb/libleveldb.a; cd $$PWD/src/leveldb ; $(MAKE) clean + LIBS += -lshlwapi + genleveldb.commands = cd $$PWD/src/leveldb && CC=$$QMAKE_CC CXX=$$QMAKE_CXX TARGET_OS=OS_WINDOWS_CROSSCOMPILE $(MAKE) OPT=\"$$QMAKE_CXXFLAGS $$QMAKE_CXXFLAGS_RELEASE\" libleveldb.a libmemenv.a && $$QMAKE_RANLIB $$PWD/src/leveldb/libleveldb.a && $$QMAKE_RANLIB $$PWD/src/leveldb/libmemenv.a } +genleveldb.target = $$PWD/src/leveldb/libleveldb.a +genleveldb.depends = FORCE +PRE_TARGETDEPS += $$PWD/src/leveldb/libleveldb.a +QMAKE_EXTRA_TARGETS += genleveldb +# Gross ugly hack that depends on qmake internals, unfortunately there is no other way to do it. +QMAKE_CLEAN += $$PWD/src/leveldb/libleveldb.a; cd $$PWD/src/leveldb ; $(MAKE) clean # regenerate src/build.h !windows|contains(USE_BUILD_INFO, 1) { @@ -342,16 +334,6 @@ SOURCES += src/qt/qrcodedialog.cpp FORMS += src/qt/forms/qrcodedialog.ui } -contains(BITCOIN_QT_TEST, 1) { -SOURCES += src/qt/test/test_main.cpp \ - src/qt/test/uritests.cpp -HEADERS += src/qt/test/uritests.h -DEPENDPATH += src/qt/test -QT += testlib -TARGET = novacoin-qt_test -DEFINES += BITCOIN_QT_TEST -} - CODECFORTR = UTF-8 # for lrelease/lupdate @@ -373,7 +355,7 @@ QMAKE_EXTRA_COMPILERS += TSQM # "Other files" to show in Qt Creator OTHER_FILES += \ - doc/*.rst doc/*.txt doc/README README.md res/bitcoin-qt.rc src/test/*.cpp src/test/*.h src/qt/test/*.cpp src/qt/test/*.h + doc/*.rst doc/*.txt doc/README README.md res/bitcoin-qt.rc # platform specific defaults, if not overridden on command line isEmpty(BOOST_LIB_SUFFIX) { diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index a64243a..b986de8 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -164,10 +164,6 @@ namespace Checkpoints if (!txdb.TxnCommit()) return error("WriteSyncCheckpoint(): failed to commit to db sync checkpoint %s", hashCheckpoint.ToString().c_str()); -#ifndef USE_LEVELDB - txdb.Close(); -#endif - Checkpoints::hashSyncCheckpoint = hashCheckpoint; return true; } @@ -198,9 +194,6 @@ namespace Checkpoints } } -#ifndef USE_LEVELDB - txdb.Close(); -#endif if (!WriteSyncCheckpoint(hashPendingCheckpoint)) return error("AcceptPendingSyncCheckpoint(): failed to write sync checkpoint %s", hashPendingCheckpoint.ToString().c_str()); hashPendingCheckpoint = 0; @@ -286,11 +279,6 @@ namespace Checkpoints { return error("ResetSyncCheckpoint: SetBestChain failed for hardened checkpoint %s", hash.ToString().c_str()); } - -#ifndef USE_LEVELDB - txdb.Close(); -#endif - } else if(!mapBlockIndex.count(hash)) { @@ -457,10 +445,6 @@ bool CSyncCheckpoint::ProcessSyncCheckpoint(CNode* pfrom) } } -#ifndef USE_LEVELDB - txdb.Close(); -#endif - if (!Checkpoints::WriteSyncCheckpoint(hashCheckpoint)) return error("ProcessSyncCheckpoint(): failed to write sync checkpoint %s", hashCheckpoint.ToString().c_str()); Checkpoints::checkpointMessage = *this; diff --git a/src/db.cpp b/src/db.cpp index 0a8c8be..cc069e1 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -111,31 +111,6 @@ bool CDBEnv::Open(boost::filesystem::path pathEnv_) fDbEnvInit = true; fMockDb = false; -#ifndef USE_LEVELDB - // 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()); - } - } -#endif - return true; } diff --git a/src/init.cpp b/src/init.cpp index f406c76..4c88efd 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -31,7 +31,9 @@ CClientUIInterface uiInterface; std::string strWalletFileName; unsigned int nNodeLifespan; unsigned int nDerivationMethodIndex; +unsigned int nMinerSleep; bool fUseFastIndex; +bool fUseFastStakeMiner; enum Checkpoints::CPMode CheckpointsMode; ////////////////////////////////////////////////////////////////////////////// @@ -360,6 +362,7 @@ bool AppInit2() nNodeLifespan = GetArg("-addrlifespan", 7); fUseFastIndex = GetBoolArg("-fastindex", true); + nMinerSleep = GetArg("-minersleep", 500); CheckpointsMode = Checkpoints::STRICT; std::string strCpMode = GetArg("-cppolicy", "strict"); diff --git a/src/kernel.cpp b/src/kernel.cpp index 959bd10..5a8d3d6 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -31,6 +31,18 @@ static std::map mapStakeModifierCheckpointsTestNet = ( 0, 0x0e00670bu ) ; +// Get time weight +int64 GetWeight(int64 nIntervalBeginning, int64 nIntervalEnd) +{ + // Kernel hash weight starts from 0 at the 30-day min age + // this change increases active coins participating the hash and helps + // to secure the network when proof-of-stake difficulty is low + // + // Maximum TimeWeight is 90 days. + + return min(nIntervalEnd - nIntervalBeginning - nStakeMinAge, (int64)nStakeMaxAge); +} + // Get the last stake modifier and its generation time from a given block static bool GetLastStakeModifier(const CBlockIndex* pindex, uint64& nStakeModifier, int64& nModifierTime) { @@ -275,17 +287,9 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned bnTargetPerCoinDay.SetCompact(nBits); int64 nValueIn = txPrev.vout[prevout.n].nValue; - int64 nTimeWeight; uint256 hashBlockFrom = blockFrom.GetHash(); - // Kernel hash weight starts from 0 at the 30-day min age - // this change increases active coins participating the hash and helps - // to secure the network when proof-of-stake difficulty is low - // - // Maximum TimeWeight is 90 days. - nTimeWeight = min((int64)nTimeTx - txPrev.nTime - nStakeMinAge, (int64)nStakeMaxAge); - - CBigNum bnCoinDayWeight = CBigNum(nValueIn) * nTimeWeight / COIN / (24 * 60 * 60); + CBigNum bnCoinDayWeight = CBigNum(nValueIn) * GetWeight((int64)txPrev.nTime, (int64)nTimeTx) / COIN / (24 * 60 * 60); targetProofOfStake = (bnCoinDayWeight * bnTargetPerCoinDay).getuint256(); // Calculate hash @@ -347,10 +351,6 @@ bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hash if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex)) return tx.DoS(1, error("CheckProofOfStake() : INFO: read txPrev failed")); // previous transaction not in main chain, may occur during initial download -#ifndef USE_LEVELDB - txdb.Close(); -#endif - // Verify signature if (!VerifySignature(txPrev, tx, 0, true, 0)) return tx.DoS(100, error("CheckProofOfStake() : VerifySignature failed on coinstake %s", tx.GetHash().ToString().c_str())); diff --git a/src/kernel.h b/src/kernel.h index d657ad5..dc2fbb0 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -33,4 +33,7 @@ unsigned int GetStakeModifierChecksum(const CBlockIndex* pindex); // Check stake modifier hard checkpoints bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierChecksum); +// Get time weight using supplied timestamps +int64 GetWeight(int64 nIntervalBeginning, int64 nIntervalEnd); + #endif // PPCOIN_KERNEL_H diff --git a/src/main.cpp b/src/main.cpp index c830a8f..ca9351f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,8 +44,8 @@ uint256 nPoWBase = uint256("0x00000000ffff00000000000000000000000000000000000000 CBigNum bnProofOfWorkLimitTestNet(~uint256(0) >> 16); -unsigned int nStakeMinAge = 60 * 60 * 24 * 30; // 30 days as minimum age for coin age -unsigned int nStakeMaxAge = 60 * 60 * 24 * 90; // 90 days as stake age of full weight +unsigned int nStakeMinAge = 60 * 60 * 24 * 30; // 30 days as zero time weight +unsigned int nStakeMaxAge = 60 * 60 * 24 * 90; // 90 days as full weight unsigned int nStakeTargetSpacing = 10 * 60; // 10-minute stakes spacing unsigned int nModifierInterval = 6 * 60 * 60; // time to elapse before new modifier is computed @@ -2701,10 +2701,9 @@ bool LoadBlockIndex(bool fAllowNew) // // Load block index // - CTxDB txdb("cr"); + CTxDB txdb("cr+"); if (!txdb.LoadBlockIndex()) return false; - txdb.Close(); // // Init with genesis block @@ -2767,25 +2766,19 @@ bool LoadBlockIndex(bool fAllowNew) return error("LoadBlockIndex() : failed to init sync checkpoint"); } - // ppcoin: if checkpoint master key changed must reset sync-checkpoint - { - CTxDB txdb; - string strPubKey = ""; - if (!txdb.ReadCheckpointPubKey(strPubKey) || strPubKey != CSyncCheckpoint::strMasterPubKey) - { - // write checkpoint master key to db - txdb.TxnBegin(); - if (!txdb.WriteCheckpointPubKey(CSyncCheckpoint::strMasterPubKey)) - return error("LoadBlockIndex() : failed to write new checkpoint master key to db"); - if (!txdb.TxnCommit()) - return error("LoadBlockIndex() : failed to commit new checkpoint master key to db"); - if ((!fTestNet) && !Checkpoints::ResetSyncCheckpoint()) - return error("LoadBlockIndex() : failed to reset sync-checkpoint"); - } -#ifndef USE_LEVELDB - txdb.Close(); -#endif + string strPubKey = ""; + // if checkpoint master key changed must reset sync-checkpoint + if (!txdb.ReadCheckpointPubKey(strPubKey) || strPubKey != CSyncCheckpoint::strMasterPubKey) + { + // write checkpoint master key to db + txdb.TxnBegin(); + if (!txdb.WriteCheckpointPubKey(CSyncCheckpoint::strMasterPubKey)) + return error("LoadBlockIndex() : failed to write new checkpoint master key to db"); + if (!txdb.TxnCommit()) + return error("LoadBlockIndex() : failed to commit new checkpoint master key to db"); + if ((!fTestNet) && !Checkpoints::ResetSyncCheckpoint()) + return error("LoadBlockIndex() : failed to reset sync-checkpoint"); } return true; diff --git a/src/makefile.bsd b/src/makefile.bsd index 550fa73..d8fccd0 100644 --- a/src/makefile.bsd +++ b/src/makefile.bsd @@ -4,7 +4,6 @@ USE_UPNP:=0 USE_IPV6:=1 -USE_LEVELDB:=1 LINK:=$(CXX) @@ -13,8 +12,6 @@ DEFS=-DBOOST_SPIRIT_THREADSAFE DEFS += $(addprefix -I,$(CURDIR) $(CURDIR)/obj $(BOOST_INCLUDE_PATH) $(BDB_INCLUDE_PATH) $(OPENSSL_INCLUDE_PATH)) LIBS = $(addprefix -L,$(BOOST_LIB_PATH) $(BDB_LIB_PATH) $(OPENSSL_LIB_PATH)) -TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data) - LMODE = dynamic LMODE2 = dynamic ifdef STATIC @@ -22,8 +19,6 @@ ifdef STATIC ifeq (${STATIC}, all) LMODE2 = static endif -else - TESTDEFS += -DBOOST_TEST_DYN_LINK endif # for boost 1.37, add -mt to the boost libraries @@ -148,31 +143,18 @@ OBJS= \ obj/zerocoin/SpendMetaData.o \ obj/zerocoin/ZeroTest.o - all: novacoind -# -# LevelDB support -# -ifeq (${USE_LEVELDB}, 1) LIBS += $(CURDIR)/leveldb/libleveldb.a $(CURDIR)/leveldb/libmemenv.a -DEFS += $(addprefix -I,$(CURDIR)/leveldb/include) -DUSE_LEVELDB +DEFS += $(addprefix -I,$(CURDIR)/leveldb/include) DEFS += $(addprefix -I,$(CURDIR)/leveldb/helpers) OBJS += obj/txdb-leveldb.o leveldb/libleveldb.a: @echo "Building LevelDB ..."; cd leveldb; make libleveldb.a libmemenv.a; cd ..; obj/txdb-leveldb.o: leveldb/libleveldb.a -endif -ifneq (${USE_LEVELDB}, 1) -OBJS += obj/txdb-bdb.o -endif - -test check: test_novacoin FORCE - ./test_novacoin # auto-generated dependencies: -include obj/*.P --include obj-test/*.P obj/build.h: FORCE /bin/sh ../share/genbuild.sh obj/build.h @@ -205,26 +187,12 @@ obj/zerocoin/%.o: zerocoin/%.cpp novacoind: $(OBJS:obj/%=obj/%) $(LINK) $(xCXXFLAGS) -o $@ $^ $(xLDFLAGS) $(LIBS) -TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) - -obj-test/%.o: test/%.cpp - $(CXX) -c $(TESTDEFS) $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< - @cp $(@:%.o=%.d) $(@:%.o=%.P); \ - sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ - -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ - rm -f $(@:%.o=%.d) - -test_novacoin: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) - $(LINK) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ -Wl,-B$(LMODE) -lboost_unit_test_framework $(xLDFLAGS) $(LIBS) - clean: - -rm -f novacoind test_novacoin + -rm -f novacoind -rm -f obj/*.o -rm -f obj/zerocoin/*.o - -rm -f obj-test/*.o -rm -f obj/*.P -rm -f obj/zerocoin/*.P - -rm -f obj-test/*.P -rm -f obj/build.h FORCE: diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw index 5ff4cf3..1edf3b8 100644 --- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -13,7 +13,6 @@ STRIP=$(TARGET_PLATFORM)-w64-mingw32-strip USE_UPNP:=0 USE_IPV6:=1 -USE_LEVELDB:=1 INCLUDEPATHS= \ -I"$(CURDIR)" \ @@ -43,8 +42,6 @@ DEBUGFLAGS=-g CFLAGS=-O3 -msse2 -w -Wall -Wextra -Wno-ignored-qualifiers -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat -static-libgcc -static-libstdc++ -TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data) - ifndef USE_UPNP override USE_UPNP = - endif @@ -110,20 +107,13 @@ OBJS= \ all: novacoind.exe -# -# LevelDB support -# -ifeq (${USE_LEVELDB}, 1) LIBS += $(CURDIR)/leveldb/libleveldb.a $(CURDIR)/leveldb/libmemenv.a -DEFS += -I"$(CURDIR)/leveldb/include" -DUSE_LEVELDB +DEFS += -I"$(CURDIR)/leveldb/include" DEFS += -I"$(CURDIR)/leveldb/helpers" OBJS += obj/txdb-leveldb.o leveldb/libleveldb.a: @echo "Building LevelDB ..." && cd leveldb && CC=$(CC) CXX=$(CXX) TARGET_OS=OS_WINDOWS_CROSSCOMPILE CXXFLAGS="-I$(INCLUDEPATHS)" LDFLAGS="-L$(LIBPATHS)" $(MAKE) libleveldb.a libmemenv.a && $(RANLIB) libleveldb.a && $(RANLIB) libmemenv.a && cd .. obj/txdb-leveldb.o: leveldb/libleveldb.a -else -OBJS += obj/txdb-bdb.o -endif obj/build.h: FORCE /bin/sh ../share/genbuild.sh obj/build.h @@ -140,15 +130,6 @@ novacoind.exe: $(OBJS:obj/%=obj/%) $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) -lshlwapi $(STRIP) novacoind.exe -TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) - -obj-test/%.o: test/%.cpp $(HEADERS) - $(CXX) -c $(TESTDEFS) $(CFLAGS) -o $@ $< - -test_novacoin.exe: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) - $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework-mt-s $(LIBS) - $(STRIP) test_novacoin.exe - obj/scrypt-x86.o: scrypt-x86.S $(CXX) -c $(CFLAGS) -MMD -o $@ $< @@ -159,8 +140,6 @@ clean: -rm -f obj/*.o -rm -f obj/zerocoin/*.o -rm -f novacoind.exe - -rm -f obj-test/*.o - -rm -f test_novacoin.exe -rm -f obj/build.h cd leveldb && TARGET_OS=OS_WINDOWS_CROSSCOMPILE $(MAKE) clean && cd .. diff --git a/src/makefile.mingw b/src/makefile.mingw index 29f5270..6802420 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -4,7 +4,6 @@ USE_UPNP:=0 USE_IPV6:=1 -USE_LEVELDB:=1 INCLUDEPATHS= \ -I"C:\boost-1.50.0-mgw" \ @@ -99,24 +98,13 @@ OBJS= \ all: novacoind.exe -# -# LevelDB support -# -ifneq (${USE_LEVELDB}, -) LIBS += $(CURDIR)/leveldb/libleveldb.a $(CURDIR)/leveldb/libmemenv.a -DEFS += $(addprefix -I,$(CURDIR)/leveldb/include) -DUSE_LEVELDB +DEFS += $(addprefix -I,$(CURDIR)/leveldb/include) DEFS += $(addprefix -I,$(CURDIR)/leveldb/helpers) OBJS += obj/txdb-leveldb.o leveldb/libleveldb.a: cd leveldb; make; cd .. obj/txdb-leveldb.o: leveldb/libleveldb.lib -else -OBJS += obj/txdb-bdb.o -endif - - -test check: test_novacoin.exe FORCE - test_novacoin.exe obj/%.o: %.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< @@ -133,18 +121,9 @@ obj/scrypt-x86_64.o: scrypt-x86_64.S novacoind.exe: $(OBJS:obj/%=obj/%) g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) -TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) - -obj-test/%.o: test/%.cpp $(HEADERS) - g++ -c $(TESTDEFS) $(CFLAGS) -o $@ $< - -test_bitcoin.exe: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) - g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework $(LIBS) - clean: - -del /Q novacoind test_novacoin + -del /Q novacoind -del /Q obj\* -del /Q obj\zerocoin\* - -del /Q obj-test\* FORCE: diff --git a/src/makefile.osx b/src/makefile.osx index c62afb1..abead78 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -21,16 +21,11 @@ LIBPATHS= \ USE_UPNP:=1 USE_IPV6:=1 -USE_LEVELDB:=1 LIBS= -dead_strip -TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data) - ifdef STATIC # Build STATIC if you are redistributing the bitcoind binary -TESTLIBS += \ - $(DEPSDIR)/lib/libboost_unit_test_framework-mt.a LIBS += \ $(DEPSDIR)/lib/db48/libdb_cxx-4.8.a \ $(DEPSDIR)/lib/libboost_system-mt.a \ @@ -41,8 +36,6 @@ LIBS += \ $(DEPSDIR)/lib/libcrypto.a \ -lz else -TESTLIBS += \ - -lboost_unit_test_framework-mt LIBS += \ -ldb_cxx-4.8 \ -lboost_system-mt \ @@ -52,7 +45,6 @@ LIBS += \ -lssl \ -lcrypto \ -lz -TESTDEFS += -DBOOST_TEST_DYN_LINK endif DEFS=-DMAC_OSX -DMSG_NOSIGNAL=0 -DBOOST_SPIRIT_THREADSAFE @@ -133,28 +125,16 @@ endif all: novacoind -# -# LevelDB support -# -ifdef USE_LEVELDB LIBS += $(CURDIR)/leveldb/libleveldb.a $(CURDIR)/leveldb/libmemenv.a -DEFS += $(addprefix -I,$(CURDIR)/leveldb/include) -DUSE_LEVELDB +DEFS += $(addprefix -I,$(CURDIR)/leveldb/include) DEFS += $(addprefix -I,$(CURDIR)/leveldb/helpers) OBJS += obj/txdb-leveldb.o leveldb/libleveldb.a: @echo "Building LevelDB ..."; cd leveldb; make; cd .. obj/txdb-leveldb.o: leveldb/libleveldb.a -else -OBJS += obj/txdb-bdb.o -endif - - -test check: test_novacoin FORCE - ./test_novacoin # auto-generated dependencies: -include obj/*.P --include obj-test/*.P obj/build.h: FORCE /bin/sh ../share/genbuild.sh obj/build.h @@ -184,26 +164,12 @@ obj/scrypt-x86_64.o: scrypt-x86_64.S novacoind: $(OBJS:obj/%=obj/%) $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) -TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) - -obj-test/%.o: test/%.cpp - $(CXX) -c $(TESTDEFS) $(CFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< - @cp $(@:%.o=%.d) $(@:%.o=%.P); \ - sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ - -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ - rm -f $(@:%.o=%.d) - -test_novacoin: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) - $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) $(TESTLIBS) - clean: - -rm -f novacoind test_novacoin + -rm -f novacoind -rm -f obj/*.o -rm -f obj/zerocoin/*.o - -rm -f obj-test/*.o -rm -f obj/*.P -rm -f obj/zerocoin/*.P - -rm -f obj-test/*.P -rm -f obj/build.h FORCE: diff --git a/src/makefile.unix b/src/makefile.unix index d36d65a..85a2f43 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -4,7 +4,6 @@ USE_UPNP:=0 USE_IPV6:=1 -USE_LEVELDB:=1 LINK:=$(CXX) ARCH:=$(system lscpu | head -n 1 | awk '{print $2}') @@ -14,8 +13,6 @@ DEFS=-DBOOST_SPIRIT_THREADSAFE DEFS += $(addprefix -I,$(CURDIR) $(CURDIR)/obj $(BOOST_INCLUDE_PATH) $(BDB_INCLUDE_PATH) $(OPENSSL_INCLUDE_PATH)) LIBS = $(addprefix -L,$(BOOST_LIB_PATH) $(BDB_LIB_PATH) $(OPENSSL_LIB_PATH)) -TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data) - LMODE = dynamic LMODE2 = dynamic ifdef STATIC @@ -23,8 +20,6 @@ ifdef STATIC ifeq (${STATIC}, all) LMODE2 = static endif -else - TESTDEFS += -DBOOST_TEST_DYN_LINK endif # for boost 1.37, add -mt to the boost libraries @@ -156,28 +151,16 @@ OBJS= \ all: novacoind -# -# LevelDB support -# -ifeq (${USE_LEVELDB}, 1) LIBS += $(CURDIR)/leveldb/libleveldb.a $(CURDIR)/leveldb/libmemenv.a -DEFS += $(addprefix -I,$(CURDIR)/leveldb/include) -DUSE_LEVELDB +DEFS += $(addprefix -I,$(CURDIR)/leveldb/include) DEFS += $(addprefix -I,$(CURDIR)/leveldb/helpers) OBJS += obj/txdb-leveldb.o leveldb/libleveldb.a: @echo "Building LevelDB ..."; cd leveldb; make libleveldb.a libmemenv.a; cd ..; obj/txdb-leveldb.o: leveldb/libleveldb.a -endif -ifneq (${USE_LEVELDB}, 1) -OBJS += obj/txdb-bdb.o -endif - -test check: test_novacoin FORCE - ./test_novacoin # auto-generated dependencies: -include obj/*.P --include obj-test/*.P obj/build.h: FORCE /bin/sh ../share/genbuild.sh obj/build.h @@ -210,26 +193,12 @@ obj/zerocoin/%.o: zerocoin/%.cpp novacoind: $(OBJS:obj/%=obj/%) $(LINK) $(xCXXFLAGS) -o $@ $^ $(xLDFLAGS) $(LIBS) -TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) - -obj-test/%.o: test/%.cpp - $(CXX) -c $(TESTDEFS) $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< - @cp $(@:%.o=%.d) $(@:%.o=%.P); \ - sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ - -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ - rm -f $(@:%.o=%.d) - -test_novacoin: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) - $(LINK) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ -Wl,-B$(LMODE) -lboost_unit_test_framework $(xLDFLAGS) $(LIBS) - clean: - -rm -f novacoind test_novacoin + -rm -f novacoind -rm -f obj/*.o -rm -f obj/zerocoin/*.o - -rm -f obj-test/*.o -rm -f obj/*.P -rm -f obj/zerocoin/*.P - -rm -f obj-test/*.P -rm -f obj/build.h FORCE: diff --git a/src/miner.cpp b/src/miner.cpp index 3b54b96..92ade15 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -15,9 +15,11 @@ using namespace std; // BitcoinMiner // -string strMintMessage = "Info: Minting suspended due to locked wallet."; +string strMintMessage = "Info: Mining suspended due to locked wallet."; string strMintWarning; +extern unsigned int nMinerSleep; + int static FormatHashBlocks(void* pbuffer, unsigned int len) { unsigned char* pdata = (unsigned char*)pbuffer; @@ -558,9 +560,11 @@ void StakeMiner(CWallet *pwallet) SetThreadPriority(THREAD_PRIORITY_NORMAL); CheckStake(pblock.get(), *pwallet); SetThreadPriority(THREAD_PRIORITY_LOWEST); + Sleep(500); } + else + Sleep(nMinerSleep); - Sleep(500); continue; } } diff --git a/src/txdb-bdb.cpp b/src/txdb-bdb.cpp deleted file mode 100644 index d9ed8da..0000000 --- a/src/txdb-bdb.cpp +++ /dev/null @@ -1,426 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "db.h" -#include "kernel.h" -#include "checkpoints.h" -#include "txdb-bdb.h" -#include "util.h" -#include "main.h" -#include -#include -#include - -#ifndef WIN32 -#include "sys/stat.h" -#endif - -using namespace std; -using namespace boost; - -void MakeMockTXDB() { - // In practice this won't do anything because the test framework always initializes - // an in-memory BDB via bitdb.MakeMock() first, as we use BDB for addresses and wallets. - if (!bitdb.IsMock()) - bitdb.MakeMock(); -} - -// -// CTxDB -// - -bool CTxDB::ReadTxIndex(uint256 hash, CTxIndex& txindex) -{ - assert(!fClient); - txindex.SetNull(); - return Read(make_pair(string("tx"), hash), txindex); -} - -bool CTxDB::UpdateTxIndex(uint256 hash, const CTxIndex& txindex) -{ - assert(!fClient); - return Write(make_pair(string("tx"), hash), txindex); -} - -bool CTxDB::AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight) -{ - assert(!fClient); - - // Add to tx index - uint256 hash = tx.GetHash(); - CTxIndex txindex(pos, tx.vout.size()); - return Write(make_pair(string("tx"), hash), txindex); -} - -bool CTxDB::EraseTxIndex(const CTransaction& tx) -{ - assert(!fClient); - uint256 hash = tx.GetHash(); - - return Erase(make_pair(string("tx"), hash)); -} - -bool CTxDB::ContainsTx(uint256 hash) -{ - assert(!fClient); - return Exists(make_pair(string("tx"), hash)); -} - -bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex) -{ - assert(!fClient); - tx.SetNull(); - if (!ReadTxIndex(hash, txindex)) - return false; - return (tx.ReadFromDisk(txindex.pos)); -} - -bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx) -{ - CTxIndex txindex; - return ReadDiskTx(hash, tx, txindex); -} - -bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex) -{ - return ReadDiskTx(outpoint.hash, tx, txindex); -} - -bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx) -{ - CTxIndex txindex; - return ReadDiskTx(outpoint.hash, tx, txindex); -} - -bool CTxDB::WriteBlockIndex(const CDiskBlockIndex& blockindex) -{ - return Write(make_pair(string("blockindex"), blockindex.GetBlockHash()), blockindex); -} - -bool CTxDB::ReadHashBestChain(uint256& hashBestChain) -{ - return Read(string("hashBestChain"), hashBestChain); -} - -bool CTxDB::WriteHashBestChain(uint256 hashBestChain) -{ - return Write(string("hashBestChain"), hashBestChain); -} - -bool CTxDB::ReadBestInvalidTrust(CBigNum& bnBestInvalidTrust) -{ - return Read(string("bnBestInvalidTrust"), bnBestInvalidTrust); -} - -bool CTxDB::WriteBestInvalidTrust(CBigNum bnBestInvalidTrust) -{ - return Write(string("bnBestInvalidTrust"), bnBestInvalidTrust); -} - -bool CTxDB::ReadSyncCheckpoint(uint256& hashCheckpoint) -{ - return Read(string("hashSyncCheckpoint"), hashCheckpoint); -} - -bool CTxDB::WriteSyncCheckpoint(uint256 hashCheckpoint) -{ - return Write(string("hashSyncCheckpoint"), hashCheckpoint); -} - -bool CTxDB::ReadCheckpointPubKey(string& strPubKey) -{ - return Read(string("strCheckpointPubKey"), strPubKey); -} - -bool CTxDB::WriteCheckpointPubKey(const string& strPubKey) -{ - return Write(string("strCheckpointPubKey"), strPubKey); -} - -CBlockIndex static * InsertBlockIndex(uint256 hash) -{ - if (hash == 0) - return NULL; - - // Return existing - map::iterator mi = mapBlockIndex.find(hash); - if (mi != mapBlockIndex.end()) - return (*mi).second; - - // Create new - CBlockIndex* pindexNew = new CBlockIndex(); - if (!pindexNew) - throw runtime_error("LoadBlockIndex() : new CBlockIndex failed"); - mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; - pindexNew->phashBlock = &((*mi).first); - - return pindexNew; -} - -bool CTxDB::LoadBlockIndex() -{ - if (!LoadBlockIndexGuts()) - return false; - - if (fRequestShutdown) - return true; - - // Calculate nChainTrust - vector > vSortedByHeight; - vSortedByHeight.reserve(mapBlockIndex.size()); - BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) - { - CBlockIndex* pindex = item.second; - vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex)); - } - sort(vSortedByHeight.begin(), vSortedByHeight.end()); - BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight) - { - CBlockIndex* pindex = item.second; - 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() : Failed stake modifier checkpoint height=%d, modifier=0x%016"PRI64x, pindex->nHeight, pindex->nStakeModifier); - } - - // Load hashBestChain pointer to end of best chain - if (!ReadHashBestChain(hashBestChain)) - { - if (pindexGenesisBlock == NULL) - return true; - return error("CTxDB::LoadBlockIndex() : hashBestChain not loaded"); - } - if (!mapBlockIndex.count(hashBestChain)) - return error("CTxDB::LoadBlockIndex() : hashBestChain not found in the block index"); - pindexBest = mapBlockIndex[hashBestChain]; - nBestHeight = pindexBest->nHeight; - nBestChainTrust = pindexBest->nChainTrust; - printf("LoadBlockIndex(): hashBestChain=%s height=%d trust=%s date=%s\n", - 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 - if (!ReadSyncCheckpoint(Checkpoints::hashSyncCheckpoint)) - return error("CTxDB::LoadBlockIndex() : hashSyncCheckpoint not loaded"); - 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); - int nCheckDepth = GetArg( "-checkblocks", 2500); - if (nCheckDepth == 0) - nCheckDepth = 1000000000; // suffices until the year 19000 - if (nCheckDepth > nBestHeight) - nCheckDepth = nBestHeight; - printf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel); - CBlockIndex* pindexFork = NULL; - map, CBlockIndex*> mapBlockPos; - for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev) - { - if (fRequestShutdown || pindex->nHeight < nBestHeight-nCheckDepth) - break; - CBlock block; - if (!block.ReadFromDisk(pindex)) - return error("LoadBlockIndex() : block.ReadFromDisk failed"); - // check level 1: verify block validity - // 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; - } - // check level 2: verify transaction index validity - if (nCheckLevel>1) - { - pair pos = make_pair(pindex->nFile, pindex->nBlockPos); - mapBlockPos[pos] = pindex; - BOOST_FOREACH(const CTransaction &tx, block.vtx) - { - uint256 hashTx = tx.GetHash(); - CTxIndex txindex; - if (ReadTxIndex(hashTx, txindex)) - { - // check level 3: checker transaction hashes - if (nCheckLevel>2 || pindex->nFile != txindex.pos.nFile || pindex->nBlockPos != txindex.pos.nBlockPos) - { - // either an error or a duplicate transaction - CTransaction txFound; - if (!txFound.ReadFromDisk(txindex.pos)) - { - printf("LoadBlockIndex() : *** cannot read mislocated transaction %s\n", hashTx.ToString().c_str()); - pindexFork = pindex->pprev; - } - else - if (txFound.GetHash() != hashTx) // not a duplicate tx - { - printf("LoadBlockIndex(): *** invalid tx position for %s\n", hashTx.ToString().c_str()); - pindexFork = pindex->pprev; - } - } - // check level 4: check whether spent txouts were spent within the main chain - unsigned int nOutput = 0; - if (nCheckLevel>3) - { - BOOST_FOREACH(const CDiskTxPos &txpos, txindex.vSpent) - { - if (!txpos.IsNull()) - { - pair posFind = make_pair(txpos.nFile, txpos.nBlockPos); - if (!mapBlockPos.count(posFind)) - { - printf("LoadBlockIndex(): *** found bad spend at %d, hashBlock=%s, hashTx=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str(), hashTx.ToString().c_str()); - pindexFork = pindex->pprev; - } - // check level 6: check whether spent txouts were spent by a valid transaction that consume them - if (nCheckLevel>5) - { - CTransaction txSpend; - if (!txSpend.ReadFromDisk(txpos)) - { - printf("LoadBlockIndex(): *** cannot read spending transaction of %s:%i from disk\n", hashTx.ToString().c_str(), nOutput); - pindexFork = pindex->pprev; - } - else if (!txSpend.CheckTransaction()) - { - printf("LoadBlockIndex(): *** spending transaction of %s:%i is invalid\n", hashTx.ToString().c_str(), nOutput); - pindexFork = pindex->pprev; - } - else - { - bool fFound = false; - BOOST_FOREACH(const CTxIn &txin, txSpend.vin) - if (txin.prevout.hash == hashTx && txin.prevout.n == nOutput) - fFound = true; - if (!fFound) - { - printf("LoadBlockIndex(): *** spending transaction of %s:%i does not spend it\n", hashTx.ToString().c_str(), nOutput); - pindexFork = pindex->pprev; - } - } - } - } - nOutput++; - } - } - } - // check level 5: check whether all prevouts are marked spent - if (nCheckLevel>4) - { - BOOST_FOREACH(const CTxIn &txin, tx.vin) - { - CTxIndex txindex; - if (ReadTxIndex(txin.prevout.hash, txindex)) - if (txindex.vSpent.size()-1 < txin.prevout.n || txindex.vSpent[txin.prevout.n].IsNull()) - { - printf("LoadBlockIndex(): *** found unspent prevout %s:%i in %s\n", txin.prevout.hash.ToString().c_str(), txin.prevout.n, hashTx.ToString().c_str()); - pindexFork = pindex->pprev; - } - } - } - } - } - } - if (pindexFork && !fRequestShutdown) - { - // Reorg back to the fork - printf("LoadBlockIndex() : *** moving best chain pointer back to block %d\n", pindexFork->nHeight); - CBlock block; - if (!block.ReadFromDisk(pindexFork)) - return error("LoadBlockIndex() : block.ReadFromDisk failed"); - CTxDB txdb; - block.SetBestChain(txdb, pindexFork); - } - - return true; -} - - - -bool CTxDB::LoadBlockIndexGuts() -{ - // Get database cursor - Dbc* pcursor = GetCursor(); - if (!pcursor) - return false; - - // Load mapBlockIndex - unsigned int fFlags = DB_SET_RANGE; - while (true) - { - // Read next record - CDataStream ssKey(SER_DISK, CLIENT_VERSION); - if (fFlags == DB_SET_RANGE) - ssKey << make_pair(string("blockindex"), uint256(0)); - CDataStream ssValue(SER_DISK, CLIENT_VERSION); - int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); - fFlags = DB_NEXT; - if (ret == DB_NOTFOUND) - break; - else if (ret != 0) - return false; - - // Unserialize - - try { - string strType; - ssKey >> strType; - if (strType == "blockindex" && !fRequestShutdown) - { - CDiskBlockIndex diskindex; - ssValue >> diskindex; - - uint256 blockHash = diskindex.GetBlockHash(); - - // Construct block index object - CBlockIndex* pindexNew = InsertBlockIndex(blockHash); - pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); - pindexNew->pnext = InsertBlockIndex(diskindex.hashNext); - pindexNew->nFile = diskindex.nFile; - pindexNew->nBlockPos = diskindex.nBlockPos; - pindexNew->nHeight = diskindex.nHeight; - pindexNew->nMint = diskindex.nMint; - pindexNew->nMoneySupply = diskindex.nMoneySupply; - pindexNew->nFlags = diskindex.nFlags; - pindexNew->nStakeModifier = diskindex.nStakeModifier; - pindexNew->prevoutStake = diskindex.prevoutStake; - pindexNew->nStakeTime = diskindex.nStakeTime; - pindexNew->hashProofOfStake = diskindex.hashProofOfStake; - pindexNew->nVersion = diskindex.nVersion; - pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; - pindexNew->nTime = diskindex.nTime; - pindexNew->nBits = diskindex.nBits; - pindexNew->nNonce = diskindex.nNonce; - - // Watch for genesis block - if (pindexGenesisBlock == NULL && blockHash == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)) - pindexGenesisBlock = pindexNew; - - if (!pindexNew->CheckIndex()) - return error("LoadBlockIndex() : CheckIndex failed at %d", pindexNew->nHeight); - - // ppcoin: build setStakeSeen - if (pindexNew->IsProofOfStake()) - setStakeSeen.insert(make_pair(pindexNew->prevoutStake, pindexNew->nStakeTime)); - } - else - { - break; // if shutdown requested or finished loading block index - } - } // try - catch (std::exception &e) { - return error("%s() : deserialize error", __PRETTY_FUNCTION__); - } - } - pcursor->close(); - - return true; -} - - diff --git a/src/txdb-bdb.h b/src/txdb-bdb.h deleted file mode 100644 index 15917c6..0000000 --- a/src/txdb-bdb.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_TXDB_BDB_H -#define BITCOIN_TXDB_BDB_H - - -/** Access to the transaction database (blkindex.dat) */ -class CTxDB : public CDB -{ -public: - CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { } -private: - CTxDB(const CTxDB&); - void operator=(const CTxDB&); -public: - bool ReadTxIndex(uint256 hash, CTxIndex& txindex); - bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex); - bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight); - bool EraseTxIndex(const CTransaction& tx); - bool ContainsTx(uint256 hash); - bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex); - bool ReadDiskTx(uint256 hash, CTransaction& tx); - bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex); - bool ReadDiskTx(COutPoint outpoint, CTransaction& tx); - bool WriteBlockIndex(const CDiskBlockIndex& blockindex); - bool ReadHashBestChain(uint256& hashBestChain); - bool WriteHashBestChain(uint256 hashBestChain); - bool ReadBestInvalidTrust(CBigNum& bnBestInvalidTrust); - bool WriteBestInvalidTrust(CBigNum bnBestInvalidTrust); - bool ReadSyncCheckpoint(uint256& hashCheckpoint); - bool WriteSyncCheckpoint(uint256 hashCheckpoint); - bool ReadCheckpointPubKey(std::string& strPubKey); - bool WriteCheckpointPubKey(const std::string& strPubKey); - bool LoadBlockIndex(); -private: - bool LoadBlockIndexGuts(); -}; - -#endif diff --git a/src/txdb-leveldb.cpp b/src/txdb-leveldb.cpp index a52a230..1f881f1 100644 --- a/src/txdb-leveldb.cpp +++ b/src/txdb-leveldb.cpp @@ -23,41 +23,28 @@ using namespace std; using namespace boost; -leveldb::DB *txdb; +leveldb::DB *txdb; // global pointer for LevelDB object instance static leveldb::Options GetOptions() { leveldb::Options options; int nCacheSizeMB = GetArg("-dbcache", 25); options.block_cache = leveldb::NewLRUCache(nCacheSizeMB * 1048576); - options.filter_policy = leveldb::NewBloomFilterPolicy(10); + options.filter_policy = leveldb::NewBloomFilterPolicy(10); return options; } -void MakeMockTXDB() { - leveldb::Options options = GetOptions(); - options.create_if_missing = true; - // This will leak but don't care here. - options.env = leveldb::NewMemEnv(leveldb::Env::Default()); - leveldb::Status status = leveldb::DB::Open(options, "txdb", &txdb); - if (!status.ok()) - throw runtime_error(strprintf("Could not create mock LevelDB: %s", status.ToString().c_str())); - CTxDB txdb("w"); - txdb.WriteVersion(CLIENT_VERSION); -} - -// NOTE: CDB subclasses are created and destroyed VERY OFTEN. Therefore we have -// to keep databases in global variables to avoid constantly creating and -// destroying them, which sucks. In future the code should be changed to not -// treat the instantiation of a database as a free operation. +// CDB subclasses are created and destroyed VERY OFTEN. That's why +// we shouldn't treat this it a free operations. CTxDB::CTxDB(const char* pszMode) { assert(pszMode); - pdb = txdb; activeBatch = NULL; fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); - if (txdb) + if (txdb) { + pdb = txdb; return; + } // First time init. filesystem::path directory = GetDataDir() / "txleveldb"; @@ -74,13 +61,19 @@ CTxDB::CTxDB(const char* pszMode) } pdb = txdb; - if (fCreate && !Exists(string("version"))) + if (Exists(string("version"))) + { + ReadVersion(nVersion); + printf("Transaction index version is %d\n", nVersion); + } + else if(fCreate) { bool fTmp = fReadOnly; fReadOnly = false; - WriteVersion(CLIENT_VERSION); + WriteVersion(DATABASE_VERSION); fReadOnly = fTmp; } + printf("Opened LevelDB successfully\n"); } diff --git a/src/txdb-leveldb.h b/src/txdb-leveldb.h index 85e412f..67b4036 100644 --- a/src/txdb-leveldb.h +++ b/src/txdb-leveldb.h @@ -42,11 +42,13 @@ public: private: leveldb::DB *pdb; // Points to the global instance. + // A batch stores up writes and deletes for atomic application. When this // field is non-NULL, writes/deletes go there instead of directly to disk. leveldb::WriteBatch *activeBatch; leveldb::Options options; bool fReadOnly; + int nVersion; protected: // Returns true and sets (value,false) if activeBatch contains the given key diff --git a/src/txdb.h b/src/txdb.h index a0f8315..a8e9f5b 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -6,19 +6,6 @@ #ifndef BITCOIN_TXDB_H #define BITCOIN_TXDB_H -// Allow switching between LevelDB and BerkelyDB here in case we need to temporarily -// go back to BDB for any reason. Once we're confident enough with LevelDB to stick -// with it, this can be deleted. - -#ifdef USE_LEVELDB #include "txdb-leveldb.h" -#else -#include "db.h" -#include "txdb-bdb.h" -#endif - -// Sets up whatever database layer was chosen for in-memory only access. Used by the -// the unit test framework. -extern void MakeMockTXDB(); #endif // BITCOIN_TXDB_H diff --git a/src/version.h b/src/version.h index 7775a76..45c66db 100644 --- a/src/version.h +++ b/src/version.h @@ -22,6 +22,11 @@ extern const std::string CLIENT_BUILD; extern const std::string CLIENT_DATE; // +// database format versioning +// +static const int DATABASE_VERSION = 60011; + +// // network protocol versioning // diff --git a/src/wallet.cpp b/src/wallet.cpp index 898ba67..ca33136 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1513,28 +1513,25 @@ bool CWallet::GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint continue; } - unsigned int nTime = pcoin.first->nTime; - - // Kernel hash weight starts from 0 at the 30-day min age - // this change increases active coins participating the hash and helps - // to secure the network when proof-of-stake difficulty is low - // - // Maximum TimeWeight is 90 days. - int64 nTimeWeight = min((int64)GetTime() - nTime - nStakeMinAge, (int64)nStakeMaxAge); + int64 nTimeWeight = GetWeight((int64)pcoin.first->nTime, (int64)GetTime()); CBigNum bnCoinDayWeight = CBigNum(pcoin.first->vout[pcoin.second].nValue) * nTimeWeight / COIN / (24 * 60 * 60); - // Count input that is more than 90 days old - if (nTime + nStakeMaxAge < GetTime()) + // Weight is greater than zero + if (nTimeWeight > 0) { - nMaxWeight += bnCoinDayWeight.getuint64(); nWeight += bnCoinDayWeight.getuint64(); } - // Count input that is more than 30 days old and less than 90 days old - if (nTime + nStakeMinAge < GetTime() && nTime + nStakeMaxAge > GetTime()) + // Weight is greater than zero, but the maximum value isn't reached yet + if (nTimeWeight > 0 && nTimeWeight < nStakeMaxAge) { nMinWeight += bnCoinDayWeight.getuint64(); - nWeight += bnCoinDayWeight.getuint64(); + } + + // Maximum weight was reached + if (nTimeWeight == nStakeMaxAge) + { + nMaxWeight += bnCoinDayWeight.getuint64(); } } @@ -1543,9 +1540,8 @@ bool CWallet::GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew, CKey& key) { - // The following split & combine thresholds are important to security + // The following combine threshold is important to security // Should not be adjusted if you don't understand the consequences - static unsigned int nStakeSplitAge = (60 * 60 * 24 * 90); int64 nCombineThreshold = GetProofOfWorkReward(GetLastBlockIndex(pindexBest, false)->nBits) / 3; CBigNum bnTargetPerCoinDay; @@ -1691,7 +1687,8 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int nCredit += pcoin.first->vout[pcoin.second].nValue; vwtxPrev.push_back(pcoin.first); txNew.vout.push_back(CTxOut(0, scriptPubKeyOut)); - if (block.GetBlockTime() + nStakeSplitAge > txNew.nTime) + + if (GetWeight(block.GetBlockTime(), (int64)txNew.nTime) < nStakeMaxAge) txNew.vout.push_back(CTxOut(0, scriptPubKeyOut)); //split stake if (fDebug && GetBoolArg("-printcoinstake")) printf("CreateCoinStake : added kernel type=%d\n", whichType); @@ -1714,6 +1711,8 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (txNew.vout.size() == 2 && ((pcoin.first->vout[pcoin.second].scriptPubKey == scriptPubKeyKernel || pcoin.first->vout[pcoin.second].scriptPubKey == txNew.vout[1].scriptPubKey)) && pcoin.first->GetHash() != txNew.vin[0].prevout.hash) { + int64 nTimeWeight = GetWeight((int64)pcoin.first->nTime, (int64)txNew.nTime); + // Stop adding more inputs if already too many inputs if (txNew.vin.size() >= 100) break; @@ -1727,8 +1726,9 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (pcoin.first->vout[pcoin.second].nValue > nCombineThreshold) continue; // Do not add input that is still too young - if (pcoin.first->nTime + nStakeMaxAge > txNew.nTime) + if (nTimeWeight < nStakeMaxAge) continue; + txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); nCredit += pcoin.first->vout[pcoin.second].nValue; vwtxPrev.push_back(pcoin.first); -- 1.7.1