diff -Nru anoncoin-0.8.5.6/anoncoin-qt.pro anoncoin-0.8.5.6+git20141111.r4233/anoncoin-qt.pro --- anoncoin-0.8.5.6/anoncoin-qt.pro 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/anoncoin-qt.pro 2014-11-11 13:56:18.000000000 +0000 @@ -1,11 +1,11 @@ TEMPLATE = app TARGET = anoncoin-qt macx:TARGET = "Anoncoin-Qt" -VERSION = 0.8.5.1 +VERSION = 0.8.5.6 INCLUDEPATH += src src/json src/qt i2psam QT += core gui network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets -DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE +DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE ENABLE_WALLET CONFIG += no_include_pwd CONFIG += thread SUBDIR = i2psam @@ -196,7 +196,7 @@ src/qt/walletview.h \ src/qt/walletstack.h \ src/qt/walletframe.h \ - src/bitcoinrpc.h \ + src/anoncoinrpc.h \ src/qt/overviewpage.h \ src/qt/csvmodelwriter.h \ src/crypter.h \ @@ -215,6 +215,7 @@ src/i2p.h \ src/scrypt.h \ src/version.h \ + src/miner.h \ src/netbase.h \ src/clientversion.h \ src/txdb.h \ @@ -273,7 +274,7 @@ src/qt/walletview.cpp \ src/qt/walletstack.cpp \ src/qt/walletframe.cpp \ - src/bitcoinrpc.cpp \ + src/anoncoinrpc.cpp \ src/rpcdump.cpp \ src/rpcnet.cpp \ src/rpcmining.cpp \ @@ -296,6 +297,7 @@ src/i2p.cpp \ src/scrypt.cpp \ src/noui.cpp \ + src/miner.cpp \ src/leveldb.cpp \ src/txdb.cpp \ src/qt/splashscreen.cpp \ diff -Nru anoncoin-0.8.5.6/contrib/gitian-descriptors/deps-win32.yml anoncoin-0.8.5.6+git20141111.r4233/contrib/gitian-descriptors/deps-win32.yml --- anoncoin-0.8.5.6/contrib/gitian-descriptors/deps-win32.yml 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/contrib/gitian-descriptors/deps-win32.yml 2014-11-11 13:56:18.000000000 +0000 @@ -1,5 +1,5 @@ --- -name: "bitcoin-deps" +name: "anoncoin-deps" suites: - "precise" architectures: @@ -90,4 +90,4 @@ cd .. # cd $INSTALLPREFIX - zip -r $OUTDIR/bitcoin-deps-win32-gitian-r9.zip include lib + zip -r $OUTDIR/anoncoin-deps-win32-gitian-r9.zip include lib diff -Nru anoncoin-0.8.5.6/contrib/gitian-descriptors/gitian-win32.yml anoncoin-0.8.5.6+git20141111.r4233/contrib/gitian-descriptors/gitian-win32.yml --- anoncoin-0.8.5.6/contrib/gitian-descriptors/gitian-win32.yml 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/contrib/gitian-descriptors/gitian-win32.yml 2014-11-11 13:56:18.000000000 +0000 @@ -1,5 +1,5 @@ --- -name: "litecoin" +name: "anoncoin" suites: - "precise" architectures: @@ -13,12 +13,12 @@ - "faketime" reference_datetime: "2011-01-30 00:00:00" remotes: -- "url": "https://github.com/litecoin-project/litecoin.git" - "dir": "litecoin" +- "url": "https://github.com/Anoncoin/anoncoin.git" + "dir": "anoncoin" files: - "qt-win32-4.8.3-gitian-r4.zip" - "boost-win32-1.54.0-gitian-r6.zip" -- "bitcoin-deps-win32-gitian-r9.zip" +- "anoncoin-deps-win32-gitian-r9.zip" script: | # STAGING=$HOME/staging @@ -28,10 +28,13 @@ cd $STAGING unzip ../build/qt-win32-4.8.3-gitian-r4.zip unzip ../build/boost-win32-1.54.0-gitian-r6.zip - unzip ../build/bitcoin-deps-win32-gitian-r9.zip + unzip ../build/anoncoin-deps-win32-gitian-r9.zip cd $HOME/build/ # - cd litecoin + cd anoncoin + cd i2psam + make -f makefile.linux-mingw + cd .. export PATH=$STAGING/host/bin:$PATH mkdir -p $OUTDIR/src git archive HEAD | tar -x -C $OUTDIR/src @@ -41,19 +44,19 @@ export FAKETIME=$REFERENCE_DATETIME export TZ=UTC ln -s $STAGING $HOME/qt - $HOME/staging/host/bin/qmake -spec unsupported/win32-g++-cross MINIUPNPC_LIB_PATH=$STAGING MINIUPNPC_INCLUDE_PATH=$STAGING BDB_LIB_PATH=$STAGING BDB_INCLUDE_PATH=$STAGING BOOST_LIB_PATH=$STAGING BOOST_INCLUDE_PATH=$STAGING BOOST_LIB_SUFFIX=-mt-s BOOST_THREAD_LIB_SUFFIX=_win32-mt-s OPENSSL_LIB_PATH=$STAGING OPENSSL_INCLUDE_PATH=$STAGING QRENCODE_LIB_PATH=$STAGING QRENCODE_INCLUDE_PATH=$STAGING USE_QRCODE=1 INCLUDEPATH=$STAGING DEFINES=BOOST_THREAD_USE_LIB BITCOIN_NEED_QT_PLUGINS=1 QMAKE_LRELEASE=lrelease QMAKE_CXXFLAGS=-frandom-seed=litecoin USE_BUILD_INFO=1 USE_SSE2=1 + $HOME/staging/host/bin/qmake -spec unsupported/win32-g++-cross MINIUPNPC_LIB_PATH=$STAGING MINIUPNPC_INCLUDE_PATH=$STAGING BDB_LIB_PATH=$STAGING BDB_INCLUDE_PATH=$STAGING BOOST_LIB_PATH=$STAGING BOOST_INCLUDE_PATH=$STAGING BOOST_LIB_SUFFIX=-mt-s BOOST_THREAD_LIB_SUFFIX=_win32-mt-s OPENSSL_LIB_PATH=$STAGING OPENSSL_INCLUDE_PATH=$STAGING QRENCODE_LIB_PATH=$STAGING QRENCODE_INCLUDE_PATH=$STAGING USE_QRCODE=1 INCLUDEPATH=$STAGING DEFINES=BOOST_THREAD_USE_LIB BITCOIN_NEED_QT_PLUGINS=1 QMAKE_LRELEASE=lrelease QMAKE_CXXFLAGS=-frandom-seed=anoncoin USE_BUILD_INFO=1 USE_SSE2=1 make $MAKEOPTS - $HOST-strip release/litecoin-qt.exe - cp release/litecoin-qt.exe $OUTDIR/ + $HOST-strip release/anoncoin-qt.exe + cp release/anoncoin-qt.exe $OUTDIR/ # cd src export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 export FAKETIME=$REFERENCE_DATETIME export TZ=UTC - make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$STAGING litecoind.exe USE_UPNP=0 DEBUGFLAGS="-frandom-seed=litecoin" USE_SSE2=1 - $HOST-strip litecoind.exe + make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$STAGING anoncoind.exe USE_UPNP=0 DEBUGFLAGS="-frandom-seed=anoncoin" USE_SSE2=1 + $HOST-strip anoncoind.exe mkdir $OUTDIR/daemon - cp litecoind.exe $OUTDIR/daemon + cp anoncoind.exe $OUTDIR/daemon cd .. mkdir nsis git archive HEAD | tar -x -C nsis @@ -62,4 +65,4 @@ cp ../../release/* ../release/ cp ../../src/*.exe . makensis ../share/setup.nsi - cp ../share/litecoin-*-win32-setup.exe $OUTDIR/ + cp ../share/anoncoin-*-win32-setup.exe $OUTDIR/ diff -Nru anoncoin-0.8.5.6/contrib/gitian-descriptors/gitian.yml anoncoin-0.8.5.6+git20141111.r4233/contrib/gitian-descriptors/gitian.yml --- anoncoin-0.8.5.6/contrib/gitian-descriptors/gitian.yml 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/contrib/gitian-descriptors/gitian.yml 2014-11-11 13:56:18.000000000 +0000 @@ -1,18 +1,15 @@ --- -name: "litecoin" +name: "anoncoin" suites: -- "lucid" +- "precise" architectures: - "i386" - "amd64" packages: -- "libdb4.8++-dev" +- "libdb5.1++-dev" - "qt4-qmake" - "libqt4-dev" -- "libboost-system-dev" -- "libboost-filesystem-dev" -- "libboost-program-options-dev" -- "libboost-thread-dev" +- "libboost-all-dev" - "libssl-dev" - "git-core" - "unzip" @@ -20,8 +17,8 @@ - "libpng12-dev" reference_datetime: "2011-01-30 00:00:00" remotes: -- "url": "https://github.com/litecoin-project/litecoin.git" - "dir": "litecoin" +- "url": "https://github.com/Anoncoin/anoncoin.git" + "dir": "anoncoin" files: - "miniupnpc-1.6.tar.gz" - "qrencode-3.2.0.tar.bz2" @@ -40,16 +37,18 @@ make $MAKEOPTS install cd .. # - cd litecoin + cd anoncoin mkdir -p $OUTDIR/src git archive HEAD | tar -x -C $OUTDIR/src cp $OUTDIR/src/doc/README.md $OUTDIR cp $OUTDIR/src/COPYING $OUTDIR - cd src - make -f makefile.unix STATIC=1 OPENSSL_INCLUDE_PATH="$INSTDIR/include" OPENSSL_LIB_PATH="$INSTDIR/lib" $MAKEOPTS litecoind USE_UPNP=0 DEBUGFLAGS= USE_SSE2=1 + cd i2psam + make -f makefile.unix + cd ../src + make -f makefile.unix STATIC=1 OPENSSL_INCLUDE_PATH="$INSTDIR/include" OPENSSL_LIB_PATH="$INSTDIR/lib" $MAKEOPTS anoncoind USE_UPNP=0 DEBUGFLAGS= USE_SSE2=1 mkdir -p $OUTDIR/bin/$GBUILD_BITS - install -s litecoind $OUTDIR/bin/$GBUILD_BITS + install -s anoncoind $OUTDIR/bin/$GBUILD_BITS cd .. qmake INCLUDEPATH="$INSTDIR/include" LIBS="-L$INSTDIR/lib" RELEASE=1 USE_QRCODE=1 USE_SSE2=1 make $MAKEOPTS - install litecoin-qt $OUTDIR/bin/$GBUILD_BITS + install anoncoin-qt $OUTDIR/bin/$GBUILD_BITS diff -Nru anoncoin-0.8.5.6/contrib/gitian-descriptors/qt-win32.yml anoncoin-0.8.5.6+git20141111.r4233/contrib/gitian-descriptors/qt-win32.yml --- anoncoin-0.8.5.6/contrib/gitian-descriptors/qt-win32.yml 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/contrib/gitian-descriptors/qt-win32.yml 2014-11-11 13:56:18.000000000 +0000 @@ -15,7 +15,7 @@ remotes: [] files: - "qt-everywhere-opensource-src-4.8.3.tar.gz" -- "bitcoin-deps-win32-gitian-r9.zip" +- "anoncoin-deps-win32-gitian-r9.zip" script: | # HOST=i686-w64-mingw32 @@ -24,8 +24,8 @@ mkdir $INSTDIR mkdir -p $INSTDIR/host/bin # - # Need mingw-compiled openssl from bitcoin-deps: - unzip bitcoin-deps-win32-gitian-r9.zip + # Need mingw-compiled openssl from anoncoin-deps: + unzip anoncoin-deps-win32-gitian-r9.zip DEPSDIR=`pwd` # tar xzf qt-everywhere-opensource-src-4.8.3.tar.gz diff -Nru anoncoin-0.8.5.6/contrib/macdeploy/fancy.plist anoncoin-0.8.5.6+git20141111.r4233/contrib/macdeploy/fancy.plist --- anoncoin-0.8.5.6/contrib/macdeploy/fancy.plist 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/contrib/macdeploy/fancy.plist 2014-11-11 13:56:18.000000000 +0000 @@ -22,7 +22,7 @@ 370 156 - Litecoin-Qt.app + Anoncoin-Qt.app 128 156 diff -Nru anoncoin-0.8.5.6/contrib/macdeploy/macdeployqtplus anoncoin-0.8.5.6+git20141111.r4233/contrib/macdeploy/macdeployqtplus --- anoncoin-0.8.5.6/contrib/macdeploy/macdeployqtplus 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/contrib/macdeploy/macdeployqtplus 2014-11-11 13:56:18.000000000 +0000 @@ -763,7 +763,7 @@ items_positions.append(itemscript.substitute(params)) params = { - "disk" : "Litecoin-Qt", + "disk" : "Anoncoin-Qt", "window_bounds" : "300,300,800,620", "icon_size" : "96", "background_commands" : "", diff -Nru anoncoin-0.8.5.6/debian/changelog anoncoin-0.8.5.6+git20141111.r4233/debian/changelog --- anoncoin-0.8.5.6/debian/changelog 2014-03-09 01:41:48.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/debian/changelog 2014-11-29 03:50:25.000000000 +0000 @@ -1,3 +1,15 @@ +anoncoin (0.8.5.6+git20141111.r4233-1~precise+1) precise; urgency=medium + + * Backport to Precise + + -- Kill Your TV Sat, 29 Nov 2014 03:50:09 +0000 + +anoncoin (0.8.5.6+git20141111.r4233-1) unstable; urgency=medium + + * New upstream git snapshot + + -- Kill Your TV Sat, 29 Nov 2014 00:38:29 +0000 + anoncoin (0.8.5.6-1ubuntu1~precise1) precise; urgency=medium * Backport for Ubuntu Precise diff -Nru anoncoin-0.8.5.6/debian/copyright anoncoin-0.8.5.6+git20141111.r4233/debian/copyright --- anoncoin-0.8.5.6/debian/copyright 2014-03-09 01:41:48.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/debian/copyright 2014-11-29 03:50:25.000000000 +0000 @@ -79,7 +79,8 @@ License: GPL-3+ Files: debian/* -Copyright: 2012-2014 Dmitry Smirnov +Copyright: 2014 Kill Your TV + 2012-2014 Dmitry Smirnov 2010-2011 Jonas Smedegaard License: GPL-2+ This package is free software; you can redistribute it and/or modify diff -Nru anoncoin-0.8.5.6/debian/examples/anoncoin.conf anoncoin-0.8.5.6+git20141111.r4233/debian/examples/anoncoin.conf --- anoncoin-0.8.5.6/debian/examples/anoncoin.conf 2014-03-09 01:41:48.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/debian/examples/anoncoin.conf 2014-11-29 03:50:25.000000000 +0000 @@ -48,6 +48,16 @@ # running on another host using this option: rpcconnect=127.0.0.1 +# Enable I2P +i2p=1 + +#i2psessionname=Anoncoin-client +#samhost= +#samport= +#mydestination= + + + # Use Secure Sockets Layer (also known as TLS or HTTPS) to communicate # with Anoncoin -server or anoncoind #rpcssl=1 diff -Nru anoncoin-0.8.5.6/debian/gbp.conf anoncoin-0.8.5.6+git20141111.r4233/debian/gbp.conf --- anoncoin-0.8.5.6/debian/gbp.conf 2014-03-09 01:41:48.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/debian/gbp.conf 2014-11-29 03:50:25.000000000 +0000 @@ -6,7 +6,7 @@ # the default clean command: #cleaner = debuild clean # the default branch for upstream sources: -upstream-branch = master-neo +upstream-branch = master # the default branch for the debian patch: debian-branch = ubuntu/precise # the default tag formats used: @@ -39,7 +39,7 @@ #ignore-new = True #export = HEAD # compress with bzip2 -compression = gzip +compression = xz # use best compression #compression-level = best # Don't send notifications, alternatives: on/true, off/false or auto diff -Nru anoncoin-0.8.5.6/debian/patches/0001-builddate.patch anoncoin-0.8.5.6+git20141111.r4233/debian/patches/0001-builddate.patch --- anoncoin-0.8.5.6/debian/patches/0001-builddate.patch 2014-03-09 01:41:48.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/debian/patches/0001-builddate.patch 2014-11-29 03:50:25.000000000 +0000 @@ -2,6 +2,14 @@ Date: Sat, 8 Mar 2014 00:02:53 +0000 Subject: builddate +Patch borrowed from the Debian litecoin packaging. Original header info +follows: + +Last-Update: 2013-11-20 +Forwarded: not-needed +Author: Dmitry Smirnov +Description: provide build date information. + --- share/genbuild.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff -Nru anoncoin-0.8.5.6/debian/patches/0002-unbundle-leveldb.patch anoncoin-0.8.5.6+git20141111.r4233/debian/patches/0002-unbundle-leveldb.patch --- anoncoin-0.8.5.6/debian/patches/0002-unbundle-leveldb.patch 2014-03-09 01:41:48.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/debian/patches/0002-unbundle-leveldb.patch 2014-11-29 03:50:25.000000000 +0000 @@ -2,17 +2,26 @@ Date: Sat, 8 Mar 2014 00:02:54 +0000 Subject: unbundle-leveldb + +Patch borrowed from the Debian litecoin packaging and rebased to apply to the +anoncoin codebase by kytv. + +Original header info follows: + +Last-Update: 2013-11-14 +Forwarded: not-needed +Author: Dmitry Smirnov +Description: use system libleveldb-dev instead of a bundled one. + --- anoncoin-qt.pro | 20 +------------------- src/leveldb.cpp | 2 +- src/makefile.unix | 8 +------- 3 files changed, 3 insertions(+), 27 deletions(-) -diff --git a/anoncoin-qt.pro b/anoncoin-qt.pro -index bb1a192..9d61153 100644 --- a/anoncoin-qt.pro +++ b/anoncoin-qt.pro -@@ -102,25 +102,7 @@ contains(BITCOIN_NEED_QT_PLUGINS, 1) { +@@ -102,25 +102,7 @@ QTPLUGIN += qcncodecs qjpcodecs qtwcodecs qkrcodecs qtaccessiblewidgets } @@ -39,8 +48,6 @@ # regenerate src/build.h !win32|contains(USE_BUILD_INFO, 1) { -diff --git a/src/leveldb.cpp b/src/leveldb.cpp -index e66f851..c465aee 100644 --- a/src/leveldb.cpp +++ b/src/leveldb.cpp @@ -8,7 +8,7 @@ @@ -52,19 +59,17 @@ #include -diff --git a/src/makefile.unix b/src/makefile.unix -index 2b9996b..0658b4c 100644 --- a/src/makefile.unix +++ b/src/makefile.unix -@@ -115,7 +115,6 @@ xCXXFLAGS=-O2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-para - xLDFLAGS=$(LDHARDENING) $(LDFLAGS) - +@@ -113,7 +113,6 @@ + # anoncoind depends on them. This is inelegant because they are redundant when listed + # in $OBJS (NOTE: compilation fails if they are not in $LIBS, even if present here). OBJS= \ - leveldb/libleveldb.a \ + ../i2psam/libi2psam.a \ obj/alert.o \ obj/version.o \ - obj/checkpoints.o \ -@@ -166,11 +165,7 @@ test check: test_anoncoin FORCE +@@ -165,11 +164,7 @@ # LevelDB support # MAKEOVERRIDES = @@ -75,9 +80,9 @@ - @echo "Building LevelDB ..." && cd leveldb && $(MAKE) CC=$(CC) CXX=$(CXX) OPT="$(xCXXFLAGS)" libleveldb.a libmemenv.a && cd .. +LIBS += -lleveldb -lmemenv - # auto-generated dependencies: - -include obj/*.P -@@ -217,6 +212,5 @@ clean: + # + # I2P support +@@ -225,6 +220,5 @@ -rm -f obj/*.P -rm -f obj-test/*.P -rm -f obj/build.h diff -Nru anoncoin-0.8.5.6/debian/patches/0003-bash-completion.patch anoncoin-0.8.5.6+git20141111.r4233/debian/patches/0003-bash-completion.patch --- anoncoin-0.8.5.6/debian/patches/0003-bash-completion.patch 2014-03-09 01:41:48.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/debian/patches/0003-bash-completion.patch 2014-11-29 03:50:25.000000000 +0000 @@ -2,6 +2,9 @@ Date: Sat, 8 Mar 2014 00:04:04 +0000 Subject: bash-completion +s/litecoin/anoncoin/ +s/Litecoin/Anoncoin/ + --- contrib/bitcoind.bash-completion | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff -Nru anoncoin-0.8.5.6/debian/patches/series anoncoin-0.8.5.6+git20141111.r4233/debian/patches/series --- anoncoin-0.8.5.6/debian/patches/series 2014-03-09 01:41:48.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/debian/patches/series 2014-11-29 03:50:25.000000000 +0000 @@ -1,3 +1,3 @@ 0001-builddate.patch -#0002-unbundle-leveldb.patch +0002-unbundle-leveldb.patch 0003-bash-completion.patch diff -Nru anoncoin-0.8.5.6/doc/build-unix.md anoncoin-0.8.5.6+git20141111.r4233/doc/build-unix.md --- anoncoin-0.8.5.6/doc/build-unix.md 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/doc/build-unix.md 2014-11-11 13:56:18.000000000 +0000 @@ -81,7 +81,7 @@ Notes ----- -The release is built with GCC and then "strip bitcoind" to strip the debug +The release is built with GCC and then "strip anoncoind" to strip the debug symbols, which reduces the executable size by about 90%. @@ -139,7 +139,7 @@ * Non-executable Stack If the stack is executable then trivial stack based buffer overflow exploits are possible if - vulnerable buffers are found. By default, bitcoin should be built with a non-executable stack + vulnerable buffers are found. By default, anoncoin should be built with a non-executable stack but if one of the libraries it uses asks for an executable stack or someone makes a mistake and uses a compiler extension which requires an executable stack, it will silently build an executable without the non-executable stack protection. diff -Nru anoncoin-0.8.5.6/doc/release-process.md anoncoin-0.8.5.6+git20141111.r4233/doc/release-process.md --- anoncoin-0.8.5.6/doc/release-process.md 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/doc/release-process.md 2014-11-11 13:56:18.000000000 +0000 @@ -24,9 +24,9 @@ ##perform gitian builds - From a directory containing the litecoin source, gitian-builder and gitian.sigs + From a directory containing the anoncoin source, gitian-builder and gitian.sigs - export SIGNER=(your gitian key, ie bluematt, sipa, etc) + export SIGNER=(your gitian key, ie Meeh, K1773R, etc) export VERSION=0.8.0 cd ./gitian-builder @@ -42,79 +42,79 @@ wget 'http://downloads.sourceforge.net/project/boost/boost/1.50.0/boost_1_50_0.tar.bz2' wget 'http://releases.qt-project.org/qt4/source/qt-everywhere-opensource-src-4.8.3.tar.gz' cd .. - ./bin/gbuild ../litecoin/contrib/gitian-descriptors/boost-win32.yml + ./bin/gbuild ../anoncoin/contrib/gitian-descriptors/boost-win32.yml mv build/out/boost-win32-1.50.0-gitian2.zip inputs/ - ./bin/gbuild ../litecoin/contrib/gitian-descriptors/qt-win32.yml + ./bin/gbuild ../anoncoin/contrib/gitian-descriptors/qt-win32.yml mv build/out/qt-win32-4.8.3-gitian-r1.zip inputs/ - ./bin/gbuild ../litecoin/contrib/gitian-descriptors/deps-win32.yml - mv build/out/litecoin-deps-0.0.5.zip inputs/ + ./bin/gbuild ../anoncoin/contrib/gitian-descriptors/deps-win32.yml + mv build/out/anoncoin-deps-0.0.5.zip inputs/ - Build litecoind and litecoin-qt on Linux32, Linux64, and Win32: + Build anoncoind and anoncoin-qt on Linux32, Linux64, and Win32: - ./bin/gbuild --commit litecoin=v${VERSION} ../litecoin/contrib/gitian-descriptors/gitian.yml - ./bin/gsign --signer $SIGNER --release ${VERSION} --destination ../gitian.sigs/ ../litecoin/contrib/gitian-descriptors/gitian.yml + ./bin/gbuild --commit anoncoin=v${VERSION} ../anoncoin/contrib/gitian-descriptors/gitian.yml + ./bin/gsign --signer $SIGNER --release ${VERSION} --destination ../gitian.sigs/ ../anoncoin/contrib/gitian-descriptors/gitian.yml pushd build/out - zip -r litecoin-${VERSION}-linux-gitian.zip * - mv litecoin-${VERSION}-linux-gitian.zip ../../ + zip -r anoncoin-${VERSION}-linux-gitian.zip * + mv anoncoin-${VERSION}-linux-gitian.zip ../../ popd - ./bin/gbuild --commit litecoin=v${VERSION} ../litecoin/contrib/gitian-descriptors/gitian-win32.yml - ./bin/gsign --signer $SIGNER --release ${VERSION}-win32 --destination ../gitian.sigs/ ../litecoin/contrib/gitian-descriptors/gitian-win32.yml + ./bin/gbuild --commit anoncoin=v${VERSION} ../anoncoin/contrib/gitian-descriptors/gitian-win32.yml + ./bin/gsign --signer $SIGNER --release ${VERSION}-win32 --destination ../gitian.sigs/ ../anoncoin/contrib/gitian-descriptors/gitian-win32.yml pushd build/out - zip -r litecoin-${VERSION}-win32-gitian.zip * - mv litecoin-${VERSION}-win32-gitian.zip ../../ + zip -r anoncoin-${VERSION}-win32-gitian.zip * + mv anoncoin-${VERSION}-win32-gitian.zip ../../ popd Build output expected: - 1. linux 32-bit and 64-bit binaries + source (litecoin-${VERSION}-linux-gitian.zip) - 2. windows 32-bit binary, installer + source (litecoin-${VERSION}-win32-gitian.zip) + 1. linux 32-bit and 64-bit binaries + source (anoncoin-${VERSION}-linux-gitian.zip) + 2. windows 32-bit binary, installer + source (anoncoin-${VERSION}-win32-gitian.zip) 3. Gitian signatures (in gitian.sigs/${VERSION}[-win32]/(your gitian key)/ repackage gitian builds for release as stand-alone zip/tar/installer exe **Linux .tar.gz:** - unzip litecoin-${VERSION}-linux-gitian.zip -d litecoin-${VERSION}-linux - tar czvf litecoin-${VERSION}-linux.tar.gz litecoin-${VERSION}-linux - rm -rf litecoin-${VERSION}-linux + unzip anoncoin-${VERSION}-linux-gitian.zip -d anoncoin-${VERSION}-linux + tar czvf anoncoin-${VERSION}-linux.tar.gz anoncoin-${VERSION}-linux + rm -rf anoncoin-${VERSION}-linux **Windows .zip and setup.exe:** - unzip litecoin-${VERSION}-win32-gitian.zip -d litecoin-${VERSION}-win32 - mv litecoin-${VERSION}-win32/litecoin-*-setup.exe . - zip -r litecoin-${VERSION}-win32.zip bitcoin-${VERSION}-win32 - rm -rf litecoin-${VERSION}-win32 + unzip anoncoin-${VERSION}-win32-gitian.zip -d anoncoin-${VERSION}-win32 + mv anoncoin-${VERSION}-win32/anoncoin-*-setup.exe . + zip -r anoncoin-${VERSION}-win32.zip bitcoin-${VERSION}-win32 + rm -rf anoncoin-${VERSION}-win32 **Perform Mac build:** - OSX binaries are created by Gavin Andresen on a 32-bit, OSX 10.6 machine. + OSX binaries are created by Meeh on a 64-bit, OSX 10.7.5 machine. - qmake RELEASE=1 USE_UPNP=1 USE_QRCODE=1 litecoin-qt.pro + qmake RELEASE=1 USE_UPNP=1 USE_QRCODE=1 anoncoin-qt.pro make export QTDIR=/opt/local/share/qt4 # needed to find translations/qt_*.qm files T=$(contrib/qt_translations.py $QTDIR/translations src/qt/locale) python2.7 share/qt/clean_mac_info_plist.py - python2.7 contrib/macdeploy/macdeployqtplus Bitcoin-Qt.app -add-qt-tr $T -dmg -fancy contrib/macdeploy/fancy.plist + python2.7 contrib/macdeploy/macdeployqtplus Anoncoin-Qt.app -add-qt-tr $T -dmg -fancy contrib/macdeploy/fancy.plist Build output expected: Bitcoin-Qt.dmg ###Next steps: * Code-sign Windows -setup.exe (in a Windows virtual machine) and - OSX Bitcoin-Qt.app (Note: only Gavin has the code-signing keys currently) + OSX Anoncoin-Qt.app (Note: only Meeh has the code-signing keys currently) * upload builds to SourceForge * create SHA256SUMS for builds, and PGP-sign it -* update litecoin.org version +* update anoncoin.org version make sure all OS download links go to the right versions * update forum version * update wiki download links -* update wiki changelog: [https://en.litecoin.it/wiki/Changelog](https://en.bitcoin.it/wiki/Changelog) +* update wiki changelog: [https://en.bitcoin.it/wiki/Changelog](https://en.bitcoin.it/wiki/Changelog) Commit your signature to gitian.sigs: @@ -129,32 +129,32 @@ ### After 3 or more people have gitian-built, repackage gitian-signed zips: -From a directory containing litecoin source, gitian.sigs and gitian zips +From a directory containing anoncoin source, gitian.sigs and gitian zips export VERSION=0.5.1 - mkdir litecoin-${VERSION}-linux-gitian - pushd litecoin-${VERSION}-linux-gitian - unzip ../litecoin-${VERSION}-linux-gitian.zip + mkdir anoncoin-${VERSION}-linux-gitian + pushd anoncoin-${VERSION}-linux-gitian + unzip ../anoncoin-${VERSION}-linux-gitian.zip mkdir gitian - cp ../litecoin/contrib/gitian-downloader/*.pgp ./gitian/ + cp ../anoncoin/contrib/gitian-downloader/*.pgp ./gitian/ for signer in $(ls ../gitian.sigs/${VERSION}/); do - cp ../gitian.sigs/${VERSION}/${signer}/litecoin-build.assert ./gitian/${signer}-build.assert - cp ../gitian.sigs/${VERSION}/${signer}/litecoin-build.assert.sig ./gitian/${signer}-build.assert.sig + cp ../gitian.sigs/${VERSION}/${signer}/anoncoin-build.assert ./gitian/${signer}-build.assert + cp ../gitian.sigs/${VERSION}/${signer}/anoncoin-build.assert.sig ./gitian/${signer}-build.assert.sig done - zip -r litecoin-${VERSION}-linux-gitian.zip * - cp litecoin-${VERSION}-linux-gitian.zip ../ + zip -r anoncoin-${VERSION}-linux-gitian.zip * + cp anoncoin-${VERSION}-linux-gitian.zip ../ popd - mkdir litecoin-${VERSION}-win32-gitian - pushd litecoin-${VERSION}-win32-gitian - unzip ../litecoin-${VERSION}-win32-gitian.zip + mkdir anoncoin-${VERSION}-win32-gitian + pushd anoncoin-${VERSION}-win32-gitian + unzip ../anoncoin-${VERSION}-win32-gitian.zip mkdir gitian - cp ../litecoin/contrib/gitian-downloader/*.pgp ./gitian/ + cp ../anoncoin/contrib/gitian-downloader/*.pgp ./gitian/ for signer in $(ls ../gitian.sigs/${VERSION}-win32/); do - cp ../gitian.sigs/${VERSION}-win32/${signer}/litecoin-build.assert ./gitian/${signer}-build.assert - cp ../gitian.sigs/${VERSION}-win32/${signer}/litecoin-build.assert.sig ./gitian/${signer}-build.assert.sig + cp ../gitian.sigs/${VERSION}-win32/${signer}/anoncoin-build.assert ./gitian/${signer}-build.assert + cp ../gitian.sigs/${VERSION}-win32/${signer}/anoncoin-build.assert.sig ./gitian/${signer}-build.assert.sig done - zip -r litecoin-${VERSION}-win32-gitian.zip * - cp litecoin-${VERSION}-win32-gitian.zip ../ + zip -r anoncoin-${VERSION}-win32-gitian.zip * + cp anoncoin-${VERSION}-win32-gitian.zip ../ popd - Upload gitian zips to SourceForge diff -Nru anoncoin-0.8.5.6/.gitignore anoncoin-0.8.5.6+git20141111.r4233/.gitignore --- anoncoin-0.8.5.6/.gitignore 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/.gitignore 2014-11-11 13:56:18.000000000 +0000 @@ -1,7 +1,7 @@ src/*.exe -src/litecoin -src/litecoind -src/test_litecoin +src/anoncoin +src/anoncoind +src/test_anoncoind .*.swp *.*~* *.bak @@ -9,17 +9,17 @@ *.orig *.o *.patch -.litecoin +.anoncoin # Compilation and Qt preprocessor part *.qm Makefile -litecoin-qt -Litecoin-Qt.app +anoncoin-qt +Anoncoin-Qt.app # Unit-tests Makefile.test -litecoin-qt_test +anoncoin-qt_test # Resources cpp qrc_*.cpp diff -Nru anoncoin-0.8.5.6/i2psam/.gitignore anoncoin-0.8.5.6+git20141111.r4233/i2psam/.gitignore --- anoncoin-0.8.5.6/i2psam/.gitignore 1970-01-01 00:00:00.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/i2psam/.gitignore 2014-11-11 13:56:18.000000000 +0000 @@ -0,0 +1 @@ +libi2psam.a diff -Nru anoncoin-0.8.5.6/i2psam/makefile.linux-mingw anoncoin-0.8.5.6+git20141111.r4233/i2psam/makefile.linux-mingw --- anoncoin-0.8.5.6/i2psam/makefile.linux-mingw 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/i2psam/makefile.linux-mingw 2014-11-11 13:56:18.000000000 +0000 @@ -7,13 +7,13 @@ ####### Compiler, tools and options -CC = i586-mingw32msvc-gcc -CXX = i586-mingw32msvc-g++ +CC = i686-w64-mingw32-gcc +CXX = i686-w64-mingw32-g++ DEFINES = -D_MT -DWIN32 -D_WINDOWS -CFLAGS = -pipe -isystem /usr/i586-mingw32msvc/include/ -O2 -Wall -Wextra $(DEFINES) +CFLAGS = -pipe -isystem /usr/i686-w64-mingw32/include/ -O2 -Wall -Wextra $(DEFINES) CXXFLAGS = -O2 -fexceptions -Wall -Wextra $(DEFINES) INCPATH = -I'../../dependencies/mingw32/qt/include' -I'../../dependencies/mingw32' -I'../../dependencies/mingw32/qt/include/ActiveQt' -I'../../dependencies/mingw32/qt/mkspecs/unsupported/win32-g++-cross' -LIB = i586-mingw32msvc-ar -ru +LIB = i686-w64-mingw32-ar -ru COPY = cp SED = sed COPY_FILE = $(COPY) diff -Nru anoncoin-0.8.5.6/INSTALL anoncoin-0.8.5.6+git20141111.r4233/INSTALL --- anoncoin-0.8.5.6/INSTALL 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/INSTALL 2014-11-11 13:56:18.000000000 +0000 @@ -1,9 +1,9 @@ -Building Litecoin +Building Anoncoin -See doc/readme-qt.rst for instructions on building Litecoin-Qt, +See doc/readme-qt.rst for instructions on building Anoncoin-Qt, the intended-for-end-users, nice-graphical-interface, reference -implementation of Litecoin. +implementation of Anoncoin. -See doc/build-*.txt for instructions on building litecoind, +See doc/build-*.txt for instructions on building anoncoind, the intended-for-services, no-graphical-interface, reference -implementation of Litecoin. +implementation of Anoncoin. diff -Nru anoncoin-0.8.5.6/README.md anoncoin-0.8.5.6+git20141111.r4233/README.md --- anoncoin-0.8.5.6/README.md 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/README.md 2014-11-11 13:56:18.000000000 +0000 @@ -1,34 +1,47 @@ -Anoncoin - a fork version of Litecoin optimized for CPU mining using scrypt as a proof of work scheme. - - 3.42 minute block targets (retarget on ~1680 blocks, 4days) - - Starts with 4.2 coin blocks until block 42000 - - 7 coin blocks until block 77777 - - 5 coin blocks after 77778, then subsidy halves in 306600 blocks (~2 years) - -Development process -=================== - -Developers work in their own trees, then submit pull requests when -they think their feature or bug fix is ready. - -The patch will be accepted if there is broad consensus that it is a -good thing. Developers should expect to rework and resubmit patches -if they don't match the project's coding conventions (see coding.txt) -or are controversial. - -The master branch is regularly built and tested, but is not guaranteed -to be completely stable. Tags are regularly created to indicate new -official, stable release versions of Anoncoin. - -Feature branches are created when there are major new features being -worked on by several people. - -From time to time a pull request will become outdated. If this occurs, and -the pull is no longer automatically mergeable; a comment on the pull will -be used to issue a warning of closure. The pull will be closed 15 days -after the warning if action is not taken by the author. Pull requests closed -in this manner will have their corresponding issue labeled 'stagnant'. - -Issues with no commits will be given a similar warning, and closed after -15 days from their last activity. Issues closed in this manner will be -labeled 'stale'. - +Anoncoin +==================== + +Anoncoin is a privacy-oriented decentralized crypto-currency which uses the I2P network to hide users' identities (Tor is also supported). + +Platforms: +- Linux - [![Build Status - Linux](https://jenkins.nordcloud.no/buildStatus/icon?job=Anoncoin-Linux)](https://jenkins.nordcloud.no/job/Anoncoin-Linux/) +- Windows (Mingw-w64) - [![Build Status - Mingw-w64](https://jenkins.nordcloud.no/buildStatus/icon?job=Anoncoin-Mingw-w64)](https://jenkins.nordcloud.no/job/Anoncoin-Mingw-w64/) +- OSX (Build status to be added soon) + +Specs: + - launched in June 2013 + - scrypt proof-of-work (same as Litecoin) + - 3 minute block targets with KGW retargeting (before block 87777, it was 3.42 minute targets using classic algorithm) + - Starts with 4.2 coin blocks until block 42000 + - 7 coin blocks until block 77777 + - 5 coin blocks after 77778, then subsidy halves when block height divisible by 306600 (~1.75 years) + - total supply will be 3,103,954 ANC + +Development process +=================== + +Developers work in their own trees, then submit pull requests when +they think their feature or bug fix is ready. + +The patch will be accepted if there is broad consensus that it is a +good thing. Developers should expect to rework and resubmit patches +if they don't match the project's coding conventions (see coding.txt) +or are controversial. + +The master branch is regularly built and tested, but is not guaranteed +to be completely stable. Tags are regularly created to indicate new +official, stable release versions of Anoncoin. + +Feature branches are created when there are major new features being +worked on by several people. + +From time to time a pull request will become outdated. If this occurs, and +the pull is no longer automatically mergeable; a comment on the pull will +be used to issue a warning of closure. The pull will be closed 15 days +after the warning if action is not taken by the author. Pull requests closed +in this manner will have their corresponding issue labeled 'stagnant'. + +Issues with no commits will be given a similar warning, and closed after +15 days from their last activity. Issues closed in this manner will be +labeled 'stale'. + diff -Nru anoncoin-0.8.5.6/share/pixmaps/bitcoin32.xpm anoncoin-0.8.5.6+git20141111.r4233/share/pixmaps/bitcoin32.xpm --- anoncoin-0.8.5.6/share/pixmaps/bitcoin32.xpm 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/share/pixmaps/bitcoin32.xpm 2014-11-11 13:56:18.000000000 +0000 @@ -1,348 +1,112 @@ -/* XPM */ -static char *graphic[] = { -/* width height num_colors chars_per_pixel */ -"32 32 309 2", -/* colors */ -" c None", -". c #444444", -"X c #474747", -"o c #666666", -"O c #888888", -"+ c None", -"@ c #AAAAAA", -"# c None", -"$ c #CCCCCC", -"% c #474747", -"& c #EEEEEE", -"* c #535353", -"= c None", -"- c #757575", -"; c #979797", -": c #B9B9B9", -"> c #DBDBDB", -", c #FDFDFD", -"< c #626262", -"1 c #848484", -"2 c #A6A6A6", -"3 c #C8C8C8", -"4 c #EAEAEA", -"5 c #686868", -"6 c #737373", -"7 c #717171", -"8 c #939393", -"9 c #B5B5B5", -"0 c #D7D7D7", -"q c #F9F9F9", -"w c #3C3C3C", -"e c #5E5E5E", -"r c #808080", -"t c #4E4E4E", -"y c None", -"u c #A2A2A2", -"i c None", -"p c #C4C4C4", -"a c #E6E6E6", -"s c #4B4B4B", -"d c None", -"f c None", -"g c #6D6D6D", -"h c #8F8F8F", -"j c #B1B1B1", -"k c #D3D3D3", -"l c #F5F5F5", -"z c None", -"x c None", -"c c #434343", -"v c None", -"b c #5A5A5A", -"n c None", -"m c #7C7C7C", -"M c None", -"N c #9E9E9E", -"B c #C0C0C0", -"V c None", -"C c #E2E2E2", -"Z c None", -"A c #5C5C5C", -"S c #474747", -"D c None", -"F c #696969", -"G c #8B8B8B", -"H c None", -"J c #ADADAD", -"K c #CFCFCF", -"L c #4A4A4A", -"P c #F1F1F1", -"I c None", -"U c #565656", -"Y c #787878", -"T c #9A9A9A", -"R c #BCBCBC", -"E c #3F3F3F", -"W c #DEDEDE", -"Q c #6F6F6F", -"! c None", -"~ c #434343", -"^ c #656565", -"/ c None", -"( c #878787", -") c #A9A9A9", -"_ c #CBCBCB", -"` c #EDEDED", -"' c None", -"] c #525252", -"[ c None", -"{ c None", -"} c #747474", -"| c #6B6B6B", -" . c #969696", -".. c #B8B8B8", -"X. c None", -"o. c #DADADA", -"O. c #515151", -"+. c None", -"@. c #FCFCFC", -"#. c None", -"$. c #3F3F3F", -"%. c #464646", -"&. c #616161", -"*. c #838383", -"=. c #A5A5A5", -"-. c #C7C7C7", -";. c #3B3B3B", -":. c None", -">. c #E9E9E9", -",. c #464646", -"<. c None", -"1. c #3B3B3B", -"2. c None", -"3. c #4E4E4E", -"4. c #707070", -"5. c #929292", -"6. c #676767", -"7. c #B4B4B4", -"8. c #424242", -"9. c #D6D6D6", -"0. c #F8F8F8", -"q. c #3B3B3B", -"w. c None", -"e. c None", -"r. c #5D5D5D", -"t. c None", -"y. c #7F7F7F", -"u. c None", -"i. c #A1A1A1", -"p. c #C3C3C3", -"a. c #E5E5E5", -"s. c None", -"d. c None", -"f. c None", -"g. c #373737", -"h. c None", -"j. c #4D4D4D", -"k. c #4A4A4A", -"l. c #6C6C6C", -"z. c #8E8E8E", -"x. c #424242", -"c. c None", -"v. c #B0B0B0", -"b. c #4D4D4D", -"n. c #D2D2D2", -"m. c None", -"M. c #F4F4F4", -"N. c #424242", -"B. c None", -"V. c #4D4D4D", -"C. c None", -"Z. c #7B7B7B", -"A. c #9D9D9D", -"S. c None", -"D. c #BFBFBF", -"F. c #E1E1E1", -"G. c None", -"H. c #636363", -"J. c None", -"K. c #424242", -"L. c #464646", -"P. c None", -"I. c None", -"U. c #686868", -"Y. c #8A8A8A", -"T. c #424242", -"R. c None", -"E. c #ACACAC", -"W. c #CECECE", -"Q. c None", -"!. c #424242", -"~. c #F0F0F0", -"^. c #555555", -"/. c #777777", -"(. c None", -"). c #999999", -"_. c None", -"`. c #BBBBBB", -"'. c #DDDDDD", -"]. c None", -"[. c #FFFFFF", -"{. c #424242", -"}. c None", -"|. c #868686", -" X c #A8A8A8", -".X c #CACACA", -"XX c #3E3E3E", -"oX c #ECECEC", -"OX c #454545", -"+X c #515151", -"@X c #737373", -"#X c #959595", -"$X c #B7B7B7", -"%X c #D9D9D9", -"&X c #454545", -"*X c #FBFBFB", -"=X c None", -"-X c None", -";X c #454545", -":X c #606060", -">X c #A4A4A4", -",X c #3A3A3A", -"o c #484848", -",o c #6A6A6A", -"X&o+XE uX+. ", -" m.;X* _X3 C P 0.*X[X[X@.0.& roXoh 6X8.v ", -" { ^XPX=oa.eXM.%X..u 8 8XwokX0 6oxXC VXg XX/ ", -" d ~ G 9.~.eX.6owX|Xg.s. ", -" I.,.- wXl ro; @ 2o=.mXm _ Xo-.K r =.XoyXg g a.P 4o,o%.KX ", -" bX+XB ~.oo*oeo9 2 GX@XkX$ p -.W (Xy.Y g 7Xr.F 4 4 YXS 1X ", -" <.DX8 pX$oGX..2o.o XJ gX_ !X$ k W.] Z.0o7 g r N j xXW O MXu. ", -" 'XLXX@ ).} W W.#opXGXU y.&o_X..9.a D.n.JXB >ow. ", -"h.b.y.rol 8X8XwoN yXQXZ.8 a ]XTX~.*.7 ) =ok 9.]XCX0 2 P o.(Xt d.", -"IX7o=.& o.&o#XUX.oE.7.7XYXooC oo>.L.F =.HXlX#o-.=.m :XW 2X).T._.", -"M s eoeX: O v.eoB eo@ogX'.>.~X6opX=.: /.3 @o5.PX,o,o9o..6o9X. Z ", -"Q.9o!X$o..3 k .XXop .} $oJXM.0.[.[.).l.z.Z./.PX7XF gXGXl B dX+ ", -"Q tXW.M...wXwX.X7.Y +Xv.[.q , [.kX< tX|XWXr 0oPX( kXW.: ~.-.* 6.", -"qo%oHXM.: $ 7..o} &ooX[.RX, RXJX* &o_XoJ.", -"! >o`.$o`.r _X_XFXEX,oRXxX~.*X_X&.8X8 yX) J @oeo$XUXEX: P j {.# ", -"e.!.i.oXTXy.i.`X.X( QX*XoX>.$o|X%o4.(X@X} /.PX%oF F }Xrooo .AXy ", -"= j.mX'.6oGX0 0 #oy.HXJXa -oa.oo-oroW TXo.]XF.tXo ^ O $o0 l.O.}.", -" 2.3.iX6o4oeoC iXY & 4 oopXCXW TX]X9.k 4olX$ dXy.Z.K & `.. f ", -" X.K. r c z ", -" 6 dX`.~X4 F U dX$.k.}Xg g F SX^ :Xb e F mXB @o>.a 7.{.#. ", -" =X&XgXK 6oa 7 (XJ 3 4o!XiXVX@ou UXN J eo$X2 pX4 _ e V.n ", -" o3Xy.wX~.~X@op 0 wXW.YXwo( |.5.A.*o .@ 4 ~X4o@X;.I ", -" G.w y.4o~Xl K @o Xr < EXOo/.&o*.NX4oxXa _ @X3of. ", -" aX,XU.: CX~.6oo.7.*o .T XD.W xX& TX7.e DXcX ", -" i OX>o( D.> 4 xX0.0.eX$oP 2X%X`.r . L 5X ", -" S.[ N.dX4.UX9X=o-.-.B j #Xl.L.x.' C. ", -" (.BXrXK.~ >o/X/X>o~ ZX0X{Xx ", -" zXqXt.)X| w.-X1o " -}; +/* XPM */ +static char * bitcoin32_xpm[] = { +"32 32 77 1", +" c None", +". c #A2A1A1", +"+ c #A1A1A1", +"@ c #A1A0A0", +"# c #9F9F9F", +"$ c #A7A7A7", +"% c #A9A9A9", +"& c #AEAEAE", +"* c #B0B0B0", +"= c #B1B1B1", +"- c #A8A8A8", +"; c #A4A4A4", +"> c #ACACAC", +", c #B2B2B2", +"' c #AAAAAA", +") c #ABABAB", +"! c #A6A6A6", +"~ c #A3A3A3", +"{ c #A8A7A7", +"] c #A5A5A5", +"^ c #ADADAD", +"/ c #9E9E9E", +"( c #ADACAC", +"_ c #A2A2A2", +": c #A0A0A0", +"< c #9D9D9D", +"[ c #A5A4A4", +"} c #9C9C9C", +"| c #9B9B9B", +"1 c #979797", +"2 c #8C8C8C", +"3 c #848484", +"4 c #838383", +"5 c #878787", +"6 c #929292", +"7 c #9A9A9A", +"8 c #AFAFAF", +"9 c #8B8B8B", +"0 c #7F7F7F", +"a c #808080", +"b c #7E7E7E", +"c c #828282", +"d c #969696", +"e c #939292", +"f c #999999", +"g c #898989", +"h c #8A8A8A", +"i c #888888", +"j c #959595", +"k c #939393", +"l c #909090", +"m c #8D8D8D", +"n c #9D9C9C", +"o c #B4B4B4", +"p c #B6B6B6", +"q c #919090", +"r c #A9A8A8", +"s c #B8B8B8", +"t c #BCBCBC", +"u c #B5B5B5", +"v c #C5C5C5", +"w c #C1C1C1", +"x c #B3B3B3", +"y c #C8C8C8", +"z c #BFBFBF", +"A c #B9B9B9", +"B c #AAA9A9", +"C c #9E9D9D", +"D c #949494", +"E c #919191", +"F c #8E8E8E", +"G c #858585", +"H c #B7B7B7", +"I c #818181", +"J c #989898", +"K c #949393", +"L c #989797", +" ", +" .+@ ", +" #$%&*==*&-; ", +" +>,')'!;~!%%)={ ", +" -*)&'!;+##+~]%^%*/ ", +" ()&'$;_:/<'[ ", +" ^%'!~+#/<}|||}/#+~!%-] ", +" '));_:/<}1234567<<#+~'%# ", +" _&8$_/<}}790aabcd<}&e ", +" *,);:/}% ", +" ]88$_/}<#+fkllmi47_:<}<+!^8j ", +" ^,);:<}<+;}7djkmh;!_/}<#~%>~ ", +" no8$_/<<#_]#:}|fk18';#<}/+!^= ", +" %^);:<}<:]]_]~_:}$p^!+/}<#~%=q ", +" r%$_#<<#_-!!%''%]st,';:/}/+]$# ", +" ;-;:<}<:;)!'^8,u&vwp&$+/}<#~~+ ", +" ]']+/}<:;-~-*=xuxyzu^]+/}<:~]+ ", +" ;>-~#<]+<}<:}f'=*)<^s8-~#<}<:;%)C ", +" !=*%~#<}/dD8=8+jEF2i9d}}/_$&u ", +" ou>]+<}|kD,**#|1DlmG57<:;'x* ", +" BH*%~#<7k<=*8&>%;+/gI7/+$^8+ ", +" :xu>]+<}1-=*8&^%]_:a4|#;',x9 ", +" (p*-~#/<~~_+_+#]~+:/}fJJfJ1dk6}_;'== ", +" +&=>-]_+#/<<<<<#:_;$)8&K ", +" [&u*^-]~+#<%]~+:_;$)8oo=L ", +" L*,Au*>-]]$)&oH,>2 ", +" #*p,o=^)8,8p)f ", +" D:]^=*>_#m ", +" "}; Binary files /tmp/HJIlW0zWiX/anoncoin-0.8.5.6/share/pixmaps/bitcoin-bc.ico and /tmp/M7FtINbfTK/anoncoin-0.8.5.6+git20141111.r4233/share/pixmaps/bitcoin-bc.ico differ Binary files /tmp/HJIlW0zWiX/anoncoin-0.8.5.6/share/pixmaps/bitcoin.ico and /tmp/M7FtINbfTK/anoncoin-0.8.5.6+git20141111.r4233/share/pixmaps/bitcoin.ico differ Binary files /tmp/HJIlW0zWiX/anoncoin-0.8.5.6/share/pixmaps/favicon.ico and /tmp/M7FtINbfTK/anoncoin-0.8.5.6+git20141111.r4233/share/pixmaps/favicon.ico differ Binary files /tmp/HJIlW0zWiX/anoncoin-0.8.5.6/share/pixmaps/nsis-header.bmp and /tmp/M7FtINbfTK/anoncoin-0.8.5.6+git20141111.r4233/share/pixmaps/nsis-header.bmp differ Binary files /tmp/HJIlW0zWiX/anoncoin-0.8.5.6/share/pixmaps/nsis-wizard.bmp and /tmp/M7FtINbfTK/anoncoin-0.8.5.6+git20141111.r4233/share/pixmaps/nsis-wizard.bmp differ diff -Nru anoncoin-0.8.5.6/share/qt/clean_mac_info_plist.py anoncoin-0.8.5.6+git20141111.r4233/share/qt/clean_mac_info_plist.py --- anoncoin-0.8.5.6/share/qt/clean_mac_info_plist.py 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/share/qt/clean_mac_info_plist.py 2014-11-11 13:56:18.000000000 +0000 @@ -9,10 +9,10 @@ bitcoinDir = "./"; inFile = bitcoinDir+"/share/qt/Info.plist" -outFile = "Bitcoin-Qt.app/Contents/Info.plist" +outFile = "Anoncoin-Qt.app/Contents/Info.plist" version = "unknown"; -fileForGrabbingVersion = bitcoinDir+"bitcoin-qt.pro" +fileForGrabbingVersion = bitcoinDir+"anoncoin-qt.pro" for line in open(fileForGrabbingVersion): lineArr = line.replace(" ", "").split("="); if lineArr[0].startswith("VERSION"): @@ -26,4 +26,4 @@ fOut = open(outFile, "w"); fOut.write(newFileContent); -print "Info.plist fresh created" \ No newline at end of file +print "Info.plist fresh created" diff -Nru anoncoin-0.8.5.6/share/setup.nsi anoncoin-0.8.5.6+git20141111.r4233/share/setup.nsi --- anoncoin-0.8.5.6/share/setup.nsi 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/share/setup.nsi 2014-11-11 13:56:18.000000000 +0000 @@ -5,9 +5,9 @@ # General Symbol Definitions !define REGKEY "SOFTWARE\$(^Name)" -!define VERSION 0.8.5.1 +!define VERSION 0.8.5.6 !define COMPANY "Anoncoin project" -!define URL https://anoncoin/ +!define URL https://anoncoin.net/ # MUI Symbol Definitions !define MUI_ICON "../share/pixmaps/bitcoin.ico" @@ -45,13 +45,13 @@ !insertmacro MUI_LANGUAGE English # Installer attributes -OutFile anoncoin-0.8.5.1-win32-setup.exe +OutFile anoncoin-0.8.5.6-win32-setup.exe InstallDir $PROGRAMFILES\Anoncoin CRCCheck on XPStyle on BrandingText " " ShowInstDetails show -VIProductVersion 0.8.5.1 +VIProductVersion 0.8.5.6 VIAddVersionKey ProductName Anoncoin VIAddVersionKey ProductVersion "${VERSION}" VIAddVersionKey CompanyName "${COMPANY}" diff -Nru anoncoin-0.8.5.6/src/anoncoinrpc.cpp anoncoin-0.8.5.6+git20141111.r4233/src/anoncoinrpc.cpp --- anoncoin-0.8.5.6/src/anoncoinrpc.cpp 1970-01-01 00:00:00.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/anoncoinrpc.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -0,0 +1,1305 @@ +// Copyright (c) 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 "init.h" +#include "util.h" +#include "sync.h" +#include "ui_interface.h" +#include "base58.h" +#include "anoncoinrpc.h" +#include "db.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace boost; +using namespace boost::asio; +using namespace json_spirit; + +static std::string strRPCUserColonPass; + +// These are created by StartRPCThreads, destroyed in StopRPCThreads +static asio::io_service* rpc_io_service = NULL; +static ssl::context* rpc_ssl_context = NULL; +static boost::thread_group* rpc_worker_group = NULL; + +static inline unsigned short GetDefaultRPCPort() +{ + return GetBoolArg("-testnet", false) ? 19376 : 9376; +} + +Object JSONRPCError(int code, const string& message) +{ + Object error; + error.push_back(Pair("code", code)); + error.push_back(Pair("message", message)); + return error; +} + +void RPCTypeCheck(const Array& params, + const list& typesExpected, + bool fAllowNull) +{ + unsigned int i = 0; + BOOST_FOREACH(Value_type t, typesExpected) + { + if (params.size() <= i) + break; + + const Value& v = params[i]; + if (!((v.type() == t) || (fAllowNull && (v.type() == null_type)))) + { + string err = strprintf("Expected type %s, got %s", + Value_type_name[t], Value_type_name[v.type()]); + throw JSONRPCError(RPC_TYPE_ERROR, err); + } + i++; + } +} + +void RPCTypeCheck(const Object& o, + const map& typesExpected, + bool fAllowNull) +{ + BOOST_FOREACH(const PAIRTYPE(string, Value_type)& t, typesExpected) + { + const Value& v = find_value(o, t.first); + if (!fAllowNull && v.type() == null_type) + throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first.c_str())); + + if (!((v.type() == t.second) || (fAllowNull && (v.type() == null_type)))) + { + string err = strprintf("Expected type %s for %s, got %s", + Value_type_name[t.second], t.first.c_str(), Value_type_name[v.type()]); + throw JSONRPCError(RPC_TYPE_ERROR, err); + } + } +} + +int64 AmountFromValue(const Value& value) +{ + double dAmount = value.get_real(); + if (dAmount <= 0.0 || dAmount > 4200000.0) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); + int64 nAmount = roundint64(dAmount * COIN); + if (!MoneyRange(nAmount)) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); + return nAmount; +} + +Value ValueFromAmount(int64 amount) +{ + return (double)amount / (double)COIN; +} + +std::string HexBits(unsigned int nBits) +{ + union { + int32_t nBits; + char cBits[4]; + } uBits; + uBits.nBits = htonl((int32_t)nBits); + return HexStr(BEGIN(uBits.cBits), END(uBits.cBits)); +} + + + +/// +/// Note: This interface may still be subject to change. +/// + +string CRPCTable::help(string strCommand) const +{ + string strRet; + set setDone; + for (map::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi) + { + const CRPCCommand *pcmd = mi->second; + string strMethod = mi->first; + // We already filter duplicates, but these deprecated screw up the sort order + if (strMethod.find("label") != string::npos) + continue; + if (strCommand != "" && strMethod != strCommand) + continue; + if (pcmd->reqWallet && !pwalletMain) + continue; + + try + { + Array params; + rpcfn_type pfn = pcmd->actor; + if (setDone.insert(pfn).second) + (*pfn)(params, true); + } + catch (std::exception& e) + { + // Help text is returned in an exception + string strHelp = string(e.what()); + if (strCommand == "") + if (strHelp.find('\n') != string::npos) + strHelp = strHelp.substr(0, strHelp.find('\n')); + strRet += strHelp + "\n"; + } + } + if (strRet == "") + strRet = strprintf("help: unknown command: %s\n", strCommand.c_str()); + strRet = strRet.substr(0,strRet.size()-1); + return strRet; +} + +Value help(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "help [command]\n" + "List commands, or get help for a command."); + + string strCommand; + if (params.size() > 0) + strCommand = params[0].get_str(); + + return tableRPC.help(strCommand); +} + + +Value stop(const Array& params, bool fHelp) +{ + // Accept the deprecated and ignored 'detach' boolean argument + if (fHelp || params.size() > 1) + throw runtime_error( + "stop\n" + "Stop Anoncoin server."); + // Shutdown will take long enough that the response should get back + StartShutdown(); + return "Anoncoin server stopping"; +} + + + +// +// Call Table +// + + +static const CRPCCommand vRPCCommands[] = +{ // name actor (function) okSafeMode threadSafe reqWallet + // ------------------------ ----------------------- ---------- ---------- --------- + { "help", &help, true, true, false }, + { "stop", &stop, true, true, false }, + { "getblockcount", &getblockcount, true, false, false }, + { "getbestblockhash", &getbestblockhash, true, false, false }, + { "getconnectioncount", &getconnectioncount, true, false, false }, + { "getpeerinfo", &getpeerinfo, true, false, false }, + { "addnode", &addnode, true, true, false }, + { "getaddednodeinfo", &getaddednodeinfo, true, true, false }, + { "getdifficulty", &getdifficulty, true, false, false }, + { "getnetworkhashps", &getnetworkhashps, true, false, false }, + { "getgenerate", &getgenerate, true, false, false }, + { "setgenerate", &setgenerate, true, false, true }, + { "gethashespersec", &gethashespersec, true, false, false }, + { "getinfo", &getinfo, true, false, false }, + { "getmininginfo", &getmininginfo, true, false, false }, + { "getnewaddress", &getnewaddress, true, false, true }, + { "getaccountaddress", &getaccountaddress, true, false, true }, + { "setaccount", &setaccount, true, false, true }, + { "getaccount", &getaccount, false, false, true }, + { "getaddressesbyaccount", &getaddressesbyaccount, true, false, true }, + { "sendtoaddress", &sendtoaddress, false, false, true }, + { "getreceivedbyaddress", &getreceivedbyaddress, false, false, true }, + { "getreceivedbyaccount", &getreceivedbyaccount, false, false, true }, + { "listreceivedbyaddress", &listreceivedbyaddress, false, false, true }, + { "listreceivedbyaccount", &listreceivedbyaccount, false, false, true }, + { "backupwallet", &backupwallet, true, false, true }, + { "keypoolrefill", &keypoolrefill, true, false, true }, + { "walletpassphrase", &walletpassphrase, true, false, true }, + { "walletpassphrasechange", &walletpassphrasechange, false, false, true }, + { "walletlock", &walletlock, true, false, true }, + { "encryptwallet", &encryptwallet, false, false, true }, + { "validateaddress", &validateaddress, true, false, false }, + { "getbalance", &getbalance, false, false, true }, + { "move", &movecmd, false, false, true }, + { "sendfrom", &sendfrom, false, false, true }, + { "sendmany", &sendmany, false, false, true }, + { "addmultisigaddress", &addmultisigaddress, false, false, true }, + { "createmultisig", &createmultisig, true, true , false }, + { "getrawmempool", &getrawmempool, true, false, false }, + { "getblock", &getblock, false, false, false }, + { "getblockhash", &getblockhash, false, false, false }, + { "gettransaction", &gettransaction, false, false, true }, + { "listtransactions", &listtransactions, false, false, true }, + { "listaddressgroupings", &listaddressgroupings, false, false, true }, + { "signmessage", &signmessage, false, false, true }, + { "verifymessage", &verifymessage, false, false, false }, + { "getwork", &getwork, true, false, true }, + { "getworkex", &getworkex, true, false, true }, + { "listaccounts", &listaccounts, false, false, true }, + { "settxfee", &settxfee, false, false, true }, + { "getblocktemplate", &getblocktemplate, true, false, false }, + { "submitblock", &submitblock, false, false, false }, + { "setmininput", &setmininput, false, false, false }, + { "listsinceblock", &listsinceblock, false, false, true }, + { "dumpprivkey", &dumpprivkey, true, false, true }, + { "importprivkey", &importprivkey, false, false, true }, + { "listunspent", &listunspent, false, false, true }, + { "getrawtransaction", &getrawtransaction, false, false, false }, + { "createrawtransaction", &createrawtransaction, false, false, false }, + { "decoderawtransaction", &decoderawtransaction, false, false, false }, + { "signrawtransaction", &signrawtransaction, false, false, false }, + { "sendrawtransaction", &sendrawtransaction, false, false, false }, + { "gettxoutsetinfo", &gettxoutsetinfo, true, false, false }, + { "gettxout", &gettxout, true, false, false }, + { "lockunspent", &lockunspent, false, false, true }, + { "listlockunspent", &listlockunspent, false, false, true }, + { "verifychain", &verifychain, true, false, false }, +}; + +CRPCTable::CRPCTable() +{ + unsigned int vcidx; + for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0])); vcidx++) + { + const CRPCCommand *pcmd; + + pcmd = &vRPCCommands[vcidx]; + mapCommands[pcmd->name] = pcmd; + } +} + +const CRPCCommand *CRPCTable::operator[](string name) const +{ + map::const_iterator it = mapCommands.find(name); + if (it == mapCommands.end()) + return NULL; + return (*it).second; +} + +// +// HTTP protocol +// +// This ain't Apache. We're just using HTTP header for the length field +// and to be compatible with other JSON-RPC implementations. +// + +string HTTPPost(const string& strMsg, const map& mapRequestHeaders) +{ + ostringstream s; + s << "POST / HTTP/1.1\r\n" + << "User-Agent: anoncoin-json-rpc/" << FormatFullVersion() << "\r\n" + << "Host: 127.0.0.1\r\n" + << "Content-Type: application/json\r\n" + << "Content-Length: " << strMsg.size() << "\r\n" + << "Connection: close\r\n" + << "Accept: application/json\r\n"; + BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapRequestHeaders) + s << item.first << ": " << item.second << "\r\n"; + s << "\r\n" << strMsg; + + return s.str(); +} + +string rfc1123Time() +{ + char buffer[64]; + time_t now; + time(&now); + struct tm* now_gmt = gmtime(&now); + string locale(setlocale(LC_TIME, NULL)); + setlocale(LC_TIME, "C"); // we want POSIX (aka "C") weekday/month strings + strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S +0000", now_gmt); + setlocale(LC_TIME, locale.c_str()); + return string(buffer); +} + +static string HTTPReply(int nStatus, const string& strMsg, bool keepalive) +{ + if (nStatus == HTTP_UNAUTHORIZED) + return strprintf("HTTP/1.0 401 Authorization Required\r\n" + "Date: %s\r\n" + "Server: anoncoin-json-rpc/%s\r\n" + "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 296\r\n" + "\r\n" + "\r\n" + "\r\n" + "\r\n" + "Error\r\n" + "\r\n" + "\r\n" + "

401 Unauthorized.

\r\n" + "\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str()); + const char *cStatus; + if (nStatus == HTTP_OK) cStatus = "OK"; + else if (nStatus == HTTP_BAD_REQUEST) cStatus = "Bad Request"; + else if (nStatus == HTTP_FORBIDDEN) cStatus = "Forbidden"; + else if (nStatus == HTTP_NOT_FOUND) cStatus = "Not Found"; + else if (nStatus == HTTP_INTERNAL_SERVER_ERROR) cStatus = "Internal Server Error"; + else cStatus = ""; + return strprintf( + "HTTP/1.1 %d %s\r\n" + "Date: %s\r\n" + "Connection: %s\r\n" + "Content-Length: %"PRIszu"\r\n" + "Content-Type: application/json\r\n" + "Server: anoncoin-json-rpc/%s\r\n" + "\r\n" + "%s", + nStatus, + cStatus, + rfc1123Time().c_str(), + keepalive ? "keep-alive" : "close", + strMsg.size(), + FormatFullVersion().c_str(), + strMsg.c_str()); +} + +bool ReadHTTPRequestLine(std::basic_istream& stream, int &proto, + string& http_method, string& http_uri) +{ + string str; + getline(stream, str); + + // HTTP request line is space-delimited + vector vWords; + boost::split(vWords, str, boost::is_any_of(" ")); + if (vWords.size() < 2) + return false; + + // HTTP methods permitted: GET, POST + http_method = vWords[0]; + if (http_method != "GET" && http_method != "POST") + return false; + + // HTTP URI must be an absolute path, relative to current host + http_uri = vWords[1]; + if (http_uri.size() == 0 || http_uri[0] != '/') + return false; + + // parse proto, if present + string strProto = ""; + if (vWords.size() > 2) + strProto = vWords[2]; + + proto = 0; + const char *ver = strstr(strProto.c_str(), "HTTP/1."); + if (ver != NULL) + proto = atoi(ver+7); + + return true; +} + +int ReadHTTPStatus(std::basic_istream& stream, int &proto) +{ + string str; + getline(stream, str); + vector vWords; + boost::split(vWords, str, boost::is_any_of(" ")); + if (vWords.size() < 2) + return HTTP_INTERNAL_SERVER_ERROR; + proto = 0; + const char *ver = strstr(str.c_str(), "HTTP/1."); + if (ver != NULL) + proto = atoi(ver+7); + return atoi(vWords[1].c_str()); +} + +int ReadHTTPHeaders(std::basic_istream& stream, map& mapHeadersRet) +{ + int nLen = 0; + loop + { + string str; + std::getline(stream, str); + if (str.empty() || str == "\r") + break; + string::size_type nColon = str.find(":"); + if (nColon != string::npos) + { + string strHeader = str.substr(0, nColon); + boost::trim(strHeader); + boost::to_lower(strHeader); + string strValue = str.substr(nColon+1); + boost::trim(strValue); + mapHeadersRet[strHeader] = strValue; + if (strHeader == "content-length") + nLen = atoi(strValue.c_str()); + } + } + return nLen; +} + +int ReadHTTPMessage(std::basic_istream& stream, map& mapHeadersRet, string& strMessageRet, + int nProto) +{ + mapHeadersRet.clear(); + strMessageRet = ""; + + // Read header + int nLen = ReadHTTPHeaders(stream, mapHeadersRet); + if (nLen < 0 || nLen > (int)MAX_SIZE) + return HTTP_INTERNAL_SERVER_ERROR; + + // Read message + if (nLen > 0) + { + vector vch(nLen); + stream.read(&vch[0], nLen); + strMessageRet = string(vch.begin(), vch.end()); + } + + string sConHdr = mapHeadersRet["connection"]; + + if ((sConHdr != "close") && (sConHdr != "keep-alive")) + { + if (nProto >= 1) + mapHeadersRet["connection"] = "keep-alive"; + else + mapHeadersRet["connection"] = "close"; + } + + return HTTP_OK; +} + +bool HTTPAuthorized(map& mapHeaders) +{ + string strAuth = mapHeaders["authorization"]; + if (strAuth.substr(0,6) != "Basic ") + return false; + string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64); + string strUserPass = DecodeBase64(strUserPass64); + return TimingResistantEqual(strUserPass, strRPCUserColonPass); +} + +// +// JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility, +// but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were +// unspecified (HTTP errors and contents of 'error'). +// +// 1.0 spec: http://json-rpc.org/wiki/specification +// 1.2 spec: http://groups.google.com/group/json-rpc/web/json-rpc-over-http +// http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx +// + +string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id) +{ + Object request; + request.push_back(Pair("method", strMethod)); + request.push_back(Pair("params", params)); + request.push_back(Pair("id", id)); + return write_string(Value(request), false) + "\n"; +} + +Object JSONRPCReplyObj(const Value& result, const Value& error, const Value& id) +{ + Object reply; + if (error.type() != null_type) + reply.push_back(Pair("result", Value::null)); + else + reply.push_back(Pair("result", result)); + reply.push_back(Pair("error", error)); + reply.push_back(Pair("id", id)); + return reply; +} + +string JSONRPCReply(const Value& result, const Value& error, const Value& id) +{ + Object reply = JSONRPCReplyObj(result, error, id); + return write_string(Value(reply), false) + "\n"; +} + +void ErrorReply(std::ostream& stream, const Object& objError, const Value& id) +{ + // Send error reply from json-rpc error object + int nStatus = HTTP_INTERNAL_SERVER_ERROR; + int code = find_value(objError, "code").get_int(); + if (code == RPC_INVALID_REQUEST) nStatus = HTTP_BAD_REQUEST; + else if (code == RPC_METHOD_NOT_FOUND) nStatus = HTTP_NOT_FOUND; + string strReply = JSONRPCReply(Value::null, objError, id); + stream << HTTPReply(nStatus, strReply, false) << std::flush; +} + +bool ClientAllowed(const boost::asio::ip::address& address) +{ + // Make sure that IPv4-compatible and IPv4-mapped IPv6 addresses are treated as IPv4 addresses + if (address.is_v6() + && (address.to_v6().is_v4_compatible() + || address.to_v6().is_v4_mapped())) + return ClientAllowed(address.to_v6().to_v4()); + + if (address == asio::ip::address_v4::loopback() + || address == asio::ip::address_v6::loopback() + || (address.is_v4() + // Check whether IPv4 addresses match 127.0.0.0/8 (loopback subnet) + && (address.to_v4().to_ulong() & 0xff000000) == 0x7f000000)) + return true; + + const string strAddress = address.to_string(); + const vector& vAllow = mapMultiArgs["-rpcallowip"]; + BOOST_FOREACH(string strAllow, vAllow) + if (WildcardMatch(strAddress, strAllow)) + return true; + return false; +} + +// +// IOStream device that speaks SSL but can also speak non-SSL +// +template +class SSLIOStreamDevice : public iostreams::device { +public: + SSLIOStreamDevice(asio::ssl::stream &streamIn, bool fUseSSLIn) : stream(streamIn) + { + fUseSSL = fUseSSLIn; + fNeedHandshake = fUseSSLIn; + } + + void handshake(ssl::stream_base::handshake_type role) + { + if (!fNeedHandshake) return; + fNeedHandshake = false; + stream.handshake(role); + } + std::streamsize read(char* s, std::streamsize n) + { + handshake(ssl::stream_base::server); // HTTPS servers read first + if (fUseSSL) return stream.read_some(asio::buffer(s, n)); + return stream.next_layer().read_some(asio::buffer(s, n)); + } + std::streamsize write(const char* s, std::streamsize n) + { + handshake(ssl::stream_base::client); // HTTPS clients write first + if (fUseSSL) return asio::write(stream, asio::buffer(s, n)); + return asio::write(stream.next_layer(), asio::buffer(s, n)); + } + bool connect(const std::string& server, const std::string& port) + { + ip::tcp::resolver resolver(stream.get_io_service()); + ip::tcp::resolver::query query(server.c_str(), port.c_str()); + ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); + ip::tcp::resolver::iterator end; + boost::system::error_code error = asio::error::host_not_found; + while (error && endpoint_iterator != end) + { + stream.lowest_layer().close(); + stream.lowest_layer().connect(*endpoint_iterator++, error); + } + if (error) + return false; + return true; + } + +private: + bool fNeedHandshake; + bool fUseSSL; + asio::ssl::stream& stream; +}; + +class AcceptedConnection +{ +public: + virtual ~AcceptedConnection() {} + + virtual std::iostream& stream() = 0; + virtual std::string peer_address_to_string() const = 0; + virtual void close() = 0; +}; + +template +class AcceptedConnectionImpl : public AcceptedConnection +{ +public: + AcceptedConnectionImpl( + asio::io_service& io_service, + ssl::context &context, + bool fUseSSL) : + sslStream(io_service, context), + _d(sslStream, fUseSSL), + _stream(_d) + { + } + + virtual std::iostream& stream() + { + return _stream; + } + + virtual std::string peer_address_to_string() const + { + return peer.address().to_string(); + } + + virtual void close() + { + _stream.close(); + } + + typename Protocol::endpoint peer; + asio::ssl::stream sslStream; + +private: + SSLIOStreamDevice _d; + iostreams::stream< SSLIOStreamDevice > _stream; +}; + +void ServiceConnection(AcceptedConnection *conn); + +// Forward declaration required for RPCListen +template +static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor > acceptor, + ssl::context& context, + bool fUseSSL, + AcceptedConnection* conn, + const boost::system::error_code& error); + +/** + * Sets up I/O resources to accept and handle a new connection. + */ +template +static void RPCListen(boost::shared_ptr< basic_socket_acceptor > acceptor, + ssl::context& context, + const bool fUseSSL) +{ + // Accept connection + AcceptedConnectionImpl* conn = new AcceptedConnectionImpl(acceptor->get_io_service(), context, fUseSSL); + + acceptor->async_accept( + conn->sslStream.lowest_layer(), + conn->peer, + boost::bind(&RPCAcceptHandler, + acceptor, + boost::ref(context), + fUseSSL, + conn, + boost::asio::placeholders::error)); +} + +/** + * Accept and handle incoming connection. + */ +template +static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor > acceptor, + ssl::context& context, + const bool fUseSSL, + AcceptedConnection* conn, + const boost::system::error_code& error) +{ + // Immediately start accepting new connections, except when we're cancelled or our socket is closed. + if (error != asio::error::operation_aborted && acceptor->is_open()) + RPCListen(acceptor, context, fUseSSL); + + AcceptedConnectionImpl* tcp_conn = dynamic_cast< AcceptedConnectionImpl* >(conn); + + // TODO: Actually handle errors + if (error) + { + delete conn; + } + + // Restrict callers by IP. It is important to + // do this before starting client thread, to filter out + // certain DoS and misbehaving clients. + else if (tcp_conn && !ClientAllowed(tcp_conn->peer.address())) + { + // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake. + if (!fUseSSL) + conn->stream() << HTTPReply(HTTP_FORBIDDEN, "", false) << std::flush; + delete conn; + } + else { + ServiceConnection(conn); + conn->close(); + delete conn; + } +} + +void StartRPCThreads() +{ + strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; + if ((mapArgs["-rpcpassword"] == "") || + (mapArgs["-rpcuser"] == mapArgs["-rpcpassword"])) + { + unsigned char rand_pwd[32]; + RAND_bytes(rand_pwd, 32); + string strWhatAmI = "To use anoncoind"; + if (mapArgs.count("-server")) + strWhatAmI = strprintf(_("To use the %s option"), "\"-server\""); + else if (mapArgs.count("-daemon")) + strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\""); + uiInterface.ThreadSafeMessageBox(strprintf( + _("%s, you must set a rpcpassword in the configuration file:\n" + "%s\n" + "It is recommended you use the following random password:\n" + "rpcuser=anoncoinrpc\n" + "rpcpassword=%s\n" + "(you do not need to remember this password)\n" + "The username and password MUST NOT be the same.\n" + "If the file does not exist, create it with owner-readable-only file permissions.\n" + "It is also recommended to set alertnotify so you are notified of problems;\n" + "for example: alertnotify=echo %%s | mail -s \"Anoncoin Alert\" admin@foo.com\n"), + strWhatAmI.c_str(), + GetConfigFile().string().c_str(), + EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()), + "", CClientUIInterface::MSG_ERROR); + StartShutdown(); + return; + } + + assert(rpc_io_service == NULL); + rpc_io_service = new asio::io_service(); + rpc_ssl_context = new ssl::context(*rpc_io_service, ssl::context::sslv23); + + const bool fUseSSL = GetBoolArg("-rpcssl"); + + if (fUseSSL) + { + rpc_ssl_context->set_options(ssl::context::no_sslv2); + + filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert")); + if (!pathCertFile.is_complete()) pathCertFile = filesystem::path(GetDataDir()) / pathCertFile; + if (filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string()); + else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string().c_str()); + + filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem")); + if (!pathPKFile.is_complete()) pathPKFile = filesystem::path(GetDataDir()) / pathPKFile; + if (filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem); + else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string().c_str()); + + string strCiphers = GetArg("-rpcsslciphers", "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH"); + SSL_CTX_set_cipher_list(rpc_ssl_context->impl(), strCiphers.c_str()); + } + + // Try a dual IPv6/IPv4 socket, falling back to separate IPv4 and IPv6 sockets + const bool loopback = !mapArgs.count("-rpcallowip"); + asio::ip::address bindAddress = loopback ? asio::ip::address_v6::loopback() : asio::ip::address_v6::any(); + ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", GetDefaultRPCPort())); + boost::system::error_code v6_only_error; + boost::shared_ptr acceptor(new ip::tcp::acceptor(*rpc_io_service)); + + bool fListening = false; + std::string strerr; + try + { + acceptor->open(endpoint.protocol()); + acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); + + // Try making the socket dual IPv6/IPv4 (if listening on the "any" address) + acceptor->set_option(boost::asio::ip::v6_only(loopback), v6_only_error); + + acceptor->bind(endpoint); + acceptor->listen(socket_base::max_connections); + + RPCListen(acceptor, *rpc_ssl_context, fUseSSL); + + fListening = true; + } + catch(boost::system::system_error &e) + { + strerr = strprintf(_("An error occurred while setting up the RPC port %u for listening on IPv6, falling back to IPv4: %s"), endpoint.port(), e.what()); + } + + try { + // If dual IPv6/IPv4 failed (or we're opening loopback interfaces only), open IPv4 separately + if (!fListening || loopback || v6_only_error) + { + bindAddress = loopback ? asio::ip::address_v4::loopback() : asio::ip::address_v4::any(); + endpoint.address(bindAddress); + + acceptor.reset(new ip::tcp::acceptor(*rpc_io_service)); + acceptor->open(endpoint.protocol()); + acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); + acceptor->bind(endpoint); + acceptor->listen(socket_base::max_connections); + + RPCListen(acceptor, *rpc_ssl_context, fUseSSL); + + fListening = true; + } + } + catch(boost::system::system_error &e) + { + strerr = strprintf(_("An error occurred while setting up the RPC port %u for listening on IPv4: %s"), endpoint.port(), e.what()); + } + + if (!fListening) { + uiInterface.ThreadSafeMessageBox(strerr, "", CClientUIInterface::MSG_ERROR); + StartShutdown(); + return; + } + + rpc_worker_group = new boost::thread_group(); + for (int i = 0; i < GetArg("-rpcthreads", 4); i++) + rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service)); +} + +void StopRPCThreads() +{ + if (rpc_io_service == NULL) return; + + rpc_io_service->stop(); + rpc_worker_group->join_all(); + delete rpc_worker_group; rpc_worker_group = NULL; + delete rpc_ssl_context; rpc_ssl_context = NULL; + delete rpc_io_service; rpc_io_service = NULL; +} + +class JSONRequest +{ +public: + Value id; + string strMethod; + Array params; + + JSONRequest() { id = Value::null; } + void parse(const Value& valRequest); +}; + +void JSONRequest::parse(const Value& valRequest) +{ + // Parse request + if (valRequest.type() != obj_type) + throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object"); + const Object& request = valRequest.get_obj(); + + // Parse id now so errors from here on will have the id + id = find_value(request, "id"); + + // Parse method + Value valMethod = find_value(request, "method"); + if (valMethod.type() == null_type) + throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method"); + if (valMethod.type() != str_type) + throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string"); + strMethod = valMethod.get_str(); + if (strMethod != "getwork" && strMethod != "getworkex" && strMethod != "getblocktemplate") + printf("ThreadRPCServer method=%s\n", strMethod.c_str()); + + // Parse params + Value valParams = find_value(request, "params"); + if (valParams.type() == array_type) + params = valParams.get_array(); + else if (valParams.type() == null_type) + params = Array(); + else + throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array"); +} + +static Object JSONRPCExecOne(const Value& req) +{ + Object rpc_result; + + JSONRequest jreq; + try { + jreq.parse(req); + + Value result = tableRPC.execute(jreq.strMethod, jreq.params); + rpc_result = JSONRPCReplyObj(result, Value::null, jreq.id); + } + catch (Object& objError) + { + rpc_result = JSONRPCReplyObj(Value::null, objError, jreq.id); + } + catch (std::exception& e) + { + rpc_result = JSONRPCReplyObj(Value::null, + JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); + } + + return rpc_result; +} + +static string JSONRPCExecBatch(const Array& vReq) +{ + Array ret; + for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) + ret.push_back(JSONRPCExecOne(vReq[reqIdx])); + + return write_string(Value(ret), false) + "\n"; +} + +void ServiceConnection(AcceptedConnection *conn) +{ + bool fRun = true; + while (fRun) + { + int nProto = 0; + map mapHeaders; + string strRequest, strMethod, strURI; + + // Read HTTP request line + if (!ReadHTTPRequestLine(conn->stream(), nProto, strMethod, strURI)) + break; + + // Read HTTP message headers and body + ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto); + + if (strURI != "/") { + conn->stream() << HTTPReply(HTTP_NOT_FOUND, "", false) << std::flush; + break; + } + + // Check authorization + if (mapHeaders.count("authorization") == 0) + { + conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush; + break; + } + if (!HTTPAuthorized(mapHeaders)) + { + printf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string().c_str()); + /* Deter brute-forcing short passwords. + If this results in a DOS the user really + shouldn't have their RPC port exposed.*/ + if (mapArgs["-rpcpassword"].size() < 20) + MilliSleep(250); + + conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush; + break; + } + if (mapHeaders["connection"] == "close") + fRun = false; + + JSONRequest jreq; + try + { + // Parse request + Value valRequest; + if (!read_string(strRequest, valRequest)) + throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); + + string strReply; + + // singleton request + if (valRequest.type() == obj_type) { + jreq.parse(valRequest); + + Value result = tableRPC.execute(jreq.strMethod, jreq.params); + + // Send reply + strReply = JSONRPCReply(result, Value::null, jreq.id); + + // array of requests + } else if (valRequest.type() == array_type) + strReply = JSONRPCExecBatch(valRequest.get_array()); + else + throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error"); + + conn->stream() << HTTPReply(HTTP_OK, strReply, fRun) << std::flush; + } + catch (Object& objError) + { + ErrorReply(conn->stream(), objError, jreq.id); + break; + } + catch (std::exception& e) + { + ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); + break; + } + } +} + +json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array ¶ms) const +{ + // Find method + const CRPCCommand *pcmd = tableRPC[strMethod]; + if (!pcmd) + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found"); + if (pcmd->reqWallet && !pwalletMain) + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); + + // Observe safe mode + string strWarning = GetWarnings("rpc"); + if (strWarning != "" && !GetBoolArg("-disablesafemode") && + !pcmd->okSafeMode) + throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning); + + try + { + // Execute + Value result; + { + if (pcmd->threadSafe) + result = pcmd->actor(params, false); + else if (!pwalletMain) { + LOCK(cs_main); + result = pcmd->actor(params, false); + } else { + LOCK2(cs_main, pwalletMain->cs_wallet); + result = pcmd->actor(params, false); + } + } + return result; + } + catch (std::exception& e) + { + throw JSONRPCError(RPC_MISC_ERROR, e.what()); + } +} + + +Object CallRPC(const string& strMethod, const Array& params) +{ + if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "") + throw runtime_error(strprintf( + _("You must set rpcpassword= in the configuration file:\n%s\n" + "If the file does not exist, create it with owner-readable-only file permissions."), + GetConfigFile().string().c_str())); + + // Connect to localhost + bool fUseSSL = GetBoolArg("-rpcssl"); + asio::io_service io_service; + ssl::context context(io_service, ssl::context::sslv23); + context.set_options(ssl::context::no_sslv2); + asio::ssl::stream sslStream(io_service, context); + SSLIOStreamDevice d(sslStream, fUseSSL); + iostreams::stream< SSLIOStreamDevice > stream(d); + if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(GetDefaultRPCPort())))) + throw runtime_error("couldn't connect to server"); + + // HTTP basic authentication + string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]); + map mapRequestHeaders; + mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64; + + // Send request + string strRequest = JSONRPCRequest(strMethod, params, 1); + string strPost = HTTPPost(strRequest, mapRequestHeaders); + stream << strPost << std::flush; + + // Receive HTTP reply status + int nProto = 0; + int nStatus = ReadHTTPStatus(stream, nProto); + + // Receive HTTP reply message headers and body + map mapHeaders; + string strReply; + ReadHTTPMessage(stream, mapHeaders, strReply, nProto); + + if (nStatus == HTTP_UNAUTHORIZED) + throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)"); + else if (nStatus >= 400 && nStatus != HTTP_BAD_REQUEST && nStatus != HTTP_NOT_FOUND && nStatus != HTTP_INTERNAL_SERVER_ERROR) + throw runtime_error(strprintf("server returned HTTP error %d", nStatus)); + else if (strReply.empty()) + throw runtime_error("no response from server"); + + // Parse reply + Value valReply; + if (!read_string(strReply, valReply)) + throw runtime_error("couldn't parse reply from server"); + const Object& reply = valReply.get_obj(); + if (reply.empty()) + throw runtime_error("expected reply to have result, error and id properties"); + + return reply; +} + + + + +template +void ConvertTo(Value& value, bool fAllowNull=false) +{ + if (fAllowNull && value.type() == null_type) + return; + if (value.type() == str_type) + { + // reinterpret string as unquoted json value + Value value2; + string strJSON = value.get_str(); + if (!read_string(strJSON, value2)) + throw runtime_error(string("Error parsing JSON:")+strJSON); + ConvertTo(value2, fAllowNull); + value = value2; + } + else + { + value = value.get_value(); + } +} + +// Convert strings to command-specific RPC representation +Array RPCConvertValues(const std::string &strMethod, const std::vector &strParams) +{ + Array params; + BOOST_FOREACH(const std::string ¶m, strParams) + params.push_back(param); + + int n = params.size(); + + // + // Special case non-string parameter types + // + if (strMethod == "stop" && n > 0) ConvertTo(params[0]); + if (strMethod == "getaddednodeinfo" && n > 0) ConvertTo(params[0]); + if (strMethod == "setgenerate" && n > 0) ConvertTo(params[0]); + if (strMethod == "setgenerate" && n > 1) ConvertTo(params[1]); + if (strMethod == "getnetworkhashps" && n > 0) ConvertTo(params[0]); + if (strMethod == "getnetworkhashps" && n > 1) ConvertTo(params[1]); + if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "settxfee" && n > 0) ConvertTo(params[0]); + if (strMethod == "setmininput" && n > 0) ConvertTo(params[0]); + if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo(params[1]); + if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo(params[0]); + if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "listreceivedbyaccount" && n > 0) ConvertTo(params[0]); + if (strMethod == "listreceivedbyaccount" && n > 1) ConvertTo(params[1]); + if (strMethod == "getbalance" && n > 1) ConvertTo(params[1]); + if (strMethod == "getblockhash" && n > 0) ConvertTo(params[0]); + if (strMethod == "move" && n > 2) ConvertTo(params[2]); + if (strMethod == "move" && n > 3) ConvertTo(params[3]); + if (strMethod == "sendfrom" && n > 2) ConvertTo(params[2]); + if (strMethod == "sendfrom" && n > 3) ConvertTo(params[3]); + if (strMethod == "listtransactions" && n > 1) ConvertTo(params[1]); + if (strMethod == "listtransactions" && n > 2) ConvertTo(params[2]); + if (strMethod == "listaccounts" && n > 0) ConvertTo(params[0]); + if (strMethod == "walletpassphrase" && n > 1) ConvertTo(params[1]); + if (strMethod == "getblocktemplate" && n > 0) ConvertTo(params[0]); + if (strMethod == "listsinceblock" && n > 1) ConvertTo(params[1]); + if (strMethod == "sendmany" && n > 1) ConvertTo(params[1]); + if (strMethod == "sendmany" && n > 2) ConvertTo(params[2]); + if (strMethod == "addmultisigaddress" && n > 0) ConvertTo(params[0]); + if (strMethod == "addmultisigaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "createmultisig" && n > 0) ConvertTo(params[0]); + if (strMethod == "createmultisig" && n > 1) ConvertTo(params[1]); + if (strMethod == "listunspent" && n > 0) ConvertTo(params[0]); + if (strMethod == "listunspent" && n > 1) ConvertTo(params[1]); + if (strMethod == "listunspent" && n > 2) ConvertTo(params[2]); + if (strMethod == "getblock" && n > 1) ConvertTo(params[1]); + if (strMethod == "getrawtransaction" && n > 1) ConvertTo(params[1]); + if (strMethod == "createrawtransaction" && n > 0) ConvertTo(params[0]); + if (strMethod == "createrawtransaction" && n > 1) ConvertTo(params[1]); + if (strMethod == "signrawtransaction" && n > 1) ConvertTo(params[1], true); + if (strMethod == "signrawtransaction" && n > 2) ConvertTo(params[2], true); + if (strMethod == "gettxout" && n > 1) ConvertTo(params[1]); + if (strMethod == "gettxout" && n > 2) ConvertTo(params[2]); + if (strMethod == "lockunspent" && n > 0) ConvertTo(params[0]); + if (strMethod == "lockunspent" && n > 1) ConvertTo(params[1]); + if (strMethod == "importprivkey" && n > 2) ConvertTo(params[2]); + if (strMethod == "verifychain" && n > 0) ConvertTo(params[0]); + if (strMethod == "verifychain" && n > 1) ConvertTo(params[1]); + + return params; +} + +int CommandLineRPC(int argc, char *argv[]) +{ + string strPrint; + int nRet = 0; + try + { + // Skip switches + while (argc > 1 && IsSwitchChar(argv[1][0])) + { + argc--; + argv++; + } + + // Method + if (argc < 2) + throw runtime_error("too few parameters"); + string strMethod = argv[1]; + + // Parameters default to strings + std::vector strParams(&argv[2], &argv[argc]); + Array params = RPCConvertValues(strMethod, strParams); + + // Execute + Object reply = CallRPC(strMethod, params); + + // Parse reply + const Value& result = find_value(reply, "result"); + const Value& error = find_value(reply, "error"); + + if (error.type() != null_type) + { + // Error + strPrint = "error: " + write_string(error, false); + int code = find_value(error.get_obj(), "code").get_int(); + nRet = abs(code); + } + else + { + // Result + if (result.type() == null_type) + strPrint = ""; + else if (result.type() == str_type) + strPrint = result.get_str(); + else + strPrint = write_string(result, true); + } + } + catch (boost::thread_interrupted) { + throw; + } + catch (std::exception& e) { + strPrint = string("error: ") + e.what(); + nRet = 87; + } + catch (...) { + PrintException(NULL, "CommandLineRPC()"); + } + + if (strPrint != "") + { + fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str()); + } + return nRet; +} + + + + +#ifdef TEST +int main(int argc, char *argv[]) +{ +#ifdef _MSC_VER + // Turn off Microsoft heap dump noise + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); +#endif + setbuf(stdin, NULL); + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + try + { + if (argc >= 2 && string(argv[1]) == "-server") + { + printf("server ready\n"); + ThreadRPCServer(NULL); + } + else + { + return CommandLineRPC(argc, argv); + } + } + catch (boost::thread_interrupted) { + throw; + } + catch (std::exception& e) { + PrintException(&e, "main()"); + } catch (...) { + PrintException(NULL, "main()"); + } + return 0; +} +#endif + +const CRPCTable tableRPC; diff -Nru anoncoin-0.8.5.6/src/anoncoinrpc.h anoncoin-0.8.5.6+git20141111.r4233/src/anoncoinrpc.h --- anoncoin-0.8.5.6/src/anoncoinrpc.h 1970-01-01 00:00:00.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/anoncoinrpc.h 2014-11-11 13:56:18.000000000 +0000 @@ -0,0 +1,209 @@ +// Copyright (c) 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. + +#ifndef _BITCOINRPC_H_ +#define _BITCOINRPC_H_ 1 + +#include +#include +#include + +class CBlockIndex; +class CReserveKey; + +#include "json/json_spirit_reader_template.h" +#include "json/json_spirit_writer_template.h" +#include "json/json_spirit_utils.h" + +#include "util.h" + +// HTTP status codes +enum HTTPStatusCode +{ + HTTP_OK = 200, + HTTP_BAD_REQUEST = 400, + HTTP_UNAUTHORIZED = 401, + HTTP_FORBIDDEN = 403, + HTTP_NOT_FOUND = 404, + HTTP_INTERNAL_SERVER_ERROR = 500, +}; + +// Bitcoin RPC error codes +enum RPCErrorCode +{ + // Standard JSON-RPC 2.0 errors + RPC_INVALID_REQUEST = -32600, + RPC_METHOD_NOT_FOUND = -32601, + RPC_INVALID_PARAMS = -32602, + RPC_INTERNAL_ERROR = -32603, + RPC_PARSE_ERROR = -32700, + + // General application defined errors + RPC_MISC_ERROR = -1, // std::exception thrown in command handling + RPC_FORBIDDEN_BY_SAFE_MODE = -2, // Server is in safe mode, and command is not allowed in safe mode + RPC_TYPE_ERROR = -3, // Unexpected type was passed as parameter + RPC_INVALID_ADDRESS_OR_KEY = -5, // Invalid address or key + RPC_OUT_OF_MEMORY = -7, // Ran out of memory during operation + RPC_INVALID_PARAMETER = -8, // Invalid, missing or duplicate parameter + RPC_DATABASE_ERROR = -20, // Database error + RPC_DESERIALIZATION_ERROR = -22, // Error parsing or validating structure in raw format + + // P2P client errors + RPC_CLIENT_NOT_CONNECTED = -9, // Bitcoin is not connected + RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10, // Still downloading initial blocks + + // Wallet errors + RPC_WALLET_ERROR = -4, // Unspecified problem with wallet (key not found etc.) + RPC_WALLET_INSUFFICIENT_FUNDS = -6, // Not enough funds in wallet or account + RPC_WALLET_INVALID_ACCOUNT_NAME = -11, // Invalid account name + RPC_WALLET_KEYPOOL_RAN_OUT = -12, // Keypool ran out, call keypoolrefill first + RPC_WALLET_UNLOCK_NEEDED = -13, // Enter the wallet passphrase with walletpassphrase first + RPC_WALLET_PASSPHRASE_INCORRECT = -14, // The wallet passphrase entered was incorrect + RPC_WALLET_WRONG_ENC_STATE = -15, // Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.) + RPC_WALLET_ENCRYPTION_FAILED = -16, // Failed to encrypt the wallet + RPC_WALLET_ALREADY_UNLOCKED = -17, // Wallet is already unlocked +}; + +json_spirit::Object JSONRPCError(int code, const std::string& message); + +void StartRPCThreads(); +void StopRPCThreads(); +int CommandLineRPC(int argc, char *argv[]); + +/** Convert parameter values for RPC call from strings to command-specific JSON objects. */ +json_spirit::Array RPCConvertValues(const std::string &strMethod, const std::vector &strParams); + +/* + Type-check arguments; throws JSONRPCError if wrong type given. Does not check that + the right number of arguments are passed, just that any passed are the correct type. + Use like: RPCTypeCheck(params, boost::assign::list_of(str_type)(int_type)(obj_type)); +*/ +void RPCTypeCheck(const json_spirit::Array& params, + const std::list& typesExpected, bool fAllowNull=false); +/* + Check for expected keys/value types in an Object. + Use like: RPCTypeCheck(object, boost::assign::map_list_of("name", str_type)("value", int_type)); +*/ +void RPCTypeCheck(const json_spirit::Object& o, + const std::map& typesExpected, bool fAllowNull=false); + +typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool fHelp); + +class CRPCCommand +{ +public: + std::string name; + rpcfn_type actor; + bool okSafeMode; + bool threadSafe; + bool reqWallet; +}; + +/** + * Bitcoin RPC command dispatcher. + */ +class CRPCTable +{ +private: + std::map mapCommands; +public: + CRPCTable(); + const CRPCCommand* operator[](std::string name) const; + std::string help(std::string name) const; + + /** + * Execute a method. + * @param method Method to execute + * @param params Array of arguments (JSON objects) + * @returns Result of the call. + * @throws an exception (json_spirit::Value) when an error happens. + */ + json_spirit::Value execute(const std::string &method, const json_spirit::Array ¶ms) const; +}; + +extern const CRPCTable tableRPC; + +extern void InitRPCMining(); +extern void ShutdownRPCMining(); + +extern int64 nWalletUnlockTime; +extern int64 AmountFromValue(const json_spirit::Value& value); +extern json_spirit::Value ValueFromAmount(int64 amount); +extern double GetDifficulty(const CBlockIndex* blockindex = NULL); +extern std::string HexBits(unsigned int nBits); +extern std::string HelpRequiringPassphrase(); +extern void EnsureWalletIsUnlocked(); + +extern json_spirit::Value getconnectioncount(const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp +extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value addnode(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getaddednodeinfo(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value dumpprivkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp +extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool fHelp); + +extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp +extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value gethashespersec(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getworkex(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getwork(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp); + +extern json_spirit::Value getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp +extern json_spirit::Value getaccountaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value setaccount(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getaccount(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getaddressesbyaccount(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value sendtoaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value signmessage(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value verifymessage(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getreceivedbyaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getreceivedbyaccount(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getbalance(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value movecmd(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value sendfrom(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value sendmany(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value addmultisigaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value createmultisig(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value listreceivedbyaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value listreceivedbyaccount(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value listtransactions(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value listaddressgroupings(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value listaccounts(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value listsinceblock(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value gettransaction(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value backupwallet(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value keypoolrefill(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value walletpassphrase(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value walletpassphrasechange(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value walletlock(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value encryptwallet(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value validateaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getinfo(const json_spirit::Array& params, bool fHelp); + +extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp +extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value lockunspent(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value listlockunspent(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value createrawtransaction(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value decoderawtransaction(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value signrawtransaction(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value sendrawtransaction(const json_spirit::Array& params, bool fHelp); + +extern json_spirit::Value getblockcount(const json_spirit::Array& params, bool fHelp); // in rpcblockchain.cpp +extern json_spirit::Value getbestblockhash(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getdifficulty(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value settxfee(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value setmininput(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getrawmempool(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value gettxoutsetinfo(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value gettxout(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHelp); + +#endif diff -Nru anoncoin-0.8.5.6/src/bitcoinrpc.cpp anoncoin-0.8.5.6+git20141111.r4233/src/bitcoinrpc.cpp --- anoncoin-0.8.5.6/src/bitcoinrpc.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/bitcoinrpc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1305 +0,0 @@ -// Copyright (c) 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 "init.h" -#include "util.h" -#include "sync.h" -#include "ui_interface.h" -#include "base58.h" -#include "bitcoinrpc.h" -#include "db.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace boost; -using namespace boost::asio; -using namespace json_spirit; - -static std::string strRPCUserColonPass; - -// These are created by StartRPCThreads, destroyed in StopRPCThreads -static asio::io_service* rpc_io_service = NULL; -static ssl::context* rpc_ssl_context = NULL; -static boost::thread_group* rpc_worker_group = NULL; - -static inline unsigned short GetDefaultRPCPort() -{ - return GetBoolArg("-testnet", false) ? 19376 : 9376; -} - -Object JSONRPCError(int code, const string& message) -{ - Object error; - error.push_back(Pair("code", code)); - error.push_back(Pair("message", message)); - return error; -} - -void RPCTypeCheck(const Array& params, - const list& typesExpected, - bool fAllowNull) -{ - unsigned int i = 0; - BOOST_FOREACH(Value_type t, typesExpected) - { - if (params.size() <= i) - break; - - const Value& v = params[i]; - if (!((v.type() == t) || (fAllowNull && (v.type() == null_type)))) - { - string err = strprintf("Expected type %s, got %s", - Value_type_name[t], Value_type_name[v.type()]); - throw JSONRPCError(RPC_TYPE_ERROR, err); - } - i++; - } -} - -void RPCTypeCheck(const Object& o, - const map& typesExpected, - bool fAllowNull) -{ - BOOST_FOREACH(const PAIRTYPE(string, Value_type)& t, typesExpected) - { - const Value& v = find_value(o, t.first); - if (!fAllowNull && v.type() == null_type) - throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first.c_str())); - - if (!((v.type() == t.second) || (fAllowNull && (v.type() == null_type)))) - { - string err = strprintf("Expected type %s for %s, got %s", - Value_type_name[t.second], t.first.c_str(), Value_type_name[v.type()]); - throw JSONRPCError(RPC_TYPE_ERROR, err); - } - } -} - -int64 AmountFromValue(const Value& value) -{ - double dAmount = value.get_real(); - if (dAmount <= 0.0 || dAmount > 4200000.0) - throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); - int64 nAmount = roundint64(dAmount * COIN); - if (!MoneyRange(nAmount)) - throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); - return nAmount; -} - -Value ValueFromAmount(int64 amount) -{ - return (double)amount / (double)COIN; -} - -std::string HexBits(unsigned int nBits) -{ - union { - int32_t nBits; - char cBits[4]; - } uBits; - uBits.nBits = htonl((int32_t)nBits); - return HexStr(BEGIN(uBits.cBits), END(uBits.cBits)); -} - - - -/// -/// Note: This interface may still be subject to change. -/// - -string CRPCTable::help(string strCommand) const -{ - string strRet; - set setDone; - for (map::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi) - { - const CRPCCommand *pcmd = mi->second; - string strMethod = mi->first; - // We already filter duplicates, but these deprecated screw up the sort order - if (strMethod.find("label") != string::npos) - continue; - if (strCommand != "" && strMethod != strCommand) - continue; - if (pcmd->reqWallet && !pwalletMain) - continue; - - try - { - Array params; - rpcfn_type pfn = pcmd->actor; - if (setDone.insert(pfn).second) - (*pfn)(params, true); - } - catch (std::exception& e) - { - // Help text is returned in an exception - string strHelp = string(e.what()); - if (strCommand == "") - if (strHelp.find('\n') != string::npos) - strHelp = strHelp.substr(0, strHelp.find('\n')); - strRet += strHelp + "\n"; - } - } - if (strRet == "") - strRet = strprintf("help: unknown command: %s\n", strCommand.c_str()); - strRet = strRet.substr(0,strRet.size()-1); - return strRet; -} - -Value help(const Array& params, bool fHelp) -{ - if (fHelp || params.size() > 1) - throw runtime_error( - "help [command]\n" - "List commands, or get help for a command."); - - string strCommand; - if (params.size() > 0) - strCommand = params[0].get_str(); - - return tableRPC.help(strCommand); -} - - -Value stop(const Array& params, bool fHelp) -{ - // Accept the deprecated and ignored 'detach' boolean argument - if (fHelp || params.size() > 1) - throw runtime_error( - "stop\n" - "Stop Anoncoin server."); - // Shutdown will take long enough that the response should get back - StartShutdown(); - return "Anoncoin server stopping"; -} - - - -// -// Call Table -// - - -static const CRPCCommand vRPCCommands[] = -{ // name actor (function) okSafeMode threadSafe reqWallet - // ------------------------ ----------------------- ---------- ---------- --------- - { "help", &help, true, true, false }, - { "stop", &stop, true, true, false }, - { "getblockcount", &getblockcount, true, false, false }, - { "getbestblockhash", &getbestblockhash, true, false, false }, - { "getconnectioncount", &getconnectioncount, true, false, false }, - { "getpeerinfo", &getpeerinfo, true, false, false }, - { "addnode", &addnode, true, true, false }, - { "getaddednodeinfo", &getaddednodeinfo, true, true, false }, - { "getdifficulty", &getdifficulty, true, false, false }, - { "getnetworkhashps", &getnetworkhashps, true, false, false }, - { "getgenerate", &getgenerate, true, false, false }, - { "setgenerate", &setgenerate, true, false, true }, - { "gethashespersec", &gethashespersec, true, false, false }, - { "getinfo", &getinfo, true, false, false }, - { "getmininginfo", &getmininginfo, true, false, false }, - { "getnewaddress", &getnewaddress, true, false, true }, - { "getaccountaddress", &getaccountaddress, true, false, true }, - { "setaccount", &setaccount, true, false, true }, - { "getaccount", &getaccount, false, false, true }, - { "getaddressesbyaccount", &getaddressesbyaccount, true, false, true }, - { "sendtoaddress", &sendtoaddress, false, false, true }, - { "getreceivedbyaddress", &getreceivedbyaddress, false, false, true }, - { "getreceivedbyaccount", &getreceivedbyaccount, false, false, true }, - { "listreceivedbyaddress", &listreceivedbyaddress, false, false, true }, - { "listreceivedbyaccount", &listreceivedbyaccount, false, false, true }, - { "backupwallet", &backupwallet, true, false, true }, - { "keypoolrefill", &keypoolrefill, true, false, true }, - { "walletpassphrase", &walletpassphrase, true, false, true }, - { "walletpassphrasechange", &walletpassphrasechange, false, false, true }, - { "walletlock", &walletlock, true, false, true }, - { "encryptwallet", &encryptwallet, false, false, true }, - { "validateaddress", &validateaddress, true, false, false }, - { "getbalance", &getbalance, false, false, true }, - { "move", &movecmd, false, false, true }, - { "sendfrom", &sendfrom, false, false, true }, - { "sendmany", &sendmany, false, false, true }, - { "addmultisigaddress", &addmultisigaddress, false, false, true }, - { "createmultisig", &createmultisig, true, true , false }, - { "getrawmempool", &getrawmempool, true, false, false }, - { "getblock", &getblock, false, false, false }, - { "getblockhash", &getblockhash, false, false, false }, - { "gettransaction", &gettransaction, false, false, true }, - { "listtransactions", &listtransactions, false, false, true }, - { "listaddressgroupings", &listaddressgroupings, false, false, true }, - { "signmessage", &signmessage, false, false, true }, - { "verifymessage", &verifymessage, false, false, false }, - { "getwork", &getwork, true, false, true }, - { "getworkex", &getworkex, true, false, true }, - { "listaccounts", &listaccounts, false, false, true }, - { "settxfee", &settxfee, false, false, true }, - { "getblocktemplate", &getblocktemplate, true, false, false }, - { "submitblock", &submitblock, false, false, false }, - { "setmininput", &setmininput, false, false, false }, - { "listsinceblock", &listsinceblock, false, false, true }, - { "dumpprivkey", &dumpprivkey, true, false, true }, - { "importprivkey", &importprivkey, false, false, true }, - { "listunspent", &listunspent, false, false, true }, - { "getrawtransaction", &getrawtransaction, false, false, false }, - { "createrawtransaction", &createrawtransaction, false, false, false }, - { "decoderawtransaction", &decoderawtransaction, false, false, false }, - { "signrawtransaction", &signrawtransaction, false, false, false }, - { "sendrawtransaction", &sendrawtransaction, false, false, false }, - { "gettxoutsetinfo", &gettxoutsetinfo, true, false, false }, - { "gettxout", &gettxout, true, false, false }, - { "lockunspent", &lockunspent, false, false, true }, - { "listlockunspent", &listlockunspent, false, false, true }, - { "verifychain", &verifychain, true, false, false }, -}; - -CRPCTable::CRPCTable() -{ - unsigned int vcidx; - for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0])); vcidx++) - { - const CRPCCommand *pcmd; - - pcmd = &vRPCCommands[vcidx]; - mapCommands[pcmd->name] = pcmd; - } -} - -const CRPCCommand *CRPCTable::operator[](string name) const -{ - map::const_iterator it = mapCommands.find(name); - if (it == mapCommands.end()) - return NULL; - return (*it).second; -} - -// -// HTTP protocol -// -// This ain't Apache. We're just using HTTP header for the length field -// and to be compatible with other JSON-RPC implementations. -// - -string HTTPPost(const string& strMsg, const map& mapRequestHeaders) -{ - ostringstream s; - s << "POST / HTTP/1.1\r\n" - << "User-Agent: anoncoin-json-rpc/" << FormatFullVersion() << "\r\n" - << "Host: 127.0.0.1\r\n" - << "Content-Type: application/json\r\n" - << "Content-Length: " << strMsg.size() << "\r\n" - << "Connection: close\r\n" - << "Accept: application/json\r\n"; - BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapRequestHeaders) - s << item.first << ": " << item.second << "\r\n"; - s << "\r\n" << strMsg; - - return s.str(); -} - -string rfc1123Time() -{ - char buffer[64]; - time_t now; - time(&now); - struct tm* now_gmt = gmtime(&now); - string locale(setlocale(LC_TIME, NULL)); - setlocale(LC_TIME, "C"); // we want POSIX (aka "C") weekday/month strings - strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S +0000", now_gmt); - setlocale(LC_TIME, locale.c_str()); - return string(buffer); -} - -static string HTTPReply(int nStatus, const string& strMsg, bool keepalive) -{ - if (nStatus == HTTP_UNAUTHORIZED) - return strprintf("HTTP/1.0 401 Authorization Required\r\n" - "Date: %s\r\n" - "Server: anoncoin-json-rpc/%s\r\n" - "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 296\r\n" - "\r\n" - "\r\n" - "\r\n" - "\r\n" - "Error\r\n" - "\r\n" - "\r\n" - "

401 Unauthorized.

\r\n" - "\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str()); - const char *cStatus; - if (nStatus == HTTP_OK) cStatus = "OK"; - else if (nStatus == HTTP_BAD_REQUEST) cStatus = "Bad Request"; - else if (nStatus == HTTP_FORBIDDEN) cStatus = "Forbidden"; - else if (nStatus == HTTP_NOT_FOUND) cStatus = "Not Found"; - else if (nStatus == HTTP_INTERNAL_SERVER_ERROR) cStatus = "Internal Server Error"; - else cStatus = ""; - return strprintf( - "HTTP/1.1 %d %s\r\n" - "Date: %s\r\n" - "Connection: %s\r\n" - "Content-Length: %"PRIszu"\r\n" - "Content-Type: application/json\r\n" - "Server: anoncoin-json-rpc/%s\r\n" - "\r\n" - "%s", - nStatus, - cStatus, - rfc1123Time().c_str(), - keepalive ? "keep-alive" : "close", - strMsg.size(), - FormatFullVersion().c_str(), - strMsg.c_str()); -} - -bool ReadHTTPRequestLine(std::basic_istream& stream, int &proto, - string& http_method, string& http_uri) -{ - string str; - getline(stream, str); - - // HTTP request line is space-delimited - vector vWords; - boost::split(vWords, str, boost::is_any_of(" ")); - if (vWords.size() < 2) - return false; - - // HTTP methods permitted: GET, POST - http_method = vWords[0]; - if (http_method != "GET" && http_method != "POST") - return false; - - // HTTP URI must be an absolute path, relative to current host - http_uri = vWords[1]; - if (http_uri.size() == 0 || http_uri[0] != '/') - return false; - - // parse proto, if present - string strProto = ""; - if (vWords.size() > 2) - strProto = vWords[2]; - - proto = 0; - const char *ver = strstr(strProto.c_str(), "HTTP/1."); - if (ver != NULL) - proto = atoi(ver+7); - - return true; -} - -int ReadHTTPStatus(std::basic_istream& stream, int &proto) -{ - string str; - getline(stream, str); - vector vWords; - boost::split(vWords, str, boost::is_any_of(" ")); - if (vWords.size() < 2) - return HTTP_INTERNAL_SERVER_ERROR; - proto = 0; - const char *ver = strstr(str.c_str(), "HTTP/1."); - if (ver != NULL) - proto = atoi(ver+7); - return atoi(vWords[1].c_str()); -} - -int ReadHTTPHeaders(std::basic_istream& stream, map& mapHeadersRet) -{ - int nLen = 0; - loop - { - string str; - std::getline(stream, str); - if (str.empty() || str == "\r") - break; - string::size_type nColon = str.find(":"); - if (nColon != string::npos) - { - string strHeader = str.substr(0, nColon); - boost::trim(strHeader); - boost::to_lower(strHeader); - string strValue = str.substr(nColon+1); - boost::trim(strValue); - mapHeadersRet[strHeader] = strValue; - if (strHeader == "content-length") - nLen = atoi(strValue.c_str()); - } - } - return nLen; -} - -int ReadHTTPMessage(std::basic_istream& stream, map& mapHeadersRet, string& strMessageRet, - int nProto) -{ - mapHeadersRet.clear(); - strMessageRet = ""; - - // Read header - int nLen = ReadHTTPHeaders(stream, mapHeadersRet); - if (nLen < 0 || nLen > (int)MAX_SIZE) - return HTTP_INTERNAL_SERVER_ERROR; - - // Read message - if (nLen > 0) - { - vector vch(nLen); - stream.read(&vch[0], nLen); - strMessageRet = string(vch.begin(), vch.end()); - } - - string sConHdr = mapHeadersRet["connection"]; - - if ((sConHdr != "close") && (sConHdr != "keep-alive")) - { - if (nProto >= 1) - mapHeadersRet["connection"] = "keep-alive"; - else - mapHeadersRet["connection"] = "close"; - } - - return HTTP_OK; -} - -bool HTTPAuthorized(map& mapHeaders) -{ - string strAuth = mapHeaders["authorization"]; - if (strAuth.substr(0,6) != "Basic ") - return false; - string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64); - string strUserPass = DecodeBase64(strUserPass64); - return TimingResistantEqual(strUserPass, strRPCUserColonPass); -} - -// -// JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility, -// but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were -// unspecified (HTTP errors and contents of 'error'). -// -// 1.0 spec: http://json-rpc.org/wiki/specification -// 1.2 spec: http://groups.google.com/group/json-rpc/web/json-rpc-over-http -// http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx -// - -string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id) -{ - Object request; - request.push_back(Pair("method", strMethod)); - request.push_back(Pair("params", params)); - request.push_back(Pair("id", id)); - return write_string(Value(request), false) + "\n"; -} - -Object JSONRPCReplyObj(const Value& result, const Value& error, const Value& id) -{ - Object reply; - if (error.type() != null_type) - reply.push_back(Pair("result", Value::null)); - else - reply.push_back(Pair("result", result)); - reply.push_back(Pair("error", error)); - reply.push_back(Pair("id", id)); - return reply; -} - -string JSONRPCReply(const Value& result, const Value& error, const Value& id) -{ - Object reply = JSONRPCReplyObj(result, error, id); - return write_string(Value(reply), false) + "\n"; -} - -void ErrorReply(std::ostream& stream, const Object& objError, const Value& id) -{ - // Send error reply from json-rpc error object - int nStatus = HTTP_INTERNAL_SERVER_ERROR; - int code = find_value(objError, "code").get_int(); - if (code == RPC_INVALID_REQUEST) nStatus = HTTP_BAD_REQUEST; - else if (code == RPC_METHOD_NOT_FOUND) nStatus = HTTP_NOT_FOUND; - string strReply = JSONRPCReply(Value::null, objError, id); - stream << HTTPReply(nStatus, strReply, false) << std::flush; -} - -bool ClientAllowed(const boost::asio::ip::address& address) -{ - // Make sure that IPv4-compatible and IPv4-mapped IPv6 addresses are treated as IPv4 addresses - if (address.is_v6() - && (address.to_v6().is_v4_compatible() - || address.to_v6().is_v4_mapped())) - return ClientAllowed(address.to_v6().to_v4()); - - if (address == asio::ip::address_v4::loopback() - || address == asio::ip::address_v6::loopback() - || (address.is_v4() - // Check whether IPv4 addresses match 127.0.0.0/8 (loopback subnet) - && (address.to_v4().to_ulong() & 0xff000000) == 0x7f000000)) - return true; - - const string strAddress = address.to_string(); - const vector& vAllow = mapMultiArgs["-rpcallowip"]; - BOOST_FOREACH(string strAllow, vAllow) - if (WildcardMatch(strAddress, strAllow)) - return true; - return false; -} - -// -// IOStream device that speaks SSL but can also speak non-SSL -// -template -class SSLIOStreamDevice : public iostreams::device { -public: - SSLIOStreamDevice(asio::ssl::stream &streamIn, bool fUseSSLIn) : stream(streamIn) - { - fUseSSL = fUseSSLIn; - fNeedHandshake = fUseSSLIn; - } - - void handshake(ssl::stream_base::handshake_type role) - { - if (!fNeedHandshake) return; - fNeedHandshake = false; - stream.handshake(role); - } - std::streamsize read(char* s, std::streamsize n) - { - handshake(ssl::stream_base::server); // HTTPS servers read first - if (fUseSSL) return stream.read_some(asio::buffer(s, n)); - return stream.next_layer().read_some(asio::buffer(s, n)); - } - std::streamsize write(const char* s, std::streamsize n) - { - handshake(ssl::stream_base::client); // HTTPS clients write first - if (fUseSSL) return asio::write(stream, asio::buffer(s, n)); - return asio::write(stream.next_layer(), asio::buffer(s, n)); - } - bool connect(const std::string& server, const std::string& port) - { - ip::tcp::resolver resolver(stream.get_io_service()); - ip::tcp::resolver::query query(server.c_str(), port.c_str()); - ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); - ip::tcp::resolver::iterator end; - boost::system::error_code error = asio::error::host_not_found; - while (error && endpoint_iterator != end) - { - stream.lowest_layer().close(); - stream.lowest_layer().connect(*endpoint_iterator++, error); - } - if (error) - return false; - return true; - } - -private: - bool fNeedHandshake; - bool fUseSSL; - asio::ssl::stream& stream; -}; - -class AcceptedConnection -{ -public: - virtual ~AcceptedConnection() {} - - virtual std::iostream& stream() = 0; - virtual std::string peer_address_to_string() const = 0; - virtual void close() = 0; -}; - -template -class AcceptedConnectionImpl : public AcceptedConnection -{ -public: - AcceptedConnectionImpl( - asio::io_service& io_service, - ssl::context &context, - bool fUseSSL) : - sslStream(io_service, context), - _d(sslStream, fUseSSL), - _stream(_d) - { - } - - virtual std::iostream& stream() - { - return _stream; - } - - virtual std::string peer_address_to_string() const - { - return peer.address().to_string(); - } - - virtual void close() - { - _stream.close(); - } - - typename Protocol::endpoint peer; - asio::ssl::stream sslStream; - -private: - SSLIOStreamDevice _d; - iostreams::stream< SSLIOStreamDevice > _stream; -}; - -void ServiceConnection(AcceptedConnection *conn); - -// Forward declaration required for RPCListen -template -static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor > acceptor, - ssl::context& context, - bool fUseSSL, - AcceptedConnection* conn, - const boost::system::error_code& error); - -/** - * Sets up I/O resources to accept and handle a new connection. - */ -template -static void RPCListen(boost::shared_ptr< basic_socket_acceptor > acceptor, - ssl::context& context, - const bool fUseSSL) -{ - // Accept connection - AcceptedConnectionImpl* conn = new AcceptedConnectionImpl(acceptor->get_io_service(), context, fUseSSL); - - acceptor->async_accept( - conn->sslStream.lowest_layer(), - conn->peer, - boost::bind(&RPCAcceptHandler, - acceptor, - boost::ref(context), - fUseSSL, - conn, - boost::asio::placeholders::error)); -} - -/** - * Accept and handle incoming connection. - */ -template -static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor > acceptor, - ssl::context& context, - const bool fUseSSL, - AcceptedConnection* conn, - const boost::system::error_code& error) -{ - // Immediately start accepting new connections, except when we're cancelled or our socket is closed. - if (error != asio::error::operation_aborted && acceptor->is_open()) - RPCListen(acceptor, context, fUseSSL); - - AcceptedConnectionImpl* tcp_conn = dynamic_cast< AcceptedConnectionImpl* >(conn); - - // TODO: Actually handle errors - if (error) - { - delete conn; - } - - // Restrict callers by IP. It is important to - // do this before starting client thread, to filter out - // certain DoS and misbehaving clients. - else if (tcp_conn && !ClientAllowed(tcp_conn->peer.address())) - { - // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake. - if (!fUseSSL) - conn->stream() << HTTPReply(HTTP_FORBIDDEN, "", false) << std::flush; - delete conn; - } - else { - ServiceConnection(conn); - conn->close(); - delete conn; - } -} - -void StartRPCThreads() -{ - strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; - if ((mapArgs["-rpcpassword"] == "") || - (mapArgs["-rpcuser"] == mapArgs["-rpcpassword"])) - { - unsigned char rand_pwd[32]; - RAND_bytes(rand_pwd, 32); - string strWhatAmI = "To use anoncoind"; - if (mapArgs.count("-server")) - strWhatAmI = strprintf(_("To use the %s option"), "\"-server\""); - else if (mapArgs.count("-daemon")) - strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\""); - uiInterface.ThreadSafeMessageBox(strprintf( - _("%s, you must set a rpcpassword in the configuration file:\n" - "%s\n" - "It is recommended you use the following random password:\n" - "rpcuser=anoncoinrpc\n" - "rpcpassword=%s\n" - "(you do not need to remember this password)\n" - "The username and password MUST NOT be the same.\n" - "If the file does not exist, create it with owner-readable-only file permissions.\n" - "It is also recommended to set alertnotify so you are notified of problems;\n" - "for example: alertnotify=echo %%s | mail -s \"Anoncoin Alert\" admin@foo.com\n"), - strWhatAmI.c_str(), - GetConfigFile().string().c_str(), - EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()), - "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return; - } - - assert(rpc_io_service == NULL); - rpc_io_service = new asio::io_service(); - rpc_ssl_context = new ssl::context(*rpc_io_service, ssl::context::sslv23); - - const bool fUseSSL = GetBoolArg("-rpcssl"); - - if (fUseSSL) - { - rpc_ssl_context->set_options(ssl::context::no_sslv2); - - filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert")); - if (!pathCertFile.is_complete()) pathCertFile = filesystem::path(GetDataDir()) / pathCertFile; - if (filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string()); - else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string().c_str()); - - filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem")); - if (!pathPKFile.is_complete()) pathPKFile = filesystem::path(GetDataDir()) / pathPKFile; - if (filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem); - else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string().c_str()); - - string strCiphers = GetArg("-rpcsslciphers", "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH"); - SSL_CTX_set_cipher_list(rpc_ssl_context->impl(), strCiphers.c_str()); - } - - // Try a dual IPv6/IPv4 socket, falling back to separate IPv4 and IPv6 sockets - const bool loopback = !mapArgs.count("-rpcallowip"); - asio::ip::address bindAddress = loopback ? asio::ip::address_v6::loopback() : asio::ip::address_v6::any(); - ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", GetDefaultRPCPort())); - boost::system::error_code v6_only_error; - boost::shared_ptr acceptor(new ip::tcp::acceptor(*rpc_io_service)); - - bool fListening = false; - std::string strerr; - try - { - acceptor->open(endpoint.protocol()); - acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - - // Try making the socket dual IPv6/IPv4 (if listening on the "any" address) - acceptor->set_option(boost::asio::ip::v6_only(loopback), v6_only_error); - - acceptor->bind(endpoint); - acceptor->listen(socket_base::max_connections); - - RPCListen(acceptor, *rpc_ssl_context, fUseSSL); - - fListening = true; - } - catch(boost::system::system_error &e) - { - strerr = strprintf(_("An error occurred while setting up the RPC port %u for listening on IPv6, falling back to IPv4: %s"), endpoint.port(), e.what()); - } - - try { - // If dual IPv6/IPv4 failed (or we're opening loopback interfaces only), open IPv4 separately - if (!fListening || loopback || v6_only_error) - { - bindAddress = loopback ? asio::ip::address_v4::loopback() : asio::ip::address_v4::any(); - endpoint.address(bindAddress); - - acceptor.reset(new ip::tcp::acceptor(*rpc_io_service)); - acceptor->open(endpoint.protocol()); - acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - acceptor->bind(endpoint); - acceptor->listen(socket_base::max_connections); - - RPCListen(acceptor, *rpc_ssl_context, fUseSSL); - - fListening = true; - } - } - catch(boost::system::system_error &e) - { - strerr = strprintf(_("An error occurred while setting up the RPC port %u for listening on IPv4: %s"), endpoint.port(), e.what()); - } - - if (!fListening) { - uiInterface.ThreadSafeMessageBox(strerr, "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return; - } - - rpc_worker_group = new boost::thread_group(); - for (int i = 0; i < GetArg("-rpcthreads", 4); i++) - rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service)); -} - -void StopRPCThreads() -{ - if (rpc_io_service == NULL) return; - - rpc_io_service->stop(); - rpc_worker_group->join_all(); - delete rpc_worker_group; rpc_worker_group = NULL; - delete rpc_ssl_context; rpc_ssl_context = NULL; - delete rpc_io_service; rpc_io_service = NULL; -} - -class JSONRequest -{ -public: - Value id; - string strMethod; - Array params; - - JSONRequest() { id = Value::null; } - void parse(const Value& valRequest); -}; - -void JSONRequest::parse(const Value& valRequest) -{ - // Parse request - if (valRequest.type() != obj_type) - throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object"); - const Object& request = valRequest.get_obj(); - - // Parse id now so errors from here on will have the id - id = find_value(request, "id"); - - // Parse method - Value valMethod = find_value(request, "method"); - if (valMethod.type() == null_type) - throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method"); - if (valMethod.type() != str_type) - throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string"); - strMethod = valMethod.get_str(); - if (strMethod != "getwork" && strMethod != "getworkex" && strMethod != "getblocktemplate") - printf("ThreadRPCServer method=%s\n", strMethod.c_str()); - - // Parse params - Value valParams = find_value(request, "params"); - if (valParams.type() == array_type) - params = valParams.get_array(); - else if (valParams.type() == null_type) - params = Array(); - else - throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array"); -} - -static Object JSONRPCExecOne(const Value& req) -{ - Object rpc_result; - - JSONRequest jreq; - try { - jreq.parse(req); - - Value result = tableRPC.execute(jreq.strMethod, jreq.params); - rpc_result = JSONRPCReplyObj(result, Value::null, jreq.id); - } - catch (Object& objError) - { - rpc_result = JSONRPCReplyObj(Value::null, objError, jreq.id); - } - catch (std::exception& e) - { - rpc_result = JSONRPCReplyObj(Value::null, - JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); - } - - return rpc_result; -} - -static string JSONRPCExecBatch(const Array& vReq) -{ - Array ret; - for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) - ret.push_back(JSONRPCExecOne(vReq[reqIdx])); - - return write_string(Value(ret), false) + "\n"; -} - -void ServiceConnection(AcceptedConnection *conn) -{ - bool fRun = true; - while (fRun) - { - int nProto = 0; - map mapHeaders; - string strRequest, strMethod, strURI; - - // Read HTTP request line - if (!ReadHTTPRequestLine(conn->stream(), nProto, strMethod, strURI)) - break; - - // Read HTTP message headers and body - ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto); - - if (strURI != "/") { - conn->stream() << HTTPReply(HTTP_NOT_FOUND, "", false) << std::flush; - break; - } - - // Check authorization - if (mapHeaders.count("authorization") == 0) - { - conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush; - break; - } - if (!HTTPAuthorized(mapHeaders)) - { - printf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string().c_str()); - /* Deter brute-forcing short passwords. - If this results in a DOS the user really - shouldn't have their RPC port exposed.*/ - if (mapArgs["-rpcpassword"].size() < 20) - MilliSleep(250); - - conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush; - break; - } - if (mapHeaders["connection"] == "close") - fRun = false; - - JSONRequest jreq; - try - { - // Parse request - Value valRequest; - if (!read_string(strRequest, valRequest)) - throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); - - string strReply; - - // singleton request - if (valRequest.type() == obj_type) { - jreq.parse(valRequest); - - Value result = tableRPC.execute(jreq.strMethod, jreq.params); - - // Send reply - strReply = JSONRPCReply(result, Value::null, jreq.id); - - // array of requests - } else if (valRequest.type() == array_type) - strReply = JSONRPCExecBatch(valRequest.get_array()); - else - throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error"); - - conn->stream() << HTTPReply(HTTP_OK, strReply, fRun) << std::flush; - } - catch (Object& objError) - { - ErrorReply(conn->stream(), objError, jreq.id); - break; - } - catch (std::exception& e) - { - ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); - break; - } - } -} - -json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array ¶ms) const -{ - // Find method - const CRPCCommand *pcmd = tableRPC[strMethod]; - if (!pcmd) - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found"); - if (pcmd->reqWallet && !pwalletMain) - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); - - // Observe safe mode - string strWarning = GetWarnings("rpc"); - if (strWarning != "" && !GetBoolArg("-disablesafemode") && - !pcmd->okSafeMode) - throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning); - - try - { - // Execute - Value result; - { - if (pcmd->threadSafe) - result = pcmd->actor(params, false); - else if (!pwalletMain) { - LOCK(cs_main); - result = pcmd->actor(params, false); - } else { - LOCK2(cs_main, pwalletMain->cs_wallet); - result = pcmd->actor(params, false); - } - } - return result; - } - catch (std::exception& e) - { - throw JSONRPCError(RPC_MISC_ERROR, e.what()); - } -} - - -Object CallRPC(const string& strMethod, const Array& params) -{ - if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "") - throw runtime_error(strprintf( - _("You must set rpcpassword= in the configuration file:\n%s\n" - "If the file does not exist, create it with owner-readable-only file permissions."), - GetConfigFile().string().c_str())); - - // Connect to localhost - bool fUseSSL = GetBoolArg("-rpcssl"); - asio::io_service io_service; - ssl::context context(io_service, ssl::context::sslv23); - context.set_options(ssl::context::no_sslv2); - asio::ssl::stream sslStream(io_service, context); - SSLIOStreamDevice d(sslStream, fUseSSL); - iostreams::stream< SSLIOStreamDevice > stream(d); - if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(GetDefaultRPCPort())))) - throw runtime_error("couldn't connect to server"); - - // HTTP basic authentication - string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]); - map mapRequestHeaders; - mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64; - - // Send request - string strRequest = JSONRPCRequest(strMethod, params, 1); - string strPost = HTTPPost(strRequest, mapRequestHeaders); - stream << strPost << std::flush; - - // Receive HTTP reply status - int nProto = 0; - int nStatus = ReadHTTPStatus(stream, nProto); - - // Receive HTTP reply message headers and body - map mapHeaders; - string strReply; - ReadHTTPMessage(stream, mapHeaders, strReply, nProto); - - if (nStatus == HTTP_UNAUTHORIZED) - throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)"); - else if (nStatus >= 400 && nStatus != HTTP_BAD_REQUEST && nStatus != HTTP_NOT_FOUND && nStatus != HTTP_INTERNAL_SERVER_ERROR) - throw runtime_error(strprintf("server returned HTTP error %d", nStatus)); - else if (strReply.empty()) - throw runtime_error("no response from server"); - - // Parse reply - Value valReply; - if (!read_string(strReply, valReply)) - throw runtime_error("couldn't parse reply from server"); - const Object& reply = valReply.get_obj(); - if (reply.empty()) - throw runtime_error("expected reply to have result, error and id properties"); - - return reply; -} - - - - -template -void ConvertTo(Value& value, bool fAllowNull=false) -{ - if (fAllowNull && value.type() == null_type) - return; - if (value.type() == str_type) - { - // reinterpret string as unquoted json value - Value value2; - string strJSON = value.get_str(); - if (!read_string(strJSON, value2)) - throw runtime_error(string("Error parsing JSON:")+strJSON); - ConvertTo(value2, fAllowNull); - value = value2; - } - else - { - value = value.get_value(); - } -} - -// Convert strings to command-specific RPC representation -Array RPCConvertValues(const std::string &strMethod, const std::vector &strParams) -{ - Array params; - BOOST_FOREACH(const std::string ¶m, strParams) - params.push_back(param); - - int n = params.size(); - - // - // Special case non-string parameter types - // - if (strMethod == "stop" && n > 0) ConvertTo(params[0]); - if (strMethod == "getaddednodeinfo" && n > 0) ConvertTo(params[0]); - if (strMethod == "setgenerate" && n > 0) ConvertTo(params[0]); - if (strMethod == "setgenerate" && n > 1) ConvertTo(params[1]); - if (strMethod == "getnetworkhashps" && n > 0) ConvertTo(params[0]); - if (strMethod == "getnetworkhashps" && n > 1) ConvertTo(params[1]); - if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); - if (strMethod == "settxfee" && n > 0) ConvertTo(params[0]); - if (strMethod == "setmininput" && n > 0) ConvertTo(params[0]); - if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo(params[1]); - if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo(params[1]); - if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo(params[0]); - if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo(params[1]); - if (strMethod == "listreceivedbyaccount" && n > 0) ConvertTo(params[0]); - if (strMethod == "listreceivedbyaccount" && n > 1) ConvertTo(params[1]); - if (strMethod == "getbalance" && n > 1) ConvertTo(params[1]); - if (strMethod == "getblockhash" && n > 0) ConvertTo(params[0]); - if (strMethod == "move" && n > 2) ConvertTo(params[2]); - if (strMethod == "move" && n > 3) ConvertTo(params[3]); - if (strMethod == "sendfrom" && n > 2) ConvertTo(params[2]); - if (strMethod == "sendfrom" && n > 3) ConvertTo(params[3]); - if (strMethod == "listtransactions" && n > 1) ConvertTo(params[1]); - if (strMethod == "listtransactions" && n > 2) ConvertTo(params[2]); - if (strMethod == "listaccounts" && n > 0) ConvertTo(params[0]); - if (strMethod == "walletpassphrase" && n > 1) ConvertTo(params[1]); - if (strMethod == "getblocktemplate" && n > 0) ConvertTo(params[0]); - if (strMethod == "listsinceblock" && n > 1) ConvertTo(params[1]); - if (strMethod == "sendmany" && n > 1) ConvertTo(params[1]); - if (strMethod == "sendmany" && n > 2) ConvertTo(params[2]); - if (strMethod == "addmultisigaddress" && n > 0) ConvertTo(params[0]); - if (strMethod == "addmultisigaddress" && n > 1) ConvertTo(params[1]); - if (strMethod == "createmultisig" && n > 0) ConvertTo(params[0]); - if (strMethod == "createmultisig" && n > 1) ConvertTo(params[1]); - if (strMethod == "listunspent" && n > 0) ConvertTo(params[0]); - if (strMethod == "listunspent" && n > 1) ConvertTo(params[1]); - if (strMethod == "listunspent" && n > 2) ConvertTo(params[2]); - if (strMethod == "getblock" && n > 1) ConvertTo(params[1]); - if (strMethod == "getrawtransaction" && n > 1) ConvertTo(params[1]); - if (strMethod == "createrawtransaction" && n > 0) ConvertTo(params[0]); - if (strMethod == "createrawtransaction" && n > 1) ConvertTo(params[1]); - if (strMethod == "signrawtransaction" && n > 1) ConvertTo(params[1], true); - if (strMethod == "signrawtransaction" && n > 2) ConvertTo(params[2], true); - if (strMethod == "gettxout" && n > 1) ConvertTo(params[1]); - if (strMethod == "gettxout" && n > 2) ConvertTo(params[2]); - if (strMethod == "lockunspent" && n > 0) ConvertTo(params[0]); - if (strMethod == "lockunspent" && n > 1) ConvertTo(params[1]); - if (strMethod == "importprivkey" && n > 2) ConvertTo(params[2]); - if (strMethod == "verifychain" && n > 0) ConvertTo(params[0]); - if (strMethod == "verifychain" && n > 1) ConvertTo(params[1]); - - return params; -} - -int CommandLineRPC(int argc, char *argv[]) -{ - string strPrint; - int nRet = 0; - try - { - // Skip switches - while (argc > 1 && IsSwitchChar(argv[1][0])) - { - argc--; - argv++; - } - - // Method - if (argc < 2) - throw runtime_error("too few parameters"); - string strMethod = argv[1]; - - // Parameters default to strings - std::vector strParams(&argv[2], &argv[argc]); - Array params = RPCConvertValues(strMethod, strParams); - - // Execute - Object reply = CallRPC(strMethod, params); - - // Parse reply - const Value& result = find_value(reply, "result"); - const Value& error = find_value(reply, "error"); - - if (error.type() != null_type) - { - // Error - strPrint = "error: " + write_string(error, false); - int code = find_value(error.get_obj(), "code").get_int(); - nRet = abs(code); - } - else - { - // Result - if (result.type() == null_type) - strPrint = ""; - else if (result.type() == str_type) - strPrint = result.get_str(); - else - strPrint = write_string(result, true); - } - } - catch (boost::thread_interrupted) { - throw; - } - catch (std::exception& e) { - strPrint = string("error: ") + e.what(); - nRet = 87; - } - catch (...) { - PrintException(NULL, "CommandLineRPC()"); - } - - if (strPrint != "") - { - fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str()); - } - return nRet; -} - - - - -#ifdef TEST -int main(int argc, char *argv[]) -{ -#ifdef _MSC_VER - // Turn off Microsoft heap dump noise - _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); -#endif - setbuf(stdin, NULL); - setbuf(stdout, NULL); - setbuf(stderr, NULL); - - try - { - if (argc >= 2 && string(argv[1]) == "-server") - { - printf("server ready\n"); - ThreadRPCServer(NULL); - } - else - { - return CommandLineRPC(argc, argv); - } - } - catch (boost::thread_interrupted) { - throw; - } - catch (std::exception& e) { - PrintException(&e, "main()"); - } catch (...) { - PrintException(NULL, "main()"); - } - return 0; -} -#endif - -const CRPCTable tableRPC; diff -Nru anoncoin-0.8.5.6/src/bitcoinrpc.h anoncoin-0.8.5.6+git20141111.r4233/src/bitcoinrpc.h --- anoncoin-0.8.5.6/src/bitcoinrpc.h 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/bitcoinrpc.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,209 +0,0 @@ -// Copyright (c) 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. - -#ifndef _BITCOINRPC_H_ -#define _BITCOINRPC_H_ 1 - -#include -#include -#include - -class CBlockIndex; -class CReserveKey; - -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_writer_template.h" -#include "json/json_spirit_utils.h" - -#include "util.h" - -// HTTP status codes -enum HTTPStatusCode -{ - HTTP_OK = 200, - HTTP_BAD_REQUEST = 400, - HTTP_UNAUTHORIZED = 401, - HTTP_FORBIDDEN = 403, - HTTP_NOT_FOUND = 404, - HTTP_INTERNAL_SERVER_ERROR = 500, -}; - -// Bitcoin RPC error codes -enum RPCErrorCode -{ - // Standard JSON-RPC 2.0 errors - RPC_INVALID_REQUEST = -32600, - RPC_METHOD_NOT_FOUND = -32601, - RPC_INVALID_PARAMS = -32602, - RPC_INTERNAL_ERROR = -32603, - RPC_PARSE_ERROR = -32700, - - // General application defined errors - RPC_MISC_ERROR = -1, // std::exception thrown in command handling - RPC_FORBIDDEN_BY_SAFE_MODE = -2, // Server is in safe mode, and command is not allowed in safe mode - RPC_TYPE_ERROR = -3, // Unexpected type was passed as parameter - RPC_INVALID_ADDRESS_OR_KEY = -5, // Invalid address or key - RPC_OUT_OF_MEMORY = -7, // Ran out of memory during operation - RPC_INVALID_PARAMETER = -8, // Invalid, missing or duplicate parameter - RPC_DATABASE_ERROR = -20, // Database error - RPC_DESERIALIZATION_ERROR = -22, // Error parsing or validating structure in raw format - - // P2P client errors - RPC_CLIENT_NOT_CONNECTED = -9, // Bitcoin is not connected - RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10, // Still downloading initial blocks - - // Wallet errors - RPC_WALLET_ERROR = -4, // Unspecified problem with wallet (key not found etc.) - RPC_WALLET_INSUFFICIENT_FUNDS = -6, // Not enough funds in wallet or account - RPC_WALLET_INVALID_ACCOUNT_NAME = -11, // Invalid account name - RPC_WALLET_KEYPOOL_RAN_OUT = -12, // Keypool ran out, call keypoolrefill first - RPC_WALLET_UNLOCK_NEEDED = -13, // Enter the wallet passphrase with walletpassphrase first - RPC_WALLET_PASSPHRASE_INCORRECT = -14, // The wallet passphrase entered was incorrect - RPC_WALLET_WRONG_ENC_STATE = -15, // Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.) - RPC_WALLET_ENCRYPTION_FAILED = -16, // Failed to encrypt the wallet - RPC_WALLET_ALREADY_UNLOCKED = -17, // Wallet is already unlocked -}; - -json_spirit::Object JSONRPCError(int code, const std::string& message); - -void StartRPCThreads(); -void StopRPCThreads(); -int CommandLineRPC(int argc, char *argv[]); - -/** Convert parameter values for RPC call from strings to command-specific JSON objects. */ -json_spirit::Array RPCConvertValues(const std::string &strMethod, const std::vector &strParams); - -/* - Type-check arguments; throws JSONRPCError if wrong type given. Does not check that - the right number of arguments are passed, just that any passed are the correct type. - Use like: RPCTypeCheck(params, boost::assign::list_of(str_type)(int_type)(obj_type)); -*/ -void RPCTypeCheck(const json_spirit::Array& params, - const std::list& typesExpected, bool fAllowNull=false); -/* - Check for expected keys/value types in an Object. - Use like: RPCTypeCheck(object, boost::assign::map_list_of("name", str_type)("value", int_type)); -*/ -void RPCTypeCheck(const json_spirit::Object& o, - const std::map& typesExpected, bool fAllowNull=false); - -typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool fHelp); - -class CRPCCommand -{ -public: - std::string name; - rpcfn_type actor; - bool okSafeMode; - bool threadSafe; - bool reqWallet; -}; - -/** - * Bitcoin RPC command dispatcher. - */ -class CRPCTable -{ -private: - std::map mapCommands; -public: - CRPCTable(); - const CRPCCommand* operator[](std::string name) const; - std::string help(std::string name) const; - - /** - * Execute a method. - * @param method Method to execute - * @param params Array of arguments (JSON objects) - * @returns Result of the call. - * @throws an exception (json_spirit::Value) when an error happens. - */ - json_spirit::Value execute(const std::string &method, const json_spirit::Array ¶ms) const; -}; - -extern const CRPCTable tableRPC; - -extern void InitRPCMining(); -extern void ShutdownRPCMining(); - -extern int64 nWalletUnlockTime; -extern int64 AmountFromValue(const json_spirit::Value& value); -extern json_spirit::Value ValueFromAmount(int64 amount); -extern double GetDifficulty(const CBlockIndex* blockindex = NULL); -extern std::string HexBits(unsigned int nBits); -extern std::string HelpRequiringPassphrase(); -extern void EnsureWalletIsUnlocked(); - -extern json_spirit::Value getconnectioncount(const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp -extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value addnode(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getaddednodeinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value dumpprivkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp -extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool fHelp); - -extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp -extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gethashespersec(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getworkex(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getwork(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp); - -extern json_spirit::Value getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp -extern json_spirit::Value getaccountaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value setaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getaddressesbyaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendtoaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value signmessage(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value verifymessage(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getreceivedbyaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getreceivedbyaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getbalance(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value movecmd(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendfrom(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendmany(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value addmultisigaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value createmultisig(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listreceivedbyaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listreceivedbyaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listtransactions(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listaddressgroupings(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listaccounts(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listsinceblock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gettransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value backupwallet(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value keypoolrefill(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value walletpassphrase(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value walletpassphrasechange(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value walletlock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value encryptwallet(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value validateaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getinfo(const json_spirit::Array& params, bool fHelp); - -extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp -extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value lockunspent(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listlockunspent(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value createrawtransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value decoderawtransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value signrawtransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendrawtransaction(const json_spirit::Array& params, bool fHelp); - -extern json_spirit::Value getblockcount(const json_spirit::Array& params, bool fHelp); // in rpcblockchain.cpp -extern json_spirit::Value getbestblockhash(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getdifficulty(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value settxfee(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value setmininput(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getrawmempool(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gettxoutsetinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gettxout(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHelp); - -#endif diff -Nru anoncoin-0.8.5.6/src/checkpoints.cpp anoncoin-0.8.5.6+git20141111.r4233/src/checkpoints.cpp --- anoncoin-0.8.5.6/src/checkpoints.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/checkpoints.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -43,8 +43,9 @@ (77777, uint256("0xf5c98062cb1ad75c792a1851a388447f0edd7cb2271b67ef1241a03c673b7735")) (77778, uint256("0xd13f93f9fdac82ea26ed8f90474ed2449c8c24be50a416e43c323a38573c30e5")) (100000, uint256("0xcc4f0b11e9e17f7a406ac4a71e6e192b9b43e32b300ddecba229c789392497eb")) - (106000, uint256("0xbe27545eb8ea31c74878b54d500161873ed035afc2fa1f4e7cfa7e84a232b8f9")) - (112800, uint256("0x4dbecbf0368b99c80da8406693f370b754f78a7b6d139a878bc69fb961f86383")) + (125000, uint256("0x52a933553dda61b4af6a418f10ce563f0c84df93619ec97f8f360f9ecc51cf5b")) + (150000, uint256("0xb1dc241da3e8e7d4ca2df75187d66f4f096840634667b987a7b60d5dde92853c")) + (210000, uint256("0xb9c2c5030199a87cb99255551b7f67bff6adf3ef2caf97258b93b417d14f9051")) ; static const CCheckpointData data = { &mapCheckpoints, diff -Nru anoncoin-0.8.5.6/src/clientversion.h anoncoin-0.8.5.6+git20141111.r4233/src/clientversion.h --- anoncoin-0.8.5.6/src/clientversion.h 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/clientversion.h 2014-11-11 13:56:18.000000000 +0000 @@ -11,7 +11,7 @@ #define CLIENT_VERSION_REVISION 5 #define CLIENT_VERSION_BUILD 6 -#define ANONOCOIN_RELEASE 7 +#define ANONCOIN_RELEASE 7 // Set to true for release, false for prerelease or test build #define CLIENT_VERSION_IS_RELEASE false diff -Nru anoncoin-0.8.5.6/src/GNUMakefile anoncoin-0.8.5.6+git20141111.r4233/src/GNUMakefile --- anoncoin-0.8.5.6/src/GNUMakefile 1970-01-01 00:00:00.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/GNUMakefile 2014-11-11 13:56:18.000000000 +0000 @@ -0,0 +1,9 @@ + +UNAME := $(shell uname -s) + +ifeq ($(UNAME),Darwin) + include Makefile.osx +else + include Makefile.unix +endif + diff -Nru anoncoin-0.8.5.6/src/init.cpp anoncoin-0.8.5.6+git20141111.r4233/src/init.cpp --- anoncoin-0.8.5.6/src/init.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/init.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -6,12 +6,16 @@ // Copyright (c) 2012-2013 giv +#include "main.h" +#include "util.h" +#ifdef ENABLE_WALLET #include "txdb.h" #include "walletdb.h" -#include "bitcoinrpc.h" +#include "miner.h" +#endif +#include "anoncoinrpc.h" #include "net.h" #include "init.h" -#include "util.h" #include "ui_interface.h" #include @@ -42,7 +46,9 @@ using namespace std; using namespace boost; +#ifdef ENABLE_WALLET CWallet* pwalletMain; +#endif CClientUIInterface uiInterface; #ifdef WIN32 @@ -115,9 +121,11 @@ nTransactionsUpdated++; StopRPCThreads(); ShutdownRPCMining(); +#ifdef ENABLE_WALLET if (pwalletMain) bitdb.Flush(false); - GenerateBitcoins(false, NULL); + GenerateAnoncoins(false, NULL); +#endif StopNode(); { LOCK(cs_main); @@ -131,12 +139,14 @@ delete pcoinsdbview; pcoinsdbview = NULL; delete pblocktree; pblocktree = NULL; } +#ifdef ENABLE_WALLET if (pwalletMain) bitdb.Flush(true); - boost::filesystem::remove(GetPidFile()); UnregisterWallet(pwalletMain); if (pwalletMain) delete pwalletMain; +#endif + boost::filesystem::remove(GetPidFile()); printf("Shutdown : done\n"); } @@ -381,12 +391,18 @@ #endif " -rpcthreads= " + _("Set the number of threads to service RPC calls (default: 4)") + "\n" + " -blocknotify= " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n" + +#ifdef ENABLE_WALLET " -walletnotify= " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n" + +#endif " -alertnotify= " + _("Execute command when a relevant alert is received (%s in cmd is replaced by message)") + "\n" + +#ifdef ENABLE_WALLET " -upgradewallet " + _("Upgrade wallet to latest format") + "\n" + +#endif " -keypool= " + _("Set key pool size to (default: 100)") + "\n" + " -rescan " + _("Rescan the block chain for missing wallet transactions") + "\n" + +#ifdef ENABLE_WALLET " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + "\n" + +#endif " -checkblocks= " + _("How many blocks to check at startup (default: 288, 0 = all)") + "\n" + " -checklevel= " + _("How thorough the block verification is (0-4, default: 3)") + "\n" + " -txindex " + _("Maintain a full transaction index (default: 0)") + "\n" + @@ -603,10 +619,12 @@ SoftSetBoolArg("-discover", false); } +#ifdef ENABLE_WALLET if (GetBoolArg("-salvagewallet")) { // Rewrite just private keys: rescan to find transactions SoftSetBoolArg("-rescan", true); } +#endif // Make sure enough file descriptors are available int nBind = std::max((int)mapArgs.count("-bind"), 1); @@ -650,7 +668,9 @@ fPrintToConsole = GetBoolArg("-printtoconsole"); fPrintToDebugger = GetBoolArg("-printtodebugger"); fLogTimestamps = GetBoolArg("-logtimestamps", true); +#ifdef ENABLE_WALLET bool fDisableWallet = GetBoolArg("-disablewallet", false); +#endif if (mapArgs.count("-timeout")) { @@ -745,7 +765,7 @@ int64 nStart; // ********************************************************* Step 5: verify wallet database integrity - +#ifdef ENABLE_WALLET if (!fDisableWallet) { uiInterface.InitMessage(_("Verifying wallet...")); @@ -791,6 +811,7 @@ return InitError(_("wallet.dat corrupt, salvage failed")); } } // (!fDisableWallet) +#endif // ********************************************************* Step 6: network initialization @@ -1076,6 +1097,7 @@ return false; } +#ifdef ENABLE_WALLET // ********************************************************* Step 8: load wallet if (fDisableWallet) { @@ -1169,6 +1191,7 @@ nWalletDBUpdated++; } } // (!fDisableWallet) +#endif // ********************************************************* Step 9: import blocks @@ -1213,9 +1236,11 @@ //// debug print printf("mapBlockIndex.size() = %"PRIszu"\n", mapBlockIndex.size()); printf("nBestHeight = %d\n", nBestHeight); +#ifdef ENABLE_WALLET printf("setKeyPool.size() = %"PRIszu"\n", pwalletMain ? pwalletMain->setKeyPool.size() : 0); printf("mapWallet.size() = %"PRIszu"\n", pwalletMain ? pwalletMain->mapWallet.size() : 0); printf("mapAddressBook.size() = %"PRIszu"\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0); +#endif StartNode(threadGroup); @@ -1224,14 +1249,17 @@ if (fServer) StartRPCThreads(); +#ifdef ENABLE_WALLET // Generate coins in the background if (pwalletMain) - GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain); + GenerateAnoncoins(GetBoolArg("-gen", false), pwalletMain); +#endif // ********************************************************* Step 12: finished uiInterface.InitMessage(_("Done loading")); +#ifdef ENABLE_WALLET if (pwalletMain) { // Add wallet transactions that aren't already in a block to mapTransactions pwalletMain->ReacceptWalletTransactions(); @@ -1239,6 +1267,7 @@ // Run a thread to flush wallet periodically threadGroup.create_thread(boost::bind(&ThreadFlushWalletDB, boost::ref(pwalletMain->strWalletFile))); } +#endif return !fRequestShutdown; } diff -Nru anoncoin-0.8.5.6/src/init.h anoncoin-0.8.5.6+git20141111.r4233/src/init.h --- anoncoin-0.8.5.6/src/init.h 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/init.h 2014-11-11 13:56:18.000000000 +0000 @@ -5,9 +5,11 @@ #ifndef BITCOIN_INIT_H #define BITCOIN_INIT_H +#ifdef ENABLE_WALLET #include "wallet.h" - +#include "miner.h" extern CWallet* pwalletMain; +#endif void StartShutdown(); bool ShutdownRequested(); diff -Nru anoncoin-0.8.5.6/src/leveldb/AUTHORS anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/AUTHORS --- anoncoin-0.8.5.6/src/leveldb/AUTHORS 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/AUTHORS 2014-11-11 13:56:18.000000000 +0000 @@ -9,3 +9,4 @@ # Partial list of contributors: Kevin Regan +Johan Bilien diff -Nru anoncoin-0.8.5.6/src/leveldb/build_detect_platform anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/build_detect_platform --- anoncoin-0.8.5.6/src/leveldb/build_detect_platform 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/build_detect_platform 2014-11-11 13:56:18.000000000 +0000 @@ -137,6 +137,16 @@ # man ld: +h internal_name PLATFORM_SHARED_LDFLAGS="-shared -Wl,+h -Wl," ;; + IOS) + PLATFORM=IOS + COMMON_FLAGS="$MEMCMP_FLAG -DOS_MACOSX" + [ -z "$INSTALL_PATH" ] && INSTALL_PATH=`pwd` + PORT_FILE=port/port_posix.cc + PLATFORM_SHARED_EXT= + PLATFORM_SHARED_LDFLAGS= + PLATFORM_SHARED_CFLAGS= + PLATFORM_SHARED_VERSIONED= + ;; OS_WINDOWS_CROSSCOMPILE | NATIVE_WINDOWS) PLATFORM=OS_WINDOWS COMMON_FLAGS="-fno-builtin-memcmp -D_REENTRANT -DOS_WINDOWS -DLEVELDB_PLATFORM_WINDOWS -DWINVER=0x0500 -D__USE_MINGW_ANSI_STDIO=1" diff -Nru anoncoin-0.8.5.6/src/leveldb/db/corruption_test.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/corruption_test.cc --- anoncoin-0.8.5.6/src/leveldb/db/corruption_test.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/corruption_test.cc 2014-11-11 13:56:18.000000000 +0000 @@ -75,7 +75,13 @@ Slice key = Key(i, &key_space); batch.Clear(); batch.Put(key, Value(i, &value_space)); - ASSERT_OK(db_->Write(WriteOptions(), &batch)); + WriteOptions options; + // Corrupt() doesn't work without this sync on windows; stat reports 0 for + // the file size. + if (i == n - 1) { + options.sync = true; + } + ASSERT_OK(db_->Write(options, &batch)); } } @@ -125,7 +131,7 @@ FileType type; std::string fname; int picked_number = -1; - for (int i = 0; i < filenames.size(); i++) { + for (size_t i = 0; i < filenames.size(); i++) { if (ParseFileName(filenames[i], &number, &type) && type == filetype && int(number) > picked_number) { // Pick latest file @@ -238,6 +244,22 @@ Check(90, 99); } +TEST(CorruptionTest, TableFileRepair) { + options_.block_size = 2 * kValueSize; // Limit scope of corruption + options_.paranoid_checks = true; + Reopen(); + Build(100); + DBImpl* dbi = reinterpret_cast(db_); + dbi->TEST_CompactMemTable(); + dbi->TEST_CompactRange(0, NULL, NULL); + dbi->TEST_CompactRange(1, NULL, NULL); + + Corrupt(kTableFile, 100, 1); + RepairDB(); + Reopen(); + Check(95, 99); +} + TEST(CorruptionTest, TableFileIndexData) { Build(10000); // Enough to build multiple Tables DBImpl* dbi = reinterpret_cast(db_); diff -Nru anoncoin-0.8.5.6/src/leveldb/db/db_bench.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/db_bench.cc --- anoncoin-0.8.5.6/src/leveldb/db/db_bench.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/db_bench.cc 2014-11-11 13:56:18.000000000 +0000 @@ -128,7 +128,7 @@ pos_ = 0; } - Slice Generate(int len) { + Slice Generate(size_t len) { if (pos_ + len > data_.size()) { pos_ = 0; assert(len < data_.size()); @@ -139,11 +139,11 @@ }; static Slice TrimSpace(Slice s) { - int start = 0; + size_t start = 0; while (start < s.size() && isspace(s[start])) { start++; } - int limit = s.size(); + size_t limit = s.size(); while (limit > start && isspace(s[limit-1])) { limit--; } @@ -399,7 +399,7 @@ heap_counter_(0) { std::vector files; Env::Default()->GetChildren(FLAGS_db, &files); - for (int i = 0; i < files.size(); i++) { + for (size_t i = 0; i < files.size(); i++) { if (Slice(files[i]).starts_with("heap-")) { Env::Default()->DeleteFile(std::string(FLAGS_db) + "/" + files[i]); } diff -Nru anoncoin-0.8.5.6/src/leveldb/db/db_impl.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/db_impl.cc --- anoncoin-0.8.5.6/src/leveldb/db/db_impl.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/db_impl.cc 2014-11-11 13:56:18.000000000 +0000 @@ -133,8 +133,7 @@ seed_(0), tmp_batch_(new WriteBatch), bg_compaction_scheduled_(false), - manual_compaction_(NULL), - consecutive_compaction_errors_(0) { + manual_compaction_(NULL) { mem_->Ref(); has_imm_.Release_Store(NULL); @@ -217,6 +216,12 @@ } void DBImpl::DeleteObsoleteFiles() { + if (!bg_error_.ok()) { + // After a background error, we don't know whether a new version may + // or may not have been committed, so we cannot safely garbage collect. + return; + } + // Make a set of all of the live files std::set live = pending_outputs_; versions_->AddLiveFiles(&live); @@ -495,7 +500,7 @@ return s; } -Status DBImpl::CompactMemTable() { +void DBImpl::CompactMemTable() { mutex_.AssertHeld(); assert(imm_ != NULL); @@ -523,9 +528,9 @@ imm_ = NULL; has_imm_.Release_Store(NULL); DeleteObsoleteFiles(); + } else { + RecordBackgroundError(s); } - - return s; } void DBImpl::CompactRange(const Slice* begin, const Slice* end) { @@ -568,16 +573,18 @@ } MutexLock l(&mutex_); - while (!manual.done) { - while (manual_compaction_ != NULL) { - bg_cv_.Wait(); - } - manual_compaction_ = &manual; - MaybeScheduleCompaction(); - while (manual_compaction_ == &manual) { + while (!manual.done && !shutting_down_.Acquire_Load() && bg_error_.ok()) { + if (manual_compaction_ == NULL) { // Idle + manual_compaction_ = &manual; + MaybeScheduleCompaction(); + } else { // Running either my compaction or another compaction. bg_cv_.Wait(); } } + if (manual_compaction_ == &manual) { + // Cancel my manual compaction since we aborted early for some reason. + manual_compaction_ = NULL; + } } Status DBImpl::TEST_CompactMemTable() { @@ -596,12 +603,22 @@ return s; } +void DBImpl::RecordBackgroundError(const Status& s) { + mutex_.AssertHeld(); + if (bg_error_.ok()) { + bg_error_ = s; + bg_cv_.SignalAll(); + } +} + void DBImpl::MaybeScheduleCompaction() { mutex_.AssertHeld(); if (bg_compaction_scheduled_) { // Already scheduled } else if (shutting_down_.Acquire_Load()) { // DB is being deleted; no more background compactions + } else if (!bg_error_.ok()) { + // Already got an error; no more changes } else if (imm_ == NULL && manual_compaction_ == NULL && !versions_->NeedsCompaction()) { @@ -619,30 +636,12 @@ void DBImpl::BackgroundCall() { MutexLock l(&mutex_); assert(bg_compaction_scheduled_); - if (!shutting_down_.Acquire_Load()) { - Status s = BackgroundCompaction(); - if (s.ok()) { - // Success - consecutive_compaction_errors_ = 0; - } else if (shutting_down_.Acquire_Load()) { - // Error most likely due to shutdown; do not wait - } else { - // Wait a little bit before retrying background compaction in - // case this is an environmental problem and we do not want to - // chew up resources for failed compactions for the duration of - // the problem. - bg_cv_.SignalAll(); // In case a waiter can proceed despite the error - Log(options_.info_log, "Waiting after background compaction error: %s", - s.ToString().c_str()); - mutex_.Unlock(); - ++consecutive_compaction_errors_; - int seconds_to_sleep = 1; - for (int i = 0; i < 3 && i < consecutive_compaction_errors_ - 1; ++i) { - seconds_to_sleep *= 2; - } - env_->SleepForMicroseconds(seconds_to_sleep * 1000000); - mutex_.Lock(); - } + if (shutting_down_.Acquire_Load()) { + // No more background work when shutting down. + } else if (!bg_error_.ok()) { + // No more background work after a background error. + } else { + BackgroundCompaction(); } bg_compaction_scheduled_ = false; @@ -653,11 +652,12 @@ bg_cv_.SignalAll(); } -Status DBImpl::BackgroundCompaction() { +void DBImpl::BackgroundCompaction() { mutex_.AssertHeld(); if (imm_ != NULL) { - return CompactMemTable(); + CompactMemTable(); + return; } Compaction* c; @@ -691,6 +691,9 @@ c->edit()->AddFile(c->level() + 1, f->number, f->file_size, f->smallest, f->largest); status = versions_->LogAndApply(c->edit(), &mutex_); + if (!status.ok()) { + RecordBackgroundError(status); + } VersionSet::LevelSummaryStorage tmp; Log(options_.info_log, "Moved #%lld to level-%d %lld bytes %s: %s\n", static_cast(f->number), @@ -701,6 +704,9 @@ } else { CompactionState* compact = new CompactionState(c); status = DoCompactionWork(compact); + if (!status.ok()) { + RecordBackgroundError(status); + } CleanupCompaction(compact); c->ReleaseInputs(); DeleteObsoleteFiles(); @@ -714,9 +720,6 @@ } else { Log(options_.info_log, "Compaction error: %s", status.ToString().c_str()); - if (options_.paranoid_checks && bg_error_.ok()) { - bg_error_ = status; - } } if (is_manual) { @@ -732,7 +735,6 @@ } manual_compaction_ = NULL; } - return status; } void DBImpl::CleanupCompaction(CompactionState* compact) { @@ -1002,6 +1004,9 @@ if (status.ok()) { status = InstallCompactionResults(compact); } + if (!status.ok()) { + RecordBackgroundError(status); + } VersionSet::LevelSummaryStorage tmp; Log(options_.info_log, "compacted to: %s", versions_->LevelSummary(&tmp)); @@ -1185,13 +1190,23 @@ { mutex_.Unlock(); status = log_->AddRecord(WriteBatchInternal::Contents(updates)); + bool sync_error = false; if (status.ok() && options.sync) { status = logfile_->Sync(); + if (!status.ok()) { + sync_error = true; + } } if (status.ok()) { status = WriteBatchInternal::InsertInto(updates, mem_); } mutex_.Lock(); + if (sync_error) { + // The state of the log file is indeterminate: the log record we + // just added may or may not show up when the DB is re-opened. + // So we force the DB into a mode where all future writes fail. + RecordBackgroundError(status); + } } if (updates == tmp_batch_) tmp_batch_->Clear(); diff -Nru anoncoin-0.8.5.6/src/leveldb/db/db_impl.h anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/db_impl.h --- anoncoin-0.8.5.6/src/leveldb/db/db_impl.h 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/db_impl.h 2014-11-11 13:56:18.000000000 +0000 @@ -87,8 +87,8 @@ // Compact the in-memory write buffer to disk. Switches to a new // log-file/memtable and writes a new descriptor iff successful. - Status CompactMemTable() - EXCLUSIVE_LOCKS_REQUIRED(mutex_); + // Errors are recorded in bg_error_. + void CompactMemTable() EXCLUSIVE_LOCKS_REQUIRED(mutex_); Status RecoverLogFile(uint64_t log_number, VersionEdit* edit, @@ -102,10 +102,12 @@ EXCLUSIVE_LOCKS_REQUIRED(mutex_); WriteBatch* BuildBatchGroup(Writer** last_writer); + void RecordBackgroundError(const Status& s); + void MaybeScheduleCompaction() EXCLUSIVE_LOCKS_REQUIRED(mutex_); static void BGWork(void* db); void BackgroundCall(); - Status BackgroundCompaction() EXCLUSIVE_LOCKS_REQUIRED(mutex_); + void BackgroundCompaction() EXCLUSIVE_LOCKS_REQUIRED(mutex_); void CleanupCompaction(CompactionState* compact) EXCLUSIVE_LOCKS_REQUIRED(mutex_); Status DoCompactionWork(CompactionState* compact) @@ -170,7 +172,6 @@ // Have we encountered a background error in paranoid mode? Status bg_error_; - int consecutive_compaction_errors_; // Per level compaction stats. stats_[level] stores the stats for // compactions that produced data for the specified "level". diff -Nru anoncoin-0.8.5.6/src/leveldb/db/db_iter.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/db_iter.cc --- anoncoin-0.8.5.6/src/leveldb/db/db_iter.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/db_iter.cc 2014-11-11 13:56:18.000000000 +0000 @@ -161,12 +161,13 @@ saved_key_.clear(); return; } + // saved_key_ already contains the key to skip past. + } else { + // Store in saved_key_ the current key so we skip it below. + SaveKey(ExtractUserKey(iter_->key()), &saved_key_); } - // Temporarily use saved_key_ as storage for key to skip. - std::string* skip = &saved_key_; - SaveKey(ExtractUserKey(iter_->key()), skip); - FindNextUserEntry(true, skip); + FindNextUserEntry(true, &saved_key_); } void DBIter::FindNextUserEntry(bool skipping, std::string* skip) { diff -Nru anoncoin-0.8.5.6/src/leveldb/db/db_test.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/db_test.cc --- anoncoin-0.8.5.6/src/leveldb/db/db_test.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/db_test.cc 2014-11-11 13:56:18.000000000 +0000 @@ -57,8 +57,11 @@ // Special Env used to delay background operations class SpecialEnv : public EnvWrapper { public: - // sstable Sync() calls are blocked while this pointer is non-NULL. - port::AtomicPointer delay_sstable_sync_; + // sstable/log Sync() calls are blocked while this pointer is non-NULL. + port::AtomicPointer delay_data_sync_; + + // sstable/log Sync() calls return an error. + port::AtomicPointer data_sync_error_; // Simulate no-space errors while this pointer is non-NULL. port::AtomicPointer no_space_; @@ -75,11 +78,9 @@ bool count_random_reads_; AtomicCounter random_read_counter_; - AtomicCounter sleep_counter_; - AtomicCounter sleep_time_counter_; - explicit SpecialEnv(Env* base) : EnvWrapper(base) { - delay_sstable_sync_.Release_Store(NULL); + delay_data_sync_.Release_Store(NULL); + data_sync_error_.Release_Store(NULL); no_space_.Release_Store(NULL); non_writable_.Release_Store(NULL); count_random_reads_ = false; @@ -88,17 +89,17 @@ } Status NewWritableFile(const std::string& f, WritableFile** r) { - class SSTableFile : public WritableFile { + class DataFile : public WritableFile { private: SpecialEnv* env_; WritableFile* base_; public: - SSTableFile(SpecialEnv* env, WritableFile* base) + DataFile(SpecialEnv* env, WritableFile* base) : env_(env), base_(base) { } - ~SSTableFile() { delete base_; } + ~DataFile() { delete base_; } Status Append(const Slice& data) { if (env_->no_space_.Acquire_Load() != NULL) { // Drop writes on the floor @@ -110,7 +111,10 @@ Status Close() { return base_->Close(); } Status Flush() { return base_->Flush(); } Status Sync() { - while (env_->delay_sstable_sync_.Acquire_Load() != NULL) { + if (env_->data_sync_error_.Acquire_Load() != NULL) { + return Status::IOError("simulated data sync error"); + } + while (env_->delay_data_sync_.Acquire_Load() != NULL) { DelayMilliseconds(100); } return base_->Sync(); @@ -147,8 +151,9 @@ Status s = target()->NewWritableFile(f, r); if (s.ok()) { - if (strstr(f.c_str(), ".sst") != NULL) { - *r = new SSTableFile(this, *r); + if (strstr(f.c_str(), ".ldb") != NULL || + strstr(f.c_str(), ".log") != NULL) { + *r = new DataFile(this, *r); } else if (strstr(f.c_str(), "MANIFEST") != NULL) { *r = new ManifestFile(this, *r); } @@ -179,12 +184,6 @@ } return s; } - - virtual void SleepForMicroseconds(int micros) { - sleep_counter_.Increment(); - sleep_time_counter_.IncrementBy(micros); - } - }; class DBTest { @@ -322,7 +321,7 @@ } // Check reverse iteration results are the reverse of forward results - int matched = 0; + size_t matched = 0; for (iter->SeekToLast(); iter->Valid(); iter->Prev()) { ASSERT_LT(matched, forward.size()); ASSERT_EQ(IterStatus(iter), forward[forward.size() - matched - 1]); @@ -484,6 +483,24 @@ } return false; } + + // Returns number of files renamed. + int RenameLDBToSST() { + std::vector filenames; + ASSERT_OK(env_->GetChildren(dbname_, &filenames)); + uint64_t number; + FileType type; + int files_renamed = 0; + for (size_t i = 0; i < filenames.size(); i++) { + if (ParseFileName(filenames[i], &number, &type) && type == kTableFile) { + const std::string from = TableFileName(dbname_, number); + const std::string to = SSTTableFileName(dbname_, number); + ASSERT_OK(env_->RenameFile(from, to)); + files_renamed++; + } + } + return files_renamed; + } }; TEST(DBTest, Empty) { @@ -525,11 +542,11 @@ ASSERT_OK(Put("foo", "v1")); ASSERT_EQ("v1", Get("foo")); - env_->delay_sstable_sync_.Release_Store(env_); // Block sync calls + env_->delay_data_sync_.Release_Store(env_); // Block sync calls Put("k1", std::string(100000, 'x')); // Fill memtable Put("k2", std::string(100000, 'y')); // Trigger compaction ASSERT_EQ("v1", Get("foo")); - env_->delay_sstable_sync_.Release_Store(NULL); // Release sync calls + env_->delay_data_sync_.Release_Store(NULL); // Release sync calls } while (ChangeOptions()); } @@ -1516,41 +1533,13 @@ Compact("a", "z"); const int num_files = CountFiles(); env_->no_space_.Release_Store(env_); // Force out-of-space errors - env_->sleep_counter_.Reset(); - for (int i = 0; i < 5; i++) { + for (int i = 0; i < 10; i++) { for (int level = 0; level < config::kNumLevels-1; level++) { dbfull()->TEST_CompactRange(level, NULL, NULL); } } env_->no_space_.Release_Store(NULL); ASSERT_LT(CountFiles(), num_files + 3); - - // Check that compaction attempts slept after errors - ASSERT_GE(env_->sleep_counter_.Read(), 5); -} - -TEST(DBTest, ExponentialBackoff) { - Options options = CurrentOptions(); - options.env = env_; - Reopen(&options); - - ASSERT_OK(Put("foo", "v1")); - ASSERT_EQ("v1", Get("foo")); - Compact("a", "z"); - env_->non_writable_.Release_Store(env_); // Force errors for new files - env_->sleep_counter_.Reset(); - env_->sleep_time_counter_.Reset(); - for (int i = 0; i < 5; i++) { - dbfull()->TEST_CompactRange(2, NULL, NULL); - } - env_->non_writable_.Release_Store(NULL); - - // Wait for compaction to finish - DelayMilliseconds(1000); - - ASSERT_GE(env_->sleep_counter_.Read(), 5); - ASSERT_LT(env_->sleep_counter_.Read(), 10); - ASSERT_GE(env_->sleep_time_counter_.Read(), 10e6); } TEST(DBTest, NonWritableFileSystem) { @@ -1573,6 +1562,37 @@ env_->non_writable_.Release_Store(NULL); } +TEST(DBTest, WriteSyncError) { + // Check that log sync errors cause the DB to disallow future writes. + + // (a) Cause log sync calls to fail + Options options = CurrentOptions(); + options.env = env_; + Reopen(&options); + env_->data_sync_error_.Release_Store(env_); + + // (b) Normal write should succeed + WriteOptions w; + ASSERT_OK(db_->Put(w, "k1", "v1")); + ASSERT_EQ("v1", Get("k1")); + + // (c) Do a sync write; should fail + w.sync = true; + ASSERT_TRUE(!db_->Put(w, "k2", "v2").ok()); + ASSERT_EQ("v1", Get("k1")); + ASSERT_EQ("NOT_FOUND", Get("k2")); + + // (d) make sync behave normally + env_->data_sync_error_.Release_Store(NULL); + + // (e) Do a non-sync write; should fail + w.sync = false; + ASSERT_TRUE(!db_->Put(w, "k3", "v3").ok()); + ASSERT_EQ("v1", Get("k1")); + ASSERT_EQ("NOT_FOUND", Get("k2")); + ASSERT_EQ("NOT_FOUND", Get("k3")); +} + TEST(DBTest, ManifestWriteError) { // Test for the following problem: // (a) Compaction produces file F @@ -1632,6 +1652,22 @@ << s.ToString(); } +TEST(DBTest, StillReadSST) { + ASSERT_OK(Put("foo", "bar")); + ASSERT_EQ("bar", Get("foo")); + + // Dump the memtable to disk. + dbfull()->TEST_CompactMemTable(); + ASSERT_EQ("bar", Get("foo")); + Close(); + ASSERT_GT(RenameLDBToSST(), 0); + Options options = CurrentOptions(); + options.paranoid_checks = true; + Status s = TryReopen(&options); + ASSERT_TRUE(s.ok()); + ASSERT_EQ("bar", Get("foo")); +} + TEST(DBTest, FilesDeletedAfterCompaction) { ASSERT_OK(Put("foo", "v2")); Compact("a", "z"); @@ -1663,7 +1699,7 @@ dbfull()->TEST_CompactMemTable(); // Prevent auto compactions triggered by seeks - env_->delay_sstable_sync_.Release_Store(env_); + env_->delay_data_sync_.Release_Store(env_); // Lookup present keys. Should rarely read from small sstable. env_->random_read_counter_.Reset(); @@ -1684,7 +1720,7 @@ fprintf(stderr, "%d missing => %d reads\n", N, reads); ASSERT_LE(reads, 3*N/100); - env_->delay_sstable_sync_.Release_Store(NULL); + env_->delay_data_sync_.Release_Store(NULL); Close(); delete options.block_cache; delete options.filter_policy; @@ -1744,7 +1780,7 @@ ASSERT_EQ(k, key); ASSERT_GE(w, 0); ASSERT_LT(w, kNumThreads); - ASSERT_LE(c, reinterpret_cast( + ASSERT_LE(static_cast(c), reinterpret_cast( t->state->counter[w].Acquire_Load())); } } diff -Nru anoncoin-0.8.5.6/src/leveldb/db/filename.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/filename.cc --- anoncoin-0.8.5.6/src/leveldb/db/filename.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/filename.cc 2014-11-11 13:56:18.000000000 +0000 @@ -29,11 +29,21 @@ return MakeFileName(name, number, "log"); } +// TableFileName returns the filenames we usually write to, while +// SSTTableFileName returns the alternative filenames we also try to read from +// for backward compatibility. For now, swap them around. +// TODO: when compatibility is no longer necessary, swap them back +// (TableFileName to use "ldb" and SSTTableFileName to use "sst"). std::string TableFileName(const std::string& name, uint64_t number) { assert(number > 0); return MakeFileName(name, number, "sst"); } +std::string SSTTableFileName(const std::string& name, uint64_t number) { + assert(number > 0); + return MakeFileName(name, number, "ldb"); +} + std::string DescriptorFileName(const std::string& dbname, uint64_t number) { assert(number > 0); char buf[100]; @@ -71,7 +81,7 @@ // dbname/LOG // dbname/LOG.old // dbname/MANIFEST-[0-9]+ -// dbname/[0-9]+.(log|sst) +// dbname/[0-9]+.(log|sst|ldb) bool ParseFileName(const std::string& fname, uint64_t* number, FileType* type) { @@ -106,7 +116,7 @@ Slice suffix = rest; if (suffix == Slice(".log")) { *type = kLogFile; - } else if (suffix == Slice(".sst")) { + } else if (suffix == Slice(".sst") || suffix == Slice(".ldb")) { *type = kTableFile; } else if (suffix == Slice(".dbtmp")) { *type = kTempFile; diff -Nru anoncoin-0.8.5.6/src/leveldb/db/filename.h anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/filename.h --- anoncoin-0.8.5.6/src/leveldb/db/filename.h 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/filename.h 2014-11-11 13:56:18.000000000 +0000 @@ -37,6 +37,11 @@ // "dbname". extern std::string TableFileName(const std::string& dbname, uint64_t number); +// Return the legacy file name for an sstable with the specified number +// in the db named by "dbname". The result will be prefixed with +// "dbname". +extern std::string SSTTableFileName(const std::string& dbname, uint64_t number); + // Return the name of the descriptor file for the db named by // "dbname" and the specified incarnation number. The result will be // prefixed with "dbname". diff -Nru anoncoin-0.8.5.6/src/leveldb/db/filename_test.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/filename_test.cc --- anoncoin-0.8.5.6/src/leveldb/db/filename_test.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/filename_test.cc 2014-11-11 13:56:18.000000000 +0000 @@ -27,6 +27,7 @@ { "100.log", 100, kLogFile }, { "0.log", 0, kLogFile }, { "0.sst", 0, kTableFile }, + { "0.ldb", 0, kTableFile }, { "CURRENT", 0, kCurrentFile }, { "LOCK", 0, kDBLockFile }, { "MANIFEST-2", 2, kDescriptorFile }, diff -Nru anoncoin-0.8.5.6/src/leveldb/db/repair.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/repair.cc --- anoncoin-0.8.5.6/src/leveldb/db/repair.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/repair.cc 2014-11-11 13:56:18.000000000 +0000 @@ -244,60 +244,133 @@ void ExtractMetaData() { std::vector kept; for (size_t i = 0; i < table_numbers_.size(); i++) { - TableInfo t; - t.meta.number = table_numbers_[i]; - Status status = ScanTable(&t); - if (!status.ok()) { - std::string fname = TableFileName(dbname_, table_numbers_[i]); - Log(options_.info_log, "Table #%llu: ignoring %s", - (unsigned long long) table_numbers_[i], - status.ToString().c_str()); - ArchiveFile(fname); - } else { - tables_.push_back(t); - } + ScanTable(table_numbers_[i]); } } - Status ScanTable(TableInfo* t) { - std::string fname = TableFileName(dbname_, t->meta.number); + Iterator* NewTableIterator(const FileMetaData& meta) { + // Same as compaction iterators: if paranoid_checks are on, turn + // on checksum verification. + ReadOptions r; + r.verify_checksums = options_.paranoid_checks; + return table_cache_->NewIterator(r, meta.number, meta.file_size); + } + + void ScanTable(uint64_t number) { + TableInfo t; + t.meta.number = number; + std::string fname = TableFileName(dbname_, number); + Status status = env_->GetFileSize(fname, &t.meta.file_size); + if (!status.ok()) { + // Try alternate file name. + fname = SSTTableFileName(dbname_, number); + Status s2 = env_->GetFileSize(fname, &t.meta.file_size); + if (s2.ok()) { + status = Status::OK(); + } + } + if (!status.ok()) { + ArchiveFile(TableFileName(dbname_, number)); + ArchiveFile(SSTTableFileName(dbname_, number)); + Log(options_.info_log, "Table #%llu: dropped: %s", + (unsigned long long) t.meta.number, + status.ToString().c_str()); + return; + } + + // Extract metadata by scanning through table. int counter = 0; - Status status = env_->GetFileSize(fname, &t->meta.file_size); - if (status.ok()) { - Iterator* iter = table_cache_->NewIterator( - ReadOptions(), t->meta.number, t->meta.file_size); - bool empty = true; - ParsedInternalKey parsed; - t->max_sequence = 0; - for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { - Slice key = iter->key(); - if (!ParseInternalKey(key, &parsed)) { - Log(options_.info_log, "Table #%llu: unparsable key %s", - (unsigned long long) t->meta.number, - EscapeString(key).c_str()); - continue; - } - - counter++; - if (empty) { - empty = false; - t->meta.smallest.DecodeFrom(key); - } - t->meta.largest.DecodeFrom(key); - if (parsed.sequence > t->max_sequence) { - t->max_sequence = parsed.sequence; - } + Iterator* iter = NewTableIterator(t.meta); + bool empty = true; + ParsedInternalKey parsed; + t.max_sequence = 0; + for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { + Slice key = iter->key(); + if (!ParseInternalKey(key, &parsed)) { + Log(options_.info_log, "Table #%llu: unparsable key %s", + (unsigned long long) t.meta.number, + EscapeString(key).c_str()); + continue; + } + + counter++; + if (empty) { + empty = false; + t.meta.smallest.DecodeFrom(key); } - if (!iter->status().ok()) { - status = iter->status(); + t.meta.largest.DecodeFrom(key); + if (parsed.sequence > t.max_sequence) { + t.max_sequence = parsed.sequence; } - delete iter; } + if (!iter->status().ok()) { + status = iter->status(); + } + delete iter; Log(options_.info_log, "Table #%llu: %d entries %s", - (unsigned long long) t->meta.number, + (unsigned long long) t.meta.number, counter, status.ToString().c_str()); - return status; + + if (status.ok()) { + tables_.push_back(t); + } else { + RepairTable(fname, t); // RepairTable archives input file. + } + } + + void RepairTable(const std::string& src, TableInfo t) { + // We will copy src contents to a new table and then rename the + // new table over the source. + + // Create builder. + std::string copy = TableFileName(dbname_, next_file_number_++); + WritableFile* file; + Status s = env_->NewWritableFile(copy, &file); + if (!s.ok()) { + return; + } + TableBuilder* builder = new TableBuilder(options_, file); + + // Copy data. + Iterator* iter = NewTableIterator(t.meta); + int counter = 0; + for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { + builder->Add(iter->key(), iter->value()); + counter++; + } + delete iter; + + ArchiveFile(src); + if (counter == 0) { + builder->Abandon(); // Nothing to save + } else { + s = builder->Finish(); + if (s.ok()) { + t.meta.file_size = builder->FileSize(); + } + } + delete builder; + builder = NULL; + + if (s.ok()) { + s = file->Close(); + } + delete file; + file = NULL; + + if (counter > 0 && s.ok()) { + std::string orig = TableFileName(dbname_, t.meta.number); + s = env_->RenameFile(copy, orig); + if (s.ok()) { + Log(options_.info_log, "Table #%llu: %d entries repaired", + (unsigned long long) t.meta.number, counter); + tables_.push_back(t); + } + } + if (!s.ok()) { + env_->DeleteFile(copy); + } } Status WriteDescriptor() { diff -Nru anoncoin-0.8.5.6/src/leveldb/db/table_cache.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/table_cache.cc --- anoncoin-0.8.5.6/src/leveldb/db/table_cache.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/table_cache.cc 2014-11-11 13:56:18.000000000 +0000 @@ -54,6 +54,12 @@ RandomAccessFile* file = NULL; Table* table = NULL; s = env_->NewRandomAccessFile(fname, &file); + if (!s.ok()) { + std::string old_fname = SSTTableFileName(dbname_, file_number); + if (env_->NewRandomAccessFile(old_fname, &file).ok()) { + s = Status::OK(); + } + } if (s.ok()) { s = Table::Open(*options_, file, file_size, &table); } diff -Nru anoncoin-0.8.5.6/src/leveldb/db/version_set.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/version_set.cc --- anoncoin-0.8.5.6/src/leveldb/db/version_set.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/version_set.cc 2014-11-11 13:56:18.000000000 +0000 @@ -876,12 +876,6 @@ } if (!s.ok()) { Log(options_->info_log, "MANIFEST write: %s\n", s.ToString().c_str()); - if (ManifestContains(record)) { - Log(options_->info_log, - "MANIFEST contains log record despite error; advancing to new " - "version to prevent mismatch between in-memory and logged state"); - s = Status::OK(); - } } } @@ -889,8 +883,6 @@ // new CURRENT file that points to it. if (s.ok() && !new_manifest_file.empty()) { s = SetCurrentFile(env_, dbname_, manifest_file_number_); - // No need to double-check MANIFEST in case of error since it - // will be discarded below. } mu->Lock(); @@ -1124,31 +1116,6 @@ return scratch->buffer; } -// Return true iff the manifest contains the specified record. -bool VersionSet::ManifestContains(const std::string& record) const { - std::string fname = DescriptorFileName(dbname_, manifest_file_number_); - Log(options_->info_log, "ManifestContains: checking %s\n", fname.c_str()); - SequentialFile* file = NULL; - Status s = env_->NewSequentialFile(fname, &file); - if (!s.ok()) { - Log(options_->info_log, "ManifestContains: %s\n", s.ToString().c_str()); - return false; - } - log::Reader reader(file, NULL, true/*checksum*/, 0); - Slice r; - std::string scratch; - bool result = false; - while (reader.ReadRecord(&r, &scratch)) { - if (r == Slice(record)) { - result = true; - break; - } - } - delete file; - Log(options_->info_log, "ManifestContains: result = %d\n", result ? 1 : 0); - return result; -} - uint64_t VersionSet::ApproximateOffsetOf(Version* v, const InternalKey& ikey) { uint64_t result = 0; for (int level = 0; level < config::kNumLevels; level++) { diff -Nru anoncoin-0.8.5.6/src/leveldb/db/version_set.h anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/version_set.h --- anoncoin-0.8.5.6/src/leveldb/db/version_set.h 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/db/version_set.h 2014-11-11 13:56:18.000000000 +0000 @@ -292,8 +292,6 @@ void AppendVersion(Version* v); - bool ManifestContains(const std::string& record) const; - Env* const env_; const std::string dbname_; const Options* const options_; diff -Nru anoncoin-0.8.5.6/src/leveldb/doc/impl.html anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/doc/impl.html --- anoncoin-0.8.5.6/src/leveldb/doc/impl.html 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/doc/impl.html 2014-11-11 13:56:18.000000000 +0000 @@ -11,7 +11,7 @@ The implementation of leveldb is similar in spirit to the representation of a single - + Bigtable tablet (section 5.3). However the organization of the files that make up the representation is somewhat different and is explained below. diff -Nru anoncoin-0.8.5.6/src/leveldb/include/leveldb/db.h anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/include/leveldb/db.h --- anoncoin-0.8.5.6/src/leveldb/include/leveldb/db.h 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/include/leveldb/db.h 2014-11-11 13:56:18.000000000 +0000 @@ -14,7 +14,7 @@ // Update Makefile if you change these static const int kMajorVersion = 1; -static const int kMinorVersion = 13; +static const int kMinorVersion = 15; struct Options; struct ReadOptions; diff -Nru anoncoin-0.8.5.6/src/leveldb/include/leveldb/env.h anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/include/leveldb/env.h --- anoncoin-0.8.5.6/src/leveldb/include/leveldb/env.h 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/include/leveldb/env.h 2014-11-11 13:56:18.000000000 +0000 @@ -13,9 +13,9 @@ #ifndef STORAGE_LEVELDB_INCLUDE_ENV_H_ #define STORAGE_LEVELDB_INCLUDE_ENV_H_ -#include #include #include +#include #include #include "leveldb/status.h" diff -Nru anoncoin-0.8.5.6/src/leveldb/issues/issue200_test.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/issues/issue200_test.cc --- anoncoin-0.8.5.6/src/leveldb/issues/issue200_test.cc 1970-01-01 00:00:00.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/issues/issue200_test.cc 2014-11-11 13:56:18.000000000 +0000 @@ -0,0 +1,59 @@ +// Copyright (c) 2013 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +// Test for issue 200: when iterator switches direction from backward +// to forward, the current key can be yielded unexpectedly if a new +// mutation has been added just before the current key. + +#include "leveldb/db.h" +#include "util/testharness.h" + +namespace leveldb { + +class Issue200 { }; + +TEST(Issue200, Test) { + // Get rid of any state from an old run. + std::string dbpath = test::TmpDir() + "/leveldb_issue200_test"; + DestroyDB(dbpath, Options()); + + DB *db; + Options options; + options.create_if_missing = true; + ASSERT_OK(DB::Open(options, dbpath, &db)); + + WriteOptions write_options; + ASSERT_OK(db->Put(write_options, "1", "b")); + ASSERT_OK(db->Put(write_options, "2", "c")); + ASSERT_OK(db->Put(write_options, "3", "d")); + ASSERT_OK(db->Put(write_options, "4", "e")); + ASSERT_OK(db->Put(write_options, "5", "f")); + + ReadOptions read_options; + Iterator *iter = db->NewIterator(read_options); + + // Add an element that should not be reflected in the iterator. + ASSERT_OK(db->Put(write_options, "25", "cd")); + + iter->Seek("5"); + ASSERT_EQ(iter->key().ToString(), "5"); + iter->Prev(); + ASSERT_EQ(iter->key().ToString(), "4"); + iter->Prev(); + ASSERT_EQ(iter->key().ToString(), "3"); + iter->Next(); + ASSERT_EQ(iter->key().ToString(), "4"); + iter->Next(); + ASSERT_EQ(iter->key().ToString(), "5"); + + delete iter; + delete db; + DestroyDB(dbpath, options); +} + +} // namespace leveldb + +int main(int argc, char** argv) { + return leveldb::test::RunAllTests(); +} diff -Nru anoncoin-0.8.5.6/src/leveldb/Makefile anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/Makefile --- anoncoin-0.8.5.6/src/leveldb/Makefile 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/Makefile 2014-11-11 13:56:18.000000000 +0000 @@ -44,6 +44,7 @@ filename_test \ filter_block_test \ issue178_test \ + issue200_test \ log_test \ memenv_test \ skiplist_test \ @@ -71,7 +72,7 @@ else # Update db.h if you change these. SHARED_MAJOR = 1 -SHARED_MINOR = 13 +SHARED_MINOR = 15 SHARED1 = libleveldb.$(PLATFORM_SHARED_EXT) SHARED2 = $(SHARED1).$(SHARED_MAJOR) SHARED3 = $(SHARED1).$(SHARED_MAJOR).$(SHARED_MINOR) @@ -154,6 +155,9 @@ issue178_test: issues/issue178_test.o $(LIBOBJECTS) $(TESTHARNESS) $(CXX) $(LDFLAGS) issues/issue178_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) +issue200_test: issues/issue200_test.o $(LIBOBJECTS) $(TESTHARNESS) + $(CXX) $(LDFLAGS) issues/issue200_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) + log_test: db/log_test.o $(LIBOBJECTS) $(TESTHARNESS) $(CXX) $(LDFLAGS) db/log_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) @@ -191,14 +195,14 @@ mkdir -p ios-x86/$(dir $@) $(CXX) $(CXXFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -c $< -o ios-x86/$@ mkdir -p ios-arm/$(dir $@) - $(DEVICEROOT)/usr/bin/$(CXX) $(CXXFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 -c $< -o ios-arm/$@ + xcrun -sdk iphoneos $(CXX) $(CXXFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 -c $< -o ios-arm/$@ lipo ios-x86/$@ ios-arm/$@ -create -output $@ .c.o: mkdir -p ios-x86/$(dir $@) $(CC) $(CFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -c $< -o ios-x86/$@ mkdir -p ios-arm/$(dir $@) - $(DEVICEROOT)/usr/bin/$(CC) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 -c $< -o ios-arm/$@ + xcrun -sdk iphoneos $(CC) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 -c $< -o ios-arm/$@ lipo ios-x86/$@ ios-arm/$@ -create -output $@ else diff -Nru anoncoin-0.8.5.6/src/leveldb/port/atomic_pointer.h anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/port/atomic_pointer.h --- anoncoin-0.8.5.6/src/leveldb/port/atomic_pointer.h 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/port/atomic_pointer.h 2014-11-11 13:56:18.000000000 +0000 @@ -50,6 +50,13 @@ // http://msdn.microsoft.com/en-us/library/ms684208(v=vs.85).aspx #define LEVELDB_HAVE_MEMORY_BARRIER +// Mac OS +#elif defined(OS_MACOSX) +inline void MemoryBarrier() { + OSMemoryBarrier(); +} +#define LEVELDB_HAVE_MEMORY_BARRIER + // Gcc on x86 #elif defined(ARCH_CPU_X86_FAMILY) && defined(__GNUC__) inline void MemoryBarrier() { @@ -68,13 +75,6 @@ } #define LEVELDB_HAVE_MEMORY_BARRIER -// Mac OS -#elif defined(OS_MACOSX) -inline void MemoryBarrier() { - OSMemoryBarrier(); -} -#define LEVELDB_HAVE_MEMORY_BARRIER - // ARM Linux #elif defined(ARCH_CPU_ARM_FAMILY) && defined(__linux__) typedef void (*LinuxKernelMemoryBarrierFunc)(void); diff -Nru anoncoin-0.8.5.6/src/leveldb/table/filter_block_test.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/table/filter_block_test.cc --- anoncoin-0.8.5.6/src/leveldb/table/filter_block_test.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/table/filter_block_test.cc 2014-11-11 13:56:18.000000000 +0000 @@ -29,7 +29,7 @@ virtual bool KeyMayMatch(const Slice& key, const Slice& filter) const { uint32_t h = Hash(key.data(), key.size(), 1); - for (int i = 0; i + 4 <= filter.size(); i += 4) { + for (size_t i = 0; i + 4 <= filter.size(); i += 4) { if (h == DecodeFixed32(filter.data() + i)) { return true; } diff -Nru anoncoin-0.8.5.6/src/leveldb/util/arena.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/arena.cc --- anoncoin-0.8.5.6/src/leveldb/util/arena.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/arena.cc 2014-11-11 13:56:18.000000000 +0000 @@ -40,7 +40,7 @@ } char* Arena::AllocateAligned(size_t bytes) { - const int align = sizeof(void*); // We'll align to pointer size + const int align = (sizeof(void*) > 8) ? sizeof(void*) : 8; assert((align & (align-1)) == 0); // Pointer size should be a power of 2 size_t current_mod = reinterpret_cast(alloc_ptr_) & (align-1); size_t slop = (current_mod == 0 ? 0 : align - current_mod); diff -Nru anoncoin-0.8.5.6/src/leveldb/util/arena.h anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/arena.h --- anoncoin-0.8.5.6/src/leveldb/util/arena.h 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/arena.h 2014-11-11 13:56:18.000000000 +0000 @@ -5,9 +5,9 @@ #ifndef STORAGE_LEVELDB_UTIL_ARENA_H_ #define STORAGE_LEVELDB_UTIL_ARENA_H_ -#include #include #include +#include #include namespace leveldb { diff -Nru anoncoin-0.8.5.6/src/leveldb/util/arena_test.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/arena_test.cc --- anoncoin-0.8.5.6/src/leveldb/util/arena_test.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/arena_test.cc 2014-11-11 13:56:18.000000000 +0000 @@ -40,7 +40,7 @@ r = arena.Allocate(s); } - for (int b = 0; b < s; b++) { + for (size_t b = 0; b < s; b++) { // Fill the "i"th allocation with a known bit pattern r[b] = i % 256; } @@ -51,10 +51,10 @@ ASSERT_LE(arena.MemoryUsage(), bytes * 1.10); } } - for (int i = 0; i < allocated.size(); i++) { + for (size_t i = 0; i < allocated.size(); i++) { size_t num_bytes = allocated[i].first; const char* p = allocated[i].second; - for (int b = 0; b < num_bytes; b++) { + for (size_t b = 0; b < num_bytes; b++) { // Check the "i"th allocation for the known bit pattern ASSERT_EQ(int(p[b]) & 0xff, i % 256); } diff -Nru anoncoin-0.8.5.6/src/leveldb/util/bloom_test.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/bloom_test.cc --- anoncoin-0.8.5.6/src/leveldb/util/bloom_test.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/bloom_test.cc 2014-11-11 13:56:18.000000000 +0000 @@ -126,7 +126,8 @@ } Build(); - ASSERT_LE(FilterSize(), (length * 10 / 8) + 40) << length; + ASSERT_LE(FilterSize(), static_cast((length * 10 / 8) + 40)) + << length; // All added keys must match for (int i = 0; i < length; i++) { diff -Nru anoncoin-0.8.5.6/src/leveldb/util/coding_test.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/coding_test.cc --- anoncoin-0.8.5.6/src/leveldb/util/coding_test.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/coding_test.cc 2014-11-11 13:56:18.000000000 +0000 @@ -112,13 +112,13 @@ } std::string s; - for (int i = 0; i < values.size(); i++) { + for (size_t i = 0; i < values.size(); i++) { PutVarint64(&s, values[i]); } const char* p = s.data(); const char* limit = p + s.size(); - for (int i = 0; i < values.size(); i++) { + for (size_t i = 0; i < values.size(); i++) { ASSERT_TRUE(p < limit); uint64_t actual; const char* start = p; @@ -143,7 +143,7 @@ std::string s; PutVarint32(&s, large_value); uint32_t result; - for (int len = 0; len < s.size() - 1; len++) { + for (size_t len = 0; len < s.size() - 1; len++) { ASSERT_TRUE(GetVarint32Ptr(s.data(), s.data() + len, &result) == NULL); } ASSERT_TRUE(GetVarint32Ptr(s.data(), s.data() + s.size(), &result) != NULL); @@ -162,7 +162,7 @@ std::string s; PutVarint64(&s, large_value); uint64_t result; - for (int len = 0; len < s.size() - 1; len++) { + for (size_t len = 0; len < s.size() - 1; len++) { ASSERT_TRUE(GetVarint64Ptr(s.data(), s.data() + len, &result) == NULL); } ASSERT_TRUE(GetVarint64Ptr(s.data(), s.data() + s.size(), &result) != NULL); diff -Nru anoncoin-0.8.5.6/src/leveldb/util/env_posix.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/env_posix.cc --- anoncoin-0.8.5.6/src/leveldb/util/env_posix.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/env_posix.cc 2014-11-11 13:56:18.000000000 +0000 @@ -176,147 +176,43 @@ } }; -// We preallocate up to an extra megabyte and use memcpy to append new -// data to the file. This is safe since we either properly close the -// file before reading from it, or for log files, the reading code -// knows enough to skip zero suffixes. -class PosixMmapFile : public WritableFile { +class PosixWritableFile : public WritableFile { private: std::string filename_; - int fd_; - size_t page_size_; - size_t map_size_; // How much extra memory to map at a time - char* base_; // The mapped region - char* limit_; // Limit of the mapped region - char* dst_; // Where to write next (in range [base_,limit_]) - char* last_sync_; // Where have we synced up to - uint64_t file_offset_; // Offset of base_ in file - - // Have we done an munmap of unsynced data? - bool pending_sync_; - - // Roundup x to a multiple of y - static size_t Roundup(size_t x, size_t y) { - return ((x + y - 1) / y) * y; - } - - size_t TruncateToPageBoundary(size_t s) { - s -= (s & (page_size_ - 1)); - assert((s % page_size_) == 0); - return s; - } - - bool UnmapCurrentRegion() { - bool result = true; - if (base_ != NULL) { - if (last_sync_ < limit_) { - // Defer syncing this data until next Sync() call, if any - pending_sync_ = true; - } - if (munmap(base_, limit_ - base_) != 0) { - result = false; - } - file_offset_ += limit_ - base_; - base_ = NULL; - limit_ = NULL; - last_sync_ = NULL; - dst_ = NULL; - - // Increase the amount we map the next time, but capped at 1MB - if (map_size_ < (1<<20)) { - map_size_ *= 2; - } - } - return result; - } - - bool MapNewRegion() { - assert(base_ == NULL); - if (ftruncate(fd_, file_offset_ + map_size_) < 0) { - return false; - } - void* ptr = mmap(NULL, map_size_, PROT_READ | PROT_WRITE, MAP_SHARED, - fd_, file_offset_); - if (ptr == MAP_FAILED) { - return false; - } - base_ = reinterpret_cast(ptr); - limit_ = base_ + map_size_; - dst_ = base_; - last_sync_ = base_; - return true; - } + FILE* file_; public: - PosixMmapFile(const std::string& fname, int fd, size_t page_size) - : filename_(fname), - fd_(fd), - page_size_(page_size), - map_size_(Roundup(65536, page_size)), - base_(NULL), - limit_(NULL), - dst_(NULL), - last_sync_(NULL), - file_offset_(0), - pending_sync_(false) { - assert((page_size & (page_size - 1)) == 0); - } + PosixWritableFile(const std::string& fname, FILE* f) + : filename_(fname), file_(f) { } - - ~PosixMmapFile() { - if (fd_ >= 0) { - PosixMmapFile::Close(); + ~PosixWritableFile() { + if (file_ != NULL) { + // Ignoring any potential errors + fclose(file_); } } virtual Status Append(const Slice& data) { - const char* src = data.data(); - size_t left = data.size(); - while (left > 0) { - assert(base_ <= dst_); - assert(dst_ <= limit_); - size_t avail = limit_ - dst_; - if (avail == 0) { - if (!UnmapCurrentRegion() || - !MapNewRegion()) { - return IOError(filename_, errno); - } - } - - size_t n = (left <= avail) ? left : avail; - memcpy(dst_, src, n); - dst_ += n; - src += n; - left -= n; + size_t r = fwrite_unlocked(data.data(), 1, data.size(), file_); + if (r != data.size()) { + return IOError(filename_, errno); } return Status::OK(); } virtual Status Close() { - Status s; - size_t unused = limit_ - dst_; - if (!UnmapCurrentRegion()) { - s = IOError(filename_, errno); - } else if (unused > 0) { - // Trim the extra space at the end of the file - if (ftruncate(fd_, file_offset_ - unused) < 0) { - s = IOError(filename_, errno); - } - } - - if (close(fd_) < 0) { - if (s.ok()) { - s = IOError(filename_, errno); - } + Status result; + if (fclose(file_) != 0) { + result = IOError(filename_, errno); } - - fd_ = -1; - base_ = NULL; - limit_ = NULL; - return s; + file_ = NULL; + return result; } virtual Status Flush() { + if (fflush_unlocked(file_) != 0) { + return IOError(filename_, errno); + } return Status::OK(); } @@ -353,26 +249,10 @@ if (!s.ok()) { return s; } - - if (pending_sync_) { - // Some unmapped data was not synced - pending_sync_ = false; - if (fdatasync(fd_) < 0) { - s = IOError(filename_, errno); - } - } - - if (dst_ > last_sync_) { - // Find the beginnings of the pages that contain the first and last - // bytes to be synced. - size_t p1 = TruncateToPageBoundary(last_sync_ - base_); - size_t p2 = TruncateToPageBoundary(dst_ - base_ - 1); - last_sync_ = dst_; - if (msync(base_ + p1, p2 - p1 + page_size_, MS_SYNC) < 0) { - s = IOError(filename_, errno); - } + if (fflush_unlocked(file_) != 0 || + fdatasync(fileno(file_)) != 0) { + s = Status::IOError(filename_, strerror(errno)); } - return s; } }; @@ -463,12 +343,12 @@ virtual Status NewWritableFile(const std::string& fname, WritableFile** result) { Status s; - const int fd = open(fname.c_str(), O_CREAT | O_RDWR | O_TRUNC, 0644); - if (fd < 0) { + FILE* f = fopen(fname.c_str(), "w"); + if (f == NULL) { *result = NULL; s = IOError(fname, errno); } else { - *result = new PosixMmapFile(fname, fd, page_size_); + *result = new PosixWritableFile(fname, f); } return s; } @@ -631,7 +511,6 @@ return NULL; } - size_t page_size_; pthread_mutex_t mu_; pthread_cond_t bgsignal_; pthread_t bgthread_; @@ -646,8 +525,7 @@ MmapLimiter mmap_limit_; }; -PosixEnv::PosixEnv() : page_size_(getpagesize()), - started_bgthread_(false) { +PosixEnv::PosixEnv() : started_bgthread_(false) { PthreadCall("mutex_init", pthread_mutex_init(&mu_, NULL)); PthreadCall("cvar_init", pthread_cond_init(&bgsignal_, NULL)); } diff -Nru anoncoin-0.8.5.6/src/leveldb/util/testharness.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/testharness.cc --- anoncoin-0.8.5.6/src/leveldb/util/testharness.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/testharness.cc 2014-11-11 13:56:18.000000000 +0000 @@ -38,7 +38,7 @@ int num = 0; if (tests != NULL) { - for (int i = 0; i < tests->size(); i++) { + for (size_t i = 0; i < tests->size(); i++) { const Test& t = (*tests)[i]; if (matcher != NULL) { std::string name = t.base; diff -Nru anoncoin-0.8.5.6/src/leveldb/util/testutil.cc anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/testutil.cc --- anoncoin-0.8.5.6/src/leveldb/util/testutil.cc 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/testutil.cc 2014-11-11 13:56:18.000000000 +0000 @@ -32,7 +32,7 @@ extern Slice CompressibleString(Random* rnd, double compressed_fraction, - int len, std::string* dst) { + size_t len, std::string* dst) { int raw = static_cast(len * compressed_fraction); if (raw < 1) raw = 1; std::string raw_data; diff -Nru anoncoin-0.8.5.6/src/leveldb/util/testutil.h anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/testutil.h --- anoncoin-0.8.5.6/src/leveldb/util/testutil.h 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/leveldb/util/testutil.h 2014-11-11 13:56:18.000000000 +0000 @@ -24,7 +24,7 @@ // "N*compressed_fraction" bytes and return a Slice that references // the generated data. extern Slice CompressibleString(Random* rnd, double compressed_fraction, - int len, std::string* dst); + size_t len, std::string* dst); // A wrapper that allows injection of errors. class ErrorEnv : public EnvWrapper { diff -Nru anoncoin-0.8.5.6/src/main.cpp anoncoin-0.8.5.6+git20141111.r4233/src/main.cpp --- anoncoin-0.8.5.6/src/main.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/main.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -11,6 +11,7 @@ #include "init.h" #include "ui_interface.h" #include "checkqueue.h" +#include "miner.h" #include #include #include @@ -66,8 +67,6 @@ const string strMessageMagic = "Anoncoin Signed Message:\n"; -double dHashesPerSec = 0.0; -int64 nHPSTimerStart = 0; // Settings int64 nTransactionFee = 0; @@ -1066,22 +1065,6 @@ return pblock->GetHash(); } -int64 static GetBlockValue(int nHeight, int64 nFees) -{ - int64 nSubsidy = 5 * COIN; - // Some adjustments to the start of the lifetime to Anoncoin - if (nHeight < 42000) { - nSubsidy = 4.2 * COIN; - } else if (nHeight < 77777) { // All luck is seven ;) - nSubsidy = 7 * COIN; - } else if (nHeight == 77778) { - nSubsidy = 10 * COIN; - } else { - nSubsidy >>= (nHeight / 306600); // Anoncoin: 306600 blocks in ~2 years - } - return nSubsidy + nFees; -} - // Protocol 1 & 2 static const int64 nTargetTimespan = 86184; //420 * 205.2; = 86184 // Anoncoin: 420 blocks @@ -1159,6 +1142,23 @@ } +int64 GetBlockValue(int nHeight, int64 nFees) +{ + int64 nSubsidy = 5 * COIN; + // Some adjustments to the start of the lifetime to Anoncoin + if (nHeight < 42000) { + nSubsidy = 4.2 * COIN; + } else if (nHeight < 77777) { // All luck is seven ;) + nSubsidy = 7 * COIN; + } else if (nHeight == 77778) { + nSubsidy = 10 * COIN; + } else { + nSubsidy >>= (nHeight / 306600); // Anoncoin: 306600 blocks in ~2 years + } + return nSubsidy + nFees; +} + + // // minimum amount of work that could possibly be required nTime after // minimum work required was nBase @@ -1289,7 +1289,7 @@ return bnNew.GetCompact(); } -unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock) +unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock) { assert(pindexLast); if (pindexLast->nHeight > nDifficultyProtocol3 || fTestNet) { @@ -4247,626 +4247,6 @@ - - - - - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// LitecoinMiner -// - -int static FormatHashBlocks(void* pbuffer, unsigned int len) -{ - unsigned char* pdata = (unsigned char*)pbuffer; - unsigned int blocks = 1 + ((len + 8) / 64); - unsigned char* pend = pdata + 64 * blocks; - memset(pdata + len, 0, 64 * blocks - len); - pdata[len] = 0x80; - unsigned int bits = len * 8; - pend[-1] = (bits >> 0) & 0xff; - pend[-2] = (bits >> 8) & 0xff; - pend[-3] = (bits >> 16) & 0xff; - pend[-4] = (bits >> 24) & 0xff; - return blocks; -} - -static const unsigned int pSHA256InitState[8] = -{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; - -void SHA256Transform(void* pstate, void* pinput, const void* pinit) -{ - SHA256_CTX ctx; - unsigned char data[64]; - - SHA256_Init(&ctx); - - for (int i = 0; i < 16; i++) - ((uint32_t*)data)[i] = ByteReverse(((uint32_t*)pinput)[i]); - - for (int i = 0; i < 8; i++) - ctx.h[i] = ((uint32_t*)pinit)[i]; - - SHA256_Update(&ctx, data, sizeof(data)); - for (int i = 0; i < 8; i++) - ((uint32_t*)pstate)[i] = ctx.h[i]; -} - -// Some explaining would be appreciated -class COrphan -{ -public: - CTransaction* ptx; - set setDependsOn; - double dPriority; - double dFeePerKb; - - COrphan(CTransaction* ptxIn) - { - ptx = ptxIn; - dPriority = dFeePerKb = 0; - } - - void print() const - { - printf("COrphan(hash=%s, dPriority=%.1f, dFeePerKb=%.1f)\n", - ptx->GetHash().ToString().c_str(), dPriority, dFeePerKb); - BOOST_FOREACH(uint256 hash, setDependsOn) - printf(" setDependsOn %s\n", hash.ToString().c_str()); - } -}; - - -uint64 nLastBlockTx = 0; -uint64 nLastBlockSize = 0; - -// We want to sort transactions by priority and fee, so: -typedef boost::tuple TxPriority; -class TxPriorityCompare -{ - bool byFee; -public: - TxPriorityCompare(bool _byFee) : byFee(_byFee) { } - bool operator()(const TxPriority& a, const TxPriority& b) - { - if (byFee) - { - if (a.get<1>() == b.get<1>()) - return a.get<0>() < b.get<0>(); - return a.get<1>() < b.get<1>(); - } - else - { - if (a.get<0>() == b.get<0>()) - return a.get<1>() < b.get<1>(); - return a.get<0>() < b.get<0>(); - } - } -}; - -CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) -{ - // Create new block - auto_ptr pblocktemplate(new CBlockTemplate()); - if(!pblocktemplate.get()) - return NULL; - CBlock *pblock = &pblocktemplate->block; // pointer for convenience - - // Create coinbase tx - CTransaction txNew; - txNew.vin.resize(1); - txNew.vin[0].prevout.SetNull(); - txNew.vout.resize(1); - txNew.vout[0].scriptPubKey = scriptPubKeyIn; - - // Add our coinbase tx as first transaction - pblock->vtx.push_back(txNew); - pblocktemplate->vTxFees.push_back(-1); // updated at end - pblocktemplate->vTxSigOps.push_back(-1); // updated at end - - // Largest block you're willing to create: - unsigned int nBlockMaxSize = GetArg("-blockmaxsize", MAX_BLOCK_SIZE_GEN/4); - // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity: - nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize)); - - // How much of the block should be dedicated to high-priority transactions, - // included regardless of the fees they pay - unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", 27000); - nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize); - - // Minimum block size you want to create; block will be filled with free transactions - // until there are no more or the block reaches this size: - unsigned int nBlockMinSize = GetArg("-blockminsize", 0); - nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); - - // Collect memory pool transactions into the block - int64 nFees = 0; - { - LOCK2(cs_main, mempool.cs); - CBlockIndex* pindexPrev = pindexBest; - CCoinsViewCache view(*pcoinsTip, true); - - // Priority order to process transactions - list vOrphan; // list memory doesn't move - map > mapDependers; - bool fPrintPriority = GetBoolArg("-printpriority"); - - // This vector will be sorted into a priority queue: - vector vecPriority; - vecPriority.reserve(mempool.mapTx.size()); - for (map::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi) - { - CTransaction& tx = (*mi).second; - if (tx.IsCoinBase() || !tx.IsFinal()) - continue; - - COrphan* porphan = NULL; - double dPriority = 0; - int64 nTotalIn = 0; - bool fMissingInputs = false; - BOOST_FOREACH(const CTxIn& txin, tx.vin) - { - // Read prev transaction - if (!view.HaveCoins(txin.prevout.hash)) - { - // This should never happen; all transactions in the memory - // pool should connect to either transactions in the chain - // or other transactions in the memory pool. - if (!mempool.mapTx.count(txin.prevout.hash)) - { - printf("ERROR: mempool transaction missing input\n"); - if (fDebug) assert("mempool transaction missing input" == 0); - fMissingInputs = true; - if (porphan) - vOrphan.pop_back(); - break; - } - - // Has to wait for dependencies - if (!porphan) - { - // Use list for automatic deletion - vOrphan.push_back(COrphan(&tx)); - porphan = &vOrphan.back(); - } - mapDependers[txin.prevout.hash].push_back(porphan); - porphan->setDependsOn.insert(txin.prevout.hash); - nTotalIn += mempool.mapTx[txin.prevout.hash].vout[txin.prevout.n].nValue; - continue; - } - const CCoins &coins = view.GetCoins(txin.prevout.hash); - - int64 nValueIn = coins.vout[txin.prevout.n].nValue; - nTotalIn += nValueIn; - - int nConf = pindexPrev->nHeight - coins.nHeight + 1; - - dPriority += (double)nValueIn * nConf; - } - if (fMissingInputs) continue; - - // Priority is sum(valuein * age) / txsize - unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); - dPriority /= nTxSize; - - // This is a more accurate fee-per-kilobyte than is used by the client code, because the - // client code rounds up the size to the nearest 1K. That's good, because it gives an - // incentive to create smaller transactions. - double dFeePerKb = double(nTotalIn-tx.GetValueOut()) / (double(nTxSize)/1000.0); - - if (porphan) - { - porphan->dPriority = dPriority; - porphan->dFeePerKb = dFeePerKb; - } - else - vecPriority.push_back(TxPriority(dPriority, dFeePerKb, &(*mi).second)); - } - - // Collect transactions into block - uint64 nBlockSize = 1000; - uint64 nBlockTx = 0; - int nBlockSigOps = 100; - bool fSortedByFee = (nBlockPrioritySize <= 0); - - TxPriorityCompare comparer(fSortedByFee); - std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); - - while (!vecPriority.empty()) - { - // Take highest priority transaction off the priority queue: - double dPriority = vecPriority.front().get<0>(); - double dFeePerKb = vecPriority.front().get<1>(); - CTransaction& tx = *(vecPriority.front().get<2>()); - - std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer); - vecPriority.pop_back(); - - // Size limits - unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); - if (nBlockSize + nTxSize >= nBlockMaxSize) - continue; - - // Legacy limits on sigOps: - unsigned int nTxSigOps = tx.GetLegacySigOpCount(); - if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) - continue; - - // Skip free transactions if we're past the minimum block size: - if (fSortedByFee && (dFeePerKb < CTransaction::nMinTxFee) && (nBlockSize + nTxSize >= nBlockMinSize)) - continue; - - // Prioritize by fee once past the priority size or we run out of high-priority - // transactions: - if (!fSortedByFee && - ((nBlockSize + nTxSize >= nBlockPrioritySize) || (dPriority < COIN * 420 / 250))) - { - fSortedByFee = true; - comparer = TxPriorityCompare(fSortedByFee); - std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); - } - - if (!tx.HaveInputs(view)) - continue; - - int64 nTxFees = tx.GetValueIn(view)-tx.GetValueOut(); - - nTxSigOps += tx.GetP2SHSigOpCount(view); - if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) - continue; - - CValidationState state; - if (!tx.CheckInputs(state, view, true, SCRIPT_VERIFY_P2SH)) - continue; - - CTxUndo txundo; - uint256 hash = tx.GetHash(); - tx.UpdateCoins(state, view, txundo, pindexPrev->nHeight+1, hash); - - // Added - pblock->vtx.push_back(tx); - pblocktemplate->vTxFees.push_back(nTxFees); - pblocktemplate->vTxSigOps.push_back(nTxSigOps); - nBlockSize += nTxSize; - ++nBlockTx; - nBlockSigOps += nTxSigOps; - nFees += nTxFees; - - if (fPrintPriority) - { - printf("priority %.1f feeperkb %.1f txid %s\n", - dPriority, dFeePerKb, tx.GetHash().ToString().c_str()); - } - - // Add transactions that depend on this one to the priority queue - if (mapDependers.count(hash)) - { - BOOST_FOREACH(COrphan* porphan, mapDependers[hash]) - { - if (!porphan->setDependsOn.empty()) - { - porphan->setDependsOn.erase(hash); - if (porphan->setDependsOn.empty()) - { - vecPriority.push_back(TxPriority(porphan->dPriority, porphan->dFeePerKb, porphan->ptx)); - std::push_heap(vecPriority.begin(), vecPriority.end(), comparer); - } - } - } - } - } - - nLastBlockTx = nBlockTx; - nLastBlockSize = nBlockSize; - printf("CreateNewBlock(): total size %"PRI64u"\n", nBlockSize); - - pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees); - pblocktemplate->vTxFees[0] = -nFees; - - // Fill in header - pblock->hashPrevBlock = pindexPrev->GetBlockHash(); - pblock->UpdateTime(pindexPrev); - pblock->nBits = GetNextWorkRequired(pindexPrev, pblock); - pblock->nNonce = 0; - pblock->vtx[0].vin[0].scriptSig = CScript() << OP_0 << OP_0; - pblocktemplate->vTxSigOps[0] = pblock->vtx[0].GetLegacySigOpCount(); - - CBlockIndex indexDummy(*pblock); - indexDummy.pprev = pindexPrev; - indexDummy.nHeight = pindexPrev->nHeight + 1; - CCoinsViewCache viewNew(*pcoinsTip, true); - CValidationState state; - if (!pblock->ConnectBlock(state, &indexDummy, viewNew, true)) - throw std::runtime_error("CreateNewBlock() : ConnectBlock failed"); - } - - return pblocktemplate.release(); -} - -CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) -{ - CPubKey pubkey; - if (!reservekey.GetReservedKey(pubkey)) - return NULL; - - CScript scriptPubKey = CScript() << pubkey << OP_CHECKSIG; - return CreateNewBlock(scriptPubKey); -} - -void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce) -{ - // Update nExtraNonce - static uint256 hashPrevBlock; - if (hashPrevBlock != pblock->hashPrevBlock) - { - nExtraNonce = 0; - hashPrevBlock = pblock->hashPrevBlock; - } - ++nExtraNonce; - unsigned int nHeight = pindexPrev->nHeight+1; // Height first in coinbase required for block.version=2 - pblock->vtx[0].vin[0].scriptSig = (CScript() << nHeight << CBigNum(nExtraNonce)) + COINBASE_FLAGS; - assert(pblock->vtx[0].vin[0].scriptSig.size() <= 100); - - pblock->hashMerkleRoot = pblock->BuildMerkleTree(); -} - - -void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1) -{ - // - // Pre-build hash buffers - // - struct - { - struct unnamed2 - { - int nVersion; - uint256 hashPrevBlock; - uint256 hashMerkleRoot; - unsigned int nTime; - unsigned int nBits; - unsigned int nNonce; - } - block; - unsigned char pchPadding0[64]; - uint256 hash1; - unsigned char pchPadding1[64]; - } - tmp; - memset(&tmp, 0, sizeof(tmp)); - - tmp.block.nVersion = pblock->nVersion; - tmp.block.hashPrevBlock = pblock->hashPrevBlock; - tmp.block.hashMerkleRoot = pblock->hashMerkleRoot; - tmp.block.nTime = pblock->nTime; - tmp.block.nBits = pblock->nBits; - tmp.block.nNonce = pblock->nNonce; - - FormatHashBlocks(&tmp.block, sizeof(tmp.block)); - FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1)); - - // Byte swap all the input buffer - for (unsigned int i = 0; i < sizeof(tmp)/4; i++) - ((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]); - - // Precalc the first half of the first hash, which stays constant - SHA256Transform(pmidstate, &tmp.block, pSHA256InitState); - - memcpy(pdata, &tmp.block, 128); - memcpy(phash1, &tmp.hash1, 64); -} - - -bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) -{ - uint256 hash = pblock->GetPoWHash(); - uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); - - if (hash > hashTarget) - return false; - - //// debug print - printf("AnoncoinMiner:\n"); - printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); - pblock->print(); - printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str()); - - // Found a solution - { - LOCK(cs_main); - if (pblock->hashPrevBlock != hashBestChain) - return error("AnoncoinMiner : generated block is stale"); - - // Remove key from key pool - reservekey.KeepKey(); - - // Track how many getdata requests this block gets - { - LOCK(wallet.cs_wallet); - wallet.mapRequestCount[pblock->GetHash()] = 0; - } - - // Process this block the same as if we had received it from another node - CValidationState state; - if (!ProcessBlock(state, NULL, pblock)) - return error("AnoncoinMiner : ProcessBlock, block not accepted"); - } - - return true; -} - -void static LitecoinMiner(CWallet *pwallet) -{ - printf("AnoncoinMiner started\n"); - SetThreadPriority(THREAD_PRIORITY_LOWEST); - RenameThread("anoncoin-miner"); - - // Each thread has its own key and counter - CReserveKey reservekey(pwallet); - unsigned int nExtraNonce = 0; - - try { loop { - while (vNodes.empty()) - MilliSleep(1000); - - // - // Create new block - // - unsigned int nTransactionsUpdatedLast = nTransactionsUpdated; - CBlockIndex* pindexPrev = pindexBest; - - auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey)); - if (!pblocktemplate.get()) - return; - CBlock *pblock = &pblocktemplate->block; - IncrementExtraNonce(pblock, pindexPrev, nExtraNonce); - - printf("Running AnoncoinMiner with %"PRIszu" transactions in block (%u bytes)\n", pblock->vtx.size(), - ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION)); - - // - // Pre-build hash buffers - // - char pmidstatebuf[32+16]; char* pmidstate = alignup<16>(pmidstatebuf); - char pdatabuf[128+16]; char* pdata = alignup<16>(pdatabuf); - char phash1buf[64+16]; char* phash1 = alignup<16>(phash1buf); - - FormatHashBuffers(pblock, pmidstate, pdata, phash1); - - unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4); - unsigned int& nBlockBits = *(unsigned int*)(pdata + 64 + 8); - //unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12); - - - // - // Search - // - int64 nStart = GetTime(); - uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); - loop - { - unsigned int nHashesDone = 0; - - uint256 thash; - char scratchpad[SCRYPT_SCRATCHPAD_SIZE]; - loop - { -#if defined(USE_SSE2) - // Detection would work, but in cases where we KNOW it always has SSE2, - // it is faster to use directly than to use a function pointer or conditional. -#if defined(_M_X64) || defined(__x86_64__) || defined(_M_AMD64) || (defined(MAC_OSX) && defined(__i386__)) - // Always SSE2: x86_64 or Intel MacOS X - scrypt_1024_1_1_256_sp_sse2(BEGIN(pblock->nVersion), BEGIN(thash), scratchpad); -#else - // Detect SSE2: 32bit x86 Linux or Windows - scrypt_1024_1_1_256_sp(BEGIN(pblock->nVersion), BEGIN(thash), scratchpad); -#endif -#else - // Generic scrypt - scrypt_1024_1_1_256_sp_generic(BEGIN(pblock->nVersion), BEGIN(thash), scratchpad); -#endif - - if (thash <= hashTarget) - { - // Found a solution - SetThreadPriority(THREAD_PRIORITY_NORMAL); - CheckWork(pblock, *pwallet, reservekey); - SetThreadPriority(THREAD_PRIORITY_LOWEST); - break; - } - pblock->nNonce += 1; - nHashesDone += 1; - if ((pblock->nNonce & 0xFF) == 0) - break; - } - - // Meter hashes/sec - static int64 nHashCounter; - if (nHPSTimerStart == 0) - { - nHPSTimerStart = GetTimeMillis(); - nHashCounter = 0; - } - else - nHashCounter += nHashesDone; - if (GetTimeMillis() - nHPSTimerStart > 4000) - { - static CCriticalSection cs; - { - LOCK(cs); - if (GetTimeMillis() - nHPSTimerStart > 4000) - { - dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart); - nHPSTimerStart = GetTimeMillis(); - nHashCounter = 0; - static int64 nLogTime; - if (GetTime() - nLogTime > 30 * 60) - { - nLogTime = GetTime(); - printf("hashmeter %6.0f khash/s\n", dHashesPerSec/1000.0); - } - } - } - } - - // Check for stop or if block needs to be rebuilt - boost::this_thread::interruption_point(); - if (vNodes.empty()) - break; - if (pblock->nNonce >= 0xffff0000) - break; - if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60) - break; - if (pindexPrev != pindexBest) - break; - - // Update nTime every few seconds - pblock->UpdateTime(pindexPrev); - nBlockTime = ByteReverse(pblock->nTime); - if (fTestNet) - { - // Changing pblock->nTime can change work required on testnet: - nBlockBits = ByteReverse(pblock->nBits); - hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); - } - } - } } - catch (boost::thread_interrupted) - { - printf("AnoncoinMiner terminated\n"); - throw; - } -} - -void GenerateBitcoins(bool fGenerate, CWallet* pwallet) -{ - static boost::thread_group* minerThreads = NULL; - - int nThreads = GetArg("-genproclimit", -1); - if (nThreads < 0) - nThreads = boost::thread::hardware_concurrency(); - - if (minerThreads != NULL) - { - minerThreads->interrupt_all(); - delete minerThreads; - minerThreads = NULL; - } - - if (nThreads == 0 || !fGenerate) - return; - - minerThreads = new boost::thread_group(); - for (int i = 0; i < nThreads; i++) - minerThreads->create_thread(boost::bind(&LitecoinMiner, pwallet)); -} - // Amount compression: // * If the amount is 0, output 0 // * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9) @@ -4943,3 +4323,13 @@ mapOrphanTransactions.clear(); } } instance_of_cmaincleanup; + + + + + + + + + + diff -Nru anoncoin-0.8.5.6/src/main.h anoncoin-0.8.5.6+git20141111.r4233/src/main.h --- anoncoin-0.8.5.6/src/main.h 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/main.h 2014-11-11 13:56:18.000000000 +0000 @@ -86,8 +86,6 @@ extern uint64 nLastBlockTx; extern uint64 nLastBlockSize; extern const std::string strMessageMagic; -extern double dHashesPerSec; -extern int64 nHPSTimerStart; extern int64 nTimeBestReceived; extern CCriticalSection cs_setpwalletRegistered; extern std::set setpwalletRegistered; @@ -107,12 +105,17 @@ static const uint64 nMinDiskSpace = 52428800; +extern double dHashesPerSec; +extern int64 nHPSTimerStart; + class CReserveKey; class CCoinsDB; class CBlockTreeDB; struct CDiskBlockPos; class CCoins; class CTxUndo; +class CBlockHeader; +class CBlock; class CCoinsView; class CCoinsViewCache; class CScriptCheck; @@ -154,17 +157,6 @@ bool SendMessages(CNode* pto, bool fSendTrickle); /** Run an instance of the script checking thread */ void ThreadScriptCheck(); -/** Run the miner threads */ -void GenerateBitcoins(bool fGenerate, CWallet* pwallet); -/** Generate a new block, without valid proof-of-work */ -CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); -CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey); -/** Modify the extranonce in a block */ -void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); -/** Do mining precalculation */ -void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1); -/** Check mined block */ -bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey); /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ bool CheckProofOfWork(uint256 hash, unsigned int nBits); /** Calculate the minimum amount of work a received block needs, without knowing its direct parent */ @@ -188,9 +180,8 @@ /** Abort with a message */ bool AbortNode(const std::string &msg); - - - +int64 GetBlockValue(int nHeight, int64 nFees); +unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock); diff -Nru anoncoin-0.8.5.6/src/makefile.linux-mingw anoncoin-0.8.5.6+git20141111.r4233/src/makefile.linux-mingw --- anoncoin-0.8.5.6/src/makefile.linux-mingw 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/makefile.linux-mingw 2014-11-11 13:56:18.000000000 +0000 @@ -33,7 +33,7 @@ -l crypto \ -l i2psam -DEFS=-D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE +DEFS=-D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE -DENABLE_WALLET DEBUGFLAGS=-g xCXXFLAGS=-O2 -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) $(CXXFLAGS) # enable: ASLR, DEP and large address aware @@ -80,7 +80,7 @@ obj/main.o \ obj/net.o \ obj/protocol.o \ - obj/bitcoinrpc.o \ + obj/anoncoinrpc.o \ obj/rpcdump.o \ obj/rpcnet.o \ obj/rpcmining.o \ @@ -97,7 +97,8 @@ obj/hash.o \ obj/bloom.o \ obj/leveldb.o \ - obj/txdb.o + obj/txdb.o \ + obj/miner.o ifdef USE_SSE2 DEFS += -DUSE_SSE2 diff -Nru anoncoin-0.8.5.6/src/makefile.mingw anoncoin-0.8.5.6+git20141111.r4233/src/makefile.mingw --- anoncoin-0.8.5.6/src/makefile.mingw 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/makefile.mingw 2014-11-11 13:56:18.000000000 +0000 @@ -46,7 +46,7 @@ -l crypto \ -l i2psam -DEFS=-D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE +DEFS=-D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE -DENABLE_WALLET DEBUGFLAGS=-g CFLAGS=-mthreads -O2 -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) # enable: ASLR, DEP and large address aware @@ -92,7 +92,7 @@ obj/main.o \ obj/net.o \ obj/protocol.o \ - obj/bitcoinrpc.o \ + obj/anoncoinrpc.o \ obj/rpcdump.o \ obj/rpcnet.o \ obj/rpcmining.o \ @@ -109,7 +109,8 @@ obj/bloom.o \ obj/noui.o \ obj/leveldb.o \ - obj/txdb.o + obj/txdb.o \ + obj/miner.o ifdef USE_SSE2 DEFS += -DUSE_SSE2 diff -Nru anoncoin-0.8.5.6/src/makefile.osx anoncoin-0.8.5.6+git20141111.r4233/src/makefile.osx --- anoncoin-0.8.5.6/src/makefile.osx 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/makefile.osx 2014-11-11 13:56:18.000000000 +0000 @@ -72,15 +72,22 @@ # I2P Support -DEFS += -DUSE_NATIVE_I2P -I"../i2psam" -LIBS += -L"../i2psam" +DEFS += -DUSE_NATIVE_I2P -I$(abspath ../i2psam) +LIBS += $(abspath ../i2psam/libi2psam.a) +../i2psam/libi2psam.a: + $(MAKE) -C ../i2psam -f makefile.unix # ppc doesn't work because we don't support big-endian CFLAGS += -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) +DEFS += -DENABLE_WALLET +# HACK: libleveldb.a and libi2psam.a are only in here so that make recognizes that +# anoncoind depends on them. This is inelegant because they are redundant when listed +# in $OBJS (NOTE: compilation fails if they are not in $LIBS, even if present here). OBJS= \ leveldb/libleveldb.a \ + ../i2psam/libi2psam.a \ obj/alert.o \ obj/version.o \ obj/checkpoints.o \ @@ -96,7 +103,7 @@ obj/main.o \ obj/net.o \ obj/protocol.o \ - obj/bitcoinrpc.o \ + obj/anoncoinrpc.o \ obj/rpcdump.o \ obj/rpcnet.o \ obj/rpcmining.o \ @@ -113,7 +120,8 @@ obj/bloom.o \ obj/noui.o \ obj/leveldb.o \ - obj/txdb.o + obj/txdb.o \ + obj/miner.o ifdef USE_SSE2 DEFS += -DUSE_SSE2 @@ -190,6 +198,7 @@ $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) $(TESTLIBS) clean: + $(MAKE) -C ../i2psam -f makefile.unix clean -rm -f anoncoind test_anoncoin -rm -f obj/*.o -rm -f obj-test/*.o diff -Nru anoncoin-0.8.5.6/src/makefile.unix anoncoin-0.8.5.6+git20141111.r4233/src/makefile.unix --- anoncoin-0.8.5.6/src/makefile.unix 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/makefile.unix 2014-11-11 13:56:18.000000000 +0000 @@ -13,7 +13,7 @@ LINK:=$(CXX) -DEFS=-DBOOST_SPIRIT_THREADSAFE -D_FILE_OFFSET_BITS=64 +DEFS=-DBOOST_SPIRIT_THREADSAFE -D_FILE_OFFSET_BITS=64 -DENABLE_WALLET 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)) @@ -62,12 +62,7 @@ -Wl,-B$(LMODE2) \ -l z \ -l dl \ - -l pthread \ - -l i2psam - -# I2P Support -DEFS += -DUSE_NATIVE_I2P -I"../i2psam" -LIBS += -L"../i2psam" + -l pthread # Hardening # Make some classes of vulnerabilities unexploitable in case one is discovered. @@ -114,8 +109,12 @@ # adds some defaults in front. Unfortunately, LDFLAGS=... $(LDFLAGS) does not work. xLDFLAGS=$(LDHARDENING) $(LDFLAGS) +# HACK: libleveldb.a and libi2psam.a are only in here so that make recognizes that +# anoncoind depends on them. This is inelegant because they are redundant when listed +# in $OBJS (NOTE: compilation fails if they are not in $LIBS, even if present here). OBJS= \ leveldb/libleveldb.a \ + ../i2psam/libi2psam.a \ obj/alert.o \ obj/version.o \ obj/checkpoints.o \ @@ -131,7 +130,7 @@ obj/main.o \ obj/net.o \ obj/protocol.o \ - obj/bitcoinrpc.o \ + obj/anoncoinrpc.o \ obj/rpcdump.o \ obj/rpcnet.o \ obj/rpcmining.o \ @@ -148,7 +147,8 @@ obj/bloom.o \ obj/noui.o \ obj/leveldb.o \ - obj/txdb.o + obj/txdb.o \ + obj/miner.o ifdef USE_SSE2 @@ -172,6 +172,14 @@ leveldb/libleveldb.a: @echo "Building LevelDB ..." && cd leveldb && $(MAKE) CC=$(CC) CXX=$(CXX) OPT="$(xCXXFLAGS)" libleveldb.a libmemenv.a && cd .. +# +# I2P support +# +LIBS += $(abspath ../i2psam/libi2psam.a) +DEFS += -DUSE_NATIVE_I2P -I$(abspath ../i2psam) +../i2psam/libi2psam.a: + $(MAKE) -C ../i2psam -f makefile.unix + # auto-generated dependencies: -include obj/*.P -include obj-test/*.P @@ -211,6 +219,7 @@ $(LINK) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ $(TESTLIBS) $(xLDFLAGS) $(LIBS) clean: + $(MAKE) -C ../i2psam -f makefile.unix clean -rm -f anoncoind test_anoncoin -rm -f obj/*.o -rm -f obj-test/*.o diff -Nru anoncoin-0.8.5.6/src/miner.cpp anoncoin-0.8.5.6+git20141111.r4233/src/miner.cpp --- anoncoin-0.8.5.6/src/miner.cpp 1970-01-01 00:00:00.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/miner.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -0,0 +1,630 @@ +#include "miner.h" + +#include "main.h" +#include "net.h" +#include "uint256.h" +#ifdef ENABLE_WALLET +#include "wallet.h" +#endif + +using namespace std; + + +////////////////////////////////////////////////////////////////////////////// +// +// AnoncoinMiner +// + +int FormatHashBlocks(void* pbuffer, unsigned int len) +{ + unsigned char* pdata = (unsigned char*)pbuffer; + unsigned int blocks = 1 + ((len + 8) / 64); + unsigned char* pend = pdata + 64 * blocks; + memset(pdata + len, 0, 64 * blocks - len); + pdata[len] = 0x80; + unsigned int bits = len * 8; + pend[-1] = (bits >> 0) & 0xff; + pend[-2] = (bits >> 8) & 0xff; + pend[-3] = (bits >> 16) & 0xff; + pend[-4] = (bits >> 24) & 0xff; + return blocks; +} + +static const unsigned int pSHA256InitState[8] = +{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; + +void SHA256Transform(void* pstate, void* pinput, const void* pinit) +{ + SHA256_CTX ctx; + unsigned char data[64]; + + SHA256_Init(&ctx); + + for (int i = 0; i < 16; i++) + ((uint32_t*)data)[i] = ByteReverse(((uint32_t*)pinput)[i]); + + for (int i = 0; i < 8; i++) + ctx.h[i] = ((uint32_t*)pinit)[i]; + + SHA256_Update(&ctx, data, sizeof(data)); + for (int i = 0; i < 8; i++) + ((uint32_t*)pstate)[i] = ctx.h[i]; +} + +// Some explaining would be appreciated +class COrphan +{ +public: + CTransaction* ptx; + set setDependsOn; + double dPriority; + double dFeePerKb; + + COrphan(CTransaction* ptxIn) + { + ptx = ptxIn; + dPriority = dFeePerKb = 0; + } + + void print() const + { + printf("COrphan(hash=%s, dPriority=%.1f, dFeePerKb=%.1f)\n", + ptx->GetHash().ToString().c_str(), dPriority, dFeePerKb); + BOOST_FOREACH(uint256 hash, setDependsOn) + printf(" setDependsOn %s\n", hash.ToString().c_str()); + } +}; + + +uint64 nLastBlockTx = 0; +uint64 nLastBlockSize = 0; + +// We want to sort transactions by priority and fee, so: +typedef boost::tuple TxPriority; +class TxPriorityCompare +{ + bool byFee; +public: + TxPriorityCompare(bool _byFee) : byFee(_byFee) { } + bool operator()(const TxPriority& a, const TxPriority& b) + { + if (byFee) + { + if (a.get<1>() == b.get<1>()) + return a.get<0>() < b.get<0>(); + return a.get<1>() < b.get<1>(); + } + else + { + if (a.get<0>() == b.get<0>()) + return a.get<1>() < b.get<1>(); + return a.get<0>() < b.get<0>(); + } + } +}; + +CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) +{ + // Create new block + auto_ptr pblocktemplate(new CBlockTemplate()); + if(!pblocktemplate.get()) + return NULL; + CBlock *pblock = &pblocktemplate->block; // pointer for convenience + + // Create coinbase tx + CTransaction txNew; + txNew.vin.resize(1); + txNew.vin[0].prevout.SetNull(); + txNew.vout.resize(1); + txNew.vout[0].scriptPubKey = scriptPubKeyIn; + + // Add our coinbase tx as first transaction + pblock->vtx.push_back(txNew); + pblocktemplate->vTxFees.push_back(-1); // updated at end + pblocktemplate->vTxSigOps.push_back(-1); // updated at end + + // Largest block you're willing to create: + unsigned int nBlockMaxSize = GetArg("-blockmaxsize", MAX_BLOCK_SIZE_GEN/4); + // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity: + nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize)); + + // How much of the block should be dedicated to high-priority transactions, + // included regardless of the fees they pay + unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", 27000); + nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize); + + // Minimum block size you want to create; block will be filled with free transactions + // until there are no more or the block reaches this size: + unsigned int nBlockMinSize = GetArg("-blockminsize", 0); + nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); + + // Collect memory pool transactions into the block + int64 nFees = 0; + { + LOCK2(cs_main, mempool.cs); + CBlockIndex* pindexPrev = pindexBest; + CCoinsViewCache view(*pcoinsTip, true); + + // Priority order to process transactions + list vOrphan; // list memory doesn't move + map > mapDependers; + bool fPrintPriority = GetBoolArg("-printpriority"); + + // This vector will be sorted into a priority queue: + vector vecPriority; + vecPriority.reserve(mempool.mapTx.size()); + for (map::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi) + { + CTransaction& tx = (*mi).second; + if (tx.IsCoinBase() || !tx.IsFinal()) + continue; + + COrphan* porphan = NULL; + double dPriority = 0; + int64 nTotalIn = 0; + bool fMissingInputs = false; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + // Read prev transaction + if (!view.HaveCoins(txin.prevout.hash)) + { + // This should never happen; all transactions in the memory + // pool should connect to either transactions in the chain + // or other transactions in the memory pool. + if (!mempool.mapTx.count(txin.prevout.hash)) + { + printf("ERROR: mempool transaction missing input\n"); + if (fDebug) assert("mempool transaction missing input" == 0); + fMissingInputs = true; + if (porphan) + vOrphan.pop_back(); + break; + } + + // Has to wait for dependencies + if (!porphan) + { + // Use list for automatic deletion + vOrphan.push_back(COrphan(&tx)); + porphan = &vOrphan.back(); + } + mapDependers[txin.prevout.hash].push_back(porphan); + porphan->setDependsOn.insert(txin.prevout.hash); + nTotalIn += mempool.mapTx[txin.prevout.hash].vout[txin.prevout.n].nValue; + continue; + } + const CCoins &coins = view.GetCoins(txin.prevout.hash); + + int64 nValueIn = coins.vout[txin.prevout.n].nValue; + nTotalIn += nValueIn; + + int nConf = pindexPrev->nHeight - coins.nHeight + 1; + + dPriority += (double)nValueIn * nConf; + } + if (fMissingInputs) continue; + + // Priority is sum(valuein * age) / txsize + unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + dPriority /= nTxSize; + + // This is a more accurate fee-per-kilobyte than is used by the client code, because the + // client code rounds up the size to the nearest 1K. That's good, because it gives an + // incentive to create smaller transactions. + double dFeePerKb = double(nTotalIn-tx.GetValueOut()) / (double(nTxSize)/1000.0); + + if (porphan) + { + porphan->dPriority = dPriority; + porphan->dFeePerKb = dFeePerKb; + } + else + vecPriority.push_back(TxPriority(dPriority, dFeePerKb, &(*mi).second)); + } + + // Collect transactions into block + uint64 nBlockSize = 1000; + uint64 nBlockTx = 0; + int nBlockSigOps = 100; + bool fSortedByFee = (nBlockPrioritySize <= 0); + + TxPriorityCompare comparer(fSortedByFee); + std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); + + while (!vecPriority.empty()) + { + // Take highest priority transaction off the priority queue: + double dPriority = vecPriority.front().get<0>(); + double dFeePerKb = vecPriority.front().get<1>(); + CTransaction& tx = *(vecPriority.front().get<2>()); + + std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer); + vecPriority.pop_back(); + + // Size limits + unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + if (nBlockSize + nTxSize >= nBlockMaxSize) + continue; + + // Legacy limits on sigOps: + unsigned int nTxSigOps = tx.GetLegacySigOpCount(); + if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) + continue; + + // Skip free transactions if we're past the minimum block size: + if (fSortedByFee && (dFeePerKb < CTransaction::nMinTxFee) && (nBlockSize + nTxSize >= nBlockMinSize)) + continue; + + // Prioritize by fee once past the priority size or we run out of high-priority + // transactions: + if (!fSortedByFee && + ((nBlockSize + nTxSize >= nBlockPrioritySize) || (dPriority < COIN * 420 / 250))) + { + fSortedByFee = true; + comparer = TxPriorityCompare(fSortedByFee); + std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); + } + + if (!tx.HaveInputs(view)) + continue; + + int64 nTxFees = tx.GetValueIn(view)-tx.GetValueOut(); + + nTxSigOps += tx.GetP2SHSigOpCount(view); + if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) + continue; + + CValidationState state; + if (!tx.CheckInputs(state, view, true, SCRIPT_VERIFY_P2SH)) + continue; + + CTxUndo txundo; + uint256 hash = tx.GetHash(); + tx.UpdateCoins(state, view, txundo, pindexPrev->nHeight+1, hash); + + // Added + pblock->vtx.push_back(tx); + pblocktemplate->vTxFees.push_back(nTxFees); + pblocktemplate->vTxSigOps.push_back(nTxSigOps); + nBlockSize += nTxSize; + ++nBlockTx; + nBlockSigOps += nTxSigOps; + nFees += nTxFees; + + if (fPrintPriority) + { + printf("priority %.1f feeperkb %.1f txid %s\n", + dPriority, dFeePerKb, tx.GetHash().ToString().c_str()); + } + + // Add transactions that depend on this one to the priority queue + if (mapDependers.count(hash)) + { + BOOST_FOREACH(COrphan* porphan, mapDependers[hash]) + { + if (!porphan->setDependsOn.empty()) + { + porphan->setDependsOn.erase(hash); + if (porphan->setDependsOn.empty()) + { + vecPriority.push_back(TxPriority(porphan->dPriority, porphan->dFeePerKb, porphan->ptx)); + std::push_heap(vecPriority.begin(), vecPriority.end(), comparer); + } + } + } + } + } + + nLastBlockTx = nBlockTx; + nLastBlockSize = nBlockSize; + printf("CreateNewBlock(): total size %"PRI64u"\n", nBlockSize); + + pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees); + pblocktemplate->vTxFees[0] = -nFees; + + // Fill in header + pblock->hashPrevBlock = pindexPrev->GetBlockHash(); + pblock->UpdateTime(pindexPrev); + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock); + pblock->nNonce = 0; + pblock->vtx[0].vin[0].scriptSig = CScript() << OP_0 << OP_0; + pblocktemplate->vTxSigOps[0] = pblock->vtx[0].GetLegacySigOpCount(); + + CBlockIndex indexDummy(*pblock); + indexDummy.pprev = pindexPrev; + indexDummy.nHeight = pindexPrev->nHeight + 1; + CCoinsViewCache viewNew(*pcoinsTip, true); + CValidationState state; + if (!pblock->ConnectBlock(state, &indexDummy, viewNew, true)) + throw std::runtime_error("CreateNewBlock() : ConnectBlock failed"); + } + + return pblocktemplate.release(); +} + +CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) +{ + CPubKey pubkey; + if (!reservekey.GetReservedKey(pubkey)) + return NULL; + + CScript scriptPubKey = CScript() << pubkey << OP_CHECKSIG; + return CreateNewBlock(scriptPubKey); +} + +void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce) +{ + // Update nExtraNonce + static uint256 hashPrevBlock; + if (hashPrevBlock != pblock->hashPrevBlock) + { + nExtraNonce = 0; + hashPrevBlock = pblock->hashPrevBlock; + } + ++nExtraNonce; + unsigned int nHeight = pindexPrev->nHeight+1; // Height first in coinbase required for block.version=2 + pblock->vtx[0].vin[0].scriptSig = (CScript() << nHeight << CBigNum(nExtraNonce)) + COINBASE_FLAGS; + assert(pblock->vtx[0].vin[0].scriptSig.size() <= 100); + + pblock->hashMerkleRoot = pblock->BuildMerkleTree(); +} + + +void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1) +{ + // + // Pre-build hash buffers + // + struct + { + struct unnamed2 + { + int nVersion; + uint256 hashPrevBlock; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + } + block; + unsigned char pchPadding0[64]; + uint256 hash1; + unsigned char pchPadding1[64]; + } + tmp; + memset(&tmp, 0, sizeof(tmp)); + + tmp.block.nVersion = pblock->nVersion; + tmp.block.hashPrevBlock = pblock->hashPrevBlock; + tmp.block.hashMerkleRoot = pblock->hashMerkleRoot; + tmp.block.nTime = pblock->nTime; + tmp.block.nBits = pblock->nBits; + tmp.block.nNonce = pblock->nNonce; + + FormatHashBlocks(&tmp.block, sizeof(tmp.block)); + FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1)); + + // Byte swap all the input buffer + for (unsigned int i = 0; i < sizeof(tmp)/4; i++) + ((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]); + + // Precalc the first half of the first hash, which stays constant + SHA256Transform(pmidstate, &tmp.block, pSHA256InitState); + + memcpy(pdata, &tmp.block, 128); + memcpy(phash1, &tmp.hash1, 64); +} + + +bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) +{ + uint256 hash = pblock->GetPoWHash(); + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + + if (hash > hashTarget) + return false; + + //// debug print + printf("AnoncoinMiner:\n"); + printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); + pblock->print(); + printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str()); + + // Found a solution + { + LOCK(cs_main); + if (pblock->hashPrevBlock != hashBestChain) + return error("AnoncoinMiner : generated block is stale"); + + // Remove key from key pool + reservekey.KeepKey(); + + // Track how many getdata requests this block gets + { + LOCK(wallet.cs_wallet); + wallet.mapRequestCount[pblock->GetHash()] = 0; + } + + // Process this block the same as if we had received it from another node + CValidationState state; + if (!ProcessBlock(state, NULL, pblock)) + return error("AnoncoinMiner : ProcessBlock, block not accepted"); + } + + return true; +} + +#ifdef ENABLE_WALLET + + +double dHashesPerSec = 0.0; +int64 nHPSTimerStart = 0; + +void AnoncoinMiner(CWallet *pwallet) +{ + printf("AnoncoinMiner started\n"); + SetThreadPriority(THREAD_PRIORITY_LOWEST); + RenameThread("anoncoin-miner"); + + // Each thread has its own key and counter + CReserveKey reservekey(pwallet); + unsigned int nExtraNonce = 0; + + try { loop { + while (vNodes.empty()) + MilliSleep(1000); + + // + // Create new block + // + unsigned int nTransactionsUpdatedLast = nTransactionsUpdated; + CBlockIndex* pindexPrev = pindexBest; + + auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey)); + if (!pblocktemplate.get()) + return; + CBlock *pblock = &pblocktemplate->block; + IncrementExtraNonce(pblock, pindexPrev, nExtraNonce); + + printf("Running AnoncoinMiner with %"PRIszu" transactions in block (%u bytes)\n", pblock->vtx.size(), + ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION)); + + // + // Pre-build hash buffers + // + char pmidstatebuf[32+16]; char* pmidstate = alignup<16>(pmidstatebuf); + char pdatabuf[128+16]; char* pdata = alignup<16>(pdatabuf); + char phash1buf[64+16]; char* phash1 = alignup<16>(phash1buf); + + FormatHashBuffers(pblock, pmidstate, pdata, phash1); + + unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4); + unsigned int& nBlockBits = *(unsigned int*)(pdata + 64 + 8); + //unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12); + + + // + // Search + // + int64 nStart = GetTime(); + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + loop + { + unsigned int nHashesDone = 0; + + uint256 thash; + char scratchpad[SCRYPT_SCRATCHPAD_SIZE]; + loop + { +#if defined(USE_SSE2) + // Detection would work, but in cases where we KNOW it always has SSE2, + // it is faster to use directly than to use a function pointer or conditional. +#if defined(_M_X64) || defined(__x86_64__) || defined(_M_AMD64) || (defined(MAC_OSX) && defined(__i386__)) + // Always SSE2: x86_64 or Intel MacOS X + scrypt_1024_1_1_256_sp_sse2(BEGIN(pblock->nVersion), BEGIN(thash), scratchpad); +#else + // Detect SSE2: 32bit x86 Linux or Windows + scrypt_1024_1_1_256_sp(BEGIN(pblock->nVersion), BEGIN(thash), scratchpad); +#endif +#else + // Generic scrypt + scrypt_1024_1_1_256_sp_generic(BEGIN(pblock->nVersion), BEGIN(thash), scratchpad); +#endif + + if (thash <= hashTarget) + { + // Found a solution + SetThreadPriority(THREAD_PRIORITY_NORMAL); + CheckWork(pblock, *pwallet, reservekey); + SetThreadPriority(THREAD_PRIORITY_LOWEST); + break; + } + pblock->nNonce += 1; + nHashesDone += 1; + if ((pblock->nNonce & 0xFF) == 0) + break; + } + + // Meter hashes/sec + static int64 nHashCounter; + if (nHPSTimerStart == 0) + { + nHPSTimerStart = GetTimeMillis(); + nHashCounter = 0; + } + else + nHashCounter += nHashesDone; + if (GetTimeMillis() - nHPSTimerStart > 4000) + { + static CCriticalSection cs; + { + LOCK(cs); + if (GetTimeMillis() - nHPSTimerStart > 4000) + { + dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart); + nHPSTimerStart = GetTimeMillis(); + nHashCounter = 0; + static int64 nLogTime; + if (GetTime() - nLogTime > 30 * 60) + { + nLogTime = GetTime(); + printf("hashmeter %6.0f khash/s\n", dHashesPerSec/1000.0); + } + } + } + } + + // Check for stop or if block needs to be rebuilt + boost::this_thread::interruption_point(); + if (vNodes.empty()) + break; + if (pblock->nNonce >= 0xffff0000) + break; + if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60) + break; + if (pindexPrev != pindexBest) + break; + + // Update nTime every few seconds + pblock->UpdateTime(pindexPrev); + nBlockTime = ByteReverse(pblock->nTime); + if (fTestNet) + { + // Changing pblock->nTime can change work required on testnet: + nBlockBits = ByteReverse(pblock->nBits); + hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + } + } + } } + catch (boost::thread_interrupted) + { + printf("AnoncoinMiner terminated\n"); + throw; + } +} + +void GenerateAnoncoins(bool fGenerate, CWallet* pwallet) +{ + static boost::thread_group* minerThreads = NULL; + + int nThreads = GetArg("-genproclimit", -1); + if (nThreads < 0) + nThreads = boost::thread::hardware_concurrency(); + + if (minerThreads != NULL) + { + minerThreads->interrupt_all(); + delete minerThreads; + minerThreads = NULL; + } + + if (nThreads == 0 || !fGenerate) + return; + + minerThreads = new boost::thread_group(); + for (int i = 0; i < nThreads; i++) + minerThreads->create_thread(boost::bind(&AnoncoinMiner, pwallet)); +} + +#endif + diff -Nru anoncoin-0.8.5.6/src/miner.h anoncoin-0.8.5.6+git20141111.r4233/src/miner.h --- anoncoin-0.8.5.6/src/miner.h 1970-01-01 00:00:00.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/miner.h 2014-11-11 13:56:18.000000000 +0000 @@ -0,0 +1,37 @@ +#ifndef ANONCOIN_MINER_H +#define ANONCOIN_MINER_H + +#include + +typedef long long int64; +typedef unsigned long long uint64; + + +class CBlock; +class CBlockHeader; +class CBlockIndex; +struct CBlockTemplate; +class CReserveKey; +class CScript; + +#ifdef ENABLE_WALLET +class CWallet; +void AnoncoinMiner(CWallet *pwallet); +#endif + +/** Run the miner threads */ +void GenerateAnoncoins(bool fGenerate, CWallet* pwallet); +/** Generate a new block, without valid proof-of-work */ +CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); +CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey); +/** Modify the extranonce in a block */ +void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); +/** Do mining precalculation */ +void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1); +/** Check mined block */ +bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey); +/** Base sha256 mining transform */ +void SHA256Transform(void* pstate, void* pinput, const void* pinit); + + +#endif diff -Nru anoncoin-0.8.5.6/src/net.cpp anoncoin-0.8.5.6+git20141111.r4233/src/net.cpp --- anoncoin-0.8.5.6/src/net.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/net.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -3,7 +3,7 @@ // 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 "util.h" #include "net.h" #include "init.h" #include "addrman.h" @@ -11,6 +11,10 @@ #include "script.h" #include "irc.h" #include "i2p.h" +#ifdef ENABLE_WALLET +#include "db.h" +#include "miner.h" +#endif #ifdef WIN32 #include @@ -1036,57 +1040,59 @@ // Accept new connections // if (!IsI2POnly()) - BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) - if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv)) { + BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) + if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv)) + { #ifdef USE_IPV6 - struct sockaddr_storage sockaddr; + struct sockaddr_storage sockaddr; #else - struct sockaddr sockaddr; + struct sockaddr sockaddr; #endif - socklen_t len = sizeof(sockaddr); - SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len); - CAddress addr; - int nInbound = 0; + socklen_t len = sizeof(sockaddr); + SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len); + CAddress addr; + int nInbound = 0; - if (hSocket != INVALID_SOCKET) - if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) - printf("Warning: Unknown socket family\n"); + if (hSocket != INVALID_SOCKET) + if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) + printf("Warning: Unknown socket family\n"); - { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - if (pnode->fInbound) - nInbound++; - } + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if (pnode->fInbound) + nInbound++; + } - if (hSocket == INVALID_SOCKET) - { - int nErr = WSAGetLastError(); - if (nErr != WSAEWOULDBLOCK) - printf("socket error accept failed: %d\n", nErr); - } - else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS) - { + if (hSocket == INVALID_SOCKET) { - LOCK(cs_setservAddNodeAddresses); - if (!setservAddNodeAddresses.count(addr)) - closesocket(hSocket); + int nErr = WSAGetLastError(); + if (nErr != WSAEWOULDBLOCK) + printf("socket error accept failed: %d\n", nErr); } - } - else if (CNode::IsBanned(addr)) - { - printf("connection from %s dropped (banned)\n", addr.ToString().c_str()); - closesocket(hSocket); - } - else - { - printf("accepted connection %s\n", addr.ToString().c_str()); - CNode* pnode = new CNode(hSocket, addr, "", true); - pnode->AddRef(); + else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS) { - LOCK(cs_vNodes); - vNodes.push_back(pnode); + { + LOCK(cs_setservAddNodeAddresses); + if (!setservAddNodeAddresses.count(addr)) + closesocket(hSocket); + } + } + else if (CNode::IsBanned(addr)) + { + printf("connection from %s dropped (banned)\n", addr.ToString().c_str()); + closesocket(hSocket); + } + else + { + printf("accepted connection %s\n", addr.ToString().c_str()); + CNode* pnode = new CNode(hSocket, addr, "", true); + pnode->AddRef(); + { + LOCK(cs_vNodes); + vNodes.push_back(pnode); + } } } } @@ -1385,7 +1391,12 @@ {"st4eyxcp73zzbpatgt26pt3rlfwb7g5ywedol65baalgpnhvzqpa.b32.i2p", "st4eyxcp73zzbpatgt26pt3rlfwb7g5ywedol65baalgpnhvzqpa.b32.i2p"}, {"qgmxpnpujddsd5ez67p4ognqsvo64tnzdbzesezdbtb3atyoxcpq.b32.i2p", "qgmxpnpujddsd5ez67p4ognqsvo64tnzdbzesezdbtb3atyoxcpq.b32.i2p"}, {"a4gii55rnvv22qm2ojre2n67bzms5utr4k3ckafwjdoym2cqmv2q.b32.i2p", "a4gii55rnvv22qm2ojre2n67bzms5utr4k3ckafwjdoym2cqmv2q.b32.i2p"}, // K1773R's seednode - {"qc37luxnbh3hkihxfl2e7nwosebh5sbfvpvjqwn7c3g5kqftb5qq.b32.i2p", "qc37luxnbh3hkihxfl2e7nwosebh5sbfvpvjqwn7c3g5kqftb5qq.b32.i2p"} // psi's seednode + {"b7ziruwpk7g2e44xyomnc2nu5tx7bc2f2ai4dzi66uxm3bc3qttq.b32.i2p", "b7ziruwpk7g2e44xyomnc2nu5tx7bc2f2ai4dzi66uxm3bc3qttq.b32.i2p"}, // K1773R's seednode (dnsseed01) + {"72vaef5cmmlcilgvpeltcp77gutsnyic2l5khsgz7kyivla5lwjq.b32.i2p", "72vaef5cmmlcilgvpeltcp77gutsnyic2l5khsgz7kyivla5lwjq.b32.i2p"}, // riddler's seednode + {"qc37luxnbh3hkihxfl2e7nwosebh5sbfvpvjqwn7c3g5kqftb5qq.b32.i2p", "qc37luxnbh3hkihxfl2e7nwosebh5sbfvpvjqwn7c3g5kqftb5qq.b32.i2p"}, // psi's seednode + {"xynjl64xlviqhkjl2fbvupj7y3wct46jtayoxm2ksba6tqzo6tsa.b32.i2p", "xynjl64xlviqhkjl2fbvupj7y3wct46jtayoxm2ksba6tqzo6tsa.b32.i2p"}, // Cryptoslave's seednode + {"7zbwzykhyjcmmessswamkxfyya7hioiy2oq7voaw27625qwruqia.b32.i2p", "7zbwzykhyjcmmessswamkxfyya7hioiy2oq7voaw27625qwruqia.b32.i2p"}, // lunokhod's seednode + {"ypwvq7jcu3uwyg4ufjqt4a26ca6pxdcnshv6q2okmmjsof5dxzkq.b32.i2p", "ypwvq7jcu3uwyg4ufjqt4a26ca6pxdcnshv6q2okmmjsof5dxzkq.b32.i2p"} // keystroke's seednode }; @@ -1398,8 +1409,10 @@ // The first name is used as information source for addrman. // The second name should resolve to a list of seed addresses. static const char *strMainNetDNSSeed[][2] = { - {"coinpool.in", "anoncoin.dnsseed.coinpool.in"}, - {"anoncoin.net", "dnsseed01.anoncoin.net"}, + {"coinpool.in", "anoncoin.dnsseed.coinpool.in"}, // Normal Seednode, NO DNS-SEED! + {"anoncoin.net", "dnsseed01.anoncoin.net"}, // Normal Seednode, NO DNS-SEED! + {"anoncoin.darkgamex.ch", "anc.dnsseed01.anoncoin.darkgamex.ch"}, // K1773R's DNSSeed + {"www.virtual-currency.com", "anc.dnsseed01.anoncoin.virtual-currency.com"}, // keystroke's DNSSeed {NULL, NULL} }; @@ -1922,8 +1935,12 @@ // and enable it by default or not. Try to enable it, if possible. if (addrBind.IsIPv6()) { #ifdef IPV6_V6ONLY +#ifdef WIN32 + setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int)); +#else setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int)); #endif +#endif #ifdef WIN32 int nProtLevel = 10 /* PROTECTION_LEVEL_UNRESTRICTED */; int nParameterId = 23 /* IPV6_PROTECTION_LEVEl */; @@ -2067,7 +2084,9 @@ bool StopNode() { printf("StopNode()\n"); - GenerateBitcoins(false, NULL); +#ifdef ENABLE_WALLET + GenerateAnoncoins(false, NULL); +#endif MapPort(false); nTransactionsUpdated++; if (semOutbound) diff -Nru anoncoin-0.8.5.6/src/net.h anoncoin-0.8.5.6+git20141111.r4233/src/net.h --- anoncoin-0.8.5.6/src/net.h 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/net.h 2014-11-11 13:56:18.000000000 +0000 @@ -21,6 +21,9 @@ #include "addrman.h" #include "hash.h" #include "bloom.h" +#ifdef ENABLE_WALLET +#include "miner.h" +#endif class CNode; class CBlockIndex; diff -Nru anoncoin-0.8.5.6/src/noui.cpp anoncoin-0.8.5.6+git20141111.r4233/src/noui.cpp --- anoncoin-0.8.5.6/src/noui.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/noui.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -5,7 +5,7 @@ #include "ui_interface.h" #include "init.h" -#include "bitcoinrpc.h" +#include "anoncoinrpc.h" #include diff -Nru anoncoin-0.8.5.6/src/qt/anoncoin.cpp anoncoin-0.8.5.6+git20141111.r4233/src/qt/anoncoin.cpp --- anoncoin-0.8.5.6/src/qt/anoncoin.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/qt/anoncoin.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -14,14 +14,16 @@ #include "bitcoingui.h" #include "clientmodel.h" +#ifdef ENABLE_WALLET #include "walletmodel.h" +#include "paymentserver.h" +#endif #include "optionsmodel.h" #include "guiutil.h" #include "guiconstants.h" #include "init.h" #include "util.h" #include "ui_interface.h" -#include "paymentserver.h" #include "splashscreen.h" #include "setupdarknet.h" @@ -174,11 +176,13 @@ // Register meta types used for QMetaObject::invokeMethod qRegisterMetaType< bool* >(); +#ifdef ENABLE_WALLET // Do this early as we don't want to bother initializing if we are just calling IPC // ... but do it after creating app, so QCoreApplication::arguments is initialized: if (PaymentServer::ipcSendCommandLine()) exit(0); PaymentServer* paymentServer = new PaymentServer(&app); +#endif // Install global event filter that makes sure that long tooltips can be word-wrapped app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app)); @@ -330,16 +334,19 @@ splash.finish(&window); ClientModel clientModel(&optionsModel); +#ifdef ENABLE_WALLET WalletModel *walletModel = 0; if(pwalletMain) walletModel = new WalletModel(pwalletMain, &optionsModel); - +#endif window.setClientModel(&clientModel); +#ifdef ENABLE_WALLET if(walletModel) { window.addWallet("~Default", walletModel); window.setCurrentWallet("~Default"); } +#endif // If -min option passed, start window minimized. if(GetBoolArg("-min")) @@ -351,18 +358,24 @@ window.show(); } +#ifdef ENABLE_WALLET // Now that initialization/startup is done, process any command-line // bitcoin: URIs QObject::connect(paymentServer, SIGNAL(receivedURI(QString)), &window, SLOT(handleURI(QString))); QTimer::singleShot(100, paymentServer, SLOT(uiReady())); +#endif app.exec(); window.hide(); window.setClientModel(0); +#ifdef ENABLE_WALLET window.removeAllWallets(); +#endif guiref = 0; +#ifdef ENABLE_WALLET delete walletModel; +#endif } // Shutdown the core and its threads, but don't exit Bitcoin-Qt here threadGroup.interrupt_all(); diff -Nru anoncoin-0.8.5.6/src/qt/locale/bitcoin_zh_CN.ts anoncoin-0.8.5.6+git20141111.r4233/src/qt/locale/bitcoin_zh_CN.ts --- anoncoin-0.8.5.6/src/qt/locale/bitcoin_zh_CN.ts 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/qt/locale/bitcoin_zh_CN.ts 2014-11-11 13:56:18.000000000 +0000 @@ -5,12 +5,12 @@ About Anoncoin - 关于莱特币 + 关于匿名币 <b>Anoncoin</b> version - <b>莱特币</b>版本 + <b>匿名币</b>版本 @@ -68,7 +68,7 @@ These are your Anoncoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. - 这是您用来收款的莱特币地址。为了标记不同的资金来源,建议为每个付款人保留不同的收款地址。 + 这是您用来收款的匿名币地址。为了标记不同的资金来源,建议为每个付款人保留不同的收款地址。 @@ -108,7 +108,7 @@ Verify a message to ensure it was signed with a specified Anoncoin address - 验证消息,确保消息是由指定的莱特币地址签名过的。 + 验证消息,确保消息是由指定的匿名币地址签名过的。 @@ -123,7 +123,7 @@ These are your Anoncoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - 这是您用来付款的莱特币地址。在付款前,请总是核实付款金额和收款地址。 + 这是您用来付款的匿名币地址。在付款前,请总是核实付款金额和收款地址。 @@ -249,7 +249,7 @@ Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR LITECOINS</b>! - 警告:如果您加密了您的钱包,但是忘记了密码,你将会<b>丢失所有的莱特币</b>! + 警告:如果您加密了您的钱包,但是忘记了密码,你将会<b>丢失所有的匿名币</b>! @@ -276,7 +276,7 @@ Anoncoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your anoncoins from being stolen by malware infecting your computer. - 将关闭软件以完成加密过程。 请您谨记:钱包加密并不是万能的,电脑中毒,您的莱特币还是有可能丢失。 + 将关闭软件以完成加密过程。 请您谨记:钱包加密并不是万能的,电脑中毒,您的匿名币还是有可能丢失。 @@ -375,7 +375,7 @@ Show information about Anoncoin - 显示莱特币的相关信息 + 显示匿名币的相关信息 @@ -420,7 +420,7 @@ Send coins to a Anoncoin address - 向一个莱特币地址发送莱特币 + 向一个匿名币地址发送匿名币 @@ -456,7 +456,7 @@ Anoncoin - 莱特币 + 匿名币 @@ -481,7 +481,7 @@ &About Anoncoin - &关于莱特币 + &关于匿名币 @@ -501,12 +501,12 @@ Sign messages with your Anoncoin addresses to prove you own them - 用莱特币地址关联的私钥为消息签名,以证明您拥有这个莱特币地址 + 用匿名币地址关联的私钥为消息签名,以证明您拥有这个匿名币地址 Verify messages to ensure they were signed with specified Anoncoin addresses - 校验消息,确保该消息是由指定的莱特币地址所有者签名的 + 校验消息,确保该消息是由指定的匿名币地址所有者签名的 @@ -537,12 +537,12 @@ Anoncoin client - 莱特币客户端 + 匿名币客户端 %n active connection(s) to Anoncoin network - 到莱特币网络的连接共有%n条 + 到匿名币网络的连接共有%n条 @@ -607,7 +607,7 @@ This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? - 该交易的字节数超标。您可以选择支付%1的交易费给处理您的交易的网络节点,有助于莱特币网络的运行。您愿意支付这笔交易费用吗? + 该交易的字节数超标。您可以选择支付%1的交易费给处理您的交易的网络节点,有助于匿名币网络的运行。您愿意支付这笔交易费用吗? @@ -657,7 +657,7 @@ URI can not be parsed! This can be caused by an invalid Anoncoin address or malformed URI parameters. - URI无法解析!原因可能是莱特币地址不正确,或者URI参数错误。 + URI无法解析!原因可能是匿名币地址不正确,或者URI参数错误。 @@ -738,7 +738,7 @@ The entered address "%1" is not a valid Anoncoin address. - 您输入的 "%1" 不是合法的莱特币地址. + 您输入的 "%1" 不是合法的匿名币地址. @@ -821,7 +821,7 @@ Automatically start Anoncoin after logging in to the system. - 登录系统后自动开启莱特币客户端 + 登录系统后自动开启匿名币客户端 @@ -846,7 +846,7 @@ Automatically open the Anoncoin client port on the router. This only works when your router supports UPnP and it is enabled. - 自动在路由器中打开莱特币端口。只有当您的路由器开启 UPnP 选项时此功能才有效。 + 自动在路由器中打开匿名币端口。只有当您的路由器开启 UPnP 选项时此功能才有效。 @@ -856,7 +856,7 @@ Connect to the Anoncoin network through a SOCKS proxy (e.g. when connecting through Tor). - 通过代理服务器连接莱特币网络(例如:通过Tor连接) + 通过代理服务器连接匿名币网络(例如:通过Tor连接) @@ -936,22 +936,22 @@ &Unit to show amounts in: - &莱特币金额单位: + &匿名币金额单位: Choose the default subdivision unit to show in the interface and when sending coins. - 选择莱特币单位。 + 选择匿名币单位。 Whether to show Anoncoin addresses in the transaction list or not. - 是否需要在交易清单中显示莱特币地址。 + 是否需要在交易清单中显示匿名币地址。 &Display addresses in transaction list - 在交易清单中&显示莱特币地址 + 在交易清单中&显示匿名币地址 @@ -1017,7 +1017,7 @@ The displayed information may be out of date. Your wallet automatically synchronizes with the Anoncoin network after a connection is established, but this process has not completed yet. - 现在显示的消息可能是过期的. 在连接上莱特币网络节点后,您的钱包将自动与网络同步,但是这个过程还没有完成. + 现在显示的消息可能是过期的. 在连接上匿名币网络节点后,您的钱包将自动与网络同步,但是这个过程还没有完成. @@ -1071,7 +1071,7 @@ Cannot start anoncoin: click-to-pay handler - 暂时无法启动莱特币:点击支付功能 + 暂时无法启动匿名币:点击支付功能 @@ -1186,7 +1186,7 @@ On testnet - 当前为莱特币测试网络 + 当前为匿名币测试网络 @@ -1241,12 +1241,12 @@ Anoncoin - Debug window - 莱特币 - 调试窗口 + 匿名币 - 调试窗口 Anoncoin Core - 莱特币核心 + 匿名币核心 @@ -1386,7 +1386,7 @@ Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - 错误: 交易被拒绝. 如果您使用的是备份钱包,可能存在两个钱包不同步的情况,另一个钱包中的莱特币已经被使用,但本地的这个钱包尚没有记录。 + 错误: 交易被拒绝. 如果您使用的是备份钱包,可能存在两个钱包不同步的情况,另一个钱包中的匿名币已经被使用,但本地的这个钱包尚没有记录。 @@ -1450,7 +1450,7 @@ Enter a Anoncoin address (e.g. Ler4HNAEfwYhBmGXcFP2Po1NpRUEiK8km2) - 请输入莱特币地址 (例如: Ler4HNAEfwYhBmGXcFP2Po1NpRUEiK8km2) + 请输入匿名币地址 (例如: Ler4HNAEfwYhBmGXcFP2Po1NpRUEiK8km2) @@ -1551,7 +1551,7 @@ Verify the message to ensure it was signed with the specified Anoncoin address - 验证消息,确保消息是由指定的莱特币地址签名过的。 + 验证消息,确保消息是由指定的匿名币地址签名过的。 @@ -1567,7 +1567,7 @@ Enter a Anoncoin address (e.g. Ler4HNAEfwYhBmGXcFP2Po1NpRUEiK8km2) - 请输入莱特币地址 (例如: Ler4HNAEfwYhBmGXcFP2Po1NpRUEiK8km2) + 请输入匿名币地址 (例如: Ler4HNAEfwYhBmGXcFP2Po1NpRUEiK8km2) @@ -1577,7 +1577,7 @@ Enter Anoncoin signature - 输入莱特币签名 + 输入匿名币签名 @@ -1785,7 +1785,7 @@ Generated coins must mature 120 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. - 新挖出的莱特币必须等确120个确认才能使用。您生产出的数据块,将被广播到全网并添加到数据块链。如果入链失败,状态将变为“未被接受”,意味着您的数据块竞争失败,挖出的莱特币将不能使用。当某个节点先于你几秒生产出新的数据块,这种情况会偶尔发生。 + 新挖出的匿名币必须等确120个确认才能使用。您生产出的数据块,将被广播到全网并添加到数据块链。如果入链失败,状态将变为“未被接受”,意味着您的数据块竞争失败,挖出的匿名币将不能使用。当某个节点先于你几秒生产出新的数据块,这种情况会偶尔发生。 @@ -1946,7 +1946,7 @@ Date and time that the transaction was received. - 接收莱特币的时间 + 接收匿名币的时间 @@ -2138,7 +2138,7 @@ Send Coins - 发送莱特币 + 发送匿名币 @@ -2189,7 +2189,7 @@ Anoncoin version - 莱特币版本 + 匿名币版本 @@ -2350,7 +2350,7 @@ Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - 错误:该交易被拒绝!发生这种错误的原因可能是:钱包中的莱特币已经被用掉,有可能您复制了wallet.dat钱包文件,然后用复制的钱包文件支付了莱特币,但是这个钱包文件中没有记录。 + 错误:该交易被拒绝!发生这种错误的原因可能是:钱包中的匿名币已经被用掉,有可能您复制了wallet.dat钱包文件,然后用复制的钱包文件支付了匿名币,但是这个钱包文件中没有记录。 @@ -2390,7 +2390,7 @@ Warning: Please check that your computer's date and time are correct! If your clock is wrong Anoncoin will not work properly. - 警告:请检查电脑的日期时间设置是否正确!时间错误可能会导致莱特币客户端运行异常。 + 警告:请检查电脑的日期时间设置是否正确!时间错误可能会导致匿名币客户端运行异常。 @@ -2905,7 +2905,7 @@ Unable to bind to %s on this computer. Anoncoin is probably already running. - 无法在本机绑定 %s 端口 . 莱特币客户端软件可能已经在运行. + 无法在本机绑定 %s 端口 . 匿名币客户端软件可能已经在运行. diff -Nru anoncoin-0.8.5.6/src/qt/optionsdialog.cpp anoncoin-0.8.5.6+git20141111.r4233/src/qt/optionsdialog.cpp --- anoncoin-0.8.5.6/src/qt/optionsdialog.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/qt/optionsdialog.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -253,7 +253,7 @@ { if(!fRestartWarningDisplayed_I2P) { - QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect after restarting Bitcoin."), QMessageBox::Ok); + QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect after restarting Anoncoin."), QMessageBox::Ok); fRestartWarningDisplayed_I2P = true; } } diff -Nru anoncoin-0.8.5.6/src/qt/rpcconsole.cpp anoncoin-0.8.5.6+git20141111.r4233/src/qt/rpcconsole.cpp --- anoncoin-0.8.5.6/src/qt/rpcconsole.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/qt/rpcconsole.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -1,8 +1,10 @@ #include "rpcconsole.h" #include "ui_rpcconsole.h" +#include "util.h" + #include "clientmodel.h" -#include "bitcoinrpc.h" +#include "anoncoinrpc.h" #include "guiutil.h" #include diff -Nru anoncoin-0.8.5.6/src/rpcblockchain.cpp anoncoin-0.8.5.6+git20141111.r4233/src/rpcblockchain.cpp --- anoncoin-0.8.5.6/src/rpcblockchain.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/rpcblockchain.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -4,7 +4,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "main.h" -#include "bitcoinrpc.h" +#include "anoncoinrpc.h" using namespace json_spirit; using namespace std; diff -Nru anoncoin-0.8.5.6/src/rpcdump.cpp anoncoin-0.8.5.6+git20141111.r4233/src/rpcdump.cpp --- anoncoin-0.8.5.6/src/rpcdump.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/rpcdump.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -3,7 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "init.h" // for pwalletMain -#include "bitcoinrpc.h" +#include "anoncoinrpc.h" #include "ui_interface.h" #include "base58.h" diff -Nru anoncoin-0.8.5.6/src/rpcmining.cpp anoncoin-0.8.5.6+git20141111.r4233/src/rpcmining.cpp --- anoncoin-0.8.5.6/src/rpcmining.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/rpcmining.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -3,10 +3,17 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "init.h" +#include "net.h" #include "main.h" +#include "util.h" + +#ifdef ENABLE_WALLET +#include "miner.h" #include "db.h" -#include "init.h" -#include "bitcoinrpc.h" +#endif + +#include "anoncoinrpc.h" using namespace json_spirit; using namespace std; @@ -63,7 +70,7 @@ return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1); } - +#ifdef ENABLE_WALLET // Key used by getwork/getblocktemplate miners. // Allocated in InitRPCMining, free'd in ShutdownRPCMining static CReserveKey* pMiningKey = NULL; @@ -84,6 +91,16 @@ delete pMiningKey; pMiningKey = NULL; } +#else +void InitRPCMining() +{ +} +void ShutdownRPCMining() +{ +} +#endif + +#ifdef ENABLE_WALLET Value getgenerate(const Array& params, bool fHelp) { @@ -121,7 +138,7 @@ mapArgs["-gen"] = (fGenerate ? "1" : "0"); assert(pwalletMain != NULL); - GenerateBitcoins(fGenerate, pwalletMain); + GenerateAnoncoins(fGenerate, pwalletMain); return Value::null; } @@ -138,6 +155,7 @@ return (boost::int64_t)dHashesPerSec; } +#endif Value getmininginfo(const Array& params, bool fHelp) { @@ -148,20 +166,22 @@ Object obj; obj.push_back(Pair("blocks", (int)nBestHeight)); - obj.push_back(Pair("currentblocksize",(uint64_t)nLastBlockSize)); - obj.push_back(Pair("currentblocktx",(uint64_t)nLastBlockTx)); + obj.push_back(Pair("currentblocksize",(boost::uint64_t)nLastBlockSize)); + obj.push_back(Pair("currentblocktx",(boost::uint64_t)nLastBlockTx)); obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("errors", GetWarnings("statusbar"))); - obj.push_back(Pair("generate", GetBoolArg("-gen"))); obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1))); +#ifdef ENABLE_WALLET + obj.push_back(Pair("generate", GetBoolArg("-gen"))); obj.push_back(Pair("hashespersec", gethashespersec(params, false))); +#endif obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); - obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); + obj.push_back(Pair("pooledtx", (boost::uint64_t)mempool.size())); obj.push_back(Pair("testnet", fTestNet)); return obj; } - +#ifdef ENABLE_WALLET Value getworkex(const Array& params, bool fHelp) { if (fHelp || params.size() > 2) @@ -410,7 +430,7 @@ return CheckWork(pblock, *pwalletMain, *pMiningKey); } } - +#endif Value getblocktemplate(const Array& params, bool fHelp) { @@ -495,7 +515,7 @@ pblock->nNonce = 0; Array transactions; - map setTxIndex; + map setTxIndex; int i = 0; BOOST_FOREACH (CTransaction& tx, pblock->vtx) { @@ -522,8 +542,8 @@ entry.push_back(Pair("depends", deps)); int index_in_template = i - 1; - entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template])); - entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template])); + entry.push_back(Pair("fee", (boost::uint64_t)pblocktemplate->vTxFees[index_in_template])); + entry.push_back(Pair("sigops", (boost::uint64_t)pblocktemplate->vTxSigOps[index_in_template])); transactions.push_back(entry); } @@ -546,16 +566,16 @@ result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); result.push_back(Pair("transactions", transactions)); result.push_back(Pair("coinbaseaux", aux)); - result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue)); + result.push_back(Pair("coinbasevalue", (boost::int64_t)pblock->vtx[0].vout[0].nValue)); result.push_back(Pair("target", hashTarget.GetHex())); - result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); + result.push_back(Pair("mintime", (boost::int64_t)pindexPrev->GetMedianTimePast()+1)); result.push_back(Pair("mutable", aMutable)); result.push_back(Pair("noncerange", "00000000ffffffff")); - result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS)); - result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE)); - result.push_back(Pair("curtime", (int64_t)pblock->nTime)); + result.push_back(Pair("sigoplimit", (boost::int64_t)MAX_BLOCK_SIGOPS)); + result.push_back(Pair("sizelimit", (boost::int64_t)MAX_BLOCK_SIZE)); + result.push_back(Pair("curtime", (boost::int64_t)pblock->nTime)); result.push_back(Pair("bits", HexBits(pblock->nBits))); - result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); + result.push_back(Pair("height", (boost::int64_t)(pindexPrev->nHeight+1))); return result; } diff -Nru anoncoin-0.8.5.6/src/rpcnet.cpp anoncoin-0.8.5.6+git20141111.r4233/src/rpcnet.cpp --- anoncoin-0.8.5.6/src/rpcnet.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/rpcnet.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -3,7 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "net.h" -#include "bitcoinrpc.h" +#include "anoncoinrpc.h" using namespace json_spirit; using namespace std; diff -Nru anoncoin-0.8.5.6/src/rpcrawtransaction.cpp anoncoin-0.8.5.6+git20141111.r4233/src/rpcrawtransaction.cpp --- anoncoin-0.8.5.6/src/rpcrawtransaction.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/rpcrawtransaction.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -6,12 +6,14 @@ #include #include "base58.h" -#include "bitcoinrpc.h" +#include "anoncoinrpc.h" #include "db.h" #include "init.h" #include "main.h" #include "net.h" +#ifdef ENABLE_WALLET #include "wallet.h" +#endif using namespace std; using namespace boost; @@ -166,6 +168,7 @@ return result; } +#ifdef ENABLE_WALLET Value listunspent(const Array& params, bool fHelp) { if (fHelp || params.size() > 3) @@ -252,6 +255,7 @@ return results; } +#endif Value createrawtransaction(const Array& params, bool fHelp) { @@ -351,7 +355,11 @@ "Returns json object with keys:\n" " hex : raw transaction with signature(s) (hex-encoded string)\n" " complete : 1 if transaction has a complete set of signature (0 if not)" +#ifdef ENABLE_WALLET + HelpRequiringPassphrase()); +#else + + "\n"; +#endif RPCTypeCheck(params, list_of(str_type)(array_type)(array_type)(str_type), true); @@ -412,8 +420,10 @@ tempKeystore.AddKey(key); } } +#ifdef ENABLE_WALLET else EnsureWalletIsUnlocked(); +#endif // Add previous txouts given in the RPC call: if (params.size() > 1 && params[1].type() != null_type) @@ -469,7 +479,11 @@ } } +#ifdef ENABLE_WALLET const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain); +#else + const CKeyStore& keystore = tempKeystore; +#endif int nHashType = SIGHASH_ALL; if (params.size() > 3 && params[3].type() != null_type) diff -Nru anoncoin-0.8.5.6/src/rpcwallet.cpp anoncoin-0.8.5.6+git20141111.r4233/src/rpcwallet.cpp --- anoncoin-0.8.5.6/src/rpcwallet.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/rpcwallet.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -7,7 +7,7 @@ #include "wallet.h" #include "walletdb.h" -#include "bitcoinrpc.h" +#include "anoncoinrpc.h" #include "init.h" #include "base58.h" diff -Nru anoncoin-0.8.5.6/src/script.cpp anoncoin-0.8.5.6+git20141111.r4233/src/script.cpp --- anoncoin-0.8.5.6/src/script.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/script.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -6,7 +6,6 @@ #include using namespace std; -using namespace boost; #include "script.h" #include "keystore.h" @@ -16,6 +15,8 @@ #include "sync.h" #include "util.h" +using namespace boost; + bool CheckSig(vector vchSig, const vector &vchPubKey, const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, int flags); diff -Nru anoncoin-0.8.5.6/src/test/rpc_tests.cpp anoncoin-0.8.5.6+git20141111.r4233/src/test/rpc_tests.cpp --- anoncoin-0.8.5.6/src/test/rpc_tests.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/test/rpc_tests.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -4,7 +4,7 @@ #include "base58.h" #include "util.h" -#include "bitcoinrpc.h" +#include "anoncoinrpc.h" using namespace std; using namespace json_spirit; diff -Nru anoncoin-0.8.5.6/src/test/test_bitcoin.cpp anoncoin-0.8.5.6+git20141111.r4233/src/test/test_bitcoin.cpp --- anoncoin-0.8.5.6/src/test/test_bitcoin.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/test/test_bitcoin.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -1,4 +1,4 @@ -#define BOOST_TEST_MODULE Litecoin Test Suite +#define BOOST_TEST_MODULE Anoncoin Test Suite #include #include diff -Nru anoncoin-0.8.5.6/src/version.cpp anoncoin-0.8.5.6+git20141111.r4233/src/version.cpp --- anoncoin-0.8.5.6/src/version.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/version.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -36,8 +36,8 @@ // git will put "#define GIT_ARCHIVE 1" on the next line inside archives. #define GIT_ARCHIVE 1 #ifdef GIT_ARCHIVE -# define GIT_COMMIT_ID "c0b7034" -# define GIT_COMMIT_DATE "Tue, 24 Dec 2013 20:07:16 +0100" +# define GIT_COMMIT_ID "832e187" +# define GIT_COMMIT_DATE "Tue, 11 Nov 2014 14:56:18 +0100" #endif #define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \ diff -Nru anoncoin-0.8.5.6/src/wallet.cpp anoncoin-0.8.5.6+git20141111.r4233/src/wallet.cpp --- anoncoin-0.8.5.6/src/wallet.cpp 2013-12-24 19:07:16.000000000 +0000 +++ anoncoin-0.8.5.6+git20141111.r4233/src/wallet.cpp 2014-11-11 13:56:18.000000000 +0000 @@ -743,6 +743,10 @@ { tx = *mapWalletPrev[hash]; } + else + { + continue; + } int nDepth = tx.SetMerkleBranch(); vtxPrev.push_back(tx); @@ -847,7 +851,10 @@ { BOOST_FOREACH(const CMerkleTx& tx, vtxPrev) { - if (!tx.IsCoinBase()) + // Important: versions of bitcoin before 0.8.6 had a bug that inserted + // empty transactions into the vtxPrev, which will cause the node to be + // banned when retransmitted, hence the check for !tx.vin.empty() + if (!tx.IsCoinBase() && !tx.vin.empty()) if (tx.GetDepthInMainChain() == 0) RelayTransaction((CTransaction)tx, tx.GetHash()); }