Merge branch 'MSVC' of https://github.com/fsb4000/novacoin into fsb4000-MSVC
authorMASM fan <masmfan@gmail.com>
Fri, 7 Nov 2014 19:10:58 +0000 (23:10 +0400)
committerMASM fan <masmfan@gmail.com>
Fri, 7 Nov 2014 19:10:58 +0000 (23:10 +0400)
Conflicts:
src/serialize.h
src/zerocoin/Commitment.cpp

117 files changed:
MSVC/libcommon/libcommon.vcxproj
MSVC/libcommon/libcommon.vcxproj.filters
MSVC/mynovacoinqt/mynovacoinqt.vcxproj
MSVC/mynovacoinqt/mynovacoinqt.vcxproj.filters
doc/Doxyfile
doc/build-msw.txt
doc/build-osx.txt
doc/build-unix.txt
doc/building novacoind and novacoinqt under Linux.txt [new file with mode: 0644]
doc/building novacoind and novacoinqt under Windows with MinGW.txt [new file with mode: 0644]
doc/readme-qt.rst
doc/release-process.txt
doc/translation_process.md
novacoin-qt.pro
src/init.cpp
src/kernel.h
src/leveldb/AUTHORS
src/leveldb/CONTRIBUTING.md [new file with mode: 0644]
src/leveldb/Makefile
src/leveldb/README.md [new file with mode: 0644]
src/leveldb/build_detect_platform
src/leveldb/db/autocompact_test.cc [new file with mode: 0644]
src/leveldb/db/corruption_test.cc
src/leveldb/db/db_bench.cc
src/leveldb/db/db_impl.cc
src/leveldb/db/db_impl.h
src/leveldb/db/db_iter.cc
src/leveldb/db/db_iter.h
src/leveldb/db/db_test.cc
src/leveldb/db/dbformat.h
src/leveldb/db/dumpfile.cc [new file with mode: 0644]
src/leveldb/db/filename.cc
src/leveldb/db/filename.h
src/leveldb/db/filename_test.cc
src/leveldb/db/leveldb_main.cc
src/leveldb/db/log_format.h
src/leveldb/db/log_reader.cc
src/leveldb/db/log_reader.h
src/leveldb/db/log_test.cc
src/leveldb/db/repair.cc
src/leveldb/db/skiplist.h
src/leveldb/db/table_cache.cc
src/leveldb/db/version_set.cc
src/leveldb/db/version_set.h
src/leveldb/db/write_batch_internal.h
src/leveldb/doc/bench/db_bench_tree_db.cc
src/leveldb/doc/impl.html
src/leveldb/doc/log_format.txt
src/leveldb/helpers/memenv/memenv.cc
src/leveldb/include/leveldb/c.h
src/leveldb/include/leveldb/cache.h
src/leveldb/include/leveldb/db.h
src/leveldb/include/leveldb/dumpfile.h [new file with mode: 0644]
src/leveldb/include/leveldb/env.h
src/leveldb/include/leveldb/iterator.h
src/leveldb/include/leveldb/options.h
src/leveldb/include/leveldb/slice.h
src/leveldb/issues/issue200_test.cc [new file with mode: 0644]
src/leveldb/port/atomic_pointer.h
src/leveldb/port/port_posix.h
src/leveldb/port/thread_annotations.h
src/leveldb/table/block.cc
src/leveldb/table/block_builder.h
src/leveldb/table/filter_block_test.cc
src/leveldb/table/format.cc
src/leveldb/table/table.cc
src/leveldb/util/arena.cc
src/leveldb/util/arena.h
src/leveldb/util/arena_test.cc
src/leveldb/util/bloom.cc
src/leveldb/util/bloom_test.cc
src/leveldb/util/coding_test.cc
src/leveldb/util/env_posix.cc
src/leveldb/util/hash.cc
src/leveldb/util/hash_test.cc [new file with mode: 0644]
src/leveldb/util/logging.cc
src/leveldb/util/logging.h
src/leveldb/util/random.h
src/leveldb/util/testharness.cc
src/leveldb/util/testutil.cc
src/leveldb/util/testutil.h
src/main.cpp
src/main.h
src/makefile.bsd
src/makefile.linux-mingw
src/makefile.mingw
src/makefile.osx
src/makefile.unix
src/obj/zerocoin/.gitignore [deleted file]
src/scrypt-arm.S
src/scrypt-generic.c [new file with mode: 0644]
src/scrypt-x86.S
src/scrypt-x86_64.S
src/scrypt.cpp
src/serialize.h
src/wallet.h
src/zerocoin/Accumulator.cpp [deleted file]
src/zerocoin/Accumulator.h [deleted file]
src/zerocoin/AccumulatorProofOfKnowledge.cpp [deleted file]
src/zerocoin/AccumulatorProofOfKnowledge.h [deleted file]
src/zerocoin/Coin.cpp [deleted file]
src/zerocoin/Coin.h [deleted file]
src/zerocoin/CoinSpend.cpp [deleted file]
src/zerocoin/CoinSpend.h [deleted file]
src/zerocoin/Commitment.cpp [deleted file]
src/zerocoin/Commitment.h [deleted file]
src/zerocoin/ParamGeneration.cpp [deleted file]
src/zerocoin/ParamGeneration.h [deleted file]
src/zerocoin/Params.cpp [deleted file]
src/zerocoin/Params.h [deleted file]
src/zerocoin/SerialNumberSignatureOfKnowledge.cpp [deleted file]
src/zerocoin/SerialNumberSignatureOfKnowledge.h [deleted file]
src/zerocoin/SpendMetaData.cpp [deleted file]
src/zerocoin/SpendMetaData.h [deleted file]
src/zerocoin/ZeroTest.cpp [deleted file]
src/zerocoin/ZeroTest.h [deleted file]
src/zerocoin/Zerocoin.h [deleted file]

index cdc7822..738634d 100644 (file)
     <ClCompile Include="..\..\src\kernel.cpp" />
     <ClCompile Include="..\..\src\pbkdf2.cpp" />
     <ClCompile Include="..\..\src\scrypt.cpp" />
-    <ClCompile Include="..\..\src\zerocoin\Accumulator.cpp" />
-    <ClCompile Include="..\..\src\zerocoin\AccumulatorProofOfKnowledge.cpp" />
-    <ClCompile Include="..\..\src\zerocoin\Coin.cpp" />
-    <ClCompile Include="..\..\src\zerocoin\CoinSpend.cpp" />
-    <ClCompile Include="..\..\src\zerocoin\Commitment.cpp" />
-    <ClCompile Include="..\..\src\zerocoin\ParamGeneration.cpp" />
-    <ClCompile Include="..\..\src\zerocoin\Params.cpp" />
-    <ClCompile Include="..\..\src\zerocoin\SerialNumberSignatureOfKnowledge.cpp" />
-    <ClCompile Include="..\..\src\zerocoin\SpendMetaData.cpp" />
-    <ClCompile Include="..\..\src\zerocoin\ZeroTest.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\src\addrman.h" />
     <ClInclude Include="..\..\src\version.h" />
     <ClInclude Include="..\..\src\wallet.h" />
     <ClInclude Include="..\..\src\walletdb.h" />
-    <ClInclude Include="..\..\src\zerocoin\Accumulator.h" />
-    <ClInclude Include="..\..\src\zerocoin\AccumulatorProofOfKnowledge.h" />
-    <ClInclude Include="..\..\src\zerocoin\Coin.h" />
-    <ClInclude Include="..\..\src\zerocoin\CoinSpend.h" />
-    <ClInclude Include="..\..\src\zerocoin\Commitment.h" />
-    <ClInclude Include="..\..\src\zerocoin\ParamGeneration.h" />
-    <ClInclude Include="..\..\src\zerocoin\Params.h" />
-    <ClInclude Include="..\..\src\zerocoin\SerialNumberSignatureOfKnowledge.h" />
-    <ClInclude Include="..\..\src\zerocoin\SpendMetaData.h" />
-    <ClInclude Include="..\..\src\zerocoin\Zerocoin.h" />
-    <ClInclude Include="..\..\src\zerocoin\ZeroTest.h" />
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{3703B138-B8DA-460E-9DD1-41BDC7588E80}</ProjectGuid>
index e74a9c2..c07e7cd 100644 (file)
     <ClCompile Include="..\..\src\walletdb.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\zerocoin\Accumulator.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\zerocoin\AccumulatorProofOfKnowledge.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\zerocoin\Coin.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\zerocoin\CoinSpend.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\zerocoin\Commitment.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\zerocoin\ParamGeneration.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\zerocoin\Params.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\zerocoin\SerialNumberSignatureOfKnowledge.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\zerocoin\SpendMetaData.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\zerocoin\ZeroTest.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\src\irc.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
     <ClInclude Include="..\..\src\walletdb.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\Accumulator.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\AccumulatorProofOfKnowledge.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\Coin.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\CoinSpend.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\Commitment.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\ParamGeneration.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\Params.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\SerialNumberSignatureOfKnowledge.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\SpendMetaData.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\Zerocoin.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\ZeroTest.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\src\scrypt.h">
       <Filter>Header Files</Filter>
     </ClInclude>
index eca47a6..d860731 100644 (file)
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\src\qt\dialogwindowflags.h" />
-    <ClInclude Include="..\..\src\zerocoin\Accumulator.h" />
-    <ClInclude Include="..\..\src\zerocoin\AccumulatorProofOfKnowledge.h" />
-    <ClInclude Include="..\..\src\zerocoin\Coin.h" />
-    <ClInclude Include="..\..\src\zerocoin\CoinSpend.h" />
-    <ClInclude Include="..\..\src\zerocoin\Commitment.h" />
-    <ClInclude Include="..\..\src\zerocoin\ParamGeneration.h" />
-    <ClInclude Include="..\..\src\zerocoin\Params.h" />
-    <ClInclude Include="..\..\src\zerocoin\SerialNumberSignatureOfKnowledge.h" />
-    <ClInclude Include="..\..\src\zerocoin\SpendMetaData.h" />
-    <ClInclude Include="..\..\src\zerocoin\ZeroTest.h" />
-    <ClInclude Include="..\..\src\zerocoin\Zerocoin.h" />
     <CustomBuild Include="..\..\src\qt\aboutdialog.h">
       <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\src\qt\aboutdialog.h;%(AdditionalInputs)</AdditionalInputs>
       <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\src\qt\aboutdialog.h;%(AdditionalInputs)</AdditionalInputs>
index 684d93e..a669e1f 100644 (file)
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="..\..\src\zerocoin\Accumulator.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\AccumulatorProofOfKnowledge.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\Coin.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\CoinSpend.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\Commitment.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\ParamGeneration.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\Params.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\SerialNumberSignatureOfKnowledge.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\SpendMetaData.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\ZeroTest.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\zerocoin\Zerocoin.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <CustomBuild Include="..\..\src\qt\aboutdialog.h">
       <Filter>Header Files</Filter>
     </CustomBuild>
index 08d4f8c..fe9f544 100644 (file)
@@ -28,7 +28,7 @@ DOXYFILE_ENCODING      = UTF-8
 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
 # by quotes) that should identify the project.
 
-PROJECT_NAME           = Bitcoin
+PROJECT_NAME           = Novacoin
 
 # The PROJECT_NUMBER tag can be used to enter a project or revision number. 
 # This could be handy for archiving the generated documentation or 
@@ -47,7 +47,7 @@ PROJECT_BRIEF          = "P2P Digital Currency"
 # exceed 55 pixels and the maximum width should not exceed 200 pixels. 
 # Doxygen will copy the logo to the output directory.
 
-PROJECT_LOGO           = doc/bitcoin_logo_doxygen.png
+PROJECT_LOGO           = doc/novacoin_logo_doxygen.png
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
 # base path where the generated documentation will be put. 
index b180515..a3929fb 100644 (file)
@@ -1,4 +1,5 @@
 Copyright (c) 2009-2012 Bitcoin Developers
+Copyright (c) 2013 NovaCoin Developers
 Distributed under the MIT/X11 software license, see the accompanying
 file license.txt or http://www.opensource.org/licenses/mit-license.php.
 This product includes software developed by the OpenSSL Project for use in
@@ -7,7 +8,7 @@ cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP
 software written by Thomas Bernard.
 
 
-See readme-qt.rst for instructions on building Bitcoin QT, the
+See readme-qt.rst for instructions on building NovaCoin QT, the
 graphical user interface.
 
 WINDOWS BUILD NOTES
@@ -76,9 +77,9 @@ make -f Makefile.mingw
 mkdir miniupnpc
 cp *.h miniupnpc/
 
-Bitcoin
+NovaCoin
 -------
 DOS prompt:
-cd \bitcoin\src
+cd \novacoin\src
 mingw32-make -f makefile.mingw
-strip bitcoind.exe
+strip novacoind.exe
index 2ae7706..e58efbf 100644 (file)
@@ -1,4 +1,5 @@
 Copyright (c) 2009-2012 Bitcoin Developers
+Copyright (c) 2013 NovaCoin Developers
 Distributed under the MIT/X11 software license, see the accompanying file
 license.txt or http://www.opensource.org/licenses/mit-license.php.  This
 product includes software developed by the OpenSSL Project for use in the
@@ -7,12 +8,12 @@ software written by Eric Young (eay@cryptsoft.com) and UPnP software written by
 Thomas Bernard.
 
 
-Mac OS X bitcoind build instructions
+Mac OS X novacoind build instructions
 Laszlo Hanyecz <solar@heliacal.net>
 Douglas Huff <dhuff@jrbobdobbs.org>
 
 
-See readme-qt.rst for instructions on building Bitcoin QT, the
+See readme-qt.rst for instructions on building NovaCoin QT, the
 graphical user interface.
 
 Tested on 10.5 and 10.6 intel.  PPC is not supported because it's big-endian.
@@ -27,7 +28,7 @@ but you can get the current version from http://developer.apple.com
 
 1.  Clone the github tree to get the source code:
 
-git clone git@github.com:bitcoin/bitcoin.git bitcoin
+git clone https://github.com/novacoin-project/novacoin
 
 2.  Download and install MacPorts from http://www.macports.org/
 
@@ -41,14 +42,14 @@ sudo port install boost db48 openssl miniupnpc
 Optionally install qrencode (and set USE_QRCODE=1):
 sudo port install qrencode
 
-4.  Now you should be able to build bitcoind:
+4.  Now you should be able to build novacoind:
 
-cd bitcoin/src
+cd novacoin/src
 make -f makefile.osx
 
 Run:
-  ./bitcoind --help  # for a list of command-line options.
+  ./novacoind --help  # for a list of command-line options.
 Run
-  ./bitcoind -daemon # to start the bitcoin daemon.
+  ./novacoind -daemon # to start the novacoin daemon.
 Run
-  ./bitcoind help # When the daemon is running, to get a list of RPC commands
+  ./novacoind help # When the daemon is running, to get a list of RPC commands
index 3dffb22..5e8d7c6 100644 (file)
@@ -1,4 +1,5 @@
 Copyright (c) 2009-2012 Bitcoin Developers
+Copyright (c) 2013 NovaCoin Developers
 Distributed under the MIT/X11 software license, see the accompanying
 file license.txt or http://www.opensource.org/licenses/mit-license.php.
 This product includes software developed by the OpenSSL Project for use in
@@ -14,10 +15,10 @@ To Build
 --------
 
 cd src/
-make -f makefile.unix            # Headless bitcoin
+make -f makefile.unix            # Headless novacoin
 
-See readme-qt.rst for instructions on building Bitcoin QT,
-the graphical bitcoin.
+See readme-qt.rst for instructions on building NovaCoin QT,
+the graphical novacoin.
 
 Dependencies
 ------------
@@ -75,21 +76,21 @@ If using Boost 1.37, append -mt to the boost libraries in the makefile.
 Dependency Build Instructions: Gentoo
 -------------------------------------
 
-Note: If you just want to install bitcoind on Gentoo, you can add the Bitcoin
+Note: If you just want to install novacoind on Gentoo, you can add the Novacoin
       overlay and use your package manager:
-          layman -a bitcoin && emerge bitcoind
+          layman -a novacoin && emerge novacoind
 
 emerge -av1 --noreplace boost glib openssl sys-libs/db:4.8
 
 Take the following steps to build (no UPnP support):
- cd ${BITCOIN_DIR}/src
+ cd ${NOVACOIN_DIR}/src
  make -f makefile.unix USE_UPNP= BDB_INCLUDE_PATH='/usr/include/db4.8'
- strip bitcoind
+ strip novacoind
 
 
 Notes
 -----
-The release is built with GCC and then "strip bitcoind" to strip the debug
+The release is built with GCC and then "strip novacoind" to strip the debug
 symbols, which reduces the executable size by about 90%.
 
 
@@ -119,7 +120,7 @@ sudo su
 
 Security
 --------
-To help make your bitcoin installation more secure by making certain attacks impossible to
+To help make your novacoin installation more secure by making certain attacks impossible to
 exploit even if a vulnerability is found, you can take the following measures:
 
 * Position Independent Executable
@@ -136,7 +137,7 @@ exploit even if a vulnerability is found, you can take the following measures:
     make -f makefile.unix ... -e PIE=1
 
     To test that you have built PIE executable, install scanelf, part of paxutils, and use:
-    scanelf -e ./bitcoin
+    scanelf -e ./novacoin
 
     The output should contain:
      TYPE
@@ -144,13 +145,13 @@ exploit even if a vulnerability is found, you can take the following measures:
 
 * 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, novacoin 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.
 
     To verify that the stack is non-executable after compiling use:
-    scanelf -e ./bitcoin
+    scanelf -e ./novacoin
 
     the output should contain:
     STK/REL/PTL
diff --git a/doc/building novacoind and novacoinqt under Linux.txt b/doc/building novacoind and novacoinqt under Linux.txt
new file mode 100644 (file)
index 0000000..977fad3
--- /dev/null
@@ -0,0 +1,22 @@
+\feffСборка для Linux
+Если предпочитаете компилировать свои собственные бинарные файлы, тогда нужны пакеты разработчика:
+
+ sudo apt-get install qt4-qmake libqt4-dev build-essential libboost-dev libboost-system-dev
+   libboost-filesystem-dev libboost-program-options-dev libboost-thread-dev
+   libssl-dev libdb++-dev libminiupnpc-dev
+
+И git также, конечно:
+
+ sudo apt-get install git
+
+После того, как установка завершалась, можно клонировать Novacoin репозитарий
+
+ git clone https://github.com/novacoin-project/novacoin.git
+
+и наконец, скомпилировать свой клиент
+
+ cd novacoin
+ qmake RELEASE=1 USE_UPNP=1 USE_O3=1
+ make
+ cd src
+ make -f makefile.unix USE_UPNP=1 STATIC=1 USE_O3=1
\ No newline at end of file
diff --git a/doc/building novacoind and novacoinqt under Windows with MinGW.txt b/doc/building novacoind and novacoinqt under Windows with MinGW.txt
new file mode 100644 (file)
index 0000000..d56e094
--- /dev/null
@@ -0,0 +1,481 @@
+\feff32 bit:
+1. Подготовка системы.
+
+1.1 Установка архиватора 7z: http://www.7-zip.org/ 
+(при написании инструкции использовался 7-Zip 9.20 64 bit X64, но скорее всего подойдёт любая версия)
+
+1.2 Установка msys shell:
+-Скачайте http://sourceforge.net/projects/mingw/files/Installer/mingw-get-setup.exe/download
+-нажмите Install
+-директория для установки C:\MinGW
+-поставить галочку напротив "...also install support for the graphical user interface."
+-убрать галочки напротив "..in the start menu, and/or .." "... on the desktop"
+-нажмите continue
+-нажмите continue
+-нажмите All Packages, затем MSYS
+-поставте галочки напротив:
+msys-autoconf-bin
+msys-automake-bin
+msys-base-bin
+msys-libtool-bin
+-нажмите Installation, Apply Changes, Apply. После завершения установки нажмите Close и закройте MinGW Installation Manager.
+
+1.3 Установка MinGW-builds project toolchain:
+Скачайте http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.1/threads-posix/dwarf/i686-4.9.1-release-posix-dwarf-rt_v3-rev1.7z/download
+и распакуйте на C:\
+
+1.4 Добавьте в переменную PATH путь C:\mingw32\bin;
+Подробное описание как это сделать на Windows 8, Windows 7, Windows XP и Windows Vista
+https://www.java.com/ru/download/help/path.xml
+(только не нужно выполнять последний пункт из этой инструкции "Откройте заново окно командной строки и выполните код java." )
+
+Проверка что вы всё сделали правильно:
+1)C:\MinGW\bin должен содержать только файл mingw-get.exe
+2)Откройте Командную строку (Нажмите кнопку Windows + R одновременно. Откроется окно "Выполнить", в поле открыть наберите cmd. Нажмите Ok). Наберите gcc -v. В командной строке выведется текст. В конце текста должно быть написано:
+Thread model: posix
+gcc version 4.9.1 (i686-posix-dwarf-rev1, Built by MinGW-W64 project)
+
+2. Построение зависимостей.
+В инструкции все зависимости сохраняются в папку c:\deps
+
+2.1 OpenSSL 
+-Скачайте http://www.openssl.org/source/openssl-1.0.1j.tar.gz
+-Перейдите в папку C:\MinGW\msys\1.0 и запустите msys.bat
+Из MinGw shell выполните следующий код:
+
+cd /c/deps/
+tar xvfz openssl-1.0.1j.tar.gz
+cd openssl-1.0.1j
+Configure no-shared no-dso mingw
+make
+
+2.2 Berkeley DB
+-Скачайте http://download.oracle.com/berkeley-db/db-6.0.20.tar.gz
+-Из MinGw shell выполните следующий код:
+
+cd /c/deps/
+tar xvfz db-6.0.20.tar.gz
+cd db-6.0.20/build_unix
+../dist/configure --enable-mingw --enable-cxx --disable-shared --disable-replication
+make
+
+2.3 Boost
+-Скачайте http://sourceforge.net/projects/boost/files/boost/1.55.0/boost_1_55_0.7z/download
+-Распакуйте boost_1_55_0.7z в папку C:\deps
+-Откройте командную строку Windows, и выполните следующий код:
+
+cd C:\deps\boost_1_55_0\
+bootstrap.bat mingw
+b2 --build-type=complete --with-chrono --with-filesystem --with-program_options --with-system --with-thread toolset=gcc variant=release link=static threading=multi runtime-link=static stage
+
+2.4 Miniupnpc
+-Скачайте http://miniupnp.free.fr/files/download.php?file=miniupnpc-1.8.20131209.tar.gz
+-Распакуйте miniupnpc-1.8.20131209.tar.gz с помощью 7z. (Распаковать нужно 2 раза, нажмите на файле miniupnpc-1.8.20131209.tar.gz левой кнопкой мыши и выберите 7-Zip, затем Распаковать здесь. Появится файл miniupnpc-1.8.20131209.tar. С ним аналогично, левая кнопка мыши -> 7-Zip -> Распаковать здесь. Появится папка miniupnpc-1.8.20131209. Переименуйте её в miniupnpc.
+-Откройте командную строку Windows, и выполните следующий код:
+
+cd C:\deps\miniupnpc
+mingw32-make -f Makefile.mingw init upnpc-static
+
+2.5 qrencode
+-Скачайте http://prdownloads.sourceforge.net/libpng/libpng-1.6.12.tar.gz?download
+-Распакуйте
+-Откройте MinGw shell (C:\MinGW\msys\1.0\msys.bat) и выполните следующий код:
+
+cd /c/deps/libpng-1.6.12
+configure --disable-shared
+make
+cp .libs/libpng16.a .libs/libpng.a
+
+-Скачайте http://fukuchi.org/works/qrencode/qrencode-3.4.4.tar.gz
+-Распакуйте
+-Выполните следующий код в MinGW shell:
+
+cd /c/deps/qrencode-3.4.4
+
+LIBS="../libpng-1.6.12/.libs/libpng.a ../../mingw32/i686-w64-mingw32/lib/libz.a" \
+png_CFLAGS="-I../libpng-1.6.12" \
+png_LIBS="-L../libpng-1.6.12/.libs" \
+configure --enable-static --disable-shared --without-tools
+
+make
+
+2.6 Qt 5 и Qt 4
+Библиотеки Qt будем хранить в папке C:\Qt
+Для ускорения компиляции  вместо 
+mingw32-make 
+используйте
+mingw32-make -j n , где вместо n количество ядер вашего процессора
+Qt 5:
+-Скачайте http://download.qt-project.org/official_releases/qt/5.3/5.3.2/submodules/qtbase-opensource-src-5.3.2.7z
+http://download.qt-project.org/official_releases/qt/5.3/5.3.2/submodules/qttools-opensource-src-5.3.2.7z
+-Распакуйте в C:\Qt
+-Переименуйте папку qtbase-opensource-src-5.3.2 в 5.3.2
+-Откройте командную строку Windows и выполните следующий код:
+
+set INCLUDE=C:\deps\libpng-1.6.12;C:\deps\openssl-1.0.1j\include
+set LIB=C:\deps\libpng-1.6.12\.libs;C:\deps\openssl-1.0.1j
+
+cd C:\Qt\5.3.2
+
+configure.bat -release -opensource -confirm-license -static -make libs -no-sql-sqlite -no-opengl -system-zlib -qt-pcre -no-icu -no-gif -system-libpng -no-libjpeg -no-freetype -no-angle -no-vcproj -openssl -no-dbus -no-audio-backend -no-wmf-backend -no-qml-debug
+
+mingw32-make
+
+set PATH=%PATH%;C:\Qt\5.3.2\bin
+
+cd C:\Qt\qttools-opensource-src-5.3.2
+qmake qttools.pro
+mingw32-make
+
+
+
+Qt4:
+-Скачайте http://download.qt-project.org/official_releases/qt/4.8/4.8.6/qt-everywhere-opensource-src-4.8.6.zip
+-Распакуйте в C:\Qt
+-Переименуйте папку qt-everywhere-opensource-src-4.8.6 в 4.8.6
+-Откройте командную строку Windows и выполните следующий код:
+
+cd C:\Qt\4.8.6
+
+configure -release -opensource -confirm-license -static -no-sql-sqlite -no-qt3support -no-opengl -qt-zlib -no-gif -qt-libpng -qt-libmng -no-libtiff -qt-libjpeg -no-dsp -no-vcproj -no-openssl -no-dbus -no-phonon -no-phonon-backend -no-multimedia -no-audio-backend -no-webkit -no-script -no-scripttools -no-declarative -no-declarative-debug -qt-style-windows -qt-style-windowsxp -qt-style-windowsvista -no-style-plastique -no-style-cleanlooks -no-style-motif -no-style-cde -nomake demos -nomake examples
+
+mingw32-make
+
+
+3. Компиляция
+Будем хранить исходники в папке C:\MyProjects
+
+3.1 Скачиваем исходники
+-Зайдите на сайт https://github.com/novacoin-project/novacoin 
+-Нажмите Download ZIP
+-Распакуйте novacoin-master.zip в C:\MyProjects
+
+3.2 Собираем novacoind 
+-Перейдите в папку C:\MyProjects\novacoin-master\src
+-Откройте файл makefile.mingw в текстовом редакторе.(При написании инструкции использовался WordPad)
+-Поменяйте USE_UPNP:=0 на USE_UPNP:=1
+-Поменяйте текущие INCLUDEPATHS, LIBPATHS, LIBS на:
+
+BOOST_SUFFIX?=-mgw49-mt-s-1_55
+
+INCLUDEPATHS= \
+ -I"$(CURDIR)" \
+ -I"$(CURDIR)/zerocoin" \
+ -I"/c/deps/boost_1_55_0" \
+ -I"/c/deps" \
+ -I"/c/deps/db-6.0.20/build_unix" \
+ -I"/c/deps/openssl-1.0.1j/include"
+LIBPATHS= \
+ -L"$(CURDIR)/leveldb" \
+ -L"/c/deps/boost_1_55_0/stage/lib" \
+ -L"/c/deps/miniupnpc" \
+ -L"/c/deps/db-6.0.20/build_unix" \
+ -L"/c/deps/openssl-1.0.1j"
+
+LIBS= \
+  -l leveldb \
+  -l memenv \
+  -l boost_system$(BOOST_SUFFIX) \
+  -l boost_filesystem$(BOOST_SUFFIX) \
+  -l boost_program_options$(BOOST_SUFFIX) \
+  -l boost_thread$(BOOST_SUFFIX) \
+  -l boost_chrono$(BOOST_SUFFIX) \
+  -l db_cxx \
+  -l ssl \
+  -l crypto
+
+-Поменяйте LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat на 
+LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat -Wl,--large-address-aware -static
+
+-Если вы хотите использовать LevelDB как базу блоков то добавьте в файл MinGW:
+USE_LEVELDB:=1
+(ниже USE_IPV6:=1)
+Так же измените 
+cd leveldb; make; cd ..
+на 
+cd leveldb; TARGET_OS=NATIVE_WINDOWS make libleveldb.a libmemenv.a; cd ..
+
+Ещё измените
+obj/txdb-leveldb.o: leveldb/libleveldb.lib
+на
+obj/txdb-leveldb.o: leveldb/libleveldb.a
+
+Если вы хотите использовать BerkeleyDB как базу блоков, то просто удалите строчку USE_LEVELDB:=1
+
+-Сохраните измененный файл makefile.mingw
+
+-Откройте MinGW shell (C:\MinGW\msys\1.0\msys.bat) и выполните следующий код:
+
+cd /c/MyProjects/novacoin-master/src
+make -f makefile.mingw
+strip novacoind.exe
+
+(Возможная ошибка:
+Fatal error: can't create obj/zerocoin/Accumulator.o: No such file or directory
+make: *** [obj/zerocoin/Accumulator.o] Error 1
+Она происходит если нет папки C:\MyProjects\novacoin-master\src\obj\zerocoin . Так что при удалении obj файлов следите, чтобы папка C:\MyProjects\novacoin-master\src\obj\zerocoin не удалилась вместе с obj файлами.)
+
+Если всё сделано правильно, то файл novacoind.exe будет находится в папке C:\MyProjects\novacoin-master\src 
+
+
+3.3 Собираем Novacoin QT
+
+Внимание: Если вы хотите собирать Novacoin Qt с LevelDB, но пропустили шаг со сборкой novacoind.exe, то 
+-Откройте MinGW shell (C:\MinGW\msys\1.0\msys.bat) и выполните следующий код:
+
+cd /c/myprojects/novacoin-master/src/leveldb
+TARGET_OS=NATIVE_WINDOWS make libleveldb.a libmemenv.a
+
+-Откройте файл C:\MyProjects\novacoin-master\novacoin-qt.pro в текстовом редакторе(при написании инструкции использовался WordPad)
+-Ниже 
+# Dependency library locations can be customized with:
+#    BOOST_INCLUDE_PATH, BOOST_LIB_PATH, BDB_INCLUDE_PATH,
+#    BDB_LIB_PATH, OPENSSL_INCLUDE_PATH and OPENSSL_LIB_PATH respectively
+замените прописанные пути к зависимостям на
+
+BOOST_LIB_SUFFIX=-mgw49-mt-s-1_55
+BOOST_INCLUDE_PATH=C:/deps/boost_1_55_0
+BOOST_LIB_PATH=C:/deps/boost_1_55_0/stage/lib
+BDB_INCLUDE_PATH=C:/deps/db-6.0.20/build_unix
+BDB_LIB_PATH=C:/deps/db-6.0.20/build_unix
+OPENSSL_INCLUDE_PATH=C:/deps/openssl-1.0.1j/include
+OPENSSL_LIB_PATH=C:/deps/openssl-1.0.1j
+MINIUPNPC_INCLUDE_PATH=C:/deps/
+MINIUPNPC_LIB_PATH=C:/deps/miniupnpc
+QRENCODE_INCLUDE_PATH=C:/deps/qrencode-3.4.4
+QRENCODE_LIB_PATH=C:/deps/qrencode-3.4.4/.libs
+
+Так же измените(если ещё не изменено) 
+LIBS += -lshlwapi
+genleveldb.commands = cd $$PWD/src/leveldb && CC=$$QMAKE_CC CXX=$$QMAKE_CXX TARGET_OS=OS_WINDOWS_CROSSCOMPILE $(MAKE) OPT=\"$$QMAKE_CXXFLAGS $$QMAKE_CXXFLAGS_RELEASE\" libleveldb.a libmemenv.a && $$QMAKE_RANLIB $$PWD/src/leveldb/libleveldb.a && $$QMAKE_RANLIB $$PWD/src/leveldb/libmemenv.a
+
+на
+LIBS += -lshlwapi
+#genleveldb.commands = cd $$PWD/src/leveldb && CC=$$QMAKE_CC CXX=$$QMAKE_CXX TARGET_OS=OS_WINDOWS_CROSSCOMPILE $(MAKE) OPT=\"$$QMAKE_CXXFLAGS $$QMAKE_CXXFLAGS_RELEASE\" libleveldb.a libmemenv.a && $$QMAKE_RANLIB $$PWD/src/leveldb/libleveldb.a && $$QMAKE_RANLIB $$PWD/src/leveldb/libmemenv.a
+
+Если в файле нет такой строчки CONFIG += static , то добавьте её.
+
+Измените 
+win32:QMAKE_LFLAGS........................
+на 
+win32:QMAKE_LFLAGS *= -Wl,--large-address-aware -static 
+
+-Сохраните измененный файл novacoin-qt.pro
+-Откройте командную строку Windows и выполните следующий код:
+
+Qt5 + транзакционный индекс BDB 
+
+set PATH=%PATH%;C:\Qt\5.3.2\bin
+cd C:\MyProjects\novacoin-master
+qmake "USE_QRCODE=1" "USE_UPNP=1" "USE_IPV6=1" novacoin-qt.pro
+mingw32-make -f Makefile.Release
+
+
+Qt5 + транзакционный индекс LevelDB
+
+set PATH=%PATH%;C:\Qt\5.3.2\bin
+cd C:\MyProjects\novacoin-master
+qmake "USE_QRCODE=1" "USE_UPNP=1" "USE_IPV6=1" "USE_LEVELDB=1" novacoin-qt.pro
+mingw32-make -f Makefile.Release
+
+Qt4 + транзакционный индекс BDB
+
+set PATH=%PATH%;C:\Qt\4.8.6\bin
+cd C:\MyProjects\novacoin-master
+qmake "USE_QRCODE=1" "USE_UPNP=1" "USE_IPV6=1" novacoin-qt.pro
+mingw32-make -f Makefile.Release
+
+Qt4 + транзакционный индекс LevelDB
+
+set PATH=%PATH%;C:\Qt\4.8.6\bin
+cd C:\MyProjects\novacoin-master
+qmake "USE_QRCODE=1" "USE_UPNP=1" "USE_IPV6=1" "USE_LEVELDB=1" novacoin-qt.pro
+mingw32-make -f Makefile.Release
+
+
+
+Если всё сделано правильно, то файл novacoin-qt.exe будет находится в папке C:\MyProjects\novacoin-master\release
+
+
+
+64 bit:
+1.1 Так же как 32 bit
+
+1.2 Так же как 32 bit
+
+1.3 Установка MinGW-builds project toolchain:
+Скачайте http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/4.9.1/threads-posix/seh/x86_64-4.9.1-release-posix-seh-rt_v3-rev1.7z/download
+и распакуйте на C:\
+
+1.4 Удалите из переменной PATH путь C:\mingw32\bin; и добавьте в PATH путь C:\mingw64\bin;
+
+Проверка что вы всё сделали правильно:
+1)C:\MinGW\bin должен содержать только файл mingw-get.exe
+2)Откройте Командную строку (Нажмите кнопку Windows + R одновременно. Откроется окно "Выполнить", в поле открыть наберите cmd. Нажмите Ok). Наберите gcc -v. В командной строке выведется текст. В конце текста должно быть написано:
+Thread model: posix
+gcc version 4.9.1 (x86_64-posix-seh-rev1, Built by MinGW-W64 project)
+
+2. Построение зависимостей.
+В инструкции все зависимости сохраняются в папку c:\deps\x64
+
+2.1  OpenSSL: http://www.openssl.org/source/openssl-1.0.1j.tar.gz
+-Перейдите в папку C:\MinGW\msys\1.0 и запустите msys.bat
+Из MinGw shell выполните следующий код:
+
+cd /c/deps/x64/
+tar xvfz openssl-1.0.1j.tar.gz
+cd openssl-1.0.1j
+Configure no-shared no-dso mingw64
+make
+
+2.2 Так же как 32 bit, только cd /c/deps/ меняется на cd /c/deps/x64/
+
+2.3 Так же как 32 bit, только распаковка в C:\deps\x64 и команда cd C:\deps\boost_1_55_0\ меняется на cd C:\deps\x64\boost_1_55_0\ 
+
+2.4 Так же как 32 bit, только распаковка в C:\deps\x64 и заменить cd C:\deps\miniupnpc на cd C:\deps\x64\miniupnpc
+
+2.5 Часть с libpng так же как 32 bit, только распаковка в C:\deps\x64 
+Затем
+-Скачайте http://fukuchi.org/works/qrencode/qrencode-3.4.4.tar.gz
+-Распакуйте в C:\deps\x64
+-Выполните следующий код в MinGW shell:
+
+cd /c/deps/x64/qrencode-3.4.4
+
+LIBS="../libpng-1.6.12/.libs/libpng.a ../../../mingw64/x86_64-w64-mingw32/lib/libz.a" \
+png_CFLAGS="-I../libpng-1.6.12" \
+png_LIBS="-L../libpng-1.6.12/.libs" \
+configure --enable-static --disable-shared --without-tools
+
+make
+
+
+2.6 Qt 5 и Qt 4
+Библиотеки Qt будем хранить в папке C:\Qt
+Для ускорения компиляции  вместо 
+mingw32-make 
+используйте
+mingw32-make -j n , где вместо n количество ядер вашего процессора
+Qt 5:
+-Скачайте http://download.qt-project.org/official_releases/qt/5.3/5.3.2/submodules/qtbase-opensource-src-5.3.2.7z
+http://download.qt-project.org/official_releases/qt/5.3/5.3.2/submodules/qttools-opensource-src-5.3.2.7z
+-Распакуйте в C:\Qt
+-Переименуйте папку qtbase-opensource-src-5.3.2 в 5.3.2-x64
+-Откройте командную строку Windows и выполните следующий код:
+
+set INCLUDE=C:\deps\x64\libpng-1.6.12;C:\deps\x64\openssl-1.0.1j\include
+set LIB=C:\deps\x64\libpng-1.6.12\.libs;C:\deps\x64\openssl-1.0.1j
+
+cd C:\Qt\5.3.2-x64
+
+configure.bat -release -opensource -confirm-license -static -make libs -no-sql-sqlite -no-opengl -system-zlib -qt-pcre -no-icu -no-gif -system-libpng -no-libjpeg -no-freetype -no-angle -no-vcproj -openssl -no-dbus -no-audio-backend -no-wmf-backend -no-qml-debug
+
+mingw32-make
+
+set PATH=%PATH%;C:\Qt\5.3.2-x64\bin
+
+cd C:\Qt\qttools-opensource-src-5.3.2-x64
+qmake qttools.pro
+mingw32-make
+
+Qt4:
+-Скачайте http://download.qt-project.org/official_releases/qt/4.8/4.8.6/qt-everywhere-opensource-src-4.8.6.zip
+-Распакуйте в C:\Qt
+-Переименуйте папку qt-everywhere-opensource-src-4.8.6 в 4.8.6-x64
+-Откройте командную строку Windows и выполните следующий код:
+
+configure -release -opensource -confirm-license -static -no-sql-sqlite -no-qt3support -no-opengl -qt-zlib -no-gif -qt-libpng -qt-libmng -no-libtiff -qt-libjpeg -no-dsp -no-vcproj -no-openssl -no-dbus -no-phonon -no-phonon-backend -no-multimedia -no-audio-backend -no-webkit -no-script -no-scripttools -no-declarative -no-declarative-debug -qt-style-windows -qt-style-windowsxp -qt-style-windowsvista -no-style-plastique -no-style-cleanlooks -no-style-motif -no-style-cde -nomake demos -nomake examples
+
+mingw32-make
+
+3. Компиляция
+Будем хранить исходники в папке C:\MyProjects
+
+3.1 Так же как 32 bit
+
+3.2 Собираем novacoind 
+-Измените makefile.mingw так же как в 32 bit
+-Откройте файл makefile.mingw в текстовом редакторе и сохраните его как makefile.ming64
+-Измените в INCLUDEPATHS и LIBPATHS /c/deps/ на /c/deps/x64/
+-Измените 
+LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat -Wl,--large-address-aware -static 
+на 
+LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat -Wl,-static, -static-libgcc
+-Удалите (если они есть)obj(.o) файлы из C:\MyProjects\novacoin-master\src\obj и C:\MyProjects\novacoin-master\src\obj\zerocoin , если остались после 32 bit
+-Удалите (если они есть)libleveldb.a и libmemenv.a в папке C:\MyProjects\novacoin-master\src\leveldb
+-Удалите (если они есть)obj(.o) файлы из 
+C:\MyProjects\novacoin-master\src\leveldb\db 
+C:\MyProjects\novacoin-master\src\leveldb\helpers\memenv
+C:\MyProjects\novacoin-master\src\leveldb\port
+C:\MyProjects\novacoin-master\src\leveldb\table
+C:\MyProjects\novacoin-master\src\leveldb\util
+-Откройте MinGW shell (C:\MinGW\msys\1.0\msys.bat) и выполните следующий код:
+
+cd /c/MyProjects/novacoin-master/src
+make -f makefile.mingw64
+strip novacoind.exe
+
+(Возможная ошибка:
+Fatal error: can't create obj/zerocoin/Accumulator.o: No such file or directory
+make: *** [obj/zerocoin/Accumulator.o] Error 1
+Она происходит если нет папки C:\MyProjects\novacoin-master\src\obj\zerocoin . Так что при удалении obj файлов следите, чтобы папка C:\MyProjects\novacoin-master\src\obj\zerocoin не удалилась вместе с obj файлами.)
+
+Если всё сделано правильно, то файл novacoind.exe будет находится в папке C:\MyProjects\novacoin-master\src 
+
+
+3.3 Собираем Novacoin QT
+Внимание: Если вы хотите собирать Novacoin Qt с LevelDB, но пропустили шаг со сборкой novacoind.exe, то 
+-Удалите (если они есть)libleveldb.a и libmemenv.a в папке C:\MyProjects\novacoin-master\src\leveldb
+-Удалите (если они есть)obj(.o) файлы из 
+C:\MyProjects\novacoin-master\src\leveldb\db 
+C:\MyProjects\novacoin-master\src\leveldb\helpers\memenv
+C:\MyProjects\novacoin-master\src\leveldb\port
+C:\MyProjects\novacoin-master\src\leveldb\table
+C:\MyProjects\novacoin-master\src\leveldb\util
+-Откройте MinGW shell (C:\MinGW\msys\1.0\msys.bat) и выполните следующий код:
+
+cd /c/myprojects/novacoin-master/src/leveldb
+TARGET_OS=NATIVE_WINDOWS make libleveldb.a libmemenv.a
+
+-Измените файл novacoin-qt.pro так же как в 32 bit
+-Откройте файл novacoin-qt.pro в текстовом редакторе и сохраните его как novacoin-qt64.pro
+-Замените в INCLUDE и LIB путях текст C:/deps на текст C:/deps/x64 (то есть вместо C:/deps/boost_1_55_0 нужно C:/deps/x64/boost_1_55_0 и т.д.)
+-Замените 
+win32:QMAKE_LFLAGS *= -Wl,--large-address-aware -static 
+на
+win32:QMAKE_LFLAGS *= -Wl,-static
+
+-Откройте командную строку Windows и выполните следующий код:
+
+Qt5 + транзакционный индекс BDB 
+
+set PATH=%PATH%;C:\Qt\5.3.2-x64\bin
+cd C:\MyProjects\novacoin-master
+qmake "USE_QRCODE=1" "USE_UPNP=1" "USE_IPV6=1" novacoin-qt64.pro
+mingw32-make -f Makefile.Release
+
+
+Qt5 + транзакционный индекс LevelDB
+
+set PATH=%PATH%;C:\Qt\5.3.2-x64\bin
+cd C:\MyProjects\novacoin-master
+qmake "USE_QRCODE=1" "USE_UPNP=1" "USE_IPV6=1" "USE_LEVELDB=1" novacoin-qt64.pro
+mingw32-make -f Makefile.Release
+
+Qt4 + транзакционный индекс BDB
+
+set PATH=%PATH%;C:\Qt\4.8.6-x64\bin
+cd C:\MyProjects\novacoin-master
+qmake "USE_QRCODE=1" "USE_UPNP=1" "USE_IPV6=1" novacoin-qt64.pro
+mingw32-make -f Makefile.Release
+
+Qt4 + транзакционный индекс LevelDB
+
+set PATH=%PATH%;C:\Qt\4.8.6-x64\bin
+cd C:\MyProjects\novacoin-master
+qmake "USE_QRCODE=1" "USE_UPNP=1" "USE_IPV6=1" "USE_LEVELDB=1" novacoin-qt64.pro
+mingw32-make -f Makefile.Release
+
+Если всё сделано правильно, то файл novacoin-qt.exe будет находится в папке C:\MyProjects\novacoin-master\release
\ No newline at end of file
index 294f31a..34ae0a3 100644 (file)
@@ -1,4 +1,4 @@
-Bitcoin-qt: Qt4 GUI for Bitcoin
+Novacoin-qt: Qt4 GUI for Novacoin
 ===============================
 
 Build instructions
@@ -23,9 +23,9 @@ then execute the following:
     qmake
     make
 
-Alternatively, install Qt Creator and open the `bitcoin-qt.pro` file.
+Alternatively, install Qt Creator and open the `novacoin-qt.pro` file.
 
-An executable named `bitcoin-qt` will be built.
+An executable named `novacoin-qt` will be built.
 
 
 Windows
@@ -73,7 +73,7 @@ Build configuration options
 UPNnP port forwarding
 ---------------------
 
-To use UPnP for port forwarding behind a NAT router (recommended, as more connections overall allow for a faster and more stable bitcoin experience), pass the following argument to qmake:
+To use UPnP for port forwarding behind a NAT router (recommended, as more connections overall allow for a faster and more stable novacoin experience), pass the following argument to qmake:
 
 ::
 
@@ -121,9 +121,9 @@ flag to qmake to control this:
 Berkely DB version warning
 ==========================
 
-A warning for people using the *static binary* version of Bitcoin on a Linux/UNIX-ish system (tl;dr: **Berkely DB databases are not forward compatible**).
+A warning for people using the *static binary* version of Novacoin on a Linux/UNIX-ish system (tl;dr: **Berkely DB databases are not forward compatible**).
 
-The static binary version of Bitcoin is linked against libdb4.8 (see also `this Debian issue`_).
+The static binary version of Novacoin is linked against libdb4.8 (see also `this Debian issue`_).
 
 Now the nasty thing is that databases from 5.X are not compatible with 4.X.
 
@@ -138,7 +138,7 @@ Ubuntu 11.10 warning
 ====================
 
 Ubuntu 11.10 has a package called 'qt-at-spi' installed by default.  At the time of writing, having that package
-installed causes bitcoin-qt to crash intermittently.  The issue has been reported as `launchpad bug 857790`_, but
+installed causes novacoin-qt to crash intermittently.  The issue has been reported as `launchpad bug 857790`_, but
 isn't yet fixed.
 
 Until the bug is fixed, you can remove the qt-at-spi package to work around the problem, though this will presumably
index ed23ef3..da5a5a3 100644 (file)
@@ -1,7 +1,7 @@
 * update translations (ping tcatm on IRC for now)
 
 * update (commit) version in sources
-  bitcoin-qt.pro
+  novacoin-qt.pro
   src/version.h
   share/setup.nsi
   doc/README*
@@ -16,7 +16,7 @@
 
 * perform gitian builds
 
-  * From a directory containing the bitcoin source, gitian-builder and gitian.sigs
+  * From a directory containing the novacoin source, gitian-builder and gitian.sigs
    export SIGNER=(your gitian key, ie bluematt, sipa, etc)
    export VERSION=0.5.1
    cd ./gitian-builder
    wget 'http://downloads.sourceforge.net/project/boost/boost/1.47.0/boost_1_47_0.tar.bz2'
    wget 'http://download.qt.nokia.com/qt/source/qt-everywhere-opensource-src-4.7.4.tar.gz'
    cd ..
-   ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/boost-win32.yml
+   ./bin/gbuild ../novacoin/contrib/gitian-descriptors/boost-win32.yml
    cp build/out/boost-win32-1.47.0-gitian.zip inputs/
-   ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/qt-win32.yml
+   ./bin/gbuild ../novacoin/contrib/gitian-descriptors/qt-win32.yml
    cp build/out/qt-win32-4.7.4-gitian.zip inputs/
-   ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/deps-win32.yml
-   cp build/out/bitcoin-deps-0.0.3.zip inputs/
+   ./bin/gbuild ../novacoin/contrib/gitian-descriptors/deps-win32.yml
+   cp build/out/novacoin-deps-0.0.3.zip inputs/
 
-  * Build bitcoind and bitcoin-qt on Linux32, Linux64, and Win32:
-   ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian.yml
-   ./bin/gsign --signer $SIGNER --release ${VERSION} --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian.yml
+  * Build novacoind and novacoin-qt on Linux32, Linux64, and Win32:
+   ./bin/gbuild --commit novacoin=v${VERSION} ../novacoin/contrib/gitian-descriptors/gitian.yml
+   ./bin/gsign --signer $SIGNER --release ${VERSION} --destination ../gitian.sigs/ ../novacoin/contrib/gitian-descriptors/gitian.yml
    pushd build/out
-   zip -r bitcoin-${VERSION}-linux-gitian.zip *
-   mv bitcoin-${VERSION}-linux-gitian.zip ../../
+   zip -r novacoin-${VERSION}-linux-gitian.zip *
+   mv novacoin-${VERSION}-linux-gitian.zip ../../
    popd
-   ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win32.yml
-   ./bin/gsign --signer $SIGNER --release ${VERSION}-win32 --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win32.yml
+   ./bin/gbuild --commit novacoin=v${VERSION} ../novacoin/contrib/gitian-descriptors/gitian-win32.yml
+   ./bin/gsign --signer $SIGNER --release ${VERSION}-win32 --destination ../gitian.sigs/ ../novacoin/contrib/gitian-descriptors/gitian-win32.yml
    pushd build/out
-   zip -r bitcoin-${VERSION}-win32-gitian.zip *
-   mv bitcoin-${VERSION}-win32-gitian.zip ../../
+   zip -r novacoin-${VERSION}-win32-gitian.zip *
+   mv novacoin-${VERSION}-win32-gitian.zip ../../
    popd
 
   Build output expected:
-  1. linux 32-bit and 64-bit binaries + source (bitcoin-${VERSION}-linux-gitian.zip)
-  2. windows 32-bit binary, installer + source (bitcoin-${VERSION}-win32-gitian.zip)
+  1. linux 32-bit and 64-bit binaries + source (novacoin-${VERSION}-linux-gitian.zip)
+  2. windows 32-bit binary, installer + source (novacoin-${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 bitcoin-${VERSION}-linux-gitian.zip -d bitcoin-${VERSION}-linux
-   tar czvf bitcoin-${VERSION}-linux.tar.gz bitcoin-${VERSION}-linux
-   rm -rf bitcoin-${VERSION}-linux
+   unzip novacoin-${VERSION}-linux-gitian.zip -d novacoin-${VERSION}-linux
+   tar czvf novacoin-${VERSION}-linux.tar.gz novacoin-${VERSION}-linux
+   rm -rf novacoin-${VERSION}-linux
 
   * Windows .zip and setup.exe:
-   unzip bitcoin-${VERSION}-win32-gitian.zip -d bitcoin-${VERSION}-win32
-   mv bitcoin-${VERSION}-win32/bitcoin-*-setup.exe .
-   zip -r bitcoin-${VERSION}-win32.zip bitcoin-${VERSION}-win32
-   rm -rf bitcoin-${VERSION}-win32
+   unzip novacoin-${VERSION}-win32-gitian.zip -d novacoin-${VERSION}-win32
+   mv novacoin-${VERSION}-win32/novacoin-*-setup.exe .
+   zip -r novacoin-${VERSION}-win32.zip novacoin-${VERSION}-win32
+   rm -rf novacoin-${VERSION}-win32
 
 * perform Mac build
   See this blog post for how Gavin set up his build environment to build the OSX
   release; note that a patched version of macdeployqt is not needed anymore, as
   the required functionality and fixes are implemented directly in macdeployqtplus:
-    http://gavintech.blogspot.com/2011/11/deploying-bitcoin-qt-on-osx.html
+    http://gavintech.blogspot.com/2011/11/deploying-novacoin-qt-on-osx.html
   Gavin also had trouble with the macports py27-appscript package; he
   ended up installing a version that worked with: /usr/bin/easy_install-2.7 appscript
 
-  qmake RELEASE=1 USE_UPNP=1 USE_QRCODE=1 bitcoin-qt.pro
+  qmake RELEASE=1 USE_UPNP=1 USE_QRCODE=1 novacoin-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 contrib/macdeploy/macdeployqtplus Bitcoin-Qt.app -add-qt-tr $T -dmg -fancy contrib/macdeploy/fancy.plist
+  python2.7 contrib/macdeploy/macdeployqtplus Novacoin-Qt.app -add-qt-tr $T -dmg -fancy contrib/macdeploy/fancy.plist
 
  Build output expected:
-  Bitcoin-Qt.dmg
+  Novacoin-Qt.dmg
 
 * upload builds to SourceForge
 
 * create SHA256SUMS for builds, and PGP-sign it
 
-* update bitcoin.org version
+* update novacoin.org version
 
 * update forum version
 
 * update wiki download links
 
-* update wiki changelog: https://en.bitcoin.it/wiki/Changelog
+* update wiki changelog: https://wiki.novaco.in/en/Changelog
 
 * Commit your signature to gitian.sigs:
   pushd gitian.sigs
 
 * After 3 or more people have gitian-built, repackage gitian-signed zips:
 
-  * From a directory containing bitcoin source, gitian.sigs and gitian zips
+  * From a directory containing novacoin source, gitian.sigs and gitian zips
    export VERSION=0.5.1
-   mkdir bitcoin-${VERSION}-linux-gitian
-   pushd bitcoin-${VERSION}-linux-gitian
-   unzip ../bitcoin-${VERSION}-linux-gitian.zip
+   mkdir novacoin-${VERSION}-linux-gitian
+   pushd novacoin-${VERSION}-linux-gitian
+   unzip ../novacoin-${VERSION}-linux-gitian.zip
    mkdir gitian
-   cp ../bitcoin/contrib/gitian-downloader/*.pgp ./gitian/
+   cp ../novacoin/contrib/gitian-downloader/*.pgp ./gitian/
    for signer in $(ls ../gitian.sigs/${VERSION}/); do
-     cp ../gitian.sigs/${VERSION}/${signer}/bitcoin-build.assert ./gitian/${signer}-build.assert
-     cp ../gitian.sigs/${VERSION}/${signer}/bitcoin-build.assert.sig ./gitian/${signer}-build.assert.sig
+     cp ../gitian.sigs/${VERSION}/${signer}/novacoin-build.assert ./gitian/${signer}-build.assert
+     cp ../gitian.sigs/${VERSION}/${signer}/novacoin-build.assert.sig ./gitian/${signer}-build.assert.sig
    done
-   zip -r bitcoin-${VERSION}-linux-gitian.zip *
-   cp bitcoin-${VERSION}-linux-gitian.zip ../
+   zip -r novacoin-${VERSION}-linux-gitian.zip *
+   cp novacoin-${VERSION}-linux-gitian.zip ../
    popd
-   mkdir bitcoin-${VERSION}-win32-gitian
-   pushd bitcoin-${VERSION}-win32-gitian
-   unzip ../bitcoin-${VERSION}-win32-gitian.zip
+   mkdir novacoin-${VERSION}-win32-gitian
+   pushd novacoin-${VERSION}-win32-gitian
+   unzip ../novacoin-${VERSION}-win32-gitian.zip
    mkdir gitian
-   cp ../bitcoin/contrib/gitian-downloader/*.pgp ./gitian/
+   cp ../novacoin/contrib/gitian-downloader/*.pgp ./gitian/
    for signer in $(ls ../gitian.sigs/${VERSION}-win32/); do
-     cp ../gitian.sigs/${VERSION}-win32/${signer}/bitcoin-build.assert ./gitian/${signer}-build.assert
-     cp ../gitian.sigs/${VERSION}-win32/${signer}/bitcoin-build.assert.sig ./gitian/${signer}-build.assert.sig
+     cp ../gitian.sigs/${VERSION}-win32/${signer}/novacoin-build.assert ./gitian/${signer}-build.assert
+     cp ../gitian.sigs/${VERSION}-win32/${signer}/novacoin-build.assert.sig ./gitian/${signer}-build.assert.sig
    done
-   zip -r bitcoin-${VERSION}-win32-gitian.zip *
-   cp bitcoin-${VERSION}-win32-gitian.zip ../
+   zip -r novacoin-${VERSION}-win32-gitian.zip *
+   cp novacoin-${VERSION}-win32-gitian.zip ../
    popd
 
   * Upload gitian zips to SourceForge
index 3ddfc0c..996feb2 100644 (file)
@@ -7,18 +7,18 @@ handle those translations.
 Files and Folders
 -----------------
 
-### bitcoin-qt.pro
+### novacoin-qt.pro
 
 This file takes care of generating `.qm` files from `.ts` files. It is mostly
 automated.
 
-### src/qt/bitcoin.qrc
+### src/qt/novacoin.qrc
 
 This file must be updated whenever a new translation is added. Please note that
 files must end with `.qm`, not `.ts`.
 
     <qresource prefix="/translations">
-        <file alias="en">locale/bitcoin_en.qm</file>
+        <file alias="en">locale/novacoin_en.qm</file>
         ...
     </qresource>
 
@@ -26,11 +26,11 @@ files must end with `.qm`, not `.ts`.
 
 This directory contains all translations. Filenames must adhere to this format:
 
-    bitcoin_xx_YY.ts or bitcoin_xx.ts
+    novacoin_xx_YY.ts or novacoin_xx.ts
 
 #### Source file
 
-`src/qt/locale/bitcoin_en.ts` is treated in a special way. It is used as the
+`src/qt/locale/novacoin_en.ts` is treated in a special way. It is used as the
 source for all other translations. Whenever a string in the code is changed
 this file must be updated to reflect those changes. Usually, this can be
 accomplished by running `lupdate` (included in the Qt SDK).
@@ -75,6 +75,6 @@ It is also possible to directly download new translations one by one from transi
 ### Fetching new translations
 
 1. `tx pull -a`
-2. update `src/qt/bitcoin.qrc` manually or via
-   `ls src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/<file alias="\2">locale/\1.qm<\/file>/'`
+2. update `src/qt/novacoin.qrc` manually or via
+   `ls src/qt/locale/*ts|xargs -n1 basename|sed 's/\(novacoin_\(.*\)\).ts/<file alias="\2">locale/\1.qm<\/file>/'`
 3. `git add` new translations from `src/qt/locale/`
index 592c556..f6b3f81 100644 (file)
@@ -18,17 +18,18 @@ CONFIG += static
 # Dependency library locations can be customized with:
 #    BOOST_INCLUDE_PATH, BOOST_LIB_PATH, BDB_INCLUDE_PATH,
 #    BDB_LIB_PATH, OPENSSL_INCLUDE_PATH and OPENSSL_LIB_PATH respectively
-BOOST_LIB_SUFFIX=-mgw49-mt-s-1_55
-BOOST_INCLUDE_PATH=C:/deps/boost_1_55_0
-BOOST_LIB_PATH=C:/deps/boost_1_55_0/stage/lib
-BDB_INCLUDE_PATH=C:/deps/db-6.0.20/build_unix
-BDB_LIB_PATH=C:/deps/db-6.0.20/build_unix
-OPENSSL_INCLUDE_PATH=C:/deps/openssl-1.0.1j/include
-OPENSSL_LIB_PATH=C:/deps/openssl-1.0.1j
-MINIUPNPC_INCLUDE_PATH=C:/deps/
-MINIUPNPC_LIB_PATH=C:/deps/miniupnpc
-QRENCODE_INCLUDE_PATH=C:/deps/qrencode-3.4.4
-QRENCODE_LIB_PATH=C:/deps/qrencode-3.4.4/.libs
+
+#BOOST_LIB_SUFFIX=-mgw49-mt-s-1_55
+#BOOST_INCLUDE_PATH=C:/deps/boost_1_55_0
+#BOOST_LIB_PATH=C:/deps/boost_1_55_0/stage/lib
+#BDB_INCLUDE_PATH=C:/deps/db-6.0.20/build_unix
+#BDB_LIB_PATH=C:/deps/db-6.0.20/build_unix
+#OPENSSL_INCLUDE_PATH=C:/deps/openssl-1.0.1j/include
+#OPENSSL_LIB_PATH=C:/deps/openssl-1.0.1j
+#MINIUPNPC_INCLUDE_PATH=C:/deps/
+#MINIUPNPC_LIB_PATH=C:/deps/miniupnpc
+#QRENCODE_INCLUDE_PATH=C:/deps/qrencode-3.4.4
+#QRENCODE_LIB_PATH=C:/deps/qrencode-3.4.4/.libs
 
 OBJECTS_DIR = build
 MOC_DIR = build
@@ -75,7 +76,7 @@ contains(USE_UPNP, -) {
     count(USE_UPNP, 0) {
         USE_UPNP=1
     }
-    DEFINES += USE_UPNP=$$USE_UPNP STATICLIB
+    DEFINES += USE_UPNP=$$USE_UPNP STATICLIB MINIUPNP_STATICLIB
     INCLUDEPATH += $$MINIUPNPC_INCLUDE_PATH
     LIBS += $$join(MINIUPNPC_LIB_PATH,,-L,) -lminiupnpc
     win32:LIBS += -liphlpapi
@@ -134,6 +135,14 @@ contains(USE_LEVELDB, 1) {
     SOURCES += src/txdb-bdb.cpp
 }
 
+contains(USE_ASM, 1) {
+    message(Using optimized scrypt core implementation)
+    SOURCES += src/scrypt-arm.S src/scrypt-x86.S src/scrypt-x86_64.S
+} else {
+    message(Using generic scrypt core implementation)
+    SOURCES += src/scrypt-generic.c
+}
+
 # regenerate src/build.h
 !windows|contains(USE_BUILD_INFO, 1) {
     genbuild.depends = FORCE
@@ -190,17 +199,6 @@ HEADERS += src/qt/bitcoingui.h \
     src/kernel.h \
     src/scrypt.h \
     src/pbkdf2.h \
-    src/zerocoin/Accumulator.h \
-    src/zerocoin/AccumulatorProofOfKnowledge.h \
-    src/zerocoin/Coin.h \
-    src/zerocoin/CoinSpend.h \
-    src/zerocoin/Commitment.h \
-    src/zerocoin/ParamGeneration.h \
-    src/zerocoin/Params.h \
-    src/zerocoin/SerialNumberSignatureOfKnowledge.h \
-    src/zerocoin/SpendMetaData.h \
-    src/zerocoin/ZeroTest.h \
-    src/zerocoin/Zerocoin.h \
     src/serialize.h \
     src/strlcpy.h \
     src/main.h \
@@ -319,21 +317,8 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
     src/qt/rpcconsole.cpp \
     src/noui.cpp \
     src/kernel.cpp \
-    src/scrypt-arm.S \
-    src/scrypt-x86.S \
-    src/scrypt-x86_64.S \
     src/scrypt.cpp \
-    src/pbkdf2.cpp \
-    src/zerocoin/Accumulator.cpp \
-    src/zerocoin/AccumulatorProofOfKnowledge.cpp \
-    src/zerocoin/Coin.cpp \
-    src/zerocoin/CoinSpend.cpp \
-    src/zerocoin/Commitment.cpp \
-    src/zerocoin/ParamGeneration.cpp \
-    src/zerocoin/Params.cpp \
-    src/zerocoin/SerialNumberSignatureOfKnowledge.cpp \
-    src/zerocoin/SpendMetaData.cpp \
-    src/zerocoin/ZeroTest.cpp
+    src/pbkdf2.cpp
 
 RESOURCES += \
     src/qt/bitcoin.qrc
index 2e9193d..03b8c13 100644 (file)
@@ -10,7 +10,6 @@
 #include "util.h"
 #include "ui_interface.h"
 #include "checkpoints.h"
-#include "zerocoin/ZeroTest.h"
 #include <boost/format.hpp>
 #include <boost/filesystem.hpp>
 #include <boost/filesystem/fstream.hpp>
@@ -778,16 +777,6 @@ bool AppInit2()
         return false;
     }
 
-    // ********************************************************* Testing Zerocoin
-
-
-    if (GetBoolArg("-zerotest", false))
-    {
-        printf("\n=== ZeroCoin tests start ===\n");
-        Test_RunAllTests();
-        printf("=== ZeroCoin tests end ===\n\n");
-    }
-
     // ********************************************************* Step 8: load wallet
 
     uiInterface.InitMessage(_("Loading wallet..."));
index a0632f9..6491cfd 100644 (file)
@@ -42,11 +42,11 @@ typedef struct KernelSearchSettings {
     unsigned int nSearchInterval; // Number of seconds allowed to go into the past
 } KernelSearchSettings;
 
-typedef set<pair<const CWalletTx*,unsigned int> > CoinsSet;
+typedef std::set<std::pair<const CWalletTx*,unsigned int> > CoinsSet;
 
 // Preloaded coins metadata
 // txid => ((txindex, (tx, vout.n)), (block, modifier))
-typedef map<uint256, pair<pair<CTxIndex, pair<const CWalletTx*,unsigned int> >, pair<CBlock, uint64> > > MetaMap;
+typedef std::map<uint256, std::pair<std::pair<CTxIndex, std::pair<const CWalletTx*,unsigned int> >, std::pair<CBlock, uint64> > > MetaMap;
 
 // Scan given coins set for kernel solution
 bool ScanForStakeKernelHash(MetaMap &mapMeta, KernelSearchSettings &settings, CoinsSet::value_type &kernelcoin, unsigned int &nTimeTx, unsigned int &nBlockTime);
index fc40194..2439d7a 100644 (file)
@@ -9,3 +9,4 @@ Sanjay Ghemawat <sanjay@google.com>
 
 # Partial list of contributors:
 Kevin Regan <kevin.d.regan@gmail.com>
+Johan Bilien <jobi@litl.com>
diff --git a/src/leveldb/CONTRIBUTING.md b/src/leveldb/CONTRIBUTING.md
new file mode 100644 (file)
index 0000000..cd600ff
--- /dev/null
@@ -0,0 +1,36 @@
+# Contributing
+
+We'd love to accept your code patches! However, before we can take them, we
+have to jump a couple of legal hurdles.
+
+## Contributor License Agreements
+
+Please fill out either the individual or corporate Contributor License
+Agreement as appropriate.
+
+* If you are an individual writing original source code and you're sure you
+own the intellectual property, then sign an [individual CLA](https://developers.google.com/open-source/cla/individual).
+* If you work for a company that wants to allow you to contribute your work,
+then sign a [corporate CLA](https://developers.google.com/open-source/cla/corporate).
+
+Follow either of the two links above to access the appropriate CLA and
+instructions for how to sign and return it.
+
+## Submitting a Patch
+
+1. Sign the contributors license agreement above.
+2. Decide which code you want to submit. A submission should be a set of changes
+that addresses one issue in the [issue tracker](https://github.com/google/leveldb/issues).
+Please don't mix more than one logical change per submission, because it makes
+the history hard to follow. If you want to make a change
+(e.g. add a sample or feature) that doesn't have a corresponding issue in the
+issue tracker, please create one.
+3. **Submitting**: When you are ready to submit, send us a Pull Request. Be
+sure to include the issue number you fixed and the name you used to sign
+the CLA.
+
+## Writing Code ##
+
+If your contribution contains code, please make sure that it follows 
+[the style guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml).
+Otherwise we will have to ask you to make changes, and that's no fun for anyone.
index f43180a..20b725e 100644 (file)
@@ -6,9 +6,12 @@
 # Uncomment exactly one of the lines labelled (A), (B), and (C) below
 # to switch between compilation modes.
 
-OPT ?= -O2 -DNDEBUG       # (A) Production use (optimized mode)
-# OPT ?= -g2              # (B) Debug mode, w/ full line-level debugging symbols
-# OPT ?= -O2 -g2 -DNDEBUG # (C) Profiling mode: opt, but w/debugging symbols
+# (A) Production use (optimized mode)
+OPT ?= -O2 -DNDEBUG
+# (B) Debug mode, w/ full line-level debugging symbols
+# OPT ?= -g2
+# (C) Profiling mode: opt, but w/debugging symbols
+# OPT ?= -O2 -g2 -DNDEBUG
 #-----------------------------------------------
 
 # detect what platform we're building on
@@ -29,8 +32,14 @@ MEMENVOBJECTS = $(MEMENV_SOURCES:.cc=.o)
 TESTUTIL = ./util/testutil.o
 TESTHARNESS = ./util/testharness.o $(TESTUTIL)
 
+# Note: iOS should probably be using libtool, not ar.
+ifeq ($(PLATFORM), IOS)
+AR=xcrun ar
+endif
+
 TESTS = \
        arena_test \
+       autocompact_test \
        bloom_test \
        c_test \
        cache_test \
@@ -42,7 +51,9 @@ TESTS = \
        env_test \
        filename_test \
        filter_block_test \
+       hash_test \
        issue178_test \
+       issue200_test \
        log_test \
        memenv_test \
        skiplist_test \
@@ -70,7 +81,7 @@ SHARED = $(SHARED1)
 else
 # Update db.h if you change these.
 SHARED_MAJOR = 1
-SHARED_MINOR = 12
+SHARED_MINOR = 18
 SHARED1 = libleveldb.$(PLATFORM_SHARED_EXT)
 SHARED2 = $(SHARED1).$(SHARED_MAJOR)
 SHARED3 = $(SHARED1).$(SHARED_MAJOR).$(SHARED_MINOR)
@@ -114,6 +125,9 @@ leveldbutil: db/leveldb_main.o $(LIBOBJECTS)
 arena_test: util/arena_test.o $(LIBOBJECTS) $(TESTHARNESS)
        $(CXX) $(LDFLAGS) util/arena_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)
 
+autocompact_test: db/autocompact_test.o $(LIBOBJECTS) $(TESTHARNESS)
+       $(CXX) $(LDFLAGS) db/autocompact_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)
+
 bloom_test: util/bloom_test.o $(LIBOBJECTS) $(TESTHARNESS)
        $(CXX) $(LDFLAGS) util/bloom_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)
 
@@ -147,9 +161,15 @@ filename_test: db/filename_test.o $(LIBOBJECTS) $(TESTHARNESS)
 filter_block_test: table/filter_block_test.o $(LIBOBJECTS) $(TESTHARNESS)
        $(CXX) $(LDFLAGS) table/filter_block_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)
 
+hash_test: util/hash_test.o $(LIBOBJECTS) $(TESTHARNESS)
+       $(CXX) $(LDFLAGS) util/hash_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)
+
 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)
 
@@ -182,20 +202,21 @@ PLATFORMSROOT=/Applications/Xcode.app/Contents/Developer/Platforms
 SIMULATORROOT=$(PLATFORMSROOT)/iPhoneSimulator.platform/Developer
 DEVICEROOT=$(PLATFORMSROOT)/iPhoneOS.platform/Developer
 IOSVERSION=$(shell defaults read $(PLATFORMSROOT)/iPhoneOS.platform/version CFBundleShortVersionString)
+IOSARCH=-arch armv6 -arch armv7 -arch armv7s -arch arm64
 
 .cc.o:
        mkdir -p ios-x86/$(dir $@)
-       $(CXX) $(CXXFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -c $< -o ios-x86/$@
+       xcrun -sdk iphonesimulator $(CXX) $(CXXFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -arch x86_64 -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/$@
-       lipo ios-x86/$@ ios-arm/$@ -create -output $@
+       xcrun -sdk iphoneos $(CXX) $(CXXFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk $(IOSARCH) -c $< -o ios-arm/$@
+       xcrun 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/$@
+       xcrun -sdk iphonesimulator $(CC) $(CFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -arch x86_64 -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/$@
-       lipo ios-x86/$@ ios-arm/$@ -create -output $@
+       xcrun -sdk iphoneos $(CC) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk $(IOSARCH) -c $< -o ios-arm/$@
+       xcrun lipo ios-x86/$@ ios-arm/$@ -create -output $@
 
 else
 .cc.o:
diff --git a/src/leveldb/README.md b/src/leveldb/README.md
new file mode 100644 (file)
index 0000000..480affb
--- /dev/null
@@ -0,0 +1,138 @@
+**LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values.**
+
+Authors: Sanjay Ghemawat (sanjay@google.com) and Jeff Dean (jeff@google.com)
+
+# Features
+  * Keys and values are arbitrary byte arrays.
+  * Data is stored sorted by key.
+  * Callers can provide a custom comparison function to override the sort order.
+  * The basic operations are `Put(key,value)`, `Get(key)`, `Delete(key)`.
+  * Multiple changes can be made in one atomic batch.
+  * Users can create a transient snapshot to get a consistent view of data.
+  * Forward and backward iteration is supported over the data.
+  * Data is automatically compressed using the [Snappy compression library](http://code.google.com/p/snappy).
+  * External activity (file system operations etc.) is relayed through a virtual interface so users can customize the operating system interactions.
+  * [Detailed documentation](http://htmlpreview.github.io/?https://github.com/google/leveldb/blob/master/doc/index.html) about how to use the library is included with the source code.
+
+
+# Limitations
+  * This is not a SQL database.  It does not have a relational data model, it does not support SQL queries, and it has no support for indexes.
+  * Only a single process (possibly multi-threaded) can access a particular database at a time.
+  * There is no client-server support builtin to the library.  An application that needs such support will have to wrap their own server around the library.
+
+# Performance
+
+Here is a performance report (with explanations) from the run of the
+included db_bench program.  The results are somewhat noisy, but should
+be enough to get a ballpark performance estimate.
+
+## Setup
+
+We use a database with a million entries.  Each entry has a 16 byte
+key, and a 100 byte value.  Values used by the benchmark compress to
+about half their original size.
+
+    LevelDB:    version 1.1
+    Date:       Sun May  1 12:11:26 2011
+    CPU:        4 x Intel(R) Core(TM)2 Quad CPU    Q6600  @ 2.40GHz
+    CPUCache:   4096 KB
+    Keys:       16 bytes each
+    Values:     100 bytes each (50 bytes after compression)
+    Entries:    1000000
+    Raw Size:   110.6 MB (estimated)
+    File Size:  62.9 MB (estimated)
+
+## Write performance
+
+The "fill" benchmarks create a brand new database, in either
+sequential, or random order.  The "fillsync" benchmark flushes data
+from the operating system to the disk after every operation; the other
+write operations leave the data sitting in the operating system buffer
+cache for a while.  The "overwrite" benchmark does random writes that
+update existing keys in the database.
+
+    fillseq      :       1.765 micros/op;   62.7 MB/s
+    fillsync     :     268.409 micros/op;    0.4 MB/s (10000 ops)
+    fillrandom   :       2.460 micros/op;   45.0 MB/s
+    overwrite    :       2.380 micros/op;   46.5 MB/s
+
+Each "op" above corresponds to a write of a single key/value pair.
+I.e., a random write benchmark goes at approximately 400,000 writes per second.
+
+Each "fillsync" operation costs much less (0.3 millisecond)
+than a disk seek (typically 10 milliseconds).  We suspect that this is
+because the hard disk itself is buffering the update in its memory and
+responding before the data has been written to the platter.  This may
+or may not be safe based on whether or not the hard disk has enough
+power to save its memory in the event of a power failure.
+
+## Read performance
+
+We list the performance of reading sequentially in both the forward
+and reverse direction, and also the performance of a random lookup.
+Note that the database created by the benchmark is quite small.
+Therefore the report characterizes the performance of leveldb when the
+working set fits in memory.  The cost of reading a piece of data that
+is not present in the operating system buffer cache will be dominated
+by the one or two disk seeks needed to fetch the data from disk.
+Write performance will be mostly unaffected by whether or not the
+working set fits in memory.
+
+    readrandom   :      16.677 micros/op;  (approximately 60,000 reads per second)
+    readseq      :       0.476 micros/op;  232.3 MB/s
+    readreverse  :       0.724 micros/op;  152.9 MB/s
+
+LevelDB compacts its underlying storage data in the background to
+improve read performance.  The results listed above were done
+immediately after a lot of random writes.  The results after
+compactions (which are usually triggered automatically) are better.
+
+    readrandom   :      11.602 micros/op;  (approximately 85,000 reads per second)
+    readseq      :       0.423 micros/op;  261.8 MB/s
+    readreverse  :       0.663 micros/op;  166.9 MB/s
+
+Some of the high cost of reads comes from repeated decompression of blocks
+read from disk.  If we supply enough cache to the leveldb so it can hold the
+uncompressed blocks in memory, the read performance improves again:
+
+    readrandom   :       9.775 micros/op;  (approximately 100,000 reads per second before compaction)
+    readrandom   :       5.215 micros/op;  (approximately 190,000 reads per second after compaction)
+
+## Repository contents
+
+See doc/index.html for more explanation. See doc/impl.html for a brief overview of the implementation.
+
+The public interface is in include/*.h.  Callers should not include or
+rely on the details of any other header files in this package.  Those
+internal APIs may be changed without warning.
+
+Guide to header files:
+
+* **include/db.h**: Main interface to the DB: Start here
+
+* **include/options.h**: Control over the behavior of an entire database,
+and also control over the behavior of individual reads and writes.
+
+* **include/comparator.h**: Abstraction for user-specified comparison function. 
+If you want just bytewise comparison of keys, you can use the default
+comparator, but clients can write their own comparator implementations if they
+want custom ordering (e.g. to handle different character encodings, etc.)
+
+* **include/iterator.h**: Interface for iterating over data. You can get
+an iterator from a DB object.
+
+* **include/write_batch.h**: Interface for atomically applying multiple
+updates to a database.
+
+* **include/slice.h**: A simple module for maintaining a pointer and a
+length into some other byte array.
+
+* **include/status.h**: Status is returned from many of the public interfaces
+and is used to report success and various kinds of errors.
+
+* **include/env.h**: 
+Abstraction of the OS environment.  A posix implementation of this interface is
+in util/env_posix.cc
+
+* **include/table.h, include/table_builder.h**: Lower-level modules that most
+clients probably won't use directly
index bdfd641..a1101c1 100755 (executable)
@@ -20,7 +20,7 @@
 #
 # The PLATFORM_CCFLAGS and PLATFORM_CXXFLAGS might include the following:
 #
-#       -DLEVELDB_CSTDATOMIC_PRESENT if <cstdatomic> is present
+#       -DLEVELDB_ATOMIC_PRESENT     if <atomic> is present
 #       -DLEVELDB_PLATFORM_POSIX     for Posix-based platforms
 #       -DSNAPPY                     if the Snappy library is present
 #
@@ -72,6 +72,12 @@ if [ "$CXX" = "g++" ]; then
 fi
 
 case "$TARGET_OS" in
+    CYGWIN_*)
+        PLATFORM=OS_LINUX
+        COMMON_FLAGS="$MEMCMP_FLAG -lpthread -DOS_LINUX -DCYGWIN"
+        PLATFORM_LDFLAGS="-lpthread"
+        PORT_FILE=port/port_posix.cc
+        ;;
     Darwin)
         PLATFORM=OS_MACOSX
         COMMON_FLAGS="$MEMCMP_FLAG -DOS_MACOSX"
@@ -137,6 +143,16 @@ case "$TARGET_OS" in
         # 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"
@@ -175,13 +191,14 @@ if [ "$CROSS_COMPILE" = "true" ]; then
 else
     CXXOUTPUT="${TMPDIR}/leveldb_build_detect_platform-cxx.$$"
 
-    # If -std=c++0x works, use <cstdatomic>.  Otherwise use port_posix.h.
+    # If -std=c++0x works, use <atomic> as fallback for when memory barriers
+    # are not available.
     $CXX $CXXFLAGS -std=c++0x -x c++ - -o $CXXOUTPUT 2>/dev/null  <<EOF
-      #include <cstdatomic>
+      #include <atomic>
       int main() {}
 EOF
     if [ "$?" = 0 ]; then
-        COMMON_FLAGS="$COMMON_FLAGS -DLEVELDB_PLATFORM_POSIX -DLEVELDB_CSTDATOMIC_PRESENT"
+        COMMON_FLAGS="$COMMON_FLAGS -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT"
         PLATFORM_CXXFLAGS="-std=c++0x"
     else
         COMMON_FLAGS="$COMMON_FLAGS -DLEVELDB_PLATFORM_POSIX"
diff --git a/src/leveldb/db/autocompact_test.cc b/src/leveldb/db/autocompact_test.cc
new file mode 100644 (file)
index 0000000..d20a236
--- /dev/null
@@ -0,0 +1,118 @@
+// 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.
+
+#include "leveldb/db.h"
+#include "db/db_impl.h"
+#include "leveldb/cache.h"
+#include "util/testharness.h"
+#include "util/testutil.h"
+
+namespace leveldb {
+
+class AutoCompactTest {
+ public:
+  std::string dbname_;
+  Cache* tiny_cache_;
+  Options options_;
+  DB* db_;
+
+  AutoCompactTest() {
+    dbname_ = test::TmpDir() + "/autocompact_test";
+    tiny_cache_ = NewLRUCache(100);
+    options_.block_cache = tiny_cache_;
+    DestroyDB(dbname_, options_);
+    options_.create_if_missing = true;
+    options_.compression = kNoCompression;
+    ASSERT_OK(DB::Open(options_, dbname_, &db_));
+  }
+
+  ~AutoCompactTest() {
+    delete db_;
+    DestroyDB(dbname_, Options());
+    delete tiny_cache_;
+  }
+
+  std::string Key(int i) {
+    char buf[100];
+    snprintf(buf, sizeof(buf), "key%06d", i);
+    return std::string(buf);
+  }
+
+  uint64_t Size(const Slice& start, const Slice& limit) {
+    Range r(start, limit);
+    uint64_t size;
+    db_->GetApproximateSizes(&r, 1, &size);
+    return size;
+  }
+
+  void DoReads(int n);
+};
+
+static const int kValueSize = 200 * 1024;
+static const int kTotalSize = 100 * 1024 * 1024;
+static const int kCount = kTotalSize / kValueSize;
+
+// Read through the first n keys repeatedly and check that they get
+// compacted (verified by checking the size of the key space).
+void AutoCompactTest::DoReads(int n) {
+  std::string value(kValueSize, 'x');
+  DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
+
+  // Fill database
+  for (int i = 0; i < kCount; i++) {
+    ASSERT_OK(db_->Put(WriteOptions(), Key(i), value));
+  }
+  ASSERT_OK(dbi->TEST_CompactMemTable());
+
+  // Delete everything
+  for (int i = 0; i < kCount; i++) {
+    ASSERT_OK(db_->Delete(WriteOptions(), Key(i)));
+  }
+  ASSERT_OK(dbi->TEST_CompactMemTable());
+
+  // Get initial measurement of the space we will be reading.
+  const int64_t initial_size = Size(Key(0), Key(n));
+  const int64_t initial_other_size = Size(Key(n), Key(kCount));
+
+  // Read until size drops significantly.
+  std::string limit_key = Key(n);
+  for (int read = 0; true; read++) {
+    ASSERT_LT(read, 100) << "Taking too long to compact";
+    Iterator* iter = db_->NewIterator(ReadOptions());
+    for (iter->SeekToFirst();
+         iter->Valid() && iter->key().ToString() < limit_key;
+         iter->Next()) {
+      // Drop data
+    }
+    delete iter;
+    // Wait a little bit to allow any triggered compactions to complete.
+    Env::Default()->SleepForMicroseconds(1000000);
+    uint64_t size = Size(Key(0), Key(n));
+    fprintf(stderr, "iter %3d => %7.3f MB [other %7.3f MB]\n",
+            read+1, size/1048576.0, Size(Key(n), Key(kCount))/1048576.0);
+    if (size <= initial_size/10) {
+      break;
+    }
+  }
+
+  // Verify that the size of the key space not touched by the reads
+  // is pretty much unchanged.
+  const int64_t final_other_size = Size(Key(n), Key(kCount));
+  ASSERT_LE(final_other_size, initial_other_size + 1048576);
+  ASSERT_GE(final_other_size, initial_other_size/5 - 1048576);
+}
+
+TEST(AutoCompactTest, ReadAll) {
+  DoReads(kCount);
+}
+
+TEST(AutoCompactTest, ReadHalf) {
+  DoReads(kCount/2);
+}
+
+}  // namespace leveldb
+
+int main(int argc, char** argv) {
+  return leveldb::test::RunAllTests();
+}
index 31b2d5f..96afc68 100644 (file)
@@ -35,6 +35,7 @@ class CorruptionTest {
   CorruptionTest() {
     tiny_cache_ = NewLRUCache(100);
     options_.env = &env_;
+    options_.block_cache = tiny_cache_;
     dbname_ = test::TmpDir() + "/db_test";
     DestroyDB(dbname_, options_);
 
@@ -50,17 +51,14 @@ class CorruptionTest {
      delete tiny_cache_;
   }
 
-  Status TryReopen(Options* options = NULL) {
+  Status TryReopen() {
     delete db_;
     db_ = NULL;
-    Options opt = (options ? *options : options_);
-    opt.env = &env_;
-    opt.block_cache = tiny_cache_;
-    return DB::Open(opt, dbname_, &db_);
+    return DB::Open(options_, dbname_, &db_);
   }
 
-  void Reopen(Options* options = NULL) {
-    ASSERT_OK(TryReopen(options));
+  void Reopen() {
+    ASSERT_OK(TryReopen());
   }
 
   void RepairDB() {
@@ -77,7 +75,13 @@ class CorruptionTest {
       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));
     }
   }
 
@@ -92,6 +96,10 @@ class CorruptionTest {
     for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
       uint64_t key;
       Slice in(iter->key());
+      if (in == "" || in == "~") {
+        // Ignore boundary keys.
+        continue;
+      }
       if (!ConsumeDecimalNumber(&in, &key) ||
           !in.empty() ||
           key < next_expected) {
@@ -123,7 +131,7 @@ class CorruptionTest {
     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
@@ -233,7 +241,23 @@ TEST(CorruptionTest, TableFile) {
   dbi->TEST_CompactRange(1, NULL, NULL);
 
   Corrupt(kTableFile, 100, 1);
-  Check(99, 99);
+  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<DBImpl*>(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) {
@@ -299,7 +323,7 @@ TEST(CorruptionTest, CompactionInputError) {
   ASSERT_EQ(1, Property("leveldb.num-files-at-level" + NumberToString(last)));
 
   Corrupt(kTableFile, 100, 1);
-  Check(9, 9);
+  Check(5, 9);
 
   // Force compactions by writing lots of values
   Build(10000);
@@ -307,32 +331,23 @@ TEST(CorruptionTest, CompactionInputError) {
 }
 
 TEST(CorruptionTest, CompactionInputErrorParanoid) {
-  Options options;
-  options.paranoid_checks = true;
-  options.write_buffer_size = 1048576;
-  Reopen(&options);
+  options_.paranoid_checks = true;
+  options_.write_buffer_size = 512 << 10;
+  Reopen();
   DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
 
-  // Fill levels >= 1 so memtable compaction outputs to level 1
-  for (int level = 1; level < config::kNumLevels; level++) {
-    dbi->Put(WriteOptions(), "", "begin");
-    dbi->Put(WriteOptions(), "~", "end");
+  // Make multiple inputs so we need to compact.
+  for (int i = 0; i < 2; i++) {
+    Build(10);
     dbi->TEST_CompactMemTable();
+    Corrupt(kTableFile, 100, 1);
+    env_.SleepForMicroseconds(100000);
   }
+  dbi->CompactRange(NULL, NULL);
 
-  Build(10);
-  dbi->TEST_CompactMemTable();
-  ASSERT_EQ(1, Property("leveldb.num-files-at-level0"));
-
-  Corrupt(kTableFile, 100, 1);
-  Check(9, 9);
-
-  // Write must eventually fail because of corrupted table
-  Status s;
+  // Write must fail because of corrupted table
   std::string tmp1, tmp2;
-  for (int i = 0; i < 10000 && s.ok(); i++) {
-    s = db_->Put(WriteOptions(), Key(i, &tmp1), Value(i, &tmp2));
-  }
+  Status s = db_->Put(WriteOptions(), Key(5, &tmp1), Value(5, &tmp2));
   ASSERT_TRUE(!s.ok()) << "write did not fail in corrupted paranoid db";
 }
 
index 7abdf87..705a170 100644 (file)
@@ -128,7 +128,7 @@ class RandomGenerator {
     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 @@ class RandomGenerator {
 };
 
 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 @@ class Benchmark {
     heap_counter_(0) {
     std::vector<std::string> 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]);
       }
@@ -431,7 +431,7 @@ class Benchmark {
         benchmarks = sep + 1;
       }
 
-      // Reset parameters that may be overriddden bwlow
+      // Reset parameters that may be overridden below
       num_ = FLAGS_num;
       reads_ = (FLAGS_reads < 0 ? FLAGS_num : FLAGS_reads);
       value_size_ = FLAGS_value_size;
@@ -811,7 +811,6 @@ class Benchmark {
 
   void SeekRandom(ThreadState* thread) {
     ReadOptions options;
-    std::string value;
     int found = 0;
     for (int i = 0; i < reads_; i++) {
       Iterator* iter = db_->NewIterator(options);
index 395d317..49b9595 100644 (file)
@@ -113,14 +113,14 @@ Options SanitizeOptions(const std::string& dbname,
   return result;
 }
 
-DBImpl::DBImpl(const Options& options, const std::string& dbname)
-    : env_(options.env),
-      internal_comparator_(options.comparator),
-      internal_filter_policy_(options.filter_policy),
-      options_(SanitizeOptions(
-          dbname, &internal_comparator_, &internal_filter_policy_, options)),
-      owns_info_log_(options_.info_log != options.info_log),
-      owns_cache_(options_.block_cache != options.block_cache),
+DBImpl::DBImpl(const Options& raw_options, const std::string& dbname)
+    : env_(raw_options.env),
+      internal_comparator_(raw_options.comparator),
+      internal_filter_policy_(raw_options.filter_policy),
+      options_(SanitizeOptions(dbname, &internal_comparator_,
+                               &internal_filter_policy_, raw_options)),
+      owns_info_log_(options_.info_log != raw_options.info_log),
+      owns_cache_(options_.block_cache != raw_options.block_cache),
       dbname_(dbname),
       db_lock_(NULL),
       shutting_down_(NULL),
@@ -130,15 +130,15 @@ DBImpl::DBImpl(const Options& options, const std::string& dbname)
       logfile_(NULL),
       logfile_number_(0),
       log_(NULL),
+      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);
 
   // Reserve ten files or so for other uses and give the rest to TableCache.
-  const int table_cache_size = options.max_open_files - kNumNonTableCacheFiles;
+  const int table_cache_size = options_.max_open_files - kNumNonTableCacheFiles;
   table_cache_ = new TableCache(dbname_, &options_, table_cache_size);
 
   versions_ = new VersionSet(dbname_, &options_, table_cache_,
@@ -216,6 +216,12 @@ void DBImpl::MaybeIgnoreError(Status* s) const {
 }
 
 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<uint64_t> live = pending_outputs_;
   versions_->AddLiveFiles(&live);
@@ -386,7 +392,7 @@ Status DBImpl::RecoverLogFile(uint64_t log_number,
   reporter.info_log = options_.info_log;
   reporter.fname = fname.c_str();
   reporter.status = (options_.paranoid_checks ? &status : NULL);
-  // We intentially make log::Reader do checksumming even if
+  // We intentionally make log::Reader do checksumming even if
   // paranoid_checks==false so that corruptions cause entire commits
   // to be skipped instead of propagating bad information (like overly
   // large sequence numbers).
@@ -494,7 +500,7 @@ Status DBImpl::WriteLevel0Table(MemTable* mem, VersionEdit* edit,
   return s;
 }
 
-Status DBImpl::CompactMemTable() {
+void DBImpl::CompactMemTable() {
   mutex_.AssertHeld();
   assert(imm_ != NULL);
 
@@ -522,9 +528,9 @@ Status DBImpl::CompactMemTable() {
     imm_ = NULL;
     has_imm_.Release_Store(NULL);
     DeleteObsoleteFiles();
+  } else {
+    RecordBackgroundError(s);
   }
-
-  return s;
 }
 
 void DBImpl::CompactRange(const Slice* begin, const Slice* end) {
@@ -567,16 +573,18 @@ void DBImpl::TEST_CompactRange(int level, const Slice* begin,const Slice* end) {
   }
 
   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() {
@@ -595,12 +603,22 @@ Status DBImpl::TEST_CompactMemTable() {
   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()) {
@@ -618,30 +636,12 @@ void DBImpl::BGWork(void* db) {
 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;
@@ -652,11 +652,12 @@ void DBImpl::BackgroundCall() {
   bg_cv_.SignalAll();
 }
 
-Status DBImpl::BackgroundCompaction() {
+void DBImpl::BackgroundCompaction() {
   mutex_.AssertHeld();
 
   if (imm_ != NULL) {
-    return CompactMemTable();
+    CompactMemTable();
+    return;
   }
 
   Compaction* c;
@@ -690,6 +691,9 @@ Status DBImpl::BackgroundCompaction() {
     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<unsigned long long>(f->number),
@@ -700,6 +704,9 @@ Status DBImpl::BackgroundCompaction() {
   } else {
     CompactionState* compact = new CompactionState(c);
     status = DoCompactionWork(compact);
+    if (!status.ok()) {
+      RecordBackgroundError(status);
+    }
     CleanupCompaction(compact);
     c->ReleaseInputs();
     DeleteObsoleteFiles();
@@ -713,9 +720,6 @@ Status DBImpl::BackgroundCompaction() {
   } 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) {
@@ -731,7 +735,6 @@ Status DBImpl::BackgroundCompaction() {
     }
     manual_compaction_ = NULL;
   }
-  return status;
 }
 
 void DBImpl::CleanupCompaction(CompactionState* compact) {
@@ -1001,6 +1004,9 @@ Status DBImpl::DoCompactionWork(CompactionState* compact) {
   if (status.ok()) {
     status = InstallCompactionResults(compact);
   }
+  if (!status.ok()) {
+    RecordBackgroundError(status);
+  }
   VersionSet::LevelSummaryStorage tmp;
   Log(options_.info_log,
       "compacted to: %s", versions_->LevelSummary(&tmp));
@@ -1027,7 +1033,8 @@ static void CleanupIteratorState(void* arg1, void* arg2) {
 }  // namespace
 
 Iterator* DBImpl::NewInternalIterator(const ReadOptions& options,
-                                      SequenceNumber* latest_snapshot) {
+                                      SequenceNumber* latest_snapshot,
+                                      uint32_t* seed) {
   IterState* cleanup = new IterState;
   mutex_.Lock();
   *latest_snapshot = versions_->LastSequence();
@@ -1051,13 +1058,15 @@ Iterator* DBImpl::NewInternalIterator(const ReadOptions& options,
   cleanup->version = versions_->current();
   internal_iter->RegisterCleanup(CleanupIteratorState, cleanup, NULL);
 
+  *seed = ++seed_;
   mutex_.Unlock();
   return internal_iter;
 }
 
 Iterator* DBImpl::TEST_NewInternalIterator() {
   SequenceNumber ignored;
-  return NewInternalIterator(ReadOptions(), &ignored);
+  uint32_t ignored_seed;
+  return NewInternalIterator(ReadOptions(), &ignored, &ignored_seed);
 }
 
 int64_t DBImpl::TEST_MaxNextLevelOverlappingBytes() {
@@ -1114,12 +1123,21 @@ Status DBImpl::Get(const ReadOptions& options,
 
 Iterator* DBImpl::NewIterator(const ReadOptions& options) {
   SequenceNumber latest_snapshot;
-  Iterator* internal_iter = NewInternalIterator(options, &latest_snapshot);
+  uint32_t seed;
+  Iterator* iter = NewInternalIterator(options, &latest_snapshot, &seed);
   return NewDBIterator(
-      &dbname_, env_, user_comparator(), internal_iter,
+      this, user_comparator(), iter,
       (options.snapshot != NULL
        ? reinterpret_cast<const SnapshotImpl*>(options.snapshot)->number_
-       : latest_snapshot));
+       : latest_snapshot),
+      seed);
+}
+
+void DBImpl::RecordReadSample(Slice key) {
+  MutexLock l(&mutex_);
+  if (versions_->current()->RecordReadSample(key)) {
+    MaybeScheduleCompaction();
+  }
 }
 
 const Snapshot* DBImpl::GetSnapshot() {
@@ -1172,13 +1190,23 @@ Status DBImpl::Write(const WriteOptions& options, WriteBatch* my_batch) {
     {
       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();
 
@@ -1239,7 +1267,7 @@ WriteBatch* DBImpl::BuildBatchGroup(Writer** last_writer) {
         break;
       }
 
-      // Append to *reuslt
+      // Append to *result
       if (result == first->batch) {
         // Switch to temporary batch instead of disturbing caller's batch
         result = tmp_batch_;
index 3c8d711..cfc9981 100644 (file)
@@ -59,13 +59,19 @@ class DBImpl : public DB {
   // file at a level >= 1.
   int64_t TEST_MaxNextLevelOverlappingBytes();
 
+  // Record a sample of bytes read at the specified internal key.
+  // Samples are taken approximately once every config::kReadBytesPeriod
+  // bytes.
+  void RecordReadSample(Slice key);
+
  private:
   friend class DB;
   struct CompactionState;
   struct Writer;
 
   Iterator* NewInternalIterator(const ReadOptions&,
-                                SequenceNumber* latest_snapshot);
+                                SequenceNumber* latest_snapshot,
+                                uint32_t* seed);
 
   Status NewDB();
 
@@ -81,8 +87,8 @@ class DBImpl : public DB {
 
   // 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,
@@ -96,10 +102,12 @@ class DBImpl : public DB {
       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)
@@ -135,6 +143,7 @@ class DBImpl : public DB {
   WritableFile* logfile_;
   uint64_t logfile_number_;
   log::Writer* log_;
+  uint32_t seed_;                // For sampling.
 
   // Queue of writers.
   std::deque<Writer*> writers_;
@@ -163,7 +172,6 @@ class DBImpl : public DB {
 
   // 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".
index 87dca2d..3b2035e 100644 (file)
@@ -5,12 +5,14 @@
 #include "db/db_iter.h"
 
 #include "db/filename.h"
+#include "db/db_impl.h"
 #include "db/dbformat.h"
 #include "leveldb/env.h"
 #include "leveldb/iterator.h"
 #include "port/port.h"
 #include "util/logging.h"
 #include "util/mutexlock.h"
+#include "util/random.h"
 
 namespace leveldb {
 
@@ -46,15 +48,16 @@ class DBIter: public Iterator {
     kReverse
   };
 
-  DBIter(const std::string* dbname, Env* env,
-         const Comparator* cmp, Iterator* iter, SequenceNumber s)
-      : dbname_(dbname),
-        env_(env),
+  DBIter(DBImpl* db, const Comparator* cmp, Iterator* iter, SequenceNumber s,
+         uint32_t seed)
+      : db_(db),
         user_comparator_(cmp),
         iter_(iter),
         sequence_(s),
         direction_(kForward),
-        valid_(false) {
+        valid_(false),
+        rnd_(seed),
+        bytes_counter_(RandomPeriod()) {
   }
   virtual ~DBIter() {
     delete iter_;
@@ -100,8 +103,12 @@ class DBIter: public Iterator {
     }
   }
 
-  const std::string* const dbname_;
-  Env* const env_;
+  // Pick next gap with average value of config::kReadBytesPeriod.
+  ssize_t RandomPeriod() {
+    return rnd_.Uniform(2*config::kReadBytesPeriod);
+  }
+
+  DBImpl* db_;
   const Comparator* const user_comparator_;
   Iterator* const iter_;
   SequenceNumber const sequence_;
@@ -112,13 +119,23 @@ class DBIter: public Iterator {
   Direction direction_;
   bool valid_;
 
+  Random rnd_;
+  ssize_t bytes_counter_;
+
   // No copying allowed
   DBIter(const DBIter&);
   void operator=(const DBIter&);
 };
 
 inline bool DBIter::ParseKey(ParsedInternalKey* ikey) {
-  if (!ParseInternalKey(iter_->key(), ikey)) {
+  Slice k = iter_->key();
+  ssize_t n = k.size() + iter_->value().size();
+  bytes_counter_ -= n;
+  while (bytes_counter_ < 0) {
+    bytes_counter_ += RandomPeriod();
+    db_->RecordReadSample(k);
+  }
+  if (!ParseInternalKey(k, ikey)) {
     status_ = Status::Corruption("corrupted internal key in DBIter");
     return false;
   } else {
@@ -144,12 +161,13 @@ void DBIter::Next() {
       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) {
@@ -288,12 +306,12 @@ void DBIter::SeekToLast() {
 }  // anonymous namespace
 
 Iterator* NewDBIterator(
-    const std::string* dbname,
-    Env* env,
+    DBImpl* db,
     const Comparator* user_key_comparator,
     Iterator* internal_iter,
-    const SequenceNumber& sequence) {
-  return new DBIter(dbname, env, user_key_comparator, internal_iter, sequence);
+    SequenceNumber sequence,
+    uint32_t seed) {
+  return new DBIter(db, user_key_comparator, internal_iter, sequence, seed);
 }
 
 }  // namespace leveldb
index d9e1b17..04927e9 100644 (file)
 
 namespace leveldb {
 
+class DBImpl;
+
 // Return a new iterator that converts internal keys (yielded by
 // "*internal_iter") that were live at the specified "sequence" number
 // into appropriate user keys.
 extern Iterator* NewDBIterator(
-    const std::string* dbname,
-    Env* env,
+    DBImpl* db,
     const Comparator* user_key_comparator,
     Iterator* internal_iter,
-    const SequenceNumber& sequence);
+    SequenceNumber sequence,
+    uint32_t seed);
 
 }  // namespace leveldb
 
index 49aae04..0fed913 100644 (file)
@@ -57,8 +57,11 @@ void DelayMilliseconds(int millis) {
 // 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 @@ class SpecialEnv : public EnvWrapper {
   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 @@ class SpecialEnv : public EnvWrapper {
   }
 
   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 @@ class SpecialEnv : public EnvWrapper {
       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 @@ class SpecialEnv : public EnvWrapper {
 
     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 @@ class SpecialEnv : public EnvWrapper {
     }
     return s;
   }
-
-  virtual void SleepForMicroseconds(int micros) {
-    sleep_counter_.Increment();
-    sleep_time_counter_.IncrementBy(micros);
-  }
-
 };
 
 class DBTest {
@@ -322,7 +321,7 @@ class DBTest {
     }
 
     // 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 @@ class DBTest {
     }
     return false;
   }
+
+  // Returns number of files renamed.
+  int RenameLDBToSST() {
+    std::vector<std::string> 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 @@ TEST(DBTest, GetFromImmutableLayer) {
     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());
 }
 
@@ -609,7 +626,7 @@ TEST(DBTest, GetEncountersEmptyLevel) {
     //   * sstable B in level 2
     // Then do enough Get() calls to arrange for an automatic compaction
     // of sstable A.  A bug would cause the compaction to be marked as
-    // occuring at level 1 (instead of the correct level 0).
+    // occurring at level 1 (instead of the correct level 0).
 
     // Step 1: First place sstables in levels 0 and 2
     int compaction_count = 0;
@@ -1516,41 +1533,13 @@ TEST(DBTest, NoSpace) {
   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 @@ TEST(DBTest, NonWritableFileSystem) {
   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 @@ TEST(DBTest, MissingSSTFile) {
       << 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 @@ TEST(DBTest, BloomFilter) {
   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 @@ TEST(DBTest, BloomFilter) {
   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 @@ static void MTThreadBody(void* arg) {
         ASSERT_EQ(k, key);
         ASSERT_GE(w, 0);
         ASSERT_LT(w, kNumThreads);
-        ASSERT_LE(c, reinterpret_cast<uintptr_t>(
+        ASSERT_LE(static_cast<uintptr_t>(c), reinterpret_cast<uintptr_t>(
             t->state->counter[w].Acquire_Load()));
       }
     }
index f7f64da..ea897b1 100644 (file)
@@ -2,8 +2,8 @@
 // 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.
 
-#ifndef STORAGE_LEVELDB_DB_FORMAT_H_
-#define STORAGE_LEVELDB_DB_FORMAT_H_
+#ifndef STORAGE_LEVELDB_DB_DBFORMAT_H_
+#define STORAGE_LEVELDB_DB_DBFORMAT_H_
 
 #include <stdio.h>
 #include "leveldb/comparator.h"
@@ -38,6 +38,9 @@ static const int kL0_StopWritesTrigger = 12;
 // space if the same key space is being repeatedly overwritten.
 static const int kMaxMemCompactLevel = 2;
 
+// Approximate gap in bytes between samples of data read during iteration.
+static const int kReadBytesPeriod = 1048576;
+
 }  // namespace config
 
 class InternalKey;
@@ -224,4 +227,4 @@ inline LookupKey::~LookupKey() {
 
 }  // namespace leveldb
 
-#endif  // STORAGE_LEVELDB_DB_FORMAT_H_
+#endif  // STORAGE_LEVELDB_DB_DBFORMAT_H_
diff --git a/src/leveldb/db/dumpfile.cc b/src/leveldb/db/dumpfile.cc
new file mode 100644 (file)
index 0000000..61c47c2
--- /dev/null
@@ -0,0 +1,225 @@
+// Copyright (c) 2012 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.
+
+#include <stdio.h>
+#include "db/dbformat.h"
+#include "db/filename.h"
+#include "db/log_reader.h"
+#include "db/version_edit.h"
+#include "db/write_batch_internal.h"
+#include "leveldb/env.h"
+#include "leveldb/iterator.h"
+#include "leveldb/options.h"
+#include "leveldb/status.h"
+#include "leveldb/table.h"
+#include "leveldb/write_batch.h"
+#include "util/logging.h"
+
+namespace leveldb {
+
+namespace {
+
+bool GuessType(const std::string& fname, FileType* type) {
+  size_t pos = fname.rfind('/');
+  std::string basename;
+  if (pos == std::string::npos) {
+    basename = fname;
+  } else {
+    basename = std::string(fname.data() + pos + 1, fname.size() - pos - 1);
+  }
+  uint64_t ignored;
+  return ParseFileName(basename, &ignored, type);
+}
+
+// Notified when log reader encounters corruption.
+class CorruptionReporter : public log::Reader::Reporter {
+ public:
+  WritableFile* dst_;
+  virtual void Corruption(size_t bytes, const Status& status) {
+    std::string r = "corruption: ";
+    AppendNumberTo(&r, bytes);
+    r += " bytes; ";
+    r += status.ToString();
+    r.push_back('\n');
+    dst_->Append(r);
+  }
+};
+
+// Print contents of a log file. (*func)() is called on every record.
+Status PrintLogContents(Env* env, const std::string& fname,
+                        void (*func)(uint64_t, Slice, WritableFile*),
+                        WritableFile* dst) {
+  SequentialFile* file;
+  Status s = env->NewSequentialFile(fname, &file);
+  if (!s.ok()) {
+    return s;
+  }
+  CorruptionReporter reporter;
+  reporter.dst_ = dst;
+  log::Reader reader(file, &reporter, true, 0);
+  Slice record;
+  std::string scratch;
+  while (reader.ReadRecord(&record, &scratch)) {
+    (*func)(reader.LastRecordOffset(), record, dst);
+  }
+  delete file;
+  return Status::OK();
+}
+
+// Called on every item found in a WriteBatch.
+class WriteBatchItemPrinter : public WriteBatch::Handler {
+ public:
+  WritableFile* dst_;
+  virtual void Put(const Slice& key, const Slice& value) {
+    std::string r = "  put '";
+    AppendEscapedStringTo(&r, key);
+    r += "' '";
+    AppendEscapedStringTo(&r, value);
+    r += "'\n";
+    dst_->Append(r);
+  }
+  virtual void Delete(const Slice& key) {
+    std::string r = "  del '";
+    AppendEscapedStringTo(&r, key);
+    r += "'\n";
+    dst_->Append(r);
+  }
+};
+
+
+// Called on every log record (each one of which is a WriteBatch)
+// found in a kLogFile.
+static void WriteBatchPrinter(uint64_t pos, Slice record, WritableFile* dst) {
+  std::string r = "--- offset ";
+  AppendNumberTo(&r, pos);
+  r += "; ";
+  if (record.size() < 12) {
+    r += "log record length ";
+    AppendNumberTo(&r, record.size());
+    r += " is too small\n";
+    dst->Append(r);
+    return;
+  }
+  WriteBatch batch;
+  WriteBatchInternal::SetContents(&batch, record);
+  r += "sequence ";
+  AppendNumberTo(&r, WriteBatchInternal::Sequence(&batch));
+  r.push_back('\n');
+  dst->Append(r);
+  WriteBatchItemPrinter batch_item_printer;
+  batch_item_printer.dst_ = dst;
+  Status s = batch.Iterate(&batch_item_printer);
+  if (!s.ok()) {
+    dst->Append("  error: " + s.ToString() + "\n");
+  }
+}
+
+Status DumpLog(Env* env, const std::string& fname, WritableFile* dst) {
+  return PrintLogContents(env, fname, WriteBatchPrinter, dst);
+}
+
+// Called on every log record (each one of which is a WriteBatch)
+// found in a kDescriptorFile.
+static void VersionEditPrinter(uint64_t pos, Slice record, WritableFile* dst) {
+  std::string r = "--- offset ";
+  AppendNumberTo(&r, pos);
+  r += "; ";
+  VersionEdit edit;
+  Status s = edit.DecodeFrom(record);
+  if (!s.ok()) {
+    r += s.ToString();
+    r.push_back('\n');
+  } else {
+    r += edit.DebugString();
+  }
+  dst->Append(r);
+}
+
+Status DumpDescriptor(Env* env, const std::string& fname, WritableFile* dst) {
+  return PrintLogContents(env, fname, VersionEditPrinter, dst);
+}
+
+Status DumpTable(Env* env, const std::string& fname, WritableFile* dst) {
+  uint64_t file_size;
+  RandomAccessFile* file = NULL;
+  Table* table = NULL;
+  Status s = env->GetFileSize(fname, &file_size);
+  if (s.ok()) {
+    s = env->NewRandomAccessFile(fname, &file);
+  }
+  if (s.ok()) {
+    // We use the default comparator, which may or may not match the
+    // comparator used in this database. However this should not cause
+    // problems since we only use Table operations that do not require
+    // any comparisons.  In particular, we do not call Seek or Prev.
+    s = Table::Open(Options(), file, file_size, &table);
+  }
+  if (!s.ok()) {
+    delete table;
+    delete file;
+    return s;
+  }
+
+  ReadOptions ro;
+  ro.fill_cache = false;
+  Iterator* iter = table->NewIterator(ro);
+  std::string r;
+  for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
+    r.clear();
+    ParsedInternalKey key;
+    if (!ParseInternalKey(iter->key(), &key)) {
+      r = "badkey '";
+      AppendEscapedStringTo(&r, iter->key());
+      r += "' => '";
+      AppendEscapedStringTo(&r, iter->value());
+      r += "'\n";
+      dst->Append(r);
+    } else {
+      r = "'";
+      AppendEscapedStringTo(&r, key.user_key);
+      r += "' @ ";
+      AppendNumberTo(&r, key.sequence);
+      r += " : ";
+      if (key.type == kTypeDeletion) {
+        r += "del";
+      } else if (key.type == kTypeValue) {
+        r += "val";
+      } else {
+        AppendNumberTo(&r, key.type);
+      }
+      r += " => '";
+      AppendEscapedStringTo(&r, iter->value());
+      r += "'\n";
+      dst->Append(r);
+    }
+  }
+  s = iter->status();
+  if (!s.ok()) {
+    dst->Append("iterator error: " + s.ToString() + "\n");
+  }
+
+  delete iter;
+  delete table;
+  delete file;
+  return Status::OK();
+}
+
+}  // namespace
+
+Status DumpFile(Env* env, const std::string& fname, WritableFile* dst) {
+  FileType ftype;
+  if (!GuessType(fname, &ftype)) {
+    return Status::InvalidArgument(fname + ": unknown file type");
+  }
+  switch (ftype) {
+    case kLogFile:         return DumpLog(env, fname, dst);
+    case kDescriptorFile:  return DumpDescriptor(env, fname, dst);
+    case kTableFile:       return DumpTable(env, fname, dst);
+    default:
+      break;
+  }
+  return Status::InvalidArgument(fname + ": not a dump-able file type");
+}
+
+}  // namespace leveldb
index 3c4d49f..348a19a 100644 (file)
@@ -28,12 +28,21 @@ std::string LogFileName(const std::string& name, uint64_t number) {
   assert(number > 0);
   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 +80,7 @@ std::string OldInfoLogFileName(const std::string& dbname) {
 //    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 +115,7 @@ bool ParseFileName(const std::string& fname,
     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;
index d5d09b1..87a7526 100644 (file)
@@ -37,6 +37,11 @@ extern std::string LogFileName(const std::string& dbname, uint64_t number);
 // "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".
index 5a26da4..a32556d 100644 (file)
@@ -27,6 +27,7 @@ TEST(FileNameTest, Parse) {
     { "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 },
index 995d761..9f4b7dd 100644 (file)
 // found in the LICENSE file. See the AUTHORS file for names of contributors.
 
 #include <stdio.h>
-#include "db/dbformat.h"
-#include "db/filename.h"
-#include "db/log_reader.h"
-#include "db/version_edit.h"
-#include "db/write_batch_internal.h"
+#include "leveldb/dumpfile.h"
 #include "leveldb/env.h"
-#include "leveldb/iterator.h"
-#include "leveldb/options.h"
 #include "leveldb/status.h"
-#include "leveldb/table.h"
-#include "leveldb/write_batch.h"
-#include "util/logging.h"
 
 namespace leveldb {
-
 namespace {
 
-bool GuessType(const std::string& fname, FileType* type) {
-  size_t pos = fname.rfind('/');
-  std::string basename;
-  if (pos == std::string::npos) {
-    basename = fname;
-  } else {
-    basename = std::string(fname.data() + pos + 1, fname.size() - pos - 1);
-  }
-  uint64_t ignored;
-  return ParseFileName(basename, &ignored, type);
-}
-
-// Notified when log reader encounters corruption.
-class CorruptionReporter : public log::Reader::Reporter {
- public:
-  virtual void Corruption(size_t bytes, const Status& status) {
-    printf("corruption: %d bytes; %s\n",
-            static_cast<int>(bytes),
-            status.ToString().c_str());
-  }
-};
-
-// Print contents of a log file. (*func)() is called on every record.
-bool PrintLogContents(Env* env, const std::string& fname,
-                      void (*func)(Slice)) {
-  SequentialFile* file;
-  Status s = env->NewSequentialFile(fname, &file);
-  if (!s.ok()) {
-    fprintf(stderr, "%s\n", s.ToString().c_str());
-    return false;
-  }
-  CorruptionReporter reporter;
-  log::Reader reader(file, &reporter, true, 0);
-  Slice record;
-  std::string scratch;
-  while (reader.ReadRecord(&record, &scratch)) {
-    printf("--- offset %llu; ",
-           static_cast<unsigned long long>(reader.LastRecordOffset()));
-    (*func)(record);
-  }
-  delete file;
-  return true;
-}
-
-// Called on every item found in a WriteBatch.
-class WriteBatchItemPrinter : public WriteBatch::Handler {
+class StdoutPrinter : public WritableFile {
  public:
-  uint64_t offset_;
-  uint64_t sequence_;
-
-  virtual void Put(const Slice& key, const Slice& value) {
-    printf("  put '%s' '%s'\n",
-           EscapeString(key).c_str(),
-           EscapeString(value).c_str());
-  }
-  virtual void Delete(const Slice& key) {
-    printf("  del '%s'\n",
-           EscapeString(key).c_str());
+  virtual Status Append(const Slice& data) {
+    fwrite(data.data(), 1, data.size(), stdout);
+    return Status::OK();
   }
+  virtual Status Close() { return Status::OK(); }
+  virtual Status Flush() { return Status::OK(); }
+  virtual Status Sync() { return Status::OK(); }
 };
 
-
-// Called on every log record (each one of which is a WriteBatch)
-// found in a kLogFile.
-static void WriteBatchPrinter(Slice record) {
-  if (record.size() < 12) {
-    printf("log record length %d is too small\n",
-           static_cast<int>(record.size()));
-    return;
-  }
-  WriteBatch batch;
-  WriteBatchInternal::SetContents(&batch, record);
-  printf("sequence %llu\n",
-         static_cast<unsigned long long>(WriteBatchInternal::Sequence(&batch)));
-  WriteBatchItemPrinter batch_item_printer;
-  Status s = batch.Iterate(&batch_item_printer);
-  if (!s.ok()) {
-    printf("  error: %s\n", s.ToString().c_str());
-  }
-}
-
-bool DumpLog(Env* env, const std::string& fname) {
-  return PrintLogContents(env, fname, WriteBatchPrinter);
-}
-
-// Called on every log record (each one of which is a WriteBatch)
-// found in a kDescriptorFile.
-static void VersionEditPrinter(Slice record) {
-  VersionEdit edit;
-  Status s = edit.DecodeFrom(record);
-  if (!s.ok()) {
-    printf("%s\n", s.ToString().c_str());
-    return;
-  }
-  printf("%s", edit.DebugString().c_str());
-}
-
-bool DumpDescriptor(Env* env, const std::string& fname) {
-  return PrintLogContents(env, fname, VersionEditPrinter);
-}
-
-bool DumpTable(Env* env, const std::string& fname) {
-  uint64_t file_size;
-  RandomAccessFile* file = NULL;
-  Table* table = NULL;
-  Status s = env->GetFileSize(fname, &file_size);
-  if (s.ok()) {
-    s = env->NewRandomAccessFile(fname, &file);
-  }
-  if (s.ok()) {
-    // We use the default comparator, which may or may not match the
-    // comparator used in this database. However this should not cause
-    // problems since we only use Table operations that do not require
-    // any comparisons.  In particular, we do not call Seek or Prev.
-    s = Table::Open(Options(), file, file_size, &table);
-  }
-  if (!s.ok()) {
-    fprintf(stderr, "%s\n", s.ToString().c_str());
-    delete table;
-    delete file;
-    return false;
-  }
-
-  ReadOptions ro;
-  ro.fill_cache = false;
-  Iterator* iter = table->NewIterator(ro);
-  for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
-    ParsedInternalKey key;
-    if (!ParseInternalKey(iter->key(), &key)) {
-      printf("badkey '%s' => '%s'\n",
-             EscapeString(iter->key()).c_str(),
-             EscapeString(iter->value()).c_str());
-    } else {
-      char kbuf[20];
-      const char* type;
-      if (key.type == kTypeDeletion) {
-        type = "del";
-      } else if (key.type == kTypeValue) {
-        type = "val";
-      } else {
-        snprintf(kbuf, sizeof(kbuf), "%d", static_cast<int>(key.type));
-        type = kbuf;
-      }
-      printf("'%s' @ %8llu : %s => '%s'\n",
-             EscapeString(key.user_key).c_str(),
-             static_cast<unsigned long long>(key.sequence),
-             type,
-             EscapeString(iter->value()).c_str());
-    }
-  }
-  s = iter->status();
-  if (!s.ok()) {
-    printf("iterator error: %s\n", s.ToString().c_str());
-  }
-
-  delete iter;
-  delete table;
-  delete file;
-  return true;
-}
-
-bool DumpFile(Env* env, const std::string& fname) {
-  FileType ftype;
-  if (!GuessType(fname, &ftype)) {
-    fprintf(stderr, "%s: unknown file type\n", fname.c_str());
-    return false;
-  }
-  switch (ftype) {
-    case kLogFile:         return DumpLog(env, fname);
-    case kDescriptorFile:  return DumpDescriptor(env, fname);
-    case kTableFile:       return DumpTable(env, fname);
-
-    default: {
-      fprintf(stderr, "%s: not a dump-able file type\n", fname.c_str());
-      break;
-    }
-  }
-  return false;
-}
-
 bool HandleDumpCommand(Env* env, char** files, int num) {
+  StdoutPrinter printer;
   bool ok = true;
   for (int i = 0; i < num; i++) {
-    ok &= DumpFile(env, files[i]);
+    Status s = DumpFile(env, files[i], &printer);
+    if (!s.ok()) {
+      fprintf(stderr, "%s\n", s.ToString().c_str());
+      ok = false;
+    }
   }
   return ok;
 }
 
-}
+}  // namespace
 }  // namespace leveldb
 
 static void Usage() {
index 2690cb9..a8c06ef 100644 (file)
@@ -26,8 +26,8 @@ static const int kMaxRecordType = kLastType;
 
 static const int kBlockSize = 32768;
 
-// Header is checksum (4 bytes), type (1 byte), length (2 bytes).
-static const int kHeaderSize = 4 + 1 + 2;
+// Header is checksum (4 bytes), length (2 bytes), type (1 byte).
+static const int kHeaderSize = 4 + 2 + 1;
 
 }  // namespace log
 }  // namespace leveldb
index b35f115..e44b66c 100644 (file)
@@ -133,7 +133,9 @@ bool Reader::ReadRecord(Slice* record, std::string* scratch) {
 
       case kEof:
         if (in_fragmented_record) {
-          ReportCorruption(scratch->size(), "partial record without end(3)");
+          // This can be caused by the writer dying immediately after
+          // writing a physical record but before completing the next; don't
+          // treat it as a corruption, just ignore the entire logical record.
           scratch->clear();
         }
         return false;
@@ -165,14 +167,14 @@ uint64_t Reader::LastRecordOffset() {
   return last_record_offset_;
 }
 
-void Reader::ReportCorruption(size_t bytes, const char* reason) {
+void Reader::ReportCorruption(uint64_t bytes, const char* reason) {
   ReportDrop(bytes, Status::Corruption(reason));
 }
 
-void Reader::ReportDrop(size_t bytes, const Status& reason) {
+void Reader::ReportDrop(uint64_t bytes, const Status& reason) {
   if (reporter_ != NULL &&
       end_of_buffer_offset_ - buffer_.size() - bytes >= initial_offset_) {
-    reporter_->Corruption(bytes, reason);
+    reporter_->Corruption(static_cast<size_t>(bytes), reason);
   }
 }
 
@@ -193,13 +195,12 @@ unsigned int Reader::ReadPhysicalRecord(Slice* result) {
           eof_ = true;
         }
         continue;
-      } else if (buffer_.size() == 0) {
-        // End of file
-        return kEof;
       } else {
-        size_t drop_size = buffer_.size();
+        // Note that if buffer_ is non-empty, we have a truncated header at the
+        // end of the file, which can be caused by the writer crashing in the
+        // middle of writing the header. Instead of considering this an error,
+        // just report EOF.
         buffer_.clear();
-        ReportCorruption(drop_size, "truncated record at end of file");
         return kEof;
       }
     }
@@ -213,8 +214,14 @@ unsigned int Reader::ReadPhysicalRecord(Slice* result) {
     if (kHeaderSize + length > buffer_.size()) {
       size_t drop_size = buffer_.size();
       buffer_.clear();
-      ReportCorruption(drop_size, "bad record length");
-      return kBadRecord;
+      if (!eof_) {
+        ReportCorruption(drop_size, "bad record length");
+        return kBadRecord;
+      }
+      // If the end of the file has been reached without reading |length| bytes
+      // of payload, assume the writer died in the middle of writing the record.
+      // Don't report a corruption.
+      return kEof;
     }
 
     if (type == kZeroType && length == 0) {
index 82d4bee..6aff791 100644 (file)
@@ -94,8 +94,8 @@ class Reader {
 
   // Reports dropped bytes to the reporter.
   // buffer_ must be updated to remove the dropped bytes prior to invocation.
-  void ReportCorruption(size_t bytes, const char* reason);
-  void ReportDrop(size_t bytes, const Status& reason);
+  void ReportCorruption(uint64_t bytes, const char* reason);
+  void ReportDrop(uint64_t bytes, const Status& reason);
 
   // No copying allowed
   Reader(const Reader&);
index 4c5cf87..dcf0562 100644 (file)
@@ -351,20 +351,32 @@ TEST(LogTest, BadRecordType) {
   ASSERT_EQ("OK", MatchError("unknown record type"));
 }
 
-TEST(LogTest, TruncatedTrailingRecord) {
+TEST(LogTest, TruncatedTrailingRecordIsIgnored) {
   Write("foo");
   ShrinkSize(4);   // Drop all payload as well as a header byte
   ASSERT_EQ("EOF", Read());
-  ASSERT_EQ(kHeaderSize - 1, DroppedBytes());
-  ASSERT_EQ("OK", MatchError("truncated record at end of file"));
+  // Truncated last record is ignored, not treated as an error.
+  ASSERT_EQ(0, DroppedBytes());
+  ASSERT_EQ("", ReportMessage());
 }
 
 TEST(LogTest, BadLength) {
+  const int kPayloadSize = kBlockSize - kHeaderSize;
+  Write(BigString("bar", kPayloadSize));
+  Write("foo");
+  // Least significant size byte is stored in header[4].
+  IncrementByte(4, 1);
+  ASSERT_EQ("foo", Read());
+  ASSERT_EQ(kBlockSize, DroppedBytes());
+  ASSERT_EQ("OK", MatchError("bad record length"));
+}
+
+TEST(LogTest, BadLengthAtEndIsIgnored) {
   Write("foo");
   ShrinkSize(1);
   ASSERT_EQ("EOF", Read());
-  ASSERT_EQ(kHeaderSize + 2, DroppedBytes());
-  ASSERT_EQ("OK", MatchError("bad record length"));
+  ASSERT_EQ(0, DroppedBytes());
+  ASSERT_EQ("", ReportMessage());
 }
 
 TEST(LogTest, ChecksumMismatch) {
@@ -415,6 +427,24 @@ TEST(LogTest, UnexpectedFirstType) {
   ASSERT_EQ("OK", MatchError("partial record without end"));
 }
 
+TEST(LogTest, MissingLastIsIgnored) {
+  Write(BigString("bar", kBlockSize));
+  // Remove the LAST block, including header.
+  ShrinkSize(14);
+  ASSERT_EQ("EOF", Read());
+  ASSERT_EQ("", ReportMessage());
+  ASSERT_EQ(0, DroppedBytes());
+}
+
+TEST(LogTest, PartialLastIsIgnored) {
+  Write(BigString("bar", kBlockSize));
+  // Cause a bad record length in the LAST block.
+  ShrinkSize(1);
+  ASSERT_EQ("EOF", Read());
+  ASSERT_EQ("", ReportMessage());
+  ASSERT_EQ(0, DroppedBytes());
+}
+
 TEST(LogTest, ErrorJoinsRecords) {
   // Consider two fragmented records:
   //    first(R1) last(R1) first(R2) last(R2)
@@ -433,7 +463,7 @@ TEST(LogTest, ErrorJoinsRecords) {
 
   ASSERT_EQ("correct", Read());
   ASSERT_EQ("EOF", Read());
-  const int dropped = DroppedBytes();
+  const size_t dropped = DroppedBytes();
   ASSERT_LE(dropped, 2*kBlockSize + 100);
   ASSERT_GE(dropped, 2*kBlockSize);
 }
index 022d52f..4cd4bb0 100644 (file)
@@ -186,7 +186,7 @@ class Repairer {
     reporter.env = env_;
     reporter.info_log = options_.info_log;
     reporter.lognum = log;
-    // We intentially make log::Reader do checksumming so that
+    // We intentionally make log::Reader do checksumming so that
     // corruptions cause entire commits to be skipped instead of
     // propagating bad information (like overly large sequence
     // numbers).
@@ -242,62 +242,134 @@ class Repairer {
   }
 
   void ExtractMetaData() {
-    std::vector<TableInfo> 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;
-        }
+    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);
-        }
-        t->meta.largest.DecodeFrom(key);
-        if (parsed.sequence > t->max_sequence) {
-          t->max_sequence = parsed.sequence;
-        }
+      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() {
index af85be6..ed8b092 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef STORAGE_LEVELDB_DB_SKIPLIST_H_
+#define STORAGE_LEVELDB_DB_SKIPLIST_H_
+
 // Copyright (c) 2011 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.
@@ -377,3 +380,5 @@ bool SkipList<Key,Comparator>::Contains(const Key& key) const {
 }
 
 }  // namespace leveldb
+
+#endif  // STORAGE_LEVELDB_DB_SKIPLIST_H_
index 497db27..e3d82cd 100644 (file)
@@ -54,6 +54,12 @@ Status TableCache::FindTable(uint64_t file_number, uint64_t file_size,
     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);
     }
index 4fd1dde..aa83df5 100644 (file)
@@ -54,20 +54,6 @@ static int64_t TotalFileSize(const std::vector<FileMetaData*>& files) {
   return sum;
 }
 
-namespace {
-std::string IntSetToString(const std::set<uint64_t>& s) {
-  std::string result = "{";
-  for (std::set<uint64_t>::const_iterator it = s.begin();
-       it != s.end();
-       ++it) {
-    result += (result.size() > 1) ? "," : "";
-    result += NumberToString(*it);
-  }
-  result += "}";
-  return result;
-}
-}  // namespace
-
 Version::~Version() {
   assert(refs_ == 0);
 
@@ -289,6 +275,51 @@ static bool NewestFirst(FileMetaData* a, FileMetaData* b) {
   return a->number > b->number;
 }
 
+void Version::ForEachOverlapping(Slice user_key, Slice internal_key,
+                                 void* arg,
+                                 bool (*func)(void*, int, FileMetaData*)) {
+  // TODO(sanjay): Change Version::Get() to use this function.
+  const Comparator* ucmp = vset_->icmp_.user_comparator();
+
+  // Search level-0 in order from newest to oldest.
+  std::vector<FileMetaData*> tmp;
+  tmp.reserve(files_[0].size());
+  for (uint32_t i = 0; i < files_[0].size(); i++) {
+    FileMetaData* f = files_[0][i];
+    if (ucmp->Compare(user_key, f->smallest.user_key()) >= 0 &&
+        ucmp->Compare(user_key, f->largest.user_key()) <= 0) {
+      tmp.push_back(f);
+    }
+  }
+  if (!tmp.empty()) {
+    std::sort(tmp.begin(), tmp.end(), NewestFirst);
+    for (uint32_t i = 0; i < tmp.size(); i++) {
+      if (!(*func)(arg, 0, tmp[i])) {
+        return;
+      }
+    }
+  }
+
+  // Search other levels.
+  for (int level = 1; level < config::kNumLevels; level++) {
+    size_t num_files = files_[level].size();
+    if (num_files == 0) continue;
+
+    // Binary search to find earliest index whose largest key >= internal_key.
+    uint32_t index = FindFile(vset_->icmp_, files_[level], internal_key);
+    if (index < num_files) {
+      FileMetaData* f = files_[level][index];
+      if (ucmp->Compare(user_key, f->smallest.user_key()) < 0) {
+        // All of "f" is past any data for user_key
+      } else {
+        if (!(*func)(arg, level, f)) {
+          return;
+        }
+      }
+    }
+  }
+}
+
 Status Version::Get(const ReadOptions& options,
                     const LookupKey& k,
                     std::string* value,
@@ -401,6 +432,44 @@ bool Version::UpdateStats(const GetStats& stats) {
   return false;
 }
 
+bool Version::RecordReadSample(Slice internal_key) {
+  ParsedInternalKey ikey;
+  if (!ParseInternalKey(internal_key, &ikey)) {
+    return false;
+  }
+
+  struct State {
+    GetStats stats;  // Holds first matching file
+    int matches;
+
+    static bool Match(void* arg, int level, FileMetaData* f) {
+      State* state = reinterpret_cast<State*>(arg);
+      state->matches++;
+      if (state->matches == 1) {
+        // Remember first match.
+        state->stats.seek_file = f;
+        state->stats.seek_file_level = level;
+      }
+      // We can stop iterating once we have a second match.
+      return state->matches < 2;
+    }
+  };
+
+  State state;
+  state.matches = 0;
+  ForEachOverlapping(ikey.user_key, internal_key, &state, &State::Match);
+
+  // Must have at least two matches since we want to merge across
+  // files. But what if we have a single file that contains many
+  // overwrites and deletions?  Should we have another mechanism for
+  // finding such files?
+  if (state.matches >= 2) {
+    // 1MB cost is about 1 seek (see comment in Builder::Apply).
+    return UpdateStats(state.stats);
+  }
+  return false;
+}
+
 void Version::Ref() {
   ++refs_;
 }
@@ -435,10 +504,13 @@ int Version::PickLevelForMemTableOutput(
       if (OverlapInLevel(level + 1, &smallest_user_key, &largest_user_key)) {
         break;
       }
-      GetOverlappingInputs(level + 2, &start, &limit, &overlaps);
-      const int64_t sum = TotalFileSize(overlaps);
-      if (sum > kMaxGrandParentOverlapBytes) {
-        break;
+      if (level + 2 < config::kNumLevels) {
+        // Check that file does not overlap too many grandparent bytes.
+        GetOverlappingInputs(level + 2, &start, &limit, &overlaps);
+        const int64_t sum = TotalFileSize(overlaps);
+        if (sum > kMaxGrandParentOverlapBytes) {
+          break;
+        }
       }
       level++;
     }
@@ -452,6 +524,8 @@ void Version::GetOverlappingInputs(
     const InternalKey* begin,
     const InternalKey* end,
     std::vector<FileMetaData*>* inputs) {
+  assert(level >= 0);
+  assert(level < config::kNumLevels);
   inputs->clear();
   Slice user_begin, user_end;
   if (begin != NULL) {
@@ -788,12 +862,6 @@ Status VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu) {
       }
       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();
-        }
       }
     }
 
@@ -801,8 +869,6 @@ Status VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu) {
     // 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();
@@ -1036,31 +1102,6 @@ const char* VersionSet::LevelSummary(LevelSummaryStorage* scratch) const {
   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++) {
index 9d084fd..8dc14b8 100644 (file)
@@ -78,6 +78,12 @@ class Version {
   // REQUIRES: lock is held
   bool UpdateStats(const GetStats& stats);
 
+  // Record a sample of bytes read at the specified internal key.
+  // Samples are taken approximately once every config::kReadBytesPeriod
+  // bytes.  Returns true if a new compaction may need to be triggered.
+  // REQUIRES: lock is held
+  bool RecordReadSample(Slice key);
+
   // Reference count management (so Versions do not disappear out from
   // under live iterators)
   void Ref();
@@ -114,6 +120,15 @@ class Version {
   class LevelFileNumIterator;
   Iterator* NewConcatenatingIterator(const ReadOptions&, int level) const;
 
+  // Call func(arg, level, f) for every file that overlaps user_key in
+  // order from newest to oldest.  If an invocation of func returns
+  // false, makes no more calls.
+  //
+  // REQUIRES: user portion of internal_key == user_key.
+  void ForEachOverlapping(Slice user_key, Slice internal_key,
+                          void* arg,
+                          bool (*func)(void*, int, FileMetaData*));
+
   VersionSet* vset_;            // VersionSet to which this Version belongs
   Version* next_;               // Next version in linked list
   Version* prev_;               // Previous version in linked list
@@ -277,8 +292,6 @@ class VersionSet {
 
   void AppendVersion(Version* v);
 
-  bool ManifestContains(const std::string& record) const;
-
   Env* const env_;
   const std::string dbname_;
   const Options* const options_;
index 4423a7f..310a3c8 100644 (file)
@@ -21,10 +21,10 @@ class WriteBatchInternal {
   // Set the count for the number of entries in the batch.
   static void SetCount(WriteBatch* batch, int n);
 
-  // Return the seqeunce number for the start of this batch.
+  // Return the sequence number for the start of this batch.
   static SequenceNumber Sequence(const WriteBatch* batch);
 
-  // Store the specified number as the seqeunce number for the start of
+  // Store the specified number as the sequence number for the start of
   // this batch.
   static void SetSequence(WriteBatch* batch, SequenceNumber seq);
 
index ed86f03..4ca381f 100644 (file)
@@ -338,7 +338,7 @@ class Benchmark {
       bool write_sync = false;
       if (name == Slice("fillseq")) {
         Write(write_sync, SEQUENTIAL, FRESH, num_, FLAGS_value_size, 1);
-        
+        DBSynchronize(db_);
       } else if (name == Slice("fillrandom")) {
         Write(write_sync, RANDOM, FRESH, num_, FLAGS_value_size, 1);
         DBSynchronize(db_);
index e870795..6a468be 100644 (file)
@@ -11,7 +11,7 @@
 
 The implementation of leveldb is similar in spirit to the
 representation of a single
-<a href="http://labs.google.com/papers/bigtable.html">
+<a href="http://research.google.com/archive/bigtable.html">
 Bigtable tablet (section 5.3)</a>.
 However the organization of the files that make up the representation
 is somewhat different and is explained below.
@@ -111,7 +111,7 @@ A compaction merges the contents of the picked files to produce a
 sequence of level-(L+1) files.  We switch to producing a new
 level-(L+1) file after the current output file has reached the target
 file size (2MB).  We also switch to a new output file when the key
-range of the current output file has grown enough to overlap more then
+range of the current output file has grown enough to overlap more than
 ten level-(L+2) files.  This last rule ensures that a later compaction
 of a level-(L+1) file will not pick up too much data from level-(L+2).
 
@@ -151,7 +151,7 @@ compaction cost will be approximately 0.5 second.
 If we throttle the background writing to something small, say 10% of
 the full 100MB/s speed, a compaction may take up to 5 seconds.  If the
 user is writing at 10MB/s, we might build up lots of level-0 files
-(~50 to hold the 5*10MB).  This may signficantly increase the cost of
+(~50 to hold the 5*10MB).  This may significantly increase the cost of
 reads due to the overhead of merging more files together on every
 read.
 
index 5228f62..4cca5ef 100644 (file)
@@ -11,7 +11,7 @@ Each block consists of a sequence of records:
 
 A record never starts within the last six bytes of a block (since it
 won't fit).  Any leftover bytes here form the trailer, which must
-consist entirely of zero bytes and must be skipped by readers.  
+consist entirely of zero bytes and must be skipped by readers.
 
 Aside: if exactly seven bytes are left in the current block, and a new
 non-zero length record is added, the writer must emit a FIRST record
@@ -33,8 +33,8 @@ The FULL record contains the contents of an entire user record.
 FIRST, MIDDLE, LAST are types used for user records that have been
 split into multiple fragments (typically because of block boundaries).
 FIRST is the type of the first fragment of a user record, LAST is the
-type of the last fragment of a user record, and MID is the type of all
-interior fragments of a user record.
+type of the last fragment of a user record, and MIDDLE is the type of
+all interior fragments of a user record.
 
 Example: consider a sequence of user records:
    A: length 1000
index 5879de1..43ef2e0 100644 (file)
@@ -55,14 +55,15 @@ class FileState {
     }
     const uint64_t available = size_ - offset;
     if (n > available) {
-      n = available;
+      n = static_cast<size_t>(available);
     }
     if (n == 0) {
       *result = Slice();
       return Status::OK();
     }
 
-    size_t block = offset / kBlockSize;
+    assert(offset / kBlockSize <= SIZE_MAX);
+    size_t block = static_cast<size_t>(offset / kBlockSize);
     size_t block_offset = offset % kBlockSize;
 
     if (n <= kBlockSize - block_offset) {
@@ -167,7 +168,7 @@ class SequentialFileImpl : public SequentialFile {
     if (pos_ > file_->Size()) {
       return Status::IOError("pos_ > file_->Size()");
     }
-    const size_t available = file_->Size() - pos_;
+    const uint64_t available = file_->Size() - pos_;
     if (n > available) {
       n = available;
     }
@@ -177,7 +178,7 @@ class SequentialFileImpl : public SequentialFile {
 
  private:
   FileState* file_;
-  size_t pos_;
+  uint64_t pos_;
 };
 
 class RandomAccessFileImpl : public RandomAccessFile {
index 1fa5886..1048fe3 100644 (file)
@@ -9,7 +9,6 @@
   Does not support:
   . getters for the option types
   . custom comparators that implement key shortening
-  . capturing post-write-snapshot
   . custom iter, db, env, cache implementations using just the C bindings
 
   Some conventions:
index 5e3b476..1a201e5 100644 (file)
@@ -96,4 +96,4 @@ class Cache {
 
 }  // namespace leveldb
 
-#endif  // STORAGE_LEVELDB_UTIL_CACHE_H_
+#endif  // STORAGE_LEVELDB_INCLUDE_CACHE_H_
index da8b11a..4c169bf 100644 (file)
@@ -14,7 +14,7 @@ namespace leveldb {
 
 // Update Makefile if you change these
 static const int kMajorVersion = 1;
-static const int kMinorVersion = 12;
+static const int kMinorVersion = 18;
 
 struct Options;
 struct ReadOptions;
diff --git a/src/leveldb/include/leveldb/dumpfile.h b/src/leveldb/include/leveldb/dumpfile.h
new file mode 100644 (file)
index 0000000..3f97fda
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright (c) 2014 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.
+
+#ifndef STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_
+#define STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_
+
+#include <string>
+#include "leveldb/env.h"
+#include "leveldb/status.h"
+
+namespace leveldb {
+
+// Dump the contents of the file named by fname in text format to
+// *dst.  Makes a sequence of dst->Append() calls; each call is passed
+// the newline-terminated text corresponding to a single item found
+// in the file.
+//
+// Returns a non-OK result if fname does not name a leveldb storage
+// file, or if the file cannot be read.
+Status DumpFile(Env* env, const std::string& fname, WritableFile* dst);
+
+}  // namespace leveldb
+
+#endif  // STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_
index fa32289..f709514 100644 (file)
@@ -13,9 +13,9 @@
 #ifndef STORAGE_LEVELDB_INCLUDE_ENV_H_
 #define STORAGE_LEVELDB_INCLUDE_ENV_H_
 
-#include <cstdarg>
 #include <string>
 #include <vector>
+#include <stdarg.h>
 #include <stdint.h>
 #include "leveldb/status.h"
 
@@ -142,7 +142,7 @@ class Env {
   // useful for computing deltas of time.
   virtual uint64_t NowMicros() = 0;
 
-  // Sleep/delay the thread for the perscribed number of micro-seconds.
+  // Sleep/delay the thread for the prescribed number of micro-seconds.
   virtual void SleepForMicroseconds(int micros) = 0;
 
  private:
index ad543eb..76aced0 100644 (file)
@@ -61,7 +61,7 @@ class Iterator {
   // Return the value for the current entry.  The underlying storage for
   // the returned slice is valid only until the next modification of
   // the iterator.
-  // REQUIRES: !AtEnd() && !AtStart()
+  // REQUIRES: Valid()
   virtual Slice value() const = 0;
 
   // If an error has occurred, return it.  Else return an ok status.
index fdda718..7c9b973 100644 (file)
@@ -153,7 +153,7 @@ struct ReadOptions {
 
   // If "snapshot" is non-NULL, read as of the supplied snapshot
   // (which must belong to the DB that is being read and which must
-  // not have been released).  If "snapshot" is NULL, use an impliicit
+  // not have been released).  If "snapshot" is NULL, use an implicit
   // snapshot of the state at the beginning of this read operation.
   // Default: NULL
   const Snapshot* snapshot;
index 74ea8fa..bc36798 100644 (file)
@@ -94,7 +94,7 @@ inline bool operator!=(const Slice& x, const Slice& y) {
 }
 
 inline int Slice::compare(const Slice& b) const {
-  const int min_len = (size_ < b.size_) ? size_ : b.size_;
+  const size_t min_len = (size_ < b.size_) ? size_ : b.size_;
   int r = memcmp(data_, b.data_, min_len);
   if (r == 0) {
     if (size_ < b.size_) r = -1;
diff --git a/src/leveldb/issues/issue200_test.cc b/src/leveldb/issues/issue200_test.cc
new file mode 100644 (file)
index 0000000..1cec79f
--- /dev/null
@@ -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();
+}
index e17bf43..9bf091f 100644 (file)
@@ -5,14 +5,13 @@
 // AtomicPointer provides storage for a lock-free pointer.
 // Platform-dependent implementation of AtomicPointer:
 // - If the platform provides a cheap barrier, we use it with raw pointers
-// - If cstdatomic is present (on newer versions of gcc, it is), we use
-//   a cstdatomic-based AtomicPointer.  However we prefer the memory
+// - If <atomic> is present (on newer versions of gcc, it is), we use
+//   a <atomic>-based AtomicPointer.  However we prefer the memory
 //   barrier based version, because at least on a gcc 4.4 32-bit build
-//   on linux, we have encountered a buggy <cstdatomic>
-//   implementation.  Also, some <cstdatomic> implementations are much
-//   slower than a memory-barrier based implementation (~16ns for
-//   <cstdatomic> based acquire-load vs. ~1ns for a barrier based
-//   acquire-load).
+//   on linux, we have encountered a buggy <atomic> implementation.
+//   Also, some <atomic> implementations are much slower than a memory-barrier
+//   based implementation (~16ns for <atomic> based acquire-load vs. ~1ns for
+//   a barrier based acquire-load).
 // This code is based on atomicops-internals-* in Google's perftools:
 // http://code.google.com/p/google-perftools/source/browse/#svn%2Ftrunk%2Fsrc%2Fbase
 
@@ -20,8 +19,8 @@
 #define PORT_ATOMIC_POINTER_H_
 
 #include <stdint.h>
-#ifdef LEVELDB_CSTDATOMIC_PRESENT
-#include <cstdatomic>
+#ifdef LEVELDB_ATOMIC_PRESENT
+#include <atomic>
 #endif
 #ifdef OS_WIN
 #include <windows.h>
@@ -50,6 +49,13 @@ namespace port {
 // 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 +74,6 @@ inline void MemoryBarrier() {
 }
 #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);
@@ -126,7 +125,7 @@ class AtomicPointer {
 };
 
 // AtomicPointer based on <cstdatomic>
-#elif defined(LEVELDB_CSTDATOMIC_PRESENT)
+#elif defined(LEVELDB_ATOMIC_PRESENT)
 class AtomicPointer {
  private:
   std::atomic<void*> rep_;
@@ -207,7 +206,7 @@ class AtomicPointer {
   inline void NoBarrier_Store(void* v) { rep_ = v; }
 };
 
-// We have neither MemoryBarrier(), nor <cstdatomic>
+// We have neither MemoryBarrier(), nor <atomic>
 #else
 #error Please implement AtomicPointer for this platform.
 
index 21c845e..ccca993 100644 (file)
   #else
     #define PLATFORM_IS_LITTLE_ENDIAN false
   #endif
-#elif defined(OS_FREEBSD)
+#elif defined(OS_FREEBSD) || defined(OS_OPENBSD) ||\
+      defined(OS_NETBSD) || defined(OS_DRAGONFLYBSD)
   #include <sys/types.h>
   #include <sys/endian.h>
   #define PLATFORM_IS_LITTLE_ENDIAN (_BYTE_ORDER == _LITTLE_ENDIAN)
-#elif defined(OS_OPENBSD) || defined(OS_NETBSD) ||\
-      defined(OS_DRAGONFLYBSD)
-  #include <sys/types.h>
-  #include <sys/endian.h>
 #elif defined(OS_HPUX)
   #define PLATFORM_IS_LITTLE_ENDIAN false
 #elif defined(OS_ANDROID)
@@ -55,7 +52,7 @@
 
 #if defined(OS_MACOSX) || defined(OS_SOLARIS) || defined(OS_FREEBSD) ||\
     defined(OS_NETBSD) || defined(OS_OPENBSD) || defined(OS_DRAGONFLYBSD) ||\
-    defined(OS_ANDROID) || defined(OS_HPUX)
+    defined(OS_ANDROID) || defined(OS_HPUX) || defined(CYGWIN)
 // Use fread/fwrite/fflush on platforms without _unlocked variants
 #define fread_unlocked fread
 #define fwrite_unlocked fwrite
index 6f9b6a7..9470ef5 100644 (file)
@@ -2,7 +2,8 @@
 // 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.
 
-#ifndef STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H
+#ifndef STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_
+#define STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_
 
 // Some environments provide custom macros to aid in static thread-safety
 // analysis.  Provide empty definitions of such macros unless they are already
@@ -56,4 +57,4 @@
 #define NO_THREAD_SAFETY_ANALYSIS
 #endif
 
-#endif  // STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H
+#endif  // STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_
index 79ea9d9..43e402c 100644 (file)
@@ -46,7 +46,7 @@ Block::~Block() {
 // Helper routine: decode the next block entry starting at "p",
 // storing the number of shared key bytes, non_shared key bytes,
 // and the length of the value in "*shared", "*non_shared", and
-// "*value_length", respectively.  Will not derefence past "limit".
+// "*value_length", respectively.  Will not dereference past "limit".
 //
 // If any errors are detected, returns NULL.  Otherwise, returns a
 // pointer to the key delta (just past the three decoded values).
index 5b545bd..4fbcb33 100644 (file)
@@ -21,7 +21,7 @@ class BlockBuilder {
   // Reset the contents as if the BlockBuilder was just constructed.
   void Reset();
 
-  // REQUIRES: Finish() has not been callled since the last call to Reset().
+  // REQUIRES: Finish() has not been called since the last call to Reset().
   // REQUIRES: key is larger than any previously added key
   void Add(const Slice& key, const Slice& value);
 
index 3a2a07c..8c4a474 100644 (file)
@@ -29,7 +29,7 @@ class TestHashFilter : public FilterPolicy {
 
   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;
       }
index cda1dec..aa63144 100644 (file)
@@ -48,7 +48,7 @@ Status Footer::DecodeFrom(Slice* input) {
   const uint64_t magic = ((static_cast<uint64_t>(magic_hi) << 32) |
                           (static_cast<uint64_t>(magic_lo)));
   if (magic != kTableMagicNumber) {
-    return Status::InvalidArgument("not an sstable (bad magic number)");
+    return Status::Corruption("not an sstable (bad magic number)");
   }
 
   Status result = metaindex_handle_.DecodeFrom(input);
index 71c1756..dff8a82 100644 (file)
@@ -41,7 +41,7 @@ Status Table::Open(const Options& options,
                    Table** table) {
   *table = NULL;
   if (size < Footer::kEncodedLength) {
-    return Status::InvalidArgument("file is too short to be an sstable");
+    return Status::Corruption("file is too short to be an sstable");
   }
 
   char footer_space[Footer::kEncodedLength];
@@ -58,7 +58,11 @@ Status Table::Open(const Options& options,
   BlockContents contents;
   Block* index_block = NULL;
   if (s.ok()) {
-    s = ReadBlock(file, ReadOptions(), footer.index_handle(), &contents);
+    ReadOptions opt;
+    if (options.paranoid_checks) {
+      opt.verify_checksums = true;
+    }
+    s = ReadBlock(file, opt, footer.index_handle(), &contents);
     if (s.ok()) {
       index_block = new Block(contents);
     }
@@ -92,6 +96,9 @@ void Table::ReadMeta(const Footer& footer) {
   // TODO(sanjay): Skip this if footer.metaindex_handle() size indicates
   // it is an empty block.
   ReadOptions opt;
+  if (rep_->options.paranoid_checks) {
+    opt.verify_checksums = true;
+  }
   BlockContents contents;
   if (!ReadBlock(rep_->file, opt, footer.metaindex_handle(), &contents).ok()) {
     // Do not propagate errors since meta info is not needed for operation
@@ -120,6 +127,9 @@ void Table::ReadFilter(const Slice& filter_handle_value) {
   // We might want to unify with ReadBlock() if we start
   // requiring checksum verification in Table::Open.
   ReadOptions opt;
+  if (rep_->options.paranoid_checks) {
+    opt.verify_checksums = true;
+  }
   BlockContents block;
   if (!ReadBlock(rep_->file, opt, filter_handle, &block).ok()) {
     return;
index 9551d6a..9367f71 100644 (file)
@@ -40,7 +40,7 @@ char* Arena::AllocateFallback(size_t bytes) {
 }
 
 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<uintptr_t>(alloc_ptr_) & (align-1);
   size_t slop = (current_mod == 0 ? 0 : align - current_mod);
index 8f7dde2..73bbf1c 100644 (file)
@@ -5,9 +5,9 @@
 #ifndef STORAGE_LEVELDB_UTIL_ARENA_H_
 #define STORAGE_LEVELDB_UTIL_ARENA_H_
 
-#include <cstddef>
 #include <vector>
 #include <assert.h>
+#include <stddef.h>
 #include <stdint.h>
 
 namespace leveldb {
index 63d1778..58e870e 100644 (file)
@@ -40,7 +40,7 @@ TEST(ArenaTest, Simple) {
       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 @@ TEST(ArenaTest, Simple) {
       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);
     }
index d7941cd..a27a2ac 100644 (file)
@@ -29,7 +29,7 @@ class BloomFilterPolicy : public FilterPolicy {
   }
 
   virtual const char* Name() const {
-    return "leveldb.BuiltinBloomFilter";
+    return "leveldb.BuiltinBloomFilter2";
   }
 
   virtual void CreateFilter(const Slice* keys, int n, std::string* dst) const {
index 0bf8e8d..77fb1b3 100644 (file)
@@ -126,7 +126,8 @@ TEST(BloomTest, VaryingLengths) {
     }
     Build();
 
-    ASSERT_LE(FilterSize(), (length * 10 / 8) + 40) << length;
+    ASSERT_LE(FilterSize(), static_cast<size_t>((length * 10 / 8) + 40))
+        << length;
 
     // All added keys must match
     for (int i = 0; i < length; i++) {
index fb5726e..521541e 100644 (file)
@@ -112,13 +112,13 @@ TEST(Coding, Varint64) {
   }
 
   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 @@ TEST(Coding, Varint32Truncation) {
   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 @@ TEST(Coding, Varint64Truncation) {
   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);
index 6badfdc..ba26678 100644 (file)
@@ -3,8 +3,6 @@
 // found in the LICENSE file. See the AUTHORS file for names of contributors.
 #if !defined(LEVELDB_PLATFORM_WINDOWS)
 
-#include <deque>
-#include <set>
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -18,9 +16,8 @@
 #include <sys/types.h>
 #include <time.h>
 #include <unistd.h>
-#if defined(LEVELDB_PLATFORM_ANDROID)
-#include <sys/stat.h>
-#endif
+#include <deque>
+#include <set>
 #include "leveldb/env.h"
 #include "leveldb/slice.h"
 #include "port/port.h"
@@ -176,172 +173,83 @@ class PosixMmapReadableFile: public RandomAccessFile {
   }
 };
 
-// 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;
-  }
+  FILE* file_;
 
-  size_t TruncateToPageBoundary(size_t s) {
-    s -= (s & (page_size_ - 1));
-    assert((s % page_size_) == 0);
-    return s;
-  }
+ public:
+  PosixWritableFile(const std::string& fname, FILE* f)
+      : filename_(fname), file_(f) { }
 
-  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;
-      }
+  ~PosixWritableFile() {
+    if (file_ != NULL) {
+      // Ignoring any potential errors
+      fclose(file_);
     }
-    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;
+  virtual Status Append(const Slice& data) {
+    size_t r = fwrite_unlocked(data.data(), 1, data.size(), file_);
+    if (r != data.size()) {
+      return IOError(filename_, errno);
     }
-    base_ = reinterpret_cast<char*>(ptr);
-    limit_ = base_ + map_size_;
-    dst_ = base_;
-    last_sync_ = base_;
-    return true;
+    return Status::OK();
   }
 
- 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);
-  }
-
-
-  ~PosixMmapFile() {
-    if (fd_ >= 0) {
-      PosixMmapFile::Close();
+  virtual Status Close() {
+    Status result;
+    if (fclose(file_) != 0) {
+      result = IOError(filename_, errno);
     }
+    file_ = NULL;
+    return result;
   }
 
-  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;
+  virtual Status Flush() {
+    if (fflush_unlocked(file_) != 0) {
+      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);
-      }
+  Status SyncDirIfManifest() {
+    const char* f = filename_.c_str();
+    const char* sep = strrchr(f, '/');
+    Slice basename;
+    std::string dir;
+    if (sep == NULL) {
+      dir = ".";
+      basename = f;
+    } else {
+      dir = std::string(f, sep - f);
+      basename = sep + 1;
     }
-
-    if (close(fd_) < 0) {
-      if (s.ok()) {
-        s = IOError(filename_, errno);
+    Status s;
+    if (basename.starts_with("MANIFEST")) {
+      int fd = open(dir.c_str(), O_RDONLY);
+      if (fd < 0) {
+        s = IOError(dir, errno);
+      } else {
+        if (fsync(fd) < 0) {
+          s = IOError(dir, errno);
+        }
+        close(fd);
       }
     }
-
-    fd_ = -1;
-    base_ = NULL;
-    limit_ = NULL;
     return s;
   }
 
-  virtual Status Flush() {
-    return Status::OK();
-  }
-
   virtual Status Sync() {
-    Status s;
-
-    if (pending_sync_) {
-      // Some unmapped data was not synced
-      pending_sync_ = false;
-      if (fdatasync(fd_) < 0) {
-        s = IOError(filename_, errno);
-      }
+    // Ensure new files referred to by the manifest are in the filesystem.
+    Status s = SyncDirIfManifest();
+    if (!s.ok()) {
+      return s;
     }
-
-    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;
   }
 };
@@ -385,7 +293,8 @@ class PosixEnv : public Env {
  public:
   PosixEnv();
   virtual ~PosixEnv() {
-    fprintf(stderr, "Destroying Env::Default()\n");
+    char msg[] = "Destroying Env::Default()\n";
+    fwrite(msg, 1, sizeof(msg), stderr);
     abort();
   }
 
@@ -432,12 +341,12 @@ class PosixEnv : public Env {
   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;
   }
@@ -600,7 +509,6 @@ class PosixEnv : public Env {
     return NULL;
   }
 
-  size_t page_size_;
   pthread_mutex_t mu_;
   pthread_cond_t bgsignal_;
   pthread_t bgthread_;
@@ -615,8 +523,7 @@ class PosixEnv : public Env {
   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));
 }
index 07cf022..ed439ce 100644 (file)
@@ -34,13 +34,13 @@ uint32_t Hash(const char* data, size_t n, uint32_t seed) {
   // Pick up remaining bytes
   switch (limit - data) {
     case 3:
-      h += data[2] << 16;
+      h += static_cast<unsigned char>(data[2]) << 16;
       FALLTHROUGH_INTENDED;
     case 2:
-      h += data[1] << 8;
+      h += static_cast<unsigned char>(data[1]) << 8;
       FALLTHROUGH_INTENDED;
     case 1:
-      h += data[0];
+      h += static_cast<unsigned char>(data[0]);
       h *= m;
       h ^= (h >> r);
       break;
diff --git a/src/leveldb/util/hash_test.cc b/src/leveldb/util/hash_test.cc
new file mode 100644 (file)
index 0000000..eaa1c92
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (c) 2011 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.
+
+#include "util/hash.h"
+#include "util/testharness.h"
+
+namespace leveldb {
+
+class HASH { };
+
+TEST(HASH, SignedUnsignedIssue) {
+  const unsigned char data1[1] = {0x62};
+  const unsigned char data2[2] = {0xc3, 0x97};
+  const unsigned char data3[3] = {0xe2, 0x99, 0xa5};
+  const unsigned char data4[4] = {0xe1, 0x80, 0xb9, 0x32};
+  const unsigned char data5[48] = {
+    0x01, 0xc0, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x14, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x04, 0x00,
+    0x00, 0x00, 0x00, 0x14,
+    0x00, 0x00, 0x00, 0x18,
+    0x28, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x02, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+  };
+
+  ASSERT_EQ(Hash(0, 0, 0xbc9f1d34), 0xbc9f1d34);
+  ASSERT_EQ(
+      Hash(reinterpret_cast<const char*>(data1), sizeof(data1), 0xbc9f1d34),
+      0xef1345c4);
+  ASSERT_EQ(
+      Hash(reinterpret_cast<const char*>(data2), sizeof(data2), 0xbc9f1d34),
+      0x5b663814);
+  ASSERT_EQ(
+      Hash(reinterpret_cast<const char*>(data3), sizeof(data3), 0xbc9f1d34),
+      0x323c078f);
+  ASSERT_EQ(
+      Hash(reinterpret_cast<const char*>(data4), sizeof(data4), 0xbc9f1d34),
+      0xed21633a);
+  ASSERT_EQ(
+      Hash(reinterpret_cast<const char*>(data5), sizeof(data5), 0x12345678),
+      0xf333dabb);
+}
+
+}  // namespace leveldb
+
+int main(int argc, char** argv) {
+  return leveldb::test::RunAllTests();
+}
index 22cf278..ca6b324 100644 (file)
@@ -45,15 +45,6 @@ std::string EscapeString(const Slice& value) {
   return r;
 }
 
-bool ConsumeChar(Slice* in, char c) {
-  if (!in->empty() && (*in)[0] == c) {
-    in->remove_prefix(1);
-    return true;
-  } else {
-    return false;
-  }
-}
-
 bool ConsumeDecimalNumber(Slice* in, uint64_t* val) {
   uint64_t v = 0;
   int digits = 0;
index b0c5da8..1b450d2 100644 (file)
@@ -32,10 +32,6 @@ extern std::string NumberToString(uint64_t num);
 // Escapes any non-printable characters found in "value".
 extern std::string EscapeString(const Slice& value);
 
-// If *in starts with "c", advances *in past the first character and
-// returns true.  Otherwise, returns false.
-extern bool ConsumeChar(Slice* in, char c);
-
 // Parse a human-readable number from "*in" into *value.  On success,
 // advances "*in" past the consumed number and sets "*val" to the
 // numeric value.  Otherwise, returns false and leaves *in in an
index 0753824..ddd51b1 100644 (file)
@@ -16,7 +16,12 @@ class Random {
  private:
   uint32_t seed_;
  public:
-  explicit Random(uint32_t s) : seed_(s & 0x7fffffffu) { }
+  explicit Random(uint32_t s) : seed_(s & 0x7fffffffu) {
+    // Avoid bad seeds.
+    if (seed_ == 0 || seed_ == 2147483647L) {
+      seed_ = 1;
+    }
+  }
   uint32_t Next() {
     static const uint32_t M = 2147483647L;   // 2^31-1
     static const uint64_t A = 16807;  // bits 14, 8, 7, 5, 2, 1, 0
index eb1bdd5..402fab3 100644 (file)
@@ -38,7 +38,7 @@ int RunAllTests() {
 
   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;
index 538d095..bee56bf 100644 (file)
@@ -32,7 +32,7 @@ std::string RandomKey(Random* rnd, int len) {
 
 
 extern Slice CompressibleString(Random* rnd, double compressed_fraction,
-                                int len, std::string* dst) {
+                                size_t len, std::string* dst) {
   int raw = static_cast<int>(len * compressed_fraction);
   if (raw < 1) raw = 1;
   std::string raw_data;
index 824e655..adad3fc 100644 (file)
@@ -24,7 +24,7 @@ extern std::string RandomKey(Random* rnd, int len);
 // "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 {
index 3037f77..4374774 100644 (file)
@@ -12,7 +12,6 @@
 #include "ui_interface.h"
 #include "checkqueue.h"
 #include "kernel.h"
-#include "zerocoin/Zerocoin.h"
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/filesystem.hpp>
 #include <boost/filesystem/fstream.hpp>
@@ -34,7 +33,6 @@ unsigned int nTransactionsUpdated = 0;
 
 map<uint256, CBlockIndex*> mapBlockIndex;
 set<pair<COutPoint, unsigned int> > setStakeSeen;
-libzerocoin::Params* ZCParams;
 
 CBigNum bnProofOfWorkLimit(~uint256(0) >> 20); // "standard" scrypt target limit for proof of work, results with 0,000244140625 proof-of-work difficulty
 CBigNum bnProofOfStakeLegacyLimit(~uint256(0) >> 24); // proof of stake target limit from block #15000 and until 20 June 2013, results with 0,00390625 proof of stake difficulty
@@ -2798,30 +2796,6 @@ FILE* AppendBlockFile(unsigned int& nFileRet)
 
 bool LoadBlockIndex(bool fAllowNew)
 {
-    CBigNum bnTrustedModulus;
-
-    if (fTestNet)
-    {
-        pchMessageStart[0] = 0xcd;
-        pchMessageStart[1] = 0xf2;
-        pchMessageStart[2] = 0xc0;
-        pchMessageStart[3] = 0xef;
-
-        bnTrustedModulus.SetHex("f0d14cf72623dacfe738d0892b599be0f31052239cddd95a3f25101c801dc990453b38c9434efe3f372db39a32c2bb44cbaea72d62c8931fa785b0ec44531308df3e46069be5573e49bb29f4d479bfc3d162f57a5965db03810be7636da265bfced9c01a6b0296c77910ebdc8016f70174f0f18a57b3b971ac43a934c6aedbc5c866764a3622b5b7e3f9832b8b3f133c849dbcc0396588abcd1e41048555746e4823fb8aba5b3d23692c6857fccce733d6bb6ec1d5ea0afafecea14a0f6f798b6b27f77dc989c557795cc39a0940ef6bb29a7fc84135193a55bcfc2f01dd73efad1b69f45a55198bd0e6bef4d338e452f6a420f1ae2b1167b923f76633ab6e55");
-        bnProofOfWorkLimit = bnProofOfWorkLimitTestNet; // 16 bits PoW target limit for testnet
-        nStakeMinAge = 2 * 60 * 60; // test net min age is 2 hours
-        nModifierInterval = 20 * 60; // test modifier interval is 20 minutes
-        nCoinbaseMaturity = 10; // test maturity is 10 blocks
-        nStakeTargetSpacing = 5 * 60; // test block spacing is 5 minutes
-    }
-    else
-    {
-        bnTrustedModulus.SetHex("d01f952e1090a5a72a3eda261083256596ccc192935ae1454c2bafd03b09e6ed11811be9f3a69f5783bbbced8c6a0c56621f42c2d19087416facf2f13cc7ed7159d1c5253119612b8449f0c7f54248e382d30ecab1928dbf075c5425dcaee1a819aa13550e0f3227b8c685b14e0eae094d65d8a610a6f49fff8145259d1187e4c6a472fa5868b2b67f957cb74b787f4311dbc13c97a2ca13acdb876ff506ebecbb904548c267d68868e07a32cd9ed461fbc2f920e9940e7788fed2e4817f274df5839c2196c80abe5c486df39795186d7bc86314ae1e8342f3c884b158b4b05b4302754bf351477d35370bad6639b2195d30006b77bf3dbb28b848fd9ecff5662bf39dde0c974e83af51b0d3d642d43834827b8c3b189065514636b8f2a59c42ba9b4fc4975d4827a5d89617a3873e4b377b4d559ad165748632bd928439cfbc5a8ef49bc2220e0b15fb0aa302367d5e99e379a961c1bc8cf89825da5525e3c8f14d7d8acca2fa9c133a2176ae69874d8b1d38b26b9c694e211018005a97b40848681b9dd38feb2de141626fb82591aad20dc629b2b6421cef1227809551a0e4e943ab99841939877f18f2d9c0addc93cf672e26b02ed94da3e6d329e8ac8f3736eebbf37bb1a21e5aadf04ee8e3b542f876aa88b2adf2608bd86329b7f7a56fd0dc1c40b48188731d11082aea360c62a0840c2db3dad7178fd7e359317ae081");
-    }
-
-    // Set up the Zerocoin Params object
-    ZCParams = new libzerocoin::Params(bnTrustedModulus);
-
     //
     // Load block index
     //
index 240b124..103c13a 100644 (file)
@@ -13,9 +13,9 @@
 #include "net.h"
 #include "script.h"
 #include "scrypt.h"
-#include "zerocoin/Zerocoin.h"
 
 #include <list>
+#include <map>
 
 class CWallet;
 class CBlock;
@@ -72,7 +72,6 @@ static const uint256 hashGenesisBlockTestNet("0x000c763e402f2436da9ed36c7286f62c
 inline int64 PastDrift(int64 nTime)   { return nTime - 2 * 60 * 60; } // up to 2 hours from the past
 inline int64 FutureDrift(int64 nTime) { return nTime + 2 * 60 * 60; } // up to 2 hours from the future
 
-extern libzerocoin::Params* ZCParams;
 extern CScript COINBASE_FLAGS;
 extern CCriticalSection cs_main;
 extern std::map<uint256, CBlockIndex*> mapBlockIndex;
index 1170153..5a30ebc 100644 (file)
@@ -128,20 +128,7 @@ OBJS= \
     obj/noui.o \
     obj/kernel.o \
     obj/pbkdf2.o \
-    obj/scrypt.o \
-    obj/scrypt-arm.o \
-    obj/scrypt-x86.o \
-    obj/scrypt-x86_64.o \
-    obj/zerocoin/Accumulator.o \
-    obj/zerocoin/AccumulatorProofOfKnowledge.o \
-    obj/zerocoin/Coin.o \
-    obj/zerocoin/CoinSpend.o \
-    obj/zerocoin/Commitment.o \
-    obj/zerocoin/ParamGeneration.o \
-    obj/zerocoin/Params.o \
-    obj/zerocoin/SerialNumberSignatureOfKnowledge.o \
-    obj/zerocoin/SpendMetaData.o \
-    obj/zerocoin/ZeroTest.o
+    obj/scrypt.o
 
 all: novacoind
 
@@ -161,13 +148,8 @@ ifneq (${USE_LEVELDB}, 1)
 OBJS += obj/txdb-bdb.o
 endif
 
-# auto-generated dependencies:
--include obj/*.P
-
-obj/build.h: FORCE
-       /bin/sh ../share/genbuild.sh obj/build.h
-version.cpp: obj/build.h
-DEFS += -DHAVE_BUILD_INFO
+ifeq (${USE_ASM}, 1)
+OBJS += obj/scrypt-arm.o obj/scrypt-x86.o obj/scrypt-x86_64.o
 
 obj/scrypt-x86.o: scrypt-x86.S
        $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
@@ -177,15 +159,23 @@ obj/scrypt-x86_64.o: scrypt-x86_64.S
 
 obj/scrypt-arm.o: scrypt-arm.S
        $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
+endif
+ifneq (${USE_ASM}, 1)
+OBJS += obj/scrypt-generic.o
 
-obj/%.o: %.cpp
-       $(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $<
-       @cp $(@:%.o=%.d) $(@:%.o=%.P); \
-         sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-             -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
-         rm -f $(@:%.o=%.d)
+obj/scrypt-generic.o: scrypt-generic.c
+       $(CC) -c $(xCXXFLAGS) -MMD -o $@ $<
+endif
+
+# auto-generated dependencies:
+-include obj/*.P
 
-obj/zerocoin/%.o: zerocoin/%.cpp
+obj/build.h: FORCE
+       /bin/sh ../share/genbuild.sh obj/build.h
+version.cpp: obj/build.h
+DEFS += -DHAVE_BUILD_INFO
+
+obj/%.o: %.cpp
        $(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $<
        @cp $(@:%.o=%.d) $(@:%.o=%.P); \
          sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
@@ -198,9 +188,7 @@ novacoind: $(OBJS:obj/%=obj/%)
 clean:
        -rm -f novacoind
        -rm -f obj/*.o
-       -rm -f obj/zerocoin/*.o
        -rm -f obj/*.P
-       -rm -f obj/zerocoin/*.P
        -rm -f obj/build.h
 
 FORCE:
index a194bf5..8bed0ff 100644 (file)
@@ -91,19 +91,7 @@ OBJS= \
     obj/noui.o \
     obj/kernel.o \
     obj/pbkdf2.o \
-    obj/scrypt.o \
-    obj/scrypt-x86.o \
-    obj/scrypt-x86_64.o \
-    obj/zerocoin/Accumulator.o \
-    obj/zerocoin/AccumulatorProofOfKnowledge.o \
-    obj/zerocoin/Coin.o \
-    obj/zerocoin/CoinSpend.o \
-    obj/zerocoin/Commitment.o \
-    obj/zerocoin/ParamGeneration.o \
-    obj/zerocoin/Params.o \
-    obj/zerocoin/SerialNumberSignatureOfKnowledge.o \
-    obj/zerocoin/SpendMetaData.o \
-    obj/zerocoin/ZeroTest.o
+    obj/scrypt.o
 
 all: novacoind.exe
 
@@ -122,6 +110,22 @@ else
 OBJS += obj/txdb-bdb.o
 endif
 
+ifeq (${USE_ASM}, 1)
+OBJS += obj/scrypt-arm.o obj/scrypt-x86.o obj/scrypt-x86_64.o
+
+obj/scrypt-x86.o: scrypt-x86.S
+       $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
+
+obj/scrypt-x86_64.o: scrypt-x86_64.S
+       $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
+endif
+ifneq (${USE_ASM}, 1)
+OBJS += obj/scrypt-generic.o
+
+obj/scrypt-generic.o: scrypt-generic.c
+       $(CC) -c $(xCXXFLAGS) -MMD -o $@ $<
+endif
+
 obj/build.h: FORCE
        /bin/sh ../share/genbuild.sh obj/build.h
 version.cpp: obj/build.h
@@ -130,22 +134,12 @@ DEFS += -DHAVE_BUILD_INFO
 obj/%.o: %.cpp $(HEADERS)
        $(CXX) -c $(CFLAGS) -o $@ $<
 
-obj/zerocoin/%.o: zerocoin/%.cpp $(HEADERS)
-       $(CXX) -c $(CFLAGS) -o $@ $<
-
 novacoind.exe: $(OBJS:obj/%=obj/%)
        $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) -lshlwapi
        $(STRIP) novacoind.exe
 
-obj/scrypt-x86.o: scrypt-x86.S
-       $(CXX) -c $(CFLAGS) -MMD -o $@ $<
-
-obj/scrypt-x86_64.o: scrypt-x86_64.S
-       $(CXX) -c $(CFLAGS) -MMD -o $@ $<
-
 clean:
        -rm -f obj/*.o
-       -rm -f obj/zerocoin/*.o
        -rm -f novacoind.exe
        -rm -f obj/build.h
        cd leveldb && TARGET_OS=OS_WINDOWS_CROSSCOMPILE $(MAKE) clean && cd ..
index 3615141..9a40913 100644 (file)
@@ -39,7 +39,7 @@ ifneq (${USE_UPNP}, -)
  INCLUDEPATHS += -I"C:\miniupnpc-1.6-mgw"
  LIBPATHS += -L"C:\miniupnpc-1.6-mgw"
  LIBS += -l miniupnpc -l iphlpapi
- DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP)
+ DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP) -DMINIUPNP_STATICLIB
 endif
 
 ifneq (${USE_IPV6}, -)
@@ -82,19 +82,7 @@ OBJS= \
     obj/noui.o \
     obj/kernel.o \
     obj/pbkdf2.o \
-    obj/scrypt.o \
-    obj/scrypt-x86.o \
-    obj/scrypt-x86_64.o \
-    obj/zerocoin/Accumulator.o \
-    obj/zerocoin/AccumulatorProofOfKnowledge.o \
-    obj/zerocoin/Coin.o \
-    obj/zerocoin/CoinSpend.o \
-    obj/zerocoin/Commitment.o \
-    obj/zerocoin/ParamGeneration.o \
-    obj/zerocoin/Params.o \
-    obj/zerocoin/SerialNumberSignatureOfKnowledge.o \
-    obj/zerocoin/SpendMetaData.o \
-    obj/zerocoin/ZeroTest.o
+    obj/scrypt.o
 
 all: novacoind.exe
 
@@ -113,17 +101,23 @@ else
 OBJS += obj/txdb-bdb.o
 endif
 
-obj/%.o: %.cpp $(HEADERS)
-       g++ -c $(CFLAGS) -o $@ $<
-
-obj/zerocoin/%.o: zerocoin/%.cpp
-       g++ -c $(CFLAGS) -o $@ $<
+ifdef USE_ASM
+OBJS += obj/scrypt-arm.o obj/scrypt-x86.o obj/scrypt-x86_64.o
 
 obj/scrypt-x86.o: scrypt-x86.S
        $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
 
 obj/scrypt-x86_64.o: scrypt-x86_64.S
        $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
+else
+OBJS += obj/scrypt-generic.o
+
+obj/scrypt-generic.o: scrypt-generic.c
+       $(CC) -c $(xCXXFLAGS) -MMD -o $@ $<
+endif
+
+obj/%.o: %.cpp $(HEADERS)
+       g++ -c $(CFLAGS) -o $@ $<
 
 novacoind.exe: $(OBJS:obj/%=obj/%)
        g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
@@ -131,6 +125,5 @@ novacoind.exe: $(OBJS:obj/%=obj/%)
 clean:
        -del /Q novacoind
        -del /Q obj\*
-       -del /Q obj\zerocoin\*
 
 FORCE:
index 3cd0962..3b6353d 100644 (file)
@@ -93,19 +93,7 @@ OBJS= \
     obj/noui.o \
     obj/pbkdf2.o \
     obj/kernel.o \
-    obj/scrypt.o \
-    obj/scrypt-x86.o \
-    obj/scrypt-x86_64.o \
-    obj/zerocoin/Accumulator.o \
-    obj/zerocoin/AccumulatorProofOfKnowledge.o \
-    obj/zerocoin/Coin.o \
-    obj/zerocoin/CoinSpend.o \
-    obj/zerocoin/Commitment.o \
-    obj/zerocoin/ParamGeneration.o \
-    obj/zerocoin/Params.o \
-    obj/zerocoin/SerialNumberSignatureOfKnowledge.o \
-    obj/zerocoin/SpendMetaData.o \
-    obj/zerocoin/ZeroTest.o
+    obj/scrypt.o
 
 ifndef USE_UPNP
        override USE_UPNP = -
@@ -140,6 +128,25 @@ else
 OBJS += obj/txdb-bdb.o
 endif
 
+ifeq (${USE_ASM}, 1)
+OBJS += obj/scrypt-arm.o obj/scrypt-x86.o obj/scrypt-x86_64.o
+
+obj/scrypt-x86.o: scrypt-x86.S
+       $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
+
+obj/scrypt-x86_64.o: scrypt-x86_64.S
+       $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
+
+obj/scrypt-arm.o: scrypt-arm.S
+       $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
+endif
+ifneq (${USE_ASM}, 1)
+OBJS += obj/scrypt-generic.o
+
+obj/scrypt-generic.o: scrypt-generic.c
+       $(CC) -c $(xCXXFLAGS) -MMD -o $@ $<
+endif
+
 # auto-generated dependencies:
 -include obj/*.P
 
@@ -155,28 +162,13 @@ obj/%.o: %.cpp
              -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
          rm -f $(@:%.o=%.d)
 
-obj/zerocoin/%.o: zerocoin/%.cpp
-       $(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $<
-       @cp $(@:%.o=%.d) $(@:%.o=%.P); \
-         sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-             -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
-         rm -f $(@:%.o=%.d)
-
-obj/scrypt-x86.o: scrypt-x86.S
-       $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
-
-obj/scrypt-x86_64.o: scrypt-x86_64.S
-       $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
-
 novacoind: $(OBJS:obj/%=obj/%)
        $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
 
 clean:
        -rm -f novacoind
        -rm -f obj/*.o
-       -rm -f obj/zerocoin/*.o
        -rm -f obj/*.P
-       -rm -f obj/zerocoin/*.P
        -rm -f obj/build.h
 
 FORCE:
index 6511849..bcc102e 100644 (file)
@@ -134,20 +134,7 @@ OBJS= \
     obj/noui.o \
     obj/kernel.o \
     obj/pbkdf2.o \
-    obj/scrypt.o \
-    obj/scrypt-arm.o \
-    obj/scrypt-x86.o \
-    obj/scrypt-x86_64.o \
-    obj/zerocoin/Accumulator.o \
-    obj/zerocoin/AccumulatorProofOfKnowledge.o \
-    obj/zerocoin/Coin.o \
-    obj/zerocoin/CoinSpend.o \
-    obj/zerocoin/Commitment.o \
-    obj/zerocoin/ParamGeneration.o \
-    obj/zerocoin/Params.o \
-    obj/zerocoin/SerialNumberSignatureOfKnowledge.o \
-    obj/zerocoin/SpendMetaData.o \
-    obj/zerocoin/ZeroTest.o
+    obj/scrypt.o
 
 all: novacoind
 
@@ -167,13 +154,8 @@ ifneq (${USE_LEVELDB}, 1)
 OBJS += obj/txdb-bdb.o
 endif
 
-# auto-generated dependencies:
--include obj/*.P
-
-obj/build.h: FORCE
-       /bin/sh ../share/genbuild.sh obj/build.h
-version.cpp: obj/build.h
-DEFS += -DHAVE_BUILD_INFO
+ifeq (${USE_ASM}, 1)
+OBJS += obj/scrypt-arm.o obj/scrypt-x86.o obj/scrypt-x86_64.o
 
 obj/scrypt-x86.o: scrypt-x86.S
        $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
@@ -183,15 +165,24 @@ obj/scrypt-x86_64.o: scrypt-x86_64.S
 
 obj/scrypt-arm.o: scrypt-arm.S
        $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
+endif
+ifneq (${USE_ASM}, 1)
+OBJS += obj/scrypt-generic.o
+
+obj/scrypt-generic.o: scrypt-generic.c
+       $(CC) -c $(xCXXFLAGS) -MMD -o $@ $<
+endif
+
+# auto-generated dependencies:
+-include obj/*.P
+
+obj/build.h: FORCE
+       /bin/sh ../share/genbuild.sh obj/build.h
+version.cpp: obj/build.h
+DEFS += -DHAVE_BUILD_INFO
 
-obj/%.o: %.cpp
-       $(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $<
-       @cp $(@:%.o=%.d) $(@:%.o=%.P); \
-         sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-             -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
-         rm -f $(@:%.o=%.d)
 
-obj/zerocoin/%.o: zerocoin/%.cpp
+obj/%.o: %.cpp
        $(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $<
        @cp $(@:%.o=%.d) $(@:%.o=%.P); \
          sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
@@ -204,9 +195,7 @@ novacoind: $(OBJS:obj/%=obj/%)
 clean:
        -rm -f novacoind
        -rm -f obj/*.o
-       -rm -f obj/zerocoin/*.o
        -rm -f obj/*.P
-       -rm -f obj/zerocoin/*.P
        -rm -f obj/build.h
 
 FORCE:
diff --git a/src/obj/zerocoin/.gitignore b/src/obj/zerocoin/.gitignore
deleted file mode 100644 (file)
index d6b7ef3..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-*
-!.gitignore
index 143eb3a..12d94b0 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 
-#if defined(OPTIMIZED_SALSA) &&  defined(__arm__) && defined(__APCS_32__)
+#if defined(__arm__) && defined(__APCS_32__)
 
 #if defined(__linux__) && defined(__ELF__)
 .section .note.GNU-stack,"",%progbits
diff --git a/src/scrypt-generic.c b/src/scrypt-generic.c
new file mode 100644 (file)
index 0000000..2da117e
--- /dev/null
@@ -0,0 +1,120 @@
+/*-
+ * Copyright 2009 Colin Percival, 2011 ArtForz, 2011 pooler, 2013 Balthazar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+// Generic scrypt_core implementation
+
+static inline void xor_salsa8(unsigned int B[16], const unsigned int Bx[16])
+{
+    unsigned int x00,x01,x02,x03,x04,x05,x06,x07,x08,x09,x10,x11,x12,x13,x14,x15;
+    int i;
+
+    x00 = (B[0] ^= Bx[0]);
+    x01 = (B[1] ^= Bx[1]);
+    x02 = (B[2] ^= Bx[2]);
+    x03 = (B[3] ^= Bx[3]);
+    x04 = (B[4] ^= Bx[4]);
+    x05 = (B[5] ^= Bx[5]);
+    x06 = (B[6] ^= Bx[6]);
+    x07 = (B[7] ^= Bx[7]);
+    x08 = (B[8] ^= Bx[8]);
+    x09 = (B[9] ^= Bx[9]);
+    x10 = (B[10] ^= Bx[10]);
+    x11 = (B[11] ^= Bx[11]);
+    x12 = (B[12] ^= Bx[12]);
+    x13 = (B[13] ^= Bx[13]);
+    x14 = (B[14] ^= Bx[14]);
+    x15 = (B[15] ^= Bx[15]);
+    for (i = 0; i < 8; i += 2) {
+#define R(a, b) (((a) << (b)) | ((a) >> (32 - (b))))
+        /* Operate on columns. */
+        x04 ^= R(x00+x12, 7); x09 ^= R(x05+x01, 7);
+        x14 ^= R(x10+x06, 7); x03 ^= R(x15+x11, 7);
+
+        x08 ^= R(x04+x00, 9); x13 ^= R(x09+x05, 9);
+        x02 ^= R(x14+x10, 9); x07 ^= R(x03+x15, 9);
+
+        x12 ^= R(x08+x04,13); x01 ^= R(x13+x09,13);
+        x06 ^= R(x02+x14,13); x11 ^= R(x07+x03,13);
+
+        x00 ^= R(x12+x08,18); x05 ^= R(x01+x13,18);
+        x10 ^= R(x06+x02,18); x15 ^= R(x11+x07,18);
+
+        /* Operate on rows. */
+        x01 ^= R(x00+x03, 7); x06 ^= R(x05+x04, 7);
+        x11 ^= R(x10+x09, 7); x12 ^= R(x15+x14, 7);
+
+        x02 ^= R(x01+x00, 9); x07 ^= R(x06+x05, 9);
+        x08 ^= R(x11+x10, 9); x13 ^= R(x12+x15, 9);
+
+        x03 ^= R(x02+x01,13); x04 ^= R(x07+x06,13);
+        x09 ^= R(x08+x11,13); x14 ^= R(x13+x12,13);
+
+        x00 ^= R(x03+x02,18); x05 ^= R(x04+x07,18);
+        x10 ^= R(x09+x08,18); x15 ^= R(x14+x13,18);
+#undef R
+    }
+    B[0] += x00;
+    B[1] += x01;
+    B[2] += x02;
+    B[3] += x03;
+    B[4] += x04;
+    B[5] += x05;
+    B[6] += x06;
+    B[7] += x07;
+    B[8] += x08;
+    B[9] += x09;
+    B[10] += x10;
+    B[11] += x11;
+    B[12] += x12;
+    B[13] += x13;
+    B[14] += x14;
+    B[15] += x15;
+}
+
+void scrypt_core(unsigned int *X, unsigned int *V)
+{
+    unsigned int i, j, k;
+
+    for (i = 0; i < 1024; i++) {
+        memcpy(&V[i * 32], X, 128);
+        xor_salsa8(&X[0], &X[16]);
+        xor_salsa8(&X[16], &X[0]);
+    }
+    for (i = 0; i < 1024; i++) {
+        j = 32 * (X[16] & 1023);
+        for (k = 0; k < 32; k++)
+            X[k] ^= V[j + k];
+        xor_salsa8(&X[0], &X[16]);
+        xor_salsa8(&X[16], &X[0]);
+    }
+}
index c1d2cef..0e97e36 100644 (file)
@@ -22,7 +22,7 @@
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 
-#if defined(OPTIMIZED_SALSA) &&  defined(__i386__)
+#if defined(__i386__)
 
 #if defined(__linux__) && defined(__ELF__)
 .section .note.GNU-stack,"",%progbits
index 3036d03..9d894f2 100644 (file)
@@ -23,7 +23,7 @@
 # SUCH DAMAGE.
 
 
-#if defined(OPTIMIZED_SALSA) && defined(__x86_64__)
+#if defined(__x86_64__)
 
 #if defined(__linux__) && defined(__ELF__)
        .section .note.GNU-stack,"",%progbits
index 06ef53c..624d8b1 100644 (file)
@@ -1,32 +1,3 @@
-/*-
- * Copyright 2009 Colin Percival, 2011 ArtForz, 2011 pooler, 2013 Balthazar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-
 #include <stdlib.h>
 #include <stdint.h>
 
@@ -38,98 +9,7 @@
 
 #define SCRYPT_BUFFER_SIZE (131072 + 63)
 
-#if defined (OPTIMIZED_SALSA) && ( defined (__x86_64__) || defined (__i386__) || defined(__arm__) )
 extern "C" void scrypt_core(unsigned int *X, unsigned int *V);
-#else
-// Generic scrypt_core implementation
-
-static inline void xor_salsa8(unsigned int B[16], const unsigned int Bx[16])
-{
-    unsigned int x00,x01,x02,x03,x04,x05,x06,x07,x08,x09,x10,x11,x12,x13,x14,x15;
-    int i;
-
-    x00 = (B[0] ^= Bx[0]);
-    x01 = (B[1] ^= Bx[1]);
-    x02 = (B[2] ^= Bx[2]);
-    x03 = (B[3] ^= Bx[3]);
-    x04 = (B[4] ^= Bx[4]);
-    x05 = (B[5] ^= Bx[5]);
-    x06 = (B[6] ^= Bx[6]);
-    x07 = (B[7] ^= Bx[7]);
-    x08 = (B[8] ^= Bx[8]);
-    x09 = (B[9] ^= Bx[9]);
-    x10 = (B[10] ^= Bx[10]);
-    x11 = (B[11] ^= Bx[11]);
-    x12 = (B[12] ^= Bx[12]);
-    x13 = (B[13] ^= Bx[13]);
-    x14 = (B[14] ^= Bx[14]);
-    x15 = (B[15] ^= Bx[15]);
-    for (i = 0; i < 8; i += 2) {
-#define R(a, b) (((a) << (b)) | ((a) >> (32 - (b))))
-        /* Operate on columns. */
-        x04 ^= R(x00+x12, 7); x09 ^= R(x05+x01, 7);
-        x14 ^= R(x10+x06, 7); x03 ^= R(x15+x11, 7);
-
-        x08 ^= R(x04+x00, 9); x13 ^= R(x09+x05, 9);
-        x02 ^= R(x14+x10, 9); x07 ^= R(x03+x15, 9);
-
-        x12 ^= R(x08+x04,13); x01 ^= R(x13+x09,13);
-        x06 ^= R(x02+x14,13); x11 ^= R(x07+x03,13);
-
-        x00 ^= R(x12+x08,18); x05 ^= R(x01+x13,18);
-        x10 ^= R(x06+x02,18); x15 ^= R(x11+x07,18);
-
-        /* Operate on rows. */
-        x01 ^= R(x00+x03, 7); x06 ^= R(x05+x04, 7);
-        x11 ^= R(x10+x09, 7); x12 ^= R(x15+x14, 7);
-
-        x02 ^= R(x01+x00, 9); x07 ^= R(x06+x05, 9);
-        x08 ^= R(x11+x10, 9); x13 ^= R(x12+x15, 9);
-
-        x03 ^= R(x02+x01,13); x04 ^= R(x07+x06,13);
-        x09 ^= R(x08+x11,13); x14 ^= R(x13+x12,13);
-
-        x00 ^= R(x03+x02,18); x05 ^= R(x04+x07,18);
-        x10 ^= R(x09+x08,18); x15 ^= R(x14+x13,18);
-#undef R
-    }
-    B[0] += x00;
-    B[1] += x01;
-    B[2] += x02;
-    B[3] += x03;
-    B[4] += x04;
-    B[5] += x05;
-    B[6] += x06;
-    B[7] += x07;
-    B[8] += x08;
-    B[9] += x09;
-    B[10] += x10;
-    B[11] += x11;
-    B[12] += x12;
-    B[13] += x13;
-    B[14] += x14;
-    B[15] += x15;
-}
-
-static inline void scrypt_core(unsigned int *X, unsigned int *V)
-{
-    unsigned int i, j, k;
-
-    for (i = 0; i < 1024; i++) {
-        memcpy(&V[i * 32], X, 128);
-        xor_salsa8(&X[0], &X[16]);
-        xor_salsa8(&X[16], &X[0]);
-    }
-    for (i = 0; i < 1024; i++) {
-        j = 32 * (X[16] & 1023);
-        for (k = 0; k < 32; k++)
-            X[k] ^= V[j + k];
-        xor_salsa8(&X[0], &X[16]);
-        xor_salsa8(&X[16], &X[0]);
-    }
-}
-
-#endif
 
 /* cpu and memory intensive function to transform a 80 byte buffer into a 32 byte output
    scratchpad size needs to be at least 63 + (128 * r * p) + (256 * r + 64) + (128 * r * N) bytes
index 7feb976..b7c5104 100644 (file)
@@ -950,19 +950,6 @@ public:
     iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); }
     void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); }
 
-    void insert(iterator it, const_iterator first, const_iterator last)
-    {
-        assert(last - first >= 0);
-        if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos)
-        {
-            // special case for inserting at the front when there's room
-            nReadPos -= (last - first);
-            memcpy(&vch[nReadPos], &first[0], last - first);
-        }
-        else
-            vch.insert(it, first, last);
-    }
-
 #ifndef _MSC_VER
     void insert(iterator it, std::vector<char>::const_iterator first, std::vector<char>::const_iterator last)
     {
index e838834..a9be672 100644 (file)
@@ -81,7 +81,7 @@ private:
     int nWalletMaxVersion;
 
     // selected coins metadata
-    map<uint256, pair<pair<CTxIndex, pair<const CWalletTx*,unsigned int> >, pair<CBlock, uint64> > > mapMeta;
+    std::map<uint256, std::pair<std::pair<CTxIndex, std::pair<const CWalletTx*,unsigned int> >, std::pair<CBlock, uint64> > > mapMeta;
 
 public:
     mutable CCriticalSection cs_wallet;
@@ -203,7 +203,7 @@ public:
     bool GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight);
     void GetStakeWeightFromValue(const int64& nTime, const int64& nValue, uint64& nWeight);
     bool CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew, CKey& key);
-    bool MergeCoins(const int64& nAmount, const int64& nMinValue, const int64& nMaxValue, list<uint256>& listMerged);
+    bool MergeCoins(const int64& nAmount, const int64& nMinValue, const int64& nMaxValue, std::list<uint256>& listMerged);
 
     std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
     std::string SendMoneyToDestination(const CTxDestination &address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
diff --git a/src/zerocoin/Accumulator.cpp b/src/zerocoin/Accumulator.cpp
deleted file mode 100644 (file)
index e05f8ac..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- * @file       Accumulator.cpp
- *
- * @brief      Accumulator and AccumulatorWitness classes for the Zerocoin library.
- *
- * @author     Ian Miers, Christina Garman and Matthew Green
- * @date       June 2013
- *
- * @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
- * @license    This project is released under the MIT license.
- **/
-
-#include <sstream>
-#include "Zerocoin.h"
-
-namespace libzerocoin {
-
-//Accumulator class
-Accumulator::Accumulator(const AccumulatorAndProofParams* p, const CoinDenomination d): params(p), denomination(d) {
-       if (!(params->initialized)) {
-               throw ZerocoinException("Invalid parameters for accumulator");
-       }
-
-       this->value = this->params->accumulatorBase;
-}
-
-Accumulator::Accumulator(const Params* p, const CoinDenomination d) {
-       this->params = &(p->accumulatorParams);
-       this->denomination = d;
-
-       if (!(params->initialized)) {
-               throw ZerocoinException("Invalid parameters for accumulator");
-       }
-
-       this->value = this->params->accumulatorBase;
-}
-
-void Accumulator::accumulate(const PublicCoin& coin) {
-       // Make sure we're initialized
-       if(!(this->value)) {
-               throw ZerocoinException("Accumulator is not initialized");
-       }
-
-       if(this->denomination != coin.getDenomination()) {
-               //std::stringstream msg;
-               std::string msg;
-               msg = "Wrong denomination for coin. Expected coins of denomination: ";
-               msg += this->denomination;
-               msg += ". Instead, got a coin of denomination: ";
-               msg += coin.getDenomination();
-               throw std::invalid_argument(msg);
-       }
-
-       if(coin.validate()) {
-               // Compute new accumulator = "old accumulator"^{element} mod N
-               this->value = this->value.pow_mod(coin.getValue(), this->params->accumulatorModulus);
-       } else {
-               throw std::invalid_argument("Coin is not valid");
-       }
-}
-
-const CoinDenomination Accumulator::getDenomination() const {
-       return static_cast<CoinDenomination> (this->denomination);
-}
-
-const Bignum& Accumulator::getValue() const {
-       return this->value;
-}
-
-Accumulator& Accumulator::operator += (const PublicCoin& c) {
-       this->accumulate(c);
-       return *this;
-}
-
-bool Accumulator::operator == (const Accumulator rhs) const {
-       return this->value == rhs.value;
-}
-
-//AccumulatorWitness class
-AccumulatorWitness::AccumulatorWitness(const Params* p,
-                                       const Accumulator& checkpoint, const PublicCoin coin): params(p), witness(checkpoint), element(coin) {
-}
-
-void AccumulatorWitness::AddElement(const PublicCoin& c) {
-       if(element != c) {
-               witness += c;
-       }
-}
-
-const Bignum& AccumulatorWitness::getValue() const {
-       return this->witness.getValue();
-}
-
-bool AccumulatorWitness::VerifyWitness(const Accumulator& a, const PublicCoin &publicCoin) const {
-       Accumulator temp(witness);
-       temp += element;
-       return (temp == a && this->element == publicCoin);
-}
-
-AccumulatorWitness& AccumulatorWitness::operator +=(
-    const PublicCoin& rhs) {
-       this->AddElement(rhs);
-       return *this;
-}
-
-} /* namespace libzerocoin */
diff --git a/src/zerocoin/Accumulator.h b/src/zerocoin/Accumulator.h
deleted file mode 100644 (file)
index deed87b..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/**
- * @file       Accumulator.h
- *
- * @brief      Accumulator and AccumulatorWitness classes for the Zerocoin library.
- *
- * @author     Ian Miers, Christina Garman and Matthew Green
- * @date       June 2013
- *
- * @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
- * @license    This project is released under the MIT license.
- **/
-#ifndef ACCUMULATOR_H_
-#define ACCUMULATOR_H_
-
-namespace libzerocoin {
-/**
- * \brief Implementation of the RSA-based accumulator.
- **/
-
-class Accumulator {
-public:
-
-       /**
-        * @brief      Construct an Accumulator from a stream.
-        * @param p    An AccumulatorAndProofParams object containing global parameters
-        * @param d    the denomination of coins we are accumulating
-        * @throw      Zerocoin exception in case of invalid parameters
-        **/
-       template<typename Stream>
-       Accumulator(const AccumulatorAndProofParams* p, Stream& strm): params(p) {
-               strm >> *this;
-       }
-
-       template<typename Stream>
-       Accumulator(const Params* p, Stream& strm) {
-               strm >> *this;
-               this->params = &(p->accumulatorParams);
-       }
-
-       /**
-        * @brief      Construct an Accumulator from a Params object.
-        * @param p    A Params object containing global parameters
-        * @param d the denomination of coins we are accumulating
-        * @throw     Zerocoin exception in case of invalid parameters
-        **/
-       Accumulator(const AccumulatorAndProofParams* p, const CoinDenomination d = ZQ_PEDERSEN);
-
-       Accumulator(const Params* p, const CoinDenomination d = ZQ_PEDERSEN);
-
-       /**
-        * Accumulate a coin into the accumulator. Validates
-        * the coin prior to accumulation.
-        *
-        * @param coin  A PublicCoin to accumulate.
-        *
-        * @throw               Zerocoin exception if the coin is not valid.
-        *
-        **/
-       void accumulate(const PublicCoin &coin);
-
-       const CoinDenomination getDenomination() const;
-       /** Get the accumulator result
-        *
-        * @return a Bignum containing the result.
-        */
-       const Bignum& getValue() const;
-
-
-       // /**
-       //  * Used to set the accumulator value
-       //  *
-       //  * Use this to handle accumulator checkpoints
-       //  * @param b the value to set the accumulator to.
-       //  * @throw  A ZerocoinException if the accumulator value is invalid.
-       //  */
-       // void setValue(Bignum &b); // shouldn't this be a constructor?
-
-       /** Used to accumulate a coin
-        *
-        * @param c the coin to accumulate
-        * @return a refrence to the updated accumulator.
-        */
-       Accumulator& operator +=(const PublicCoin& c);
-       bool operator==(const Accumulator rhs) const;
-
-       IMPLEMENT_SERIALIZE
-       (
-           READWRITE(value);
-           READWRITE(denomination);
-       )
-private:
-       const AccumulatorAndProofParams* params;
-       Bignum value;
-       // Denomination is stored as an INT because storing
-       // and enum raises amigiuities in the serialize code //FIXME if possible
-       int denomination;
-};
-
-/**A witness that a PublicCoin is in the accumulation of a set of coins
- *
- */
-class AccumulatorWitness {
-public:
-       template<typename Stream>
-       AccumulatorWitness(const Params* p, Stream& strm): params(p) {
-               strm >> *this;
-       }
-
-       /**  Construct's a witness.  You must add all elements after the witness
-        * @param p pointer to params
-        * @param checkpoint the last known accumulator value before the element was added
-        * @param coin the coin we want a witness to
-        */
-       AccumulatorWitness(const Params* p, const Accumulator& checkpoint, const PublicCoin coin);
-
-       /** Adds element to the set whose's accumulation we are proving coin is a member of
-        *
-        * @param c the coin to add
-        */
-       void AddElement(const PublicCoin& c);
-
-       /**
-        *
-        * @return the value of the witness
-        */
-       const Bignum& getValue() const;
-
-       /** Checks that this is a witness to the accumulation of coin
-        * @param a             the accumulator we are checking against.
-        * @param publicCoin    the coin we're providing a witness for
-        * @return True if the witness computation validates
-        */
-       bool VerifyWitness(const Accumulator& a, const PublicCoin &publicCoin) const;
-
-       /**
-        * Adds rhs to the set whose's accumulation ware proving coin is a member of
-        * @param rhs the PublicCoin to add
-        * @return
-        */
-       AccumulatorWitness& operator +=(const PublicCoin& rhs);
-private:
-       const Params* params;
-       Accumulator witness;
-       const PublicCoin element;
-};
-
-} /* namespace libzerocoin */
-#endif /* ACCUMULATOR_H_ */
diff --git a/src/zerocoin/AccumulatorProofOfKnowledge.cpp b/src/zerocoin/AccumulatorProofOfKnowledge.cpp
deleted file mode 100644 (file)
index ed9ac91..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/**
- * @file       AccumulatorProofOfKnowledge.cpp
- *
- * @brief      AccumulatorProofOfKnowledge class for the Zerocoin library.
- *
- * @author     Ian Miers, Christina Garman and Matthew Green
- * @date       June 2013
- *
- * @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
- * @license    This project is released under the MIT license.
- **/
-
-#include "Zerocoin.h"
-
-namespace libzerocoin {
-
-AccumulatorProofOfKnowledge::AccumulatorProofOfKnowledge(const AccumulatorAndProofParams* p): params(p) {}
-
-AccumulatorProofOfKnowledge::AccumulatorProofOfKnowledge(const AccumulatorAndProofParams* p,
-        const Commitment& commitmentToCoin, const AccumulatorWitness& witness,
-        Accumulator& a): params(p) {
-
-       Bignum sg = params->accumulatorPoKCommitmentGroup.g;
-       Bignum sh = params->accumulatorPoKCommitmentGroup.h;
-
-       Bignum g_n = params->accumulatorQRNCommitmentGroup.g;
-       Bignum h_n = params->accumulatorQRNCommitmentGroup.h;
-
-       Bignum e = commitmentToCoin.getContents();
-       Bignum r = commitmentToCoin.getRandomness();
-
-       Bignum r_1 = Bignum::randBignum(params->accumulatorModulus/4);
-       Bignum r_2 = Bignum::randBignum(params->accumulatorModulus/4);
-       Bignum r_3 = Bignum::randBignum(params->accumulatorModulus/4);
-
-       this->C_e = g_n.pow_mod(e, params->accumulatorModulus) * h_n.pow_mod(r_1, params->accumulatorModulus);
-       this->C_u = witness.getValue() * h_n.pow_mod(r_2, params->accumulatorModulus);
-       this->C_r = g_n.pow_mod(r_2, params->accumulatorModulus) * h_n.pow_mod(r_3, params->accumulatorModulus);
-
-       Bignum r_alpha = Bignum::randBignum(params->maxCoinValue * Bignum(2).pow(params->k_prime + params->k_dprime));
-       if(!(Bignum::randBignum(Bignum(3)) % 2)) {
-               r_alpha = 0-r_alpha;
-       }
-
-       Bignum r_gamma = Bignum::randBignum(params->accumulatorPoKCommitmentGroup.modulus);
-       Bignum r_phi = Bignum::randBignum(params->accumulatorPoKCommitmentGroup.modulus);
-       Bignum r_psi = Bignum::randBignum(params->accumulatorPoKCommitmentGroup.modulus);
-       Bignum r_sigma = Bignum::randBignum(params->accumulatorPoKCommitmentGroup.modulus);
-       Bignum r_xi = Bignum::randBignum(params->accumulatorPoKCommitmentGroup.modulus);
-
-       Bignum r_epsilon =  Bignum::randBignum((params->accumulatorModulus/4) * Bignum(2).pow(params->k_prime + params->k_dprime));
-       if(!(Bignum::randBignum(Bignum(3)) % 2)) {
-               r_epsilon = 0-r_epsilon;
-       }
-       Bignum r_eta = Bignum::randBignum((params->accumulatorModulus/4) * Bignum(2).pow(params->k_prime + params->k_dprime));
-       if(!(Bignum::randBignum(Bignum(3)) % 2)) {
-               r_eta = 0-r_eta;
-       }
-       Bignum r_zeta = Bignum::randBignum((params->accumulatorModulus/4) * Bignum(2).pow(params->k_prime + params->k_dprime));
-       if(!(Bignum::randBignum(Bignum(3)) % 2)) {
-               r_zeta = 0-r_zeta;
-       }
-
-       Bignum r_beta = Bignum::randBignum((params->accumulatorModulus/4) * params->accumulatorPoKCommitmentGroup.modulus * Bignum(2).pow(params->k_prime + params->k_dprime));
-       if(!(Bignum::randBignum(Bignum(3)) % 2)) {
-               r_beta = 0-r_beta;
-       }
-       Bignum r_delta = Bignum::randBignum((params->accumulatorModulus/4) * params->accumulatorPoKCommitmentGroup.modulus * Bignum(2).pow(params->k_prime + params->k_dprime));
-       if(!(Bignum::randBignum(Bignum(3)) % 2)) {
-               r_delta = 0-r_delta;
-       }
-
-       this->st_1 = (sg.pow_mod(r_alpha, params->accumulatorPoKCommitmentGroup.modulus) * sh.pow_mod(r_phi, params->accumulatorPoKCommitmentGroup.modulus)) % params->accumulatorPoKCommitmentGroup.modulus;
-       this->st_2 = (((commitmentToCoin.getCommitmentValue() * sg.inverse(params->accumulatorPoKCommitmentGroup.modulus)).pow_mod(r_gamma, params->accumulatorPoKCommitmentGroup.modulus)) * sh.pow_mod(r_psi, params->accumulatorPoKCommitmentGroup.modulus)) % params->accumulatorPoKCommitmentGroup.modulus;
-       this->st_3 = ((sg * commitmentToCoin.getCommitmentValue()).pow_mod(r_sigma, params->accumulatorPoKCommitmentGroup.modulus) * sh.pow_mod(r_xi, params->accumulatorPoKCommitmentGroup.modulus)) % params->accumulatorPoKCommitmentGroup.modulus;
-
-       this->t_1 = (h_n.pow_mod(r_zeta, params->accumulatorModulus) * g_n.pow_mod(r_epsilon, params->accumulatorModulus)) % params->accumulatorModulus;
-       this->t_2 = (h_n.pow_mod(r_eta, params->accumulatorModulus) * g_n.pow_mod(r_alpha, params->accumulatorModulus)) % params->accumulatorModulus;
-       this->t_3 = (C_u.pow_mod(r_alpha, params->accumulatorModulus) * ((h_n.inverse(params->accumulatorModulus)).pow_mod(r_beta, params->accumulatorModulus))) % params->accumulatorModulus;
-       this->t_4 = (C_r.pow_mod(r_alpha, params->accumulatorModulus) * ((h_n.inverse(params->accumulatorModulus)).pow_mod(r_delta, params->accumulatorModulus)) * ((g_n.inverse(params->accumulatorModulus)).pow_mod(r_beta, params->accumulatorModulus))) % params->accumulatorModulus;
-
-       CHashWriter hasher(0,0);
-       hasher << *params << sg << sh << g_n << h_n << commitmentToCoin.getCommitmentValue() << C_e << C_u << C_r << st_1 << st_2 << st_3 << t_1 << t_2 << t_3 << t_4;
-
-       //According to the proof, this hash should be of length k_prime bits.  It is currently greater than that, which should not be a problem, but we should check this.
-       Bignum c = Bignum(hasher.GetHash());
-
-       this->s_alpha = r_alpha - c*e;
-       this->s_beta = r_beta - c*r_2*e;
-       this->s_zeta = r_zeta - c*r_3;
-       this->s_sigma = r_sigma - c*((e+1).inverse(params->accumulatorPoKCommitmentGroup.groupOrder));
-       this->s_eta = r_eta - c*r_1;
-       this->s_epsilon = r_epsilon - c*r_2;
-       this->s_delta = r_delta - c*r_3*e;
-       this->s_xi = r_xi + c*r*((e+1).inverse(params->accumulatorPoKCommitmentGroup.groupOrder));
-       this->s_phi = (r_phi - c*r) % params->accumulatorPoKCommitmentGroup.groupOrder;
-       this->s_gamma = r_gamma - c*((e-1).inverse(params->accumulatorPoKCommitmentGroup.groupOrder));
-       this->s_psi = r_psi + c*r*((e-1).inverse(params->accumulatorPoKCommitmentGroup.groupOrder));
-}
-
-/** Verifies that a commitment c is accumulated in accumulator a
- */
-bool AccumulatorProofOfKnowledge:: Verify(const Accumulator& a, const Bignum& valueOfCommitmentToCoin) const {
-       Bignum sg = params->accumulatorPoKCommitmentGroup.g;
-       Bignum sh = params->accumulatorPoKCommitmentGroup.h;
-
-       Bignum g_n = params->accumulatorQRNCommitmentGroup.g;
-       Bignum h_n = params->accumulatorQRNCommitmentGroup.h;
-
-       //According to the proof, this hash should be of length k_prime bits.  It is currently greater than that, which should not be a problem, but we should check this.
-       CHashWriter hasher(0,0);
-       hasher << *params << sg << sh << g_n << h_n << valueOfCommitmentToCoin << C_e << C_u << C_r << st_1 << st_2 << st_3 << t_1 << t_2 << t_3 << t_4;
-
-       Bignum c = Bignum(hasher.GetHash()); //this hash should be of length k_prime bits
-
-       Bignum st_1_prime = (valueOfCommitmentToCoin.pow_mod(c, params->accumulatorPoKCommitmentGroup.modulus) * sg.pow_mod(s_alpha, params->accumulatorPoKCommitmentGroup.modulus) * sh.pow_mod(s_phi, params->accumulatorPoKCommitmentGroup.modulus)) % params->accumulatorPoKCommitmentGroup.modulus;
-       Bignum st_2_prime = (sg.pow_mod(c, params->accumulatorPoKCommitmentGroup.modulus) * ((valueOfCommitmentToCoin * sg.inverse(params->accumulatorPoKCommitmentGroup.modulus)).pow_mod(s_gamma, params->accumulatorPoKCommitmentGroup.modulus)) * sh.pow_mod(s_psi, params->accumulatorPoKCommitmentGroup.modulus)) % params->accumulatorPoKCommitmentGroup.modulus;
-       Bignum st_3_prime = (sg.pow_mod(c, params->accumulatorPoKCommitmentGroup.modulus) * (sg * valueOfCommitmentToCoin).pow_mod(s_sigma, params->accumulatorPoKCommitmentGroup.modulus) * sh.pow_mod(s_xi, params->accumulatorPoKCommitmentGroup.modulus)) % params->accumulatorPoKCommitmentGroup.modulus;
-
-       Bignum t_1_prime = (C_r.pow_mod(c, params->accumulatorModulus) * h_n.pow_mod(s_zeta, params->accumulatorModulus) * g_n.pow_mod(s_epsilon, params->accumulatorModulus)) % params->accumulatorModulus;
-       Bignum t_2_prime = (C_e.pow_mod(c, params->accumulatorModulus) * h_n.pow_mod(s_eta, params->accumulatorModulus) * g_n.pow_mod(s_alpha, params->accumulatorModulus)) % params->accumulatorModulus;
-       Bignum t_3_prime = ((a.getValue()).pow_mod(c, params->accumulatorModulus) * C_u.pow_mod(s_alpha, params->accumulatorModulus) * ((h_n.inverse(params->accumulatorModulus)).pow_mod(s_beta, params->accumulatorModulus))) % params->accumulatorModulus;
-       Bignum t_4_prime = (C_r.pow_mod(s_alpha, params->accumulatorModulus) * ((h_n.inverse(params->accumulatorModulus)).pow_mod(s_delta, params->accumulatorModulus)) * ((g_n.inverse(params->accumulatorModulus)).pow_mod(s_beta, params->accumulatorModulus))) % params->accumulatorModulus;
-
-       bool result = false;
-
-       bool result_st1 = (st_1 == st_1_prime);
-       bool result_st2 = (st_2 == st_2_prime);
-       bool result_st3 = (st_3 == st_3_prime);
-
-       bool result_t1 = (t_1 == t_1_prime);
-       bool result_t2 = (t_2 == t_2_prime);
-       bool result_t3 = (t_3 == t_3_prime);
-       bool result_t4 = (t_4 == t_4_prime);
-
-       bool result_range = ((s_alpha >= -(params->maxCoinValue * Bignum(2).pow(params->k_prime + params->k_dprime + 1))) && (s_alpha <= (params->maxCoinValue * Bignum(2).pow(params->k_prime + params->k_dprime + 1))));
-
-       result = result_st1 && result_st2 && result_st3 && result_t1 && result_t2 && result_t3 && result_t4 && result_range;
-
-       return result;
-}
-
-} /* namespace libzerocoin */
diff --git a/src/zerocoin/AccumulatorProofOfKnowledge.h b/src/zerocoin/AccumulatorProofOfKnowledge.h
deleted file mode 100644 (file)
index 4078940..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * @file       AccumulatorProofOfKnowledge.h
- *
- * @brief      AccumulatorProofOfKnowledge class for the Zerocoin library.
- *
- * @author     Ian Miers, Christina Garman and Matthew Green
- * @date       June 2013
- *
- * @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
- * @license    This project is released under the MIT license.
- **/
-
-#ifndef ACCUMULATEPROOF_H_
-#define ACCUMULATEPROOF_H_
-
-namespace libzerocoin {
-
-/**A prove that a value insde the commitment commitmentToCoin is in an accumulator a.
- *
- */
-class AccumulatorProofOfKnowledge {
-public:
-       AccumulatorProofOfKnowledge(const AccumulatorAndProofParams* p);
-
-       /** Generates a proof that a commitment to a coin c was accumulated
-        * @param p  Cryptographic parameters
-        * @param commitmentToCoin commitment containing the coin we want to prove is accumulated
-        * @param witness The witness to the accumulation of the coin
-        * @param a
-        */
-       AccumulatorProofOfKnowledge(const AccumulatorAndProofParams* p, const Commitment& commitmentToCoin, const AccumulatorWitness& witness, Accumulator& a);
-       /** Verifies that  a commitment c is accumulated in accumulated a
-        */
-       bool Verify(const Accumulator& a,const Bignum& valueOfCommitmentToCoin) const;
-
-       IMPLEMENT_SERIALIZE
-       (
-           READWRITE(C_e);
-           READWRITE(C_u);
-           READWRITE(C_r);
-           READWRITE(st_1);
-           READWRITE(st_2);
-           READWRITE(st_3);
-           READWRITE(t_1);
-           READWRITE(t_2);
-           READWRITE(t_3);
-           READWRITE(t_4);
-           READWRITE(s_alpha);
-           READWRITE(s_beta);
-           READWRITE(s_zeta);
-           READWRITE(s_sigma);
-           READWRITE(s_eta);
-           READWRITE(s_epsilon);
-           READWRITE(s_delta);
-           READWRITE(s_xi);
-           READWRITE(s_phi);
-           READWRITE(s_gamma);
-           READWRITE(s_psi);
-       )
-private:
-       const AccumulatorAndProofParams* params;
-
-       /* Return values for proof */
-       Bignum C_e;
-       Bignum C_u;
-       Bignum C_r;
-
-       Bignum st_1;
-       Bignum st_2;
-       Bignum st_3;
-
-       Bignum t_1;
-       Bignum t_2;
-       Bignum t_3;
-       Bignum t_4;
-
-       Bignum s_alpha;
-       Bignum s_beta;
-       Bignum s_zeta;
-       Bignum s_sigma;
-       Bignum s_eta;
-       Bignum s_epsilon;
-       Bignum s_delta;
-       Bignum s_xi;
-       Bignum s_phi;
-       Bignum s_gamma;
-       Bignum s_psi;
-};
-
-} /* namespace libzerocoin */
-#endif /* ACCUMULATEPROOF_H_ */
diff --git a/src/zerocoin/Coin.cpp b/src/zerocoin/Coin.cpp
deleted file mode 100644 (file)
index c9aa9a5..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/**
- * @file       Coin.cpp
- *
- * @brief      PublicCoin and PrivateCoin classes for the Zerocoin library.
- *
- * @author     Ian Miers, Christina Garman and Matthew Green
- * @date       June 2013
- *
- * @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
- * @license    This project is released under the MIT license.
- **/
-
-#include <stdexcept>
-#include "Zerocoin.h"
-
-namespace libzerocoin {
-
-//PublicCoin class
-PublicCoin::PublicCoin(const Params* p):
-       params(p), denomination(ZQ_PEDERSEN) {
-       if(this->params->initialized == false) {
-               throw std::invalid_argument("Params are not initialized");
-       }
-};
-
-PublicCoin::PublicCoin(const Params* p, const Bignum& coin, const CoinDenomination d):
-       params(p), value(coin), denomination(d) {
-       if(this->params->initialized == false) {
-               throw std::invalid_argument("Params are not initialized");
-       }
-};
-
-bool PublicCoin::operator==(const PublicCoin& rhs) const {
-       return this->value == rhs.value;// FIXME check param equality
-}
-
-bool PublicCoin::operator!=(const PublicCoin& rhs) const {
-       return !(*this == rhs);
-}
-
-const Bignum& PublicCoin::getValue() const {
-       return this->value;
-}
-
-const CoinDenomination PublicCoin::getDenomination() const {
-       return static_cast<CoinDenomination>(this->denomination);
-}
-
-bool PublicCoin::validate() const {
-       return (this->params->accumulatorParams.minCoinValue < value) && (value < this->params->accumulatorParams.maxCoinValue) && value.isPrime(params->zkp_iterations);
-}
-
-//PrivateCoin class
-PrivateCoin::PrivateCoin(const Params* p, const CoinDenomination denomination): params(p), publicCoin(p) {
-       // Verify that the parameters are valid
-       if(this->params->initialized == false) {
-               throw std::invalid_argument("Params are not initialized");
-       }
-
-#ifdef ZEROCOIN_FAST_MINT
-       // Mint a new coin with a random serial number using the fast process.
-       // This is more vulnerable to timing attacks so don't mint coins when
-       // somebody could be timing you.
-       this->mintCoinFast(denomination);
-#else
-       // Mint a new coin with a random serial number using the standard process.
-       this->mintCoin(denomination);
-#endif
-       
-}
-
-/**
- *
- * @return the coins serial number
- */
-const Bignum& PrivateCoin::getSerialNumber() const {
-       return this->serialNumber;
-}
-
-const Bignum& PrivateCoin::getRandomness() const {
-       return this->randomness;
-}
-
-void PrivateCoin::mintCoin(const CoinDenomination denomination) {
-       // Repeat this process up to MAX_COINMINT_ATTEMPTS times until
-       // we obtain a prime number
-       for(uint32_t attempt = 0; attempt < MAX_COINMINT_ATTEMPTS; attempt++) {
-
-               // Generate a random serial number in the range 0...{q-1} where
-               // "q" is the order of the commitment group.
-               Bignum s = Bignum::randBignum(this->params->coinCommitmentGroup.groupOrder);
-
-               // Generate a Pedersen commitment to the serial number "s"
-               Commitment coin(&params->coinCommitmentGroup, s);
-
-               // Now verify that the commitment is a prime number
-               // in the appropriate range. If not, we'll throw this coin
-               // away and generate a new one.
-               if (coin.getCommitmentValue().isPrime(ZEROCOIN_MINT_PRIME_PARAM) &&
-                       coin.getCommitmentValue() >= params->accumulatorParams.minCoinValue &&
-                       coin.getCommitmentValue() <= params->accumulatorParams.maxCoinValue) {
-                       // Found a valid coin. Store it.
-                       this->serialNumber = s;
-                       this->randomness = coin.getRandomness();
-                       this->publicCoin = PublicCoin(params,coin.getCommitmentValue(), denomination);
-
-                       // Success! We're done.
-                       return;
-               }
-       }
-
-       // We only get here if we did not find a coin within
-       // MAX_COINMINT_ATTEMPTS. Throw an exception.
-       throw ZerocoinException("Unable to mint a new Zerocoin (too many attempts)");
-}
-
-void PrivateCoin::mintCoinFast(const CoinDenomination denomination) {
-       
-       // Generate a random serial number in the range 0...{q-1} where
-       // "q" is the order of the commitment group.
-       Bignum s = Bignum::randBignum(this->params->coinCommitmentGroup.groupOrder);
-       
-       // Generate a random number "r" in the range 0...{q-1}
-       Bignum r = Bignum::randBignum(this->params->coinCommitmentGroup.groupOrder);
-       
-       // Manually compute a Pedersen commitment to the serial number "s" under randomness "r"
-       // C = g^s * h^r mod p
-       Bignum commitmentValue = this->params->coinCommitmentGroup.g.pow_mod(s, this->params->coinCommitmentGroup.modulus).mul_mod(this->params->coinCommitmentGroup.h.pow_mod(r, this->params->coinCommitmentGroup.modulus), this->params->coinCommitmentGroup.modulus);
-       
-       // Repeat this process up to MAX_COINMINT_ATTEMPTS times until
-       // we obtain a prime number
-       for (uint32_t attempt = 0; attempt < MAX_COINMINT_ATTEMPTS; attempt++) {
-               // First verify that the commitment is a prime number
-               // in the appropriate range. If not, we'll throw this coin
-               // away and generate a new one.
-               if (commitmentValue.isPrime(ZEROCOIN_MINT_PRIME_PARAM) &&
-                       commitmentValue >= params->accumulatorParams.minCoinValue &&
-                       commitmentValue <= params->accumulatorParams.maxCoinValue) {
-                       // Found a valid coin. Store it.
-                       this->serialNumber = s;
-                       this->randomness = r;
-                       this->publicCoin = PublicCoin(params, commitmentValue, denomination);
-                               
-                       // Success! We're done.
-                       return;
-               }
-               
-               // Generate a new random "r_delta" in 0...{q-1}
-               Bignum r_delta = Bignum::randBignum(this->params->coinCommitmentGroup.groupOrder);
-
-               // The commitment was not prime. Increment "r" and recalculate "C":
-               // r = r + r_delta mod q
-               // C = C * h mod p
-               r = (r + r_delta) % this->params->coinCommitmentGroup.groupOrder;
-               commitmentValue = commitmentValue.mul_mod(this->params->coinCommitmentGroup.h.pow_mod(r_delta, this->params->coinCommitmentGroup.modulus), this->params->coinCommitmentGroup.modulus);
-       }
-               
-       // We only get here if we did not find a coin within
-       // MAX_COINMINT_ATTEMPTS. Throw an exception.
-       throw ZerocoinException("Unable to mint a new Zerocoin (too many attempts)");
-}
-       
-const PublicCoin& PrivateCoin::getPublicCoin() const {
-       return this->publicCoin;
-}
-
-} /* namespace libzerocoin */
diff --git a/src/zerocoin/Coin.h b/src/zerocoin/Coin.h
deleted file mode 100644 (file)
index 09e3caa..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
- * @file       Coin.h
- *
- * @brief      PublicCoin and PrivateCoin classes for the Zerocoin library.
- *
- * @author     Ian Miers, Christina Garman and Matthew Green
- * @date       June 2013
- *
- * @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
- * @license    This project is released under the MIT license.
- **/
-
-#ifndef COIN_H_
-#define COIN_H_
-#include "../bignum.h"
-#include "Params.h"
-namespace libzerocoin {
-
-enum  CoinDenomination {
-    ZQ_LOVELACE = 1,
-    ZQ_GOLDWASSER = 10,
-    ZQ_RACKOFF = 25,
-    ZQ_PEDERSEN = 50,
-    ZQ_WILLIAMSON = 100 // Malcolm J. Williamson,
-                    // the scientist who actually invented
-                    // Public key cryptography
-};
-
-/** A Public coin is the part of a coin that
- * is published to the network and what is handled
- * by other clients. It contains only the value
- * of commitment to a serial number and the
- * denomination of the coin.
- */
-class PublicCoin {
-public:
-       template<typename Stream>
-       PublicCoin(const Params* p, Stream& strm): params(p) {
-               strm >> *this;
-       }
-
-       PublicCoin( const Params* p);
-
-       /**Generates a public coin
-        *
-        * @param p cryptographic paramters
-        * @param coin the value of the commitment.
-        * @param denomination The denomination of the coin. Defaults to ZQ_PEDERSEN
-        */
-       PublicCoin( const Params* p, const Bignum& coin, const CoinDenomination d = ZQ_PEDERSEN);
-       const Bignum& getValue() const;
-       const CoinDenomination getDenomination() const;
-       bool operator==(const PublicCoin& rhs) const;
-       bool operator!=(const PublicCoin& rhs) const;
-       /** Checks that a coin prime
-        *  and in the appropriate range
-        *  given the parameters
-        * @return true if valid
-        */
-       bool validate() const;
-       IMPLEMENT_SERIALIZE
-       (
-           READWRITE(value);
-           READWRITE(denomination);
-       )
-private:
-       const Params* params;
-       Bignum value;
-       // Denomination is stored as an INT because storing
-       // and enum raises amigiuities in the serialize code //FIXME if possible
-       int denomination;
-};
-
-/**
- * A private coin. As the name implies, the content
- * of this should stay private except PublicCoin.
- *
- * Contains a coin's serial number, a commitment to it,
- * and opening randomness for the commitment.
- *
- * @warning Failure to keep this secret(or safe),
- * @warning will result in the theft of your coins
- * @warning and a TOTAL loss of anonymity.
- */
-class PrivateCoin {
-public:
-       template<typename Stream>
-       PrivateCoin(const Params* p, Stream& strm): params(p) {
-               strm >> *this;
-       }
-       PrivateCoin(const Params* p,const CoinDenomination denomination = ZQ_PEDERSEN);
-       const PublicCoin& getPublicCoin() const;
-       const Bignum& getSerialNumber() const;
-       const Bignum& getRandomness() const;
-
-       IMPLEMENT_SERIALIZE
-       (
-           READWRITE(publicCoin);
-           READWRITE(randomness);
-           READWRITE(serialNumber);
-       )
-private:
-       const Params* params;
-       PublicCoin publicCoin;
-       Bignum randomness;
-       Bignum serialNumber;
-
-       /**
-        * @brief Mint a new coin.
-        * @param denomination the denomination of the coin to mint
-        * @throws ZerocoinException if the process takes too long
-        *
-        * Generates a new Zerocoin by (a) selecting a random serial
-        * number, (b) committing to this serial number and repeating until
-        * the resulting commitment is prime. Stores the
-        * resulting commitment (coin) and randomness (trapdoor).
-        **/
-       void mintCoin(const CoinDenomination denomination);
-       
-       /**
-        * @brief Mint a new coin using a faster process.
-        * @param denomination the denomination of the coin to mint
-        * @throws ZerocoinException if the process takes too long
-        *
-        * Generates a new Zerocoin by (a) selecting a random serial
-        * number, (b) committing to this serial number and repeating until
-        * the resulting commitment is prime. Stores the
-        * resulting commitment (coin) and randomness (trapdoor).
-        * This routine is substantially faster than the
-        * mintCoin() routine, but could be more vulnerable
-        * to timing attacks. Don't use it if you think someone
-        * could be timing your coin minting.
-        **/
-       void mintCoinFast(const CoinDenomination denomination);
-
-};
-
-} /* namespace libzerocoin */
-#endif /* COIN_H_ */
diff --git a/src/zerocoin/CoinSpend.cpp b/src/zerocoin/CoinSpend.cpp
deleted file mode 100644 (file)
index c7890f5..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * @file       CoinSpend.cpp
- *
- * @brief      CoinSpend class for the Zerocoin library.
- *
- * @author     Ian Miers, Christina Garman and Matthew Green
- * @date       June 2013
- *
- * @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
- * @license    This project is released under the MIT license.
- **/
-
-#include "Zerocoin.h"
-
-namespace libzerocoin {
-
-CoinSpend::CoinSpend(const Params* p, const PrivateCoin& coin,
-                     Accumulator& a, const AccumulatorWitness& witness, const SpendMetaData& m):
-       params(p),
-       denomination(coin.getPublicCoin().getDenomination()),
-       coinSerialNumber((coin.getSerialNumber())),
-       accumulatorPoK(&p->accumulatorParams),
-       serialNumberSoK(p),
-       commitmentPoK(&p->serialNumberSoKCommitmentGroup, &p->accumulatorParams.accumulatorPoKCommitmentGroup) {
-
-       // Sanity check: let's verify that the Witness is valid with respect to
-       // the coin and Accumulator provided.
-       if (!(witness.VerifyWitness(a, coin.getPublicCoin()))) {
-               throw std::invalid_argument("Accumulator witness does not verify");
-       }
-
-       // 1: Generate two separate commitments to the public coin (C), each under
-       // a different set of public parameters. We do this because the RSA accumulator
-       // has specific requirements for the commitment parameters that are not
-       // compatible with the group we use for the serial number proof.
-       // Specifically, our serial number proof requires the order of the commitment group
-       // to be the same as the modulus of the upper group. The Accumulator proof requires a
-       // group with a significantly larger order.
-       const Commitment fullCommitmentToCoinUnderSerialParams(&p->serialNumberSoKCommitmentGroup, coin.getPublicCoin().getValue());
-       this->serialCommitmentToCoinValue = fullCommitmentToCoinUnderSerialParams.getCommitmentValue();
-
-       const Commitment fullCommitmentToCoinUnderAccParams(&p->accumulatorParams.accumulatorPoKCommitmentGroup, coin.getPublicCoin().getValue());
-       this->accCommitmentToCoinValue = fullCommitmentToCoinUnderAccParams.getCommitmentValue();
-
-       // 2. Generate a ZK proof that the two commitments contain the same public coin.
-       this->commitmentPoK = CommitmentProofOfKnowledge(&p->serialNumberSoKCommitmentGroup, &p->accumulatorParams.accumulatorPoKCommitmentGroup, fullCommitmentToCoinUnderSerialParams, fullCommitmentToCoinUnderAccParams);
-
-       // Now generate the two core ZK proofs:
-       // 3. Proves that the committed public coin is in the Accumulator (PoK of "witness")
-       this->accumulatorPoK = AccumulatorProofOfKnowledge(&p->accumulatorParams, fullCommitmentToCoinUnderAccParams, witness, a);
-
-       // 4. Proves that the coin is correct w.r.t. serial number and hidden coin secret
-       // (This proof is bound to the coin 'metadata', i.e., transaction hash)
-       this->serialNumberSoK = SerialNumberSignatureOfKnowledge(p, coin, fullCommitmentToCoinUnderSerialParams, signatureHash(m));
-}
-
-const Bignum&
-CoinSpend::getCoinSerialNumber() {
-       return this->coinSerialNumber;
-}
-
-const CoinDenomination
-CoinSpend::getDenomination() {
-       return static_cast<CoinDenomination>(this->denomination);
-}
-
-bool
-CoinSpend::Verify(const Accumulator& a, const SpendMetaData &m) const {
-       // Verify both of the sub-proofs using the given meta-data
-       return  (a.getDenomination() == this->denomination)
-               && commitmentPoK.Verify(serialCommitmentToCoinValue, accCommitmentToCoinValue)
-               && accumulatorPoK.Verify(a, accCommitmentToCoinValue)
-               && serialNumberSoK.Verify(coinSerialNumber, serialCommitmentToCoinValue, signatureHash(m));
-}
-
-const uint256 CoinSpend::signatureHash(const SpendMetaData &m) const {
-       CHashWriter h(0,0);
-       h << m << serialCommitmentToCoinValue << accCommitmentToCoinValue << commitmentPoK << accumulatorPoK;
-       return h.GetHash();
-}
-
-} /* namespace libzerocoin */
diff --git a/src/zerocoin/CoinSpend.h b/src/zerocoin/CoinSpend.h
deleted file mode 100644 (file)
index 8bf6925..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * @file       CoinSpend.h
- *
- * @brief      CoinSpend class for the Zerocoin library.
- *
- * @author     Ian Miers, Christina Garman and Matthew Green
- * @date       June 2013
- *
- * @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
- * @license    This project is released under the MIT license.
- **/
-
-#ifndef COINSPEND_H_
-#define COINSPEND_H_
-
-#include "Params.h"
-#include "Coin.h"
-#include "Commitment.h"
-#include "../bignum.h"
-#include "Accumulator.h"
-#include "AccumulatorProofOfKnowledge.h"
-#include "SerialNumberSignatureOfKnowledge.h"
-#include "SpendMetaData.h"
-#include "../serialize.h"
-
-namespace libzerocoin {
-
-/** The complete proof needed to spend a zerocoin.
- * Composes together a proof that a coin is accumulated
- * and that it has a given serial number.
- */
-class CoinSpend {
-public:
-       template<typename Stream>
-       CoinSpend(const Params* p,  Stream& strm):denomination(ZQ_PEDERSEN),
-               accumulatorPoK(&p->accumulatorParams),
-               serialNumberSoK(p),
-               commitmentPoK(&p->serialNumberSoKCommitmentGroup, &p->accumulatorParams.accumulatorPoKCommitmentGroup) {
-               strm >> *this;
-       }
-       /**Generates a proof spending a zerocoin.
-        *
-        * To use this, provide an unspent PrivateCoin, the latest Accumulator
-        * (e.g from the most recent Bitcoin block) containing the public part
-        * of the coin, a witness to that, and whatever medeta data is needed.
-        *
-        * Once constructed, this proof can be serialized and sent.
-        * It is validated simply be calling validate.
-        * @warning Validation only checks that the proof is correct
-        * @warning for the specified values in this class. These values must be validated
-        *  Clients ought to check that
-        * 1) params is the right params
-        * 2) the accumulator actually is in some block
-        * 3) that the serial number is unspent
-        * 4) that the transaction
-        *
-        * @param p cryptographic parameters
-        * @param coin The coin to be spend
-        * @param a The current accumulator containing the coin
-        * @param witness The witness showing that the accumulator contains the coin
-        * @param m arbitrary meta data related to the spend that might be needed by Bitcoin
-        *                      (i.e. the transaction hash)
-        * @throw ZerocoinException if the process fails
-        */
-       CoinSpend(const Params* p, const PrivateCoin& coin, Accumulator& a, const AccumulatorWitness& witness, const SpendMetaData& m);
-
-       /** Returns the serial number of the coin spend by this proof.
-        *
-        * @return the coin's serial number
-        */
-       const Bignum& getCoinSerialNumber();
-
-       /**Gets the denomination of the coin spent in this proof.
-        *
-        * @return the denomination
-        */
-       const CoinDenomination getDenomination();
-
-       bool Verify(const Accumulator& a, const SpendMetaData &metaData) const;
-
-       IMPLEMENT_SERIALIZE
-       (
-           READWRITE(denomination);
-           READWRITE(accCommitmentToCoinValue);
-           READWRITE(serialCommitmentToCoinValue);
-           READWRITE(coinSerialNumber);
-           READWRITE(accumulatorPoK);
-           READWRITE(serialNumberSoK);
-           READWRITE(commitmentPoK);
-       )
-
-private:
-       const Params *params;
-       const uint256 signatureHash(const SpendMetaData &m) const;
-       // Denomination is stored as an INT because storing
-       // and enum raises amigiuities in the serialize code //FIXME if possible
-       int denomination;
-       Bignum accCommitmentToCoinValue;
-       Bignum serialCommitmentToCoinValue;
-       Bignum coinSerialNumber;
-       AccumulatorProofOfKnowledge accumulatorPoK;
-       SerialNumberSignatureOfKnowledge serialNumberSoK;
-       CommitmentProofOfKnowledge commitmentPoK;
-};
-
-} /* namespace libzerocoin */
-#endif /* COINSPEND_H_ */
diff --git a/src/zerocoin/Commitment.cpp b/src/zerocoin/Commitment.cpp
deleted file mode 100644 (file)
index fbe83ae..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/**
- * @file       Commitment.cpp
- *
- * @brief      Commitment and CommitmentProof classes for the Zerocoin library.
- *
- * @author     Ian Miers, Christina Garman and Matthew Green
- * @date       June 2013
- *
- * @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
- * @license    This project is released under the MIT license.
- **/
-
-#include <stdlib.h>
-#include "Zerocoin.h"
-
-namespace libzerocoin {
-
-//Commitment class
-Commitment::Commitment(const IntegerGroupParams* p,
-                                   const Bignum& value): params(p), contents(value) {
-       this->randomness = Bignum::randBignum(params->groupOrder);
-       this->commitmentValue = (params->g.pow_mod(this->contents, params->modulus).mul_mod(
-                                params->h.pow_mod(this->randomness, params->modulus), params->modulus));
-}
-
-const Bignum& Commitment::getCommitmentValue() const {
-       return this->commitmentValue;
-}
-
-const Bignum& Commitment::getRandomness() const {
-       return this->randomness;
-}
-
-const Bignum& Commitment::getContents() const {
-       return this->contents;
-}
-
-//CommitmentProofOfKnowledge class
-CommitmentProofOfKnowledge::CommitmentProofOfKnowledge(const IntegerGroupParams* ap, const IntegerGroupParams* bp): ap(ap), bp(bp) {}
-
-// TODO: get parameters from the commitment group
-CommitmentProofOfKnowledge::CommitmentProofOfKnowledge(const IntegerGroupParams* aParams,
-        const IntegerGroupParams* bParams, const Commitment& a, const Commitment& b):
-       ap(aParams),bp(bParams)
-{
-       Bignum r1, r2, r3;
-
-       // First: make sure that the two commitments have the
-       // same contents.
-       if (a.getContents() != b.getContents()) {
-               throw std::invalid_argument("Both commitments must contain the same value");
-       }
-
-       // Select three random values "r1, r2, r3" in the range 0 to (2^l)-1 where l is:
-       // length of challenge value + max(modulus 1, modulus 2, order 1, order 2) + margin.
-       // We set "margin" to be a relatively generous  security parameter.
-       //
-       // We choose these large values to ensure statistical zero knowledge.
-       uint32_t randomSize = COMMITMENT_EQUALITY_CHALLENGE_SIZE + COMMITMENT_EQUALITY_SECMARGIN +
-                             std::max(std::max(this->ap->modulus.bitSize(), this->bp->modulus.bitSize()),
-                                      std::max(this->ap->groupOrder.bitSize(), this->bp->groupOrder.bitSize()));
-       Bignum maxRange = (Bignum(2).pow(randomSize) - Bignum(1));
-
-       r1 = Bignum::randBignum(maxRange);
-       r2 = Bignum::randBignum(maxRange);
-       r3 = Bignum::randBignum(maxRange);
-
-       // Generate two random, ephemeral commitments "T1, T2"
-       // of the form:
-       // T1 = g1^r1 * h1^r2 mod p1
-       // T2 = g2^r1 * h2^r3 mod p2
-       //
-       // Where (g1, h1, p1) are from "aParams" and (g2, h2, p2) are from "bParams".
-       Bignum T1 = this->ap->g.pow_mod(r1, this->ap->modulus).mul_mod((this->ap->h.pow_mod(r2, this->ap->modulus)), this->ap->modulus);
-       Bignum T2 = this->bp->g.pow_mod(r1, this->bp->modulus).mul_mod((this->bp->h.pow_mod(r3, this->bp->modulus)), this->bp->modulus);
-
-       // Now hash commitment "A" with commitment "B" as well as the
-       // parameters and the two ephemeral commitments "T1, T2" we just generated
-       this->challenge = calculateChallenge(a.getCommitmentValue(), b.getCommitmentValue(), T1, T2);
-
-       // Let "m" be the contents of the commitments "A, B". We have:
-       // A =  g1^m  * h1^x  mod p1
-       // B =  g2^m  * h2^y  mod p2
-       // T1 = g1^r1 * h1^r2 mod p1
-       // T2 = g2^r1 * h2^r3 mod p2
-       //
-       // Now compute:
-       //  S1 = r1 + (m * challenge)   -- note, not modular arithmetic
-       //  S2 = r2 + (x * challenge)   -- note, not modular arithmetic
-       //  S3 = r3 + (y * challenge)   -- note, not modular arithmetic
-       this->S1 = r1 + (a.getContents() * this->challenge);
-       this->S2 = r2 + (a.getRandomness() * this->challenge);
-       this->S3 = r3 + (b.getRandomness() * this->challenge);
-
-       // We're done. The proof is S1, S2, S3 and "challenge", all of which
-       // are stored in member variables.
-}
-
-bool CommitmentProofOfKnowledge::Verify(const Bignum& A, const Bignum& B) const
-{
-       // Compute the maximum range of S1, S2, S3 and verify that the given values are
-       // in a correct range. This might be an unnecessary check.
-       uint32_t maxSize = 64 * (COMMITMENT_EQUALITY_CHALLENGE_SIZE + COMMITMENT_EQUALITY_SECMARGIN +
-                                std::max(std::max(this->ap->modulus.bitSize(), this->bp->modulus.bitSize()),
-                                         std::max(this->ap->groupOrder.bitSize(), this->bp->groupOrder.bitSize())));
-
-       if ((uint32_t)this->S1.bitSize() > maxSize ||
-               (uint32_t)this->S2.bitSize() > maxSize ||
-               (uint32_t)this->S3.bitSize() > maxSize ||
-               this->S1 < Bignum(0) ||
-               this->S2 < Bignum(0) ||
-               this->S3 < Bignum(0) ||
-               this->challenge < Bignum(0) ||
-               this->challenge > (Bignum(2).pow(COMMITMENT_EQUALITY_CHALLENGE_SIZE) - Bignum(1))) {
-               // Invalid inputs. Reject.
-               return false;
-       }
-
-       // Compute T1 = g1^S1 * h1^S2 * inverse(A^{challenge}) mod p1
-       Bignum T1 = A.pow_mod(this->challenge, ap->modulus).inverse(ap->modulus).mul_mod(
-                       (ap->g.pow_mod(S1, ap->modulus).mul_mod(ap->h.pow_mod(S2, ap->modulus), ap->modulus)),
-                       ap->modulus);
-
-       // Compute T2 = g2^S1 * h2^S3 * inverse(B^{challenge}) mod p2
-       Bignum T2 = B.pow_mod(this->challenge, bp->modulus).inverse(bp->modulus).mul_mod(
-                       (bp->g.pow_mod(S1, bp->modulus).mul_mod(bp->h.pow_mod(S3, bp->modulus), bp->modulus)),
-                       bp->modulus);
-
-       // Hash T1 and T2 along with all of the public parameters
-       Bignum computedChallenge = calculateChallenge(A, B, T1, T2);
-
-       // Return success if the computed challenge matches the incoming challenge
-       if(computedChallenge == this->challenge) {
-               return true;
-       }
-
-       // Otherwise return failure
-       return false;
-}
-
-const Bignum CommitmentProofOfKnowledge::calculateChallenge(const Bignum& a, const Bignum& b, const Bignum &commitOne, const Bignum &commitTwo) const {
-       CHashWriter hasher(0,0);
-
-       // Hash together the following elements:
-       // * A string identifying the proof
-       // * Commitment A
-       // * Commitment B
-       // * Ephemeral commitment T1
-       // * Ephemeral commitment T2
-       // * A serialized instance of the commitment A parameters
-       // * A serialized instance of the commitment B parameters
-
-       hasher << std::string(ZEROCOIN_COMMITMENT_EQUALITY_PROOF);
-       hasher << commitOne;
-       hasher << std::string("||");
-       hasher << commitTwo;
-       hasher << std::string("||");
-       hasher << a;
-       hasher << std::string("||");
-       hasher << b;
-       hasher << std::string("||");
-       hasher << *(this->ap);
-       hasher << std::string("||");
-       hasher << *(this->bp);
-
-       // Convert the SHA256 result into a Bignum
-       // Note that if we ever change the size of the hash function we will have
-       // to update COMMITMENT_EQUALITY_CHALLENGE_SIZE appropriately!
-       return Bignum(hasher.GetHash());
-}
-
-} /* namespace libzerocoin */
diff --git a/src/zerocoin/Commitment.h b/src/zerocoin/Commitment.h
deleted file mode 100644 (file)
index d8630a3..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * @file       Commitment.h
- *
- * @brief      Commitment and CommitmentProof classes for the Zerocoin library.
- *
- * @author     Ian Miers, Christina Garman and Matthew Green
- * @date       June 2013
- *
- * @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
- * @license    This project is released under the MIT license.
- **/
-
-#ifndef COMMITMENT_H_
-#define COMMITMENT_H_
-
-#include "Params.h"
-#include "../serialize.h"
-
-// We use a SHA256 hash for our PoK challenges. Update the following
-// if we ever change hash functions.
-#define COMMITMENT_EQUALITY_CHALLENGE_SIZE  256
-
-// A 512-bit security parameter for the statistical ZK PoK.
-#define COMMITMENT_EQUALITY_SECMARGIN       512
-
-namespace libzerocoin {
-
-/**
- * A commitment, complete with contents and opening randomness.
- * These should remain secret. Publish only the commitment value.
- */
-class Commitment {
-public:
-       /**Generates a Pedersen commitment to the given value.
-        *
-        * @param p the group parameters for the coin
-        * @param value the value to commit to
-        */
-       Commitment(const IntegerGroupParams* p, const Bignum& value);
-       const Bignum& getCommitmentValue() const;
-       const Bignum& getRandomness() const;
-       const Bignum& getContents() const;
-private:
-       const IntegerGroupParams *params;
-       Bignum commitmentValue;
-       Bignum randomness;
-       const Bignum contents;
-       IMPLEMENT_SERIALIZE
-       (
-           READWRITE(commitmentValue);
-           READWRITE(randomness);
-           READWRITE(contents);
-       )
-};
-
-/**Proof that two commitments open to the same value.
- *
- */
-class CommitmentProofOfKnowledge {
-public:
-       CommitmentProofOfKnowledge(const IntegerGroupParams* ap, const IntegerGroupParams* bp);
-       /** Generates a proof that two commitments, a and b, open to the same value.
-        *
-        * @param ap the IntegerGroup for commitment a
-        * @param bp the IntegerGroup for commitment b
-        * @param a the first commitment
-        * @param b the second commitment
-        */
-       CommitmentProofOfKnowledge(const IntegerGroupParams* aParams, const IntegerGroupParams* bParams, const Commitment& a, const Commitment& b);
-       //FIXME: is it best practice that this is here?
-       template<typename Stream>
-       CommitmentProofOfKnowledge(const IntegerGroupParams* aParams,
-                                  const IntegerGroupParams* bParams, Stream& strm): ap(aParams), bp(bParams)
-       {
-               strm >> *this;
-       }
-
-       const Bignum calculateChallenge(const Bignum& a, const Bignum& b, const Bignum &commitOne, const Bignum &commitTwo) const;
-
-       /**Verifies the proof
-        *
-        * @return true if the proof is valid.
-        */
-       /**Verifies the proof of equality of the two commitments
-        *
-        * @param A value of commitment one
-        * @param B value of commitment two
-        * @return
-        */
-       bool Verify(const Bignum& A, const Bignum& B) const;
-       IMPLEMENT_SERIALIZE
-       (
-           READWRITE(S1);
-           READWRITE(S2);
-           READWRITE(S3);
-           READWRITE(challenge);
-       )
-private:
-       const IntegerGroupParams *ap, *bp;
-
-       Bignum S1, S2, S3, challenge;
-};
-
-} /* namespace libzerocoin */
-#endif /* COMMITMENT_H_ */
diff --git a/src/zerocoin/ParamGeneration.cpp b/src/zerocoin/ParamGeneration.cpp
deleted file mode 100644 (file)
index d5bd36b..0000000
+++ /dev/null
@@ -1,654 +0,0 @@
-/// \file       ParamGeneration.cpp
-///
-/// \brief      Parameter manipulation routines for the Zerocoin cryptographic
-///             components.
-///
-/// \author     Ian Miers, Christina Garman and Matthew Green
-/// \date       June 2013
-///
-/// \copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
-/// \license    This project is released under the MIT license.
-
-#include <string>
-#include "Zerocoin.h"
-
-using namespace std;
-
-namespace libzerocoin {
-
-/// \brief Fill in a set of Zerocoin parameters from a modulus "N".
-/// \param N                A trusted RSA modulus
-/// \param aux              An optional auxiliary string used in derivation
-/// \param securityLevel    A security level
-///
-/// \throws         ZerocoinException if the process fails
-///
-/// Fills in a ZC_Params data structure deterministically from
-/// a trustworthy RSA modulus "N", which is provided as a Bignum.
-///
-/// Note: this routine makes the fundamental assumption that "N"
-/// encodes a valid RSA-style modulus of the form "e1*e2" for some
-/// unknown safe primes "e1" and "e2". These factors must not
-/// be known to any party, or the security of Zerocoin is
-/// compromised. The integer "N" must be a MINIMUM of 1023
-/// in length, and 3072 bits is strongly recommended.
-///
-
-void
-CalculateParams(Params &params, Bignum N, string aux, uint32_t securityLevel)
-{
-       params.initialized = false;
-       params.accumulatorParams.initialized = false;
-
-       // Verify that |N| is > 1023 bits.
-       uint32_t NLen = N.bitSize();
-       if (NLen < 1023) {
-               throw ZerocoinException("Modulus must be at least 1023 bits");
-       }
-
-       // Verify that "securityLevel" is  at least 80 bits (minimum).
-       if (securityLevel < 80) {
-               throw ZerocoinException("Security level must be at least 80 bits.");
-       }
-
-       // Set the accumulator modulus to "N".
-       params.accumulatorParams.accumulatorModulus = N;
-
-       // Calculate the required size of the field "F_p" into which
-       // we're embedding the coin commitment group. This may throw an
-       // exception if the securityLevel is too large to be supported
-       // by the current modulus.
-       uint32_t pLen = 0;
-       uint32_t qLen = 0;
-       calculateGroupParamLengths(NLen - 2, securityLevel, &pLen, &qLen);
-
-       // Calculate candidate parameters ("p", "q") for the coin commitment group
-       // using a deterministic process based on "N", the "aux" string, and
-       // the dedicated string "COMMITMENTGROUP".
-       params.coinCommitmentGroup = deriveIntegerGroupParams(calculateSeed(N, aux, securityLevel, STRING_COMMIT_GROUP),
-                                    pLen, qLen);
-
-       // Next, we derive parameters for a second Accumulated Value commitment group.
-       // This is a Schnorr group with the specific property that the order of the group
-       // must be exactly equal to "q" from the commitment group. We set
-       // the modulus of the new group equal to "2q+1" and test to see if this is prime.
-       params.serialNumberSoKCommitmentGroup = deriveIntegerGroupFromOrder(params.coinCommitmentGroup.modulus);
-
-       // Calculate the parameters for the internal commitment
-       // using the same process.
-       params.accumulatorParams.accumulatorPoKCommitmentGroup = deriveIntegerGroupParams(calculateSeed(N, aux, securityLevel, STRING_AIC_GROUP),
-               qLen + 300, qLen + 1);
-
-       // Calculate the parameters for the accumulator QRN commitment generators. This isn't really
-       // a whole group, just a pair of random generators in QR_N.
-       uint32_t resultCtr;
-       params.accumulatorParams.accumulatorQRNCommitmentGroup.g = generateIntegerFromSeed(NLen - 1,
-               calculateSeed(N, aux, securityLevel, STRING_QRNCOMMIT_GROUPG),
-               &resultCtr).pow_mod(Bignum(2), N);
-       params.accumulatorParams.accumulatorQRNCommitmentGroup.h = generateIntegerFromSeed(NLen - 1,
-               calculateSeed(N, aux, securityLevel, STRING_QRNCOMMIT_GROUPG),
-               &resultCtr).pow_mod(Bignum(2), N);
-
-       // Calculate the accumulator base, which we calculate as "u = C**2 mod N"
-       // where C is an arbitrary value. In the unlikely case that "u = 1" we increment
-       // "C" and repeat.
-       Bignum constant(ACCUMULATOR_BASE_CONSTANT);
-       params.accumulatorParams.accumulatorBase = Bignum(1);
-       for (uint32_t count = 0; count < MAX_ACCUMGEN_ATTEMPTS && params.accumulatorParams.accumulatorBase.isOne(); count++) {
-               params.accumulatorParams.accumulatorBase = constant.pow_mod(Bignum(2), params.accumulatorParams.accumulatorModulus);
-       }
-
-       // Compute the accumulator range. The upper range is the largest possible coin commitment value.
-       // The lower range is sqrt(upper range) + 1. Since OpenSSL doesn't have
-       // a square root function we use a slightly higher approximation.
-       params.accumulatorParams.maxCoinValue = params.coinCommitmentGroup.modulus;
-       params.accumulatorParams.minCoinValue = Bignum(2).pow((params.coinCommitmentGroup.modulus.bitSize() / 2) + 3);
-
-       // If all went well, mark params as successfully initialized.
-       params.accumulatorParams.initialized = true;
-
-       // If all went well, mark params as successfully initialized.
-       params.initialized = true;
-}
-
-/// \brief Format a seed string by hashing several values.
-/// \param N                A Bignum
-/// \param aux              An auxiliary string
-/// \param securityLevel    The security level in bits
-/// \param groupName        A group description string
-/// \throws         ZerocoinException if the process fails
-///
-/// Returns the hash of the value.
-
-uint256
-calculateGeneratorSeed(uint256 seed, uint256 pSeed, uint256 qSeed, string label, uint32_t index, uint32_t count)
-{
-       CHashWriter hasher(0,0);
-       uint256     hash;
-
-       // Compute the hash of:
-       // <modulus>||<securitylevel>||<auxString>||groupName
-       hasher << seed;
-       hasher << string("||");
-       hasher << pSeed;
-       hasher << string("||");
-       hasher << qSeed;
-       hasher << string("||");
-       hasher << label;
-       hasher << string("||");
-       hasher << index;
-       hasher << string("||");
-       hasher << count;
-
-       return hasher.GetHash();
-}
-
-/// \brief Format a seed string by hashing several values.
-/// \param N                A Bignum
-/// \param aux              An auxiliary string
-/// \param securityLevel    The security level in bits
-/// \param groupName        A group description string
-/// \throws         ZerocoinException if the process fails
-///
-/// Returns the hash of the value.
-
-uint256
-calculateSeed(Bignum modulus, string auxString, uint32_t securityLevel, string groupName)
-{
-       CHashWriter hasher(0,0);
-       uint256     hash;
-
-       // Compute the hash of:
-       // <modulus>||<securitylevel>||<auxString>||groupName
-       hasher << modulus;
-       hasher << string("||");
-       hasher << securityLevel;
-       hasher << string("||");
-       hasher << auxString;
-       hasher << string("||");
-       hasher << groupName;
-
-       return hasher.GetHash();
-}
-
-uint256
-calculateHash(uint256 input)
-{
-       CHashWriter hasher(0,0);
-
-       // Compute the hash of "input"
-       hasher << input;
-
-       return hasher.GetHash();
-}
-
-/// \brief Calculate field/group parameter sizes based on a security level.
-/// \param maxPLen          Maximum size of the field (modulus "p") in bits.
-/// \param securityLevel    Required security level in bits (at least 80)
-/// \param pLen             Result: length of "p" in bits
-/// \param qLen             Result: length of "q" in bits
-/// \throws                 ZerocoinException if the process fails
-///
-/// Calculates the appropriate sizes of "p" and "q" for a prime-order
-/// subgroup of order "q" embedded within a field "F_p". The sizes
-/// are based on a 'securityLevel' provided in symmetric-equivalent
-/// bits. Our choices slightly exceed the specs in FIPS 186-3:
-///
-/// securityLevel = 80:     pLen = 1024, qLen = 256
-/// securityLevel = 112:    pLen = 2048, qLen = 256
-/// securityLevel = 128:    qLen = 3072, qLen = 320
-///
-/// If the length of "p" exceeds the length provided in "maxPLen", or
-/// if "securityLevel < 80" this routine throws an exception.
-
-void
-calculateGroupParamLengths(uint32_t maxPLen, uint32_t securityLevel,
-                           uint32_t *pLen, uint32_t *qLen)
-{
-       *pLen = *qLen = 0;
-
-       if (securityLevel < 80) {
-               throw ZerocoinException("Security level must be at least 80 bits.");
-       } else if (securityLevel == 80) {
-               *qLen = 256;
-               *pLen = 1024;
-       } else if (securityLevel <= 112) {
-               *qLen = 256;
-               *pLen = 2048;
-       } else if (securityLevel <= 128) {
-               *qLen = 320;
-               *pLen = 3072;
-       } else {
-               throw ZerocoinException("Security level not supported.");
-       }
-
-       if (*pLen > maxPLen) {
-               throw ZerocoinException("Modulus size is too small for this security level.");
-       }
-}
-
-/// \brief Deterministically compute a set of group parameters using NIST procedures.
-/// \param seedStr  A byte string seeding the process.
-/// \param pLen     The desired length of the modulus "p" in bits
-/// \param qLen     The desired length of the order "q" in bits
-/// \return         An IntegerGroupParams object
-///
-/// Calculates the description of a group G of prime order "q" embedded within
-/// a field "F_p". The input to this routine is in arbitrary seed. It uses the
-/// algorithms described in FIPS 186-3 Appendix A.1.2 to calculate
-/// primes "p" and "q". It uses the procedure in Appendix A.2.3 to
-/// derive two generators "g", "h".
-
-IntegerGroupParams
-deriveIntegerGroupParams(uint256 seed, uint32_t pLen, uint32_t qLen)
-{
-       IntegerGroupParams result;
-       Bignum p;
-       Bignum q;
-       uint256 pSeed, qSeed;
-
-       // Calculate "p" and "q" and "domain_parameter_seed" from the
-       // "seed" buffer above, using the procedure described in NIST
-       // FIPS 186-3, Appendix A.1.2.
-       calculateGroupModulusAndOrder(seed, pLen, qLen, &(result.modulus),
-                                     &(result.groupOrder), &pSeed, &qSeed);
-
-       // Calculate the generators "g", "h" using the process described in
-       // NIST FIPS 186-3, Appendix A.2.3. This algorithm takes ("p", "q",
-       // "domain_parameter_seed", "index"). We use "index" value 1
-       // to generate "g" and "index" value 2 to generate "h".
-       result.g = calculateGroupGenerator(seed, pSeed, qSeed, result.modulus, result.groupOrder, 1);
-       result.h = calculateGroupGenerator(seed, pSeed, qSeed, result.modulus, result.groupOrder, 2);
-
-       // Perform some basic tests to make sure we have good parameters
-       if ((uint32_t)(result.modulus.bitSize()) < pLen ||          // modulus is pLen bits long
-               (uint32_t)(result.groupOrder.bitSize()) < qLen ||       // order is qLen bits long
-               !(result.modulus.isPrime()) ||                          // modulus is prime
-               !(result.groupOrder.isPrime()) ||                       // order is prime
-               !((result.g.pow_mod(result.groupOrder, result.modulus)).isOne()) || // g^order mod modulus = 1
-               !((result.h.pow_mod(result.groupOrder, result.modulus)).isOne()) || // h^order mod modulus = 1
-               ((result.g.pow_mod(Bignum(100), result.modulus)).isOne()) ||        // g^100 mod modulus != 1
-               ((result.h.pow_mod(Bignum(100), result.modulus)).isOne()) ||        // h^100 mod modulus != 1
-               result.g == result.h ||                                 // g != h
-               result.g.isOne()) {                                     // g != 1
-               // If any of the above tests fail, throw an exception
-               throw ZerocoinException("Group parameters are not valid");
-       }
-
-       return result;
-}
-
-/// \brief Deterministically compute a  set of group parameters with a specified order.
-/// \param groupOrder   The order of the group
-/// \return         An IntegerGroupParams object
-///
-/// Given "q" calculates the description of a group G of prime order "q" embedded within
-/// a field "F_p".
-
-IntegerGroupParams
-deriveIntegerGroupFromOrder(Bignum &groupOrder)
-{
-       IntegerGroupParams result;
-
-       // Set the order to "groupOrder"
-       result.groupOrder = groupOrder;
-
-       // Try possible values for "modulus" of the form "groupOrder * 2 * i" where
-       // "p" is prime and i is a counter starting at 1.
-       for (uint32_t i = 1; i < NUM_SCHNORRGEN_ATTEMPTS; i++) {
-               // Set modulus equal to "groupOrder * 2 * i"
-               result.modulus = (result.groupOrder * Bignum(i*2)) + Bignum(1);
-
-               // Test the result for primality
-               // TODO: This is a probabilistic routine and thus not the right choice
-               if (result.modulus.isPrime(256)) {
-
-                       // Success.
-                       //
-                       // Calculate the generators "g", "h" using the process described in
-                       // NIST FIPS 186-3, Appendix A.2.3. This algorithm takes ("p", "q",
-                       // "domain_parameter_seed", "index"). We use "index" value 1
-                       // to generate "g" and "index" value 2 to generate "h".
-                       uint256 seed = calculateSeed(groupOrder, "", 128, "");
-                       uint256 pSeed = calculateHash(seed);
-                       uint256 qSeed = calculateHash(pSeed);
-                       result.g = calculateGroupGenerator(seed, pSeed, qSeed, result.modulus, result.groupOrder, 1);
-                       result.h = calculateGroupGenerator(seed, pSeed, qSeed, result.modulus, result.groupOrder, 2);
-
-                       // Perform some basic tests to make sure we have good parameters
-                       if (!(result.modulus.isPrime()) ||                          // modulus is prime
-                               !(result.groupOrder.isPrime()) ||                       // order is prime
-                               !((result.g.pow_mod(result.groupOrder, result.modulus)).isOne()) || // g^order mod modulus = 1
-                               !((result.h.pow_mod(result.groupOrder, result.modulus)).isOne()) || // h^order mod modulus = 1
-                               ((result.g.pow_mod(Bignum(100), result.modulus)).isOne()) ||        // g^100 mod modulus != 1
-                               ((result.h.pow_mod(Bignum(100), result.modulus)).isOne()) ||        // h^100 mod modulus != 1
-                               result.g == result.h ||                                 // g != h
-                               result.g.isOne()) {                                     // g != 1
-                               // If any of the above tests fail, throw an exception
-                               throw ZerocoinException("Group parameters are not valid");
-                       }
-
-                       return result;
-               }
-       }
-
-       // If we reached this point group generation has failed. Throw an exception.
-       throw ZerocoinException("Too many attempts to generate Schnorr group.");
-}
-
-/// \brief Deterministically compute a group description using NIST procedures.
-/// \param seed                         A byte string seeding the process.
-/// \param pLen                         The desired length of the modulus "p" in bits
-/// \param qLen                         The desired length of the order "q" in bits
-/// \param resultModulus                A value "p" describing a finite field "F_p"
-/// \param resultGroupOrder             A value "q" describing the order of a subgroup
-/// \param resultDomainParameterSeed    A resulting seed for use in later calculations.
-///
-/// Calculates the description of a group G of prime order "q" embedded within
-/// a field "F_p". The input to this routine is in arbitrary seed. It uses the
-/// algorithms described in FIPS 186-3 Appendix A.1.2 to calculate
-/// primes "p" and "q".
-
-void
-calculateGroupModulusAndOrder(uint256 seed, uint32_t pLen, uint32_t qLen,
-                              Bignum *resultModulus, Bignum *resultGroupOrder,
-                              uint256 *resultPseed, uint256 *resultQseed)
-{
-       // Verify that the seed length is >= qLen
-       if (qLen > (sizeof(seed)) * 8) {
-               // TODO: The use of 256-bit seeds limits us to 256-bit group orders. We should probably change this.
-               // throw ZerocoinException("Seed is too short to support the required security level.");
-       }
-
-#ifdef ZEROCOIN_DEBUG
-       cout << "calculateGroupModulusAndOrder: pLen = " << pLen << endl;
-#endif
-
-       // Generate a random prime for the group order.
-       // This may throw an exception, which we'll pass upwards.
-       // Result is the value "resultGroupOrder", "qseed" and "qgen_counter".
-       uint256     qseed;
-       uint32_t    qgen_counter;
-       *resultGroupOrder = generateRandomPrime(qLen, seed, &qseed, &qgen_counter);
-
-       // Using ⎡pLen / 2 + 1⎤ as the length and qseed as the input_seed, use the random prime
-       // routine to obtain p0 , pseed, and pgen_counter. We pass exceptions upward.
-       uint32_t    p0len = ceil((pLen / 2.0) + 1);
-       uint256     pseed;
-       uint32_t    pgen_counter;
-       Bignum p0 = generateRandomPrime(p0len, qseed, &pseed, &pgen_counter);
-
-       // Set x = 0, old_counter = pgen_counter
-       uint32_t    old_counter = pgen_counter;
-
-       // Generate a random integer "x" of pLen bits
-       uint32_t iterations;
-       Bignum x = generateIntegerFromSeed(pLen, pseed, &iterations);
-       pseed += (iterations + 1);
-
-       // Set x = 2^{pLen−1} + (x mod 2^{pLen–1}).
-       Bignum powerOfTwo = Bignum(2).pow(pLen-1);
-       x = powerOfTwo + (x % powerOfTwo);
-
-       // t = ⎡x / (2 * resultGroupOrder * p0)⎤.
-       // TODO: we don't have a ceiling function
-       Bignum t = x / (Bignum(2) * (*resultGroupOrder) * p0);
-
-       // Now loop until we find a valid prime "p" or we fail due to
-       // pgen_counter exceeding ((4*pLen) + old_counter).
-       for ( ; pgen_counter <= ((4*pLen) + old_counter) ; pgen_counter++) {
-               // If (2 * t * resultGroupOrder * p0 + 1) > 2^{pLen}, then
-               // t = ⎡2^{pLen−1} / (2 * resultGroupOrder * p0)⎤.
-               powerOfTwo = Bignum(2).pow(pLen);
-               Bignum prod = (Bignum(2) * t * (*resultGroupOrder) * p0) + Bignum(1);
-               if (prod > powerOfTwo) {
-                       // TODO: implement a ceil function
-                       t = Bignum(2).pow(pLen-1) / (Bignum(2) * (*resultGroupOrder) * p0);
-               }
-
-               // Compute a candidate prime resultModulus = 2tqp0 + 1.
-               *resultModulus = (Bignum(2) * t * (*resultGroupOrder) * p0) + Bignum(1);
-
-               // Verify that resultModulus is prime. First generate a pseudorandom integer "a".
-               Bignum a = generateIntegerFromSeed(pLen, pseed, &iterations);
-               pseed += iterations + 1;
-
-               // Set a = 2 + (a mod (resultModulus–3)).
-               a = Bignum(2) + (a % ((*resultModulus) - Bignum(3)));
-
-               // Set z = a^{2 * t * resultGroupOrder} mod resultModulus
-               Bignum z = a.pow_mod(Bignum(2) * t * (*resultGroupOrder), (*resultModulus));
-
-               // If GCD(z–1, resultModulus) == 1 AND (z^{p0} mod resultModulus == 1)
-               // then we have found our result. Return.
-               if ((resultModulus->gcd(z - Bignum(1))).isOne() &&
-                       (z.pow_mod(p0, (*resultModulus))).isOne()) {
-                       // Success! Return the seeds and primes.
-                       *resultPseed = pseed;
-                       *resultQseed = qseed;
-                       return;
-               }
-
-               // This prime did not work out. Increment "t" and try again.
-               t = t + Bignum(1);
-       } // loop continues until pgen_counter exceeds a limit
-
-       // We reach this point only if we exceeded our maximum iteration count.
-       // Throw an exception.
-       throw ZerocoinException("Unable to generate a prime modulus for the group");
-}
-
-/// \brief Deterministically compute a generator for a given group.
-/// \param seed                         A first seed for the process.
-/// \param pSeed                        A second seed for the process.
-/// \param qSeed                        A third seed for the process.
-/// \param modulus                      Proposed prime modulus for the field.
-/// \param groupOrder                   Proposed order of the group.
-/// \param index                        Index value, selects which generator you're building.
-/// \return                             The resulting generator.
-/// \throws                             A ZerocoinException if error.
-///
-/// Generates a random group generator deterministically as a function of (seed,pSeed,qSeed)
-/// Uses the algorithm described in FIPS 186-3 Appendix A.2.3.
-
-Bignum
-calculateGroupGenerator(uint256 seed, uint256 pSeed, uint256 qSeed, Bignum modulus, Bignum groupOrder, uint32_t index)
-{
-       Bignum result;
-
-       // Verify that 0 <= index < 256
-       if (index > 255) {
-               throw ZerocoinException("Invalid index for group generation");
-       }
-
-       // Compute e = (modulus - 1) / groupOrder
-       Bignum e = (modulus - Bignum(1)) / groupOrder;
-
-       // Loop until we find a generator
-       for (uint32_t count = 1; count < MAX_GENERATOR_ATTEMPTS; count++) {
-               // hash = Hash(seed || pSeed || qSeed || “ggen” || index || count
-               uint256 hash = calculateGeneratorSeed(seed, pSeed, qSeed, "ggen", index, count);
-               Bignum W(hash);
-
-               // Compute result = W^e mod p
-               result = W.pow_mod(e, modulus);
-
-               // If result > 1, we have a generator
-               if (result > 1) {
-                       return result;
-               }
-       }
-
-       // We only get here if we failed to find a generator
-       throw ZerocoinException("Unable to find a generator, too many attempts");
-}
-
-/// \brief Deterministically compute a random prime number.
-/// \param primeBitLen                  Desired bit length of the prime.
-/// \param in_seed                      Input seed for the process.
-/// \param out_seed                     Result: output seed from the process.
-/// \param prime_gen_counter            Result: number of iterations required.
-/// \return                             The resulting prime number.
-/// \throws                             A ZerocoinException if error.
-///
-/// Generates a random prime number of primeBitLen bits from a given input
-/// seed. Uses the Shawe-Taylor algorithm as described in FIPS 186-3
-/// Appendix C.6. This is a recursive function.
-
-Bignum
-generateRandomPrime(uint32_t primeBitLen, uint256 in_seed, uint256 *out_seed,
-                    uint32_t *prime_gen_counter)
-{
-       // Verify that primeBitLen is not too small
-       if (primeBitLen < 2) {
-               throw ZerocoinException("Prime length is too short");
-       }
-
-       // If primeBitLen < 33 bits, perform the base case.
-       if (primeBitLen < 33) {
-               Bignum result(0);
-
-               // Set prime_seed = in_seed, prime_gen_counter = 0.
-               uint256     prime_seed = in_seed;
-               (*prime_gen_counter) = 0;
-
-               // Loop up to "4 * primeBitLen" iterations.
-               while ((*prime_gen_counter) < (4 * primeBitLen)) {
-
-                       // Generate a pseudorandom integer "c" of length primeBitLength bits
-                       uint32_t iteration_count;
-                       Bignum c = generateIntegerFromSeed(primeBitLen, prime_seed, &iteration_count);
-#ifdef ZEROCOIN_DEBUG
-                       cout << "generateRandomPrime: primeBitLen = " << primeBitLen << endl;
-                       cout << "Generated c = " << c << endl;
-#endif
-
-                       prime_seed += (iteration_count + 1);
-                       (*prime_gen_counter)++;
-
-                       // Set "intc" to be the least odd integer >= "c" we just generated
-                       uint32_t intc = c.getulong();
-                       intc = (2 * floor(intc / 2.0)) + 1;
-#ifdef ZEROCOIN_DEBUG
-                       cout << "Should be odd. c = " << intc << endl;
-                       cout << "The big num is: c = " << c << endl;
-#endif
-
-                       // Perform trial division on this (relatively small) integer to determine if "intc"
-                       // is prime. If so, return success.
-                       if (primalityTestByTrialDivision(intc)) {
-                               // Return "intc" converted back into a Bignum and "prime_seed". We also updated
-                               // the variable "prime_gen_counter" in previous statements.
-                               result = intc;
-                               *out_seed = prime_seed;
-
-                               // Success
-                               return result;
-                       }
-               } // while()
-
-               // If we reached this point there was an error finding a candidate prime
-               // so throw an exception.
-               throw ZerocoinException("Unable to find prime in Shawe-Taylor algorithm");
-
-               // END OF BASE CASE
-       }
-       // If primeBitLen >= 33 bits, perform the recursive case.
-       else {
-               // Recurse to find a new random prime of roughly half the size
-               uint32_t newLength = ceil((double)primeBitLen / 2.0) + 1;
-               Bignum c0 = generateRandomPrime(newLength, in_seed, out_seed, prime_gen_counter);
-
-               // Generate a random integer "x" of primeBitLen bits using the output
-               // of the previous call.
-               uint32_t numIterations;
-               Bignum x = generateIntegerFromSeed(primeBitLen, *out_seed, &numIterations);
-               (*out_seed) += numIterations + 1;
-
-               // Compute "t" = ⎡x / (2 * c0⎤
-               // TODO no Ceiling call
-               Bignum t = x / (Bignum(2) * c0);
-
-               // Repeat the following procedure until we find a prime (or time out)
-               for (uint32_t testNum = 0; testNum < MAX_PRIMEGEN_ATTEMPTS; testNum++) {
-
-                       // If ((2 * t * c0) + 1 > 2^{primeBitLen}),
-                       // then t = ⎡2^{primeBitLen} – 1 / (2 * c0)⎤.
-                       if ((Bignum(2) * t * c0) > (Bignum(2).pow(Bignum(primeBitLen)))) {
-                               t = ((Bignum(2).pow(Bignum(primeBitLen))) - Bignum(1)) / (Bignum(2) * c0);
-                       }
-
-                       // Set c = (2 * t * c0) + 1
-                       Bignum c = (Bignum(2) * t * c0) + Bignum(1);
-
-                       // Increment prime_gen_counter
-                       (*prime_gen_counter)++;
-
-                       // Test "c" for primality as follows:
-                       // 1. First pick an integer "a" in between 2 and (c - 2)
-                       Bignum a = generateIntegerFromSeed(c.bitSize(), (*out_seed), &numIterations);
-                       a = Bignum(2) + (a % (c - Bignum(3)));
-                       (*out_seed) += (numIterations + 1);
-
-                       // 2. Compute "z" = a^{2*t} mod c
-                       Bignum z = a.pow_mod(Bignum(2) * t, c);
-
-                       // 3. Check if "c" is prime.
-                       //    Specifically, verify that gcd((z-1), c) == 1 AND (z^c0 mod c) == 1
-                       // If so we return "c" as our result.
-                       if (c.gcd(z - Bignum(1)).isOne() && z.pow_mod(c0, c).isOne()) {
-                               // Return "c", out_seed and prime_gen_counter
-                               // (the latter two of which were already updated)
-                               return c;
-                       }
-
-                       // 4. If the test did not succeed, increment "t" and loop
-                       t = t + Bignum(1);
-               } // end of test loop
-       }
-
-       // We only reach this point if the test loop has iterated MAX_PRIMEGEN_ATTEMPTS
-       // and failed to identify a valid prime. Throw an exception.
-       throw ZerocoinException("Unable to generate random prime (too many tests)");
-}
-
-Bignum
-generateIntegerFromSeed(uint32_t numBits, uint256 seed, uint32_t *numIterations)
-{
-       Bignum      result(0);
-       uint32_t    iterations = ceil((double)numBits / (double)HASH_OUTPUT_BITS);
-
-#ifdef ZEROCOIN_DEBUG
-       cout << "numBits = " << numBits << endl;
-       cout << "iterations = " << iterations << endl;
-#endif
-
-       // Loop "iterations" times filling up the value "result" with random bits
-       for (uint32_t count = 0; count < iterations; count++) {
-               // result += ( H(pseed + count) * 2^{count * p0len} )
-               result += Bignum(calculateHash(seed + count)) * Bignum(2).pow(count * HASH_OUTPUT_BITS);
-       }
-
-       result = Bignum(2).pow(numBits - 1) + (result % (Bignum(2).pow(numBits - 1)));
-
-       // Return the number of iterations and the result
-       *numIterations = iterations;
-       return result;
-}
-
-/// \brief Determines whether a uint32_t is a prime through trial division.
-/// \param candidate       Candidate to test.
-/// \return                true if the value is prime, false otherwise
-///
-/// Performs trial division to determine whether a uint32_t is prime.
-
-bool
-primalityTestByTrialDivision(uint32_t candidate)
-{
-       // TODO: HACK HACK WRONG WRONG
-       Bignum canBignum(candidate);
-
-       return canBignum.isPrime();
-}
-
-} // namespace libzerocoin
diff --git a/src/zerocoin/ParamGeneration.h b/src/zerocoin/ParamGeneration.h
deleted file mode 100644 (file)
index de2d452..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/// \file       ParamGeneration.h
-///
-/// \brief      Parameter generation routines for Zerocoin.
-///
-/// \author     Ian Miers, Christina Garman and Matthew Green
-/// \date       June 2013
-///
-/// \copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
-/// \license    This project is released under the MIT license.
-
-#ifndef PARAMGENERATION_H_
-#define PARAMGENERATION_H_
-
-namespace libzerocoin {
-
-void CalculateParams(Params &params, Bignum N, std::string aux, uint32_t securityLevel);
-void calculateGroupParamLengths(uint32_t maxPLen, uint32_t securityLevel,
-                                uint32_t *pLen, uint32_t *qLen);
-
-// Constants
-#define STRING_COMMIT_GROUP         "COIN_COMMITMENT_GROUP"
-#define STRING_AVC_GROUP            "ACCUMULATED_VALUE_COMMITMENT_GROUP"
-#define STRING_AVC_ORDER            "ACCUMULATED_VALUE_COMMITMENT_ORDER"
-#define STRING_AIC_GROUP            "ACCUMULATOR_INTERNAL_COMMITMENT_GROUP"
-#define STRING_QRNCOMMIT_GROUPG     "ACCUMULATOR_QRN_COMMITMENT_GROUPG"
-#define STRING_QRNCOMMIT_GROUPH     "ACCUMULATOR_QRN_COMMITMENT_GROUPH"
-#define ACCUMULATOR_BASE_CONSTANT   31
-#define MAX_PRIMEGEN_ATTEMPTS       10000
-#define MAX_ACCUMGEN_ATTEMPTS       10000
-#define MAX_GENERATOR_ATTEMPTS      10000
-#define NUM_SCHNORRGEN_ATTEMPTS     10000
-
-// Prototypes
-bool                primalityTestByTrialDivision(uint32_t candidate);
-uint256             calculateSeed(Bignum modulus, std::string auxString, uint32_t securityLevel, std::string groupName);
-uint256             calculateGeneratorSeed(uint256 seed, uint256 pSeed, uint256 qSeed, std::string label, uint32_t index, uint32_t count);
-
-uint256             calculateHash(uint256 input);
-IntegerGroupParams  deriveIntegerGroupParams(uint256 seed, uint32_t pLen, uint32_t qLen);
-IntegerGroupParams  deriveIntegerGroupFromOrder(Bignum &groupOrder);
-void                calculateGroupModulusAndOrder(uint256 seed, uint32_t pLen, uint32_t qLen,
-        Bignum *resultModulus, Bignum *resultGroupOrder,
-        uint256 *resultPseed, uint256 *resultQseed);
-Bignum              calculateGroupGenerator(uint256 seed, uint256 pSeed, uint256 qSeed, Bignum modulus,
-        Bignum groupOrder, uint32_t index);
-Bignum              generateRandomPrime(uint32_t primeBitLen, uint256 in_seed, uint256 *out_seed,
-                                        uint32_t *prime_gen_counter);
-Bignum              generateIntegerFromSeed(uint32_t numBits, uint256 seed, uint32_t *numIterations);
-bool                primalityTestByTrialDivision(uint32_t candidate);
-
-}/* namespace libzerocoin */
-
-#endif /* PARAMGENERATION_H_ */
diff --git a/src/zerocoin/Params.cpp b/src/zerocoin/Params.cpp
deleted file mode 100644 (file)
index c275044..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
-* @file       Params.cpp
-*
-* @brief      Parameter class for Zerocoin.
-*
-* @author     Ian Miers, Christina Garman and Matthew Green
-* @date       June 2013
-*
-* @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
-* @license    This project is released under the MIT license.
-**/
-#include "Zerocoin.h"
-
-namespace libzerocoin {
-
-Params::Params(Bignum N, uint32_t securityLevel) {
-       this->zkp_hash_len = securityLevel;
-       this->zkp_iterations = securityLevel;
-
-       this->accumulatorParams.k_prime = ACCPROOF_KPRIME;
-       this->accumulatorParams.k_dprime = ACCPROOF_KDPRIME;
-
-       // Generate the parameters
-       CalculateParams(*this, N, ZEROCOIN_PROTOCOL_VERSION, securityLevel);
-
-       this->accumulatorParams.initialized = true;
-       this->initialized = true;
-}
-
-AccumulatorAndProofParams::AccumulatorAndProofParams() {
-       this->initialized = false;
-}
-
-IntegerGroupParams::IntegerGroupParams() {
-       this->initialized = false;
-}
-
-Bignum IntegerGroupParams::randomElement() const {
-       // The generator of the group raised
-       // to a random number less than the order of the group
-       // provides us with a uniformly distributed random number.
-       return this->g.pow_mod(Bignum::randBignum(this->groupOrder),this->modulus);
-}
-
-} /* namespace libzerocoin */
diff --git a/src/zerocoin/Params.h b/src/zerocoin/Params.h
deleted file mode 100644 (file)
index 60a5af4..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/**
-* @file       Params.h
-*
-* @brief      Parameter classes for Zerocoin.
-*
-* @author     Ian Miers, Christina Garman and Matthew Green
-* @date       June 2013
-*
-* @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
-* @license    This project is released under the MIT license.
-**/
-#ifndef PARAMS_H_
-#define PARAMS_H_
-
-namespace libzerocoin {
-
-class IntegerGroupParams {
-public:
-       /** @brief Integer group class, default constructor
-       *
-       * Allocates an empty (uninitialized) set of parameters.
-       **/
-       IntegerGroupParams();
-
-       /**
-        * Generates a random group element
-        * @return a random element in the group.
-        */
-       Bignum randomElement() const;
-       bool initialized;
-
-       /**
-        * A generator for the group.
-        */
-       Bignum g;
-
-       /**
-        * A second generator for the group.
-        * Note log_g(h) and log_h(g) must
-        * be unknown.
-        */
-       Bignum h;
-
-       /**
-        * The modulus for the group.
-        */
-       Bignum modulus;
-
-       /**
-        * The order of the group
-        */
-       Bignum groupOrder;
-
-       IMPLEMENT_SERIALIZE
-       (
-           READWRITE(initialized);
-           READWRITE(g);
-           READWRITE(h);
-           READWRITE(modulus);
-           READWRITE(groupOrder);
-       )
-};
-
-class AccumulatorAndProofParams {
-public:
-       /** @brief Construct a set of Zerocoin parameters from a modulus "N".
-       * @param N                A trusted RSA modulus
-       * @param securityLevel    A security level expressed in symmetric bits (default 80)
-       *
-       * Allocates and derives a set of Zerocoin parameters from
-       * a trustworthy RSA modulus "N". This routine calculates all
-       * of the remaining parameters (group descriptions etc.) from N
-       * using a verifiable, deterministic procedure.
-       *
-       * Note: this constructor makes the fundamental assumption that "N"
-       * encodes a valid RSA-style modulus of the form "e1 * e2" where
-       * "e1" and "e2" are safe primes. The factors "e1", "e2" MUST NOT
-       * be known to any party, or the security of Zerocoin is
-       * compromised. The integer "N" must be a MINIMUM of 1024
-       * in length. 3072 bits is strongly recommended.
-       **/
-       AccumulatorAndProofParams();
-
-       //AccumulatorAndProofParams(Bignum accumulatorModulus);
-
-       bool initialized;
-
-       /**
-        * Modulus used for the accumulator.
-        * Product of two safe primes who's factorization is unknown.
-        */
-       Bignum accumulatorModulus;
-
-       /**
-        * The initial value for the accumulator
-        * A random Quadratic residue mod n thats not 1
-        */
-       Bignum accumulatorBase;
-
-       /**
-        * Lower bound on the value for committed coin.
-        * Required by the accumulator proof.
-        */
-       Bignum minCoinValue;
-
-       /**
-        * Upper bound on the value for a comitted coin.
-        * Required by the accumulator proof.
-        */
-       Bignum maxCoinValue;
-
-       /**
-        * The second of two groups used to form a commitment to
-        * a coin (which it self is a commitment to a serial number).
-        * This one differs from serialNumberSokCommitment due to
-        * restrictions from Camenisch and Lysyanskaya's paper.
-        */
-       IntegerGroupParams accumulatorPoKCommitmentGroup;
-
-       /**
-        * Hidden order quadratic residue group mod N.
-        * Used in the accumulator proof.
-        */
-       IntegerGroupParams accumulatorQRNCommitmentGroup;
-
-       /**
-        * Security parameter.
-        * Bit length of the challenges used in the accumulator proof.
-        */
-       uint32_t k_prime;
-
-       /**
-        * Security parameter.
-        * The statistical zero-knowledgeness of the accumulator proof.
-        */
-       uint32_t k_dprime;
-
-       IMPLEMENT_SERIALIZE
-       (
-           READWRITE(initialized);
-           READWRITE(accumulatorModulus);
-           READWRITE(accumulatorBase);
-           READWRITE(accumulatorPoKCommitmentGroup);
-           READWRITE(accumulatorQRNCommitmentGroup);
-           READWRITE(minCoinValue);
-           READWRITE(maxCoinValue);
-           READWRITE(k_prime);
-           READWRITE(k_dprime);
-       )
-};
-
-class Params {
-public:
-       /** @brief Construct a set of Zerocoin parameters from a modulus "N".
-       * @param N                A trusted RSA modulus
-       * @param securityLevel    A security level expressed in symmetric bits (default 80)
-       *
-       * Allocates and derives a set of Zerocoin parameters from
-       * a trustworthy RSA modulus "N". This routine calculates all
-       * of the remaining parameters (group descriptions etc.) from N
-       * using a verifiable, deterministic procedure.
-       *
-       * Note: this constructor makes the fundamental assumption that "N"
-       * encodes a valid RSA-style modulus of the form "e1 * e2" where
-       * "e1" and "e2" are safe primes. The factors "e1", "e2" MUST NOT
-       * be known to any party, or the security of Zerocoin is
-       * compromised. The integer "N" must be a MINIMUM of 1024
-       * in length. 3072 bits is strongly recommended.
-       **/
-       Params(Bignum accumulatorModulus,
-              uint32_t securityLevel = ZEROCOIN_DEFAULT_SECURITYLEVEL);
-
-       bool initialized;
-
-       AccumulatorAndProofParams accumulatorParams;
-
-       /**
-        * The Quadratic Residue group from which we form
-        * a coin as a commitment  to a serial number.
-        */
-       IntegerGroupParams coinCommitmentGroup;
-
-       /**
-        * One of two groups used to form a commitment to
-        * a coin (which it self is a commitment to a serial number).
-        * This is the one used in the serial number poof.
-        * It's order must be equal to the modulus of coinCommitmentGroup.
-        */
-       IntegerGroupParams serialNumberSoKCommitmentGroup;
-
-       /**
-        * The number of iterations to use in the serial
-        * number proof.
-        */
-       uint32_t zkp_iterations;
-
-       /**
-        * The amount of the hash function we use for
-        * proofs.
-        */
-       uint32_t zkp_hash_len;
-
-       IMPLEMENT_SERIALIZE
-       (
-           READWRITE(initialized);
-           READWRITE(accumulatorParams);
-           READWRITE(coinCommitmentGroup);
-           READWRITE(serialNumberSoKCommitmentGroup);
-           READWRITE(zkp_iterations);
-           READWRITE(zkp_hash_len);
-       )
-};
-
-} /* namespace libzerocoin */
-
-#endif /* PARAMS_H_ */
diff --git a/src/zerocoin/SerialNumberSignatureOfKnowledge.cpp b/src/zerocoin/SerialNumberSignatureOfKnowledge.cpp
deleted file mode 100644 (file)
index 1654c50..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
-* @file       SerialNumberSignatureOfKnowledge.cpp
-*
-* @brief      SerialNumberSignatureOfKnowledge class for the Zerocoin library.
-*
-* @author     Ian Miers, Christina Garman and Matthew Green
-* @date       June 2013
-*
-* @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
-* @license    This project is released under the MIT license.
-**/
-
-#include "Zerocoin.h"
-
-namespace libzerocoin {
-
-SerialNumberSignatureOfKnowledge::SerialNumberSignatureOfKnowledge(const Params* p): params(p) { }
-
-SerialNumberSignatureOfKnowledge::SerialNumberSignatureOfKnowledge(const
-        Params* p, const PrivateCoin& coin, const Commitment& commitmentToCoin,
-        uint256 msghash):params(p),
-       s_notprime(p->zkp_iterations),
-       sprime(p->zkp_iterations) {
-
-       // Sanity check: verify that the order of the "accumulatedValueCommitmentGroup" is
-       // equal to the modulus of "coinCommitmentGroup". Otherwise we will produce invalid
-       // proofs.
-       if (params->coinCommitmentGroup.modulus != params->serialNumberSoKCommitmentGroup.groupOrder) {
-               throw ZerocoinException("Groups are not structured correctly.");
-       }
-
-       Bignum a = params->coinCommitmentGroup.g;
-       Bignum b = params->coinCommitmentGroup.h;
-       Bignum g = params->serialNumberSoKCommitmentGroup.g;
-       Bignum h = params->serialNumberSoKCommitmentGroup.h;
-
-       CHashWriter hasher(0,0);
-       hasher << *params << commitmentToCoin.getCommitmentValue() << coin.getSerialNumber();
-
-       vector<Bignum> r(params->zkp_iterations);
-       vector<Bignum> v(params->zkp_iterations);
-       vector<Bignum> c(params->zkp_iterations);
-
-
-       for(uint32_t i=0; i < params->zkp_iterations; i++) {
-               //FIXME we really ought to use one BN_CTX for all of these
-               // operations for performance reasons, not the one that
-               // is created individually  by the wrapper
-               r[i] = Bignum::randBignum(params->coinCommitmentGroup.groupOrder);
-               v[i] = Bignum::randBignum(params->serialNumberSoKCommitmentGroup.groupOrder);
-       }
-
-       // Openssl's rng is not thread safe, so we don't call it in a parallel loop,
-       // instead we generate the random values beforehand and run the calculations
-       // based on those values in parallel.
-#ifdef ZEROCOIN_THREADING
-       #pragma omp parallel for
-#endif
-       for(uint32_t i=0; i < params->zkp_iterations; i++) {
-               // compute g^{ {a^x b^r} h^v} mod p2
-               c[i] = challengeCalculation(coin.getSerialNumber(), r[i], v[i]);
-       }
-
-       // We can't hash data in parallel either
-       // because OPENMP cannot not guarantee loops
-       // execute in order.
-       for(uint32_t i=0; i < params->zkp_iterations; i++) {
-               hasher << c[i];
-       }
-       this->hash = hasher.GetHash();
-       unsigned char *hashbytes =  (unsigned char*) &hash;
-
-#ifdef ZEROCOIN_THREADING
-       #pragma omp parallel for
-#endif
-       for(uint32_t i = 0; i < params->zkp_iterations; i++) {
-               int bit = i % 8;
-               int byte = i / 8;
-
-               bool challenge_bit = ((hashbytes[byte] >> bit) & 0x01);
-               if (challenge_bit) {
-                       s_notprime[i]       = r[i];
-                       sprime[i]           = v[i];
-               } else {
-                       s_notprime[i]       = r[i] - coin.getRandomness();
-                       sprime[i]           = v[i] - (commitmentToCoin.getRandomness() *
-                                                     b.pow_mod(r[i] - coin.getRandomness(), params->serialNumberSoKCommitmentGroup.groupOrder));
-               }
-       }
-}
-
-inline Bignum SerialNumberSignatureOfKnowledge::challengeCalculation(const Bignum& a_exp,const Bignum& b_exp,
-        const Bignum& h_exp) const {
-
-       Bignum a = params->coinCommitmentGroup.g;
-       Bignum b = params->coinCommitmentGroup.h;
-       Bignum g = params->serialNumberSoKCommitmentGroup.g;
-       Bignum h = params->serialNumberSoKCommitmentGroup.h;
-
-       Bignum exponent = (a.pow_mod(a_exp, params->serialNumberSoKCommitmentGroup.groupOrder)
-                          * b.pow_mod(b_exp, params->serialNumberSoKCommitmentGroup.groupOrder)) % params->serialNumberSoKCommitmentGroup.groupOrder;
-
-       return (g.pow_mod(exponent, params->serialNumberSoKCommitmentGroup.modulus) * h.pow_mod(h_exp, params->serialNumberSoKCommitmentGroup.modulus)) % params->serialNumberSoKCommitmentGroup.modulus;
-}
-
-bool SerialNumberSignatureOfKnowledge::Verify(const Bignum& coinSerialNumber, const Bignum& valueOfCommitmentToCoin,
-        const uint256 msghash) const {
-       Bignum a = params->coinCommitmentGroup.g;
-       Bignum b = params->coinCommitmentGroup.h;
-       Bignum g = params->serialNumberSoKCommitmentGroup.g;
-       Bignum h = params->serialNumberSoKCommitmentGroup.h;
-       CHashWriter hasher(0,0);
-       hasher << *params << valueOfCommitmentToCoin <<coinSerialNumber;
-
-       vector<CBigNum> tprime(params->zkp_iterations);
-       unsigned char *hashbytes = (unsigned char*) &this->hash;
-#ifdef ZEROCOIN_THREADING
-       #pragma omp parallel for
-#endif
-       for(uint32_t i = 0; i < params->zkp_iterations; i++) {
-               int bit = i % 8;
-               int byte = i / 8;
-               bool challenge_bit = ((hashbytes[byte] >> bit) & 0x01);
-               if(challenge_bit) {
-                       tprime[i] = challengeCalculation(coinSerialNumber, s_notprime[i], sprime[i]);
-               } else {
-                       Bignum exp = b.pow_mod(s_notprime[i], params->serialNumberSoKCommitmentGroup.groupOrder);
-                       tprime[i] = ((valueOfCommitmentToCoin.pow_mod(exp, params->serialNumberSoKCommitmentGroup.modulus) % params->serialNumberSoKCommitmentGroup.modulus) *
-                                    (h.pow_mod(sprime[i], params->serialNumberSoKCommitmentGroup.modulus) % params->serialNumberSoKCommitmentGroup.modulus)) %
-                                   params->serialNumberSoKCommitmentGroup.modulus;
-               }
-       }
-       for(uint32_t i = 0; i < params->zkp_iterations; i++) {
-               hasher << tprime[i];
-       }
-       return hasher.GetHash() == hash;
-}
-
-} /* namespace libzerocoin */
diff --git a/src/zerocoin/SerialNumberSignatureOfKnowledge.h b/src/zerocoin/SerialNumberSignatureOfKnowledge.h
deleted file mode 100644 (file)
index 3177618..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
-* @file       SerialNumberSignatureOfKnowledge.h
-*
-* @brief      SerialNumberSignatureOfKnowledge class for the Zerocoin library.
-*
-* @author     Ian Miers, Christina Garman and Matthew Green
-* @date       June 2013
-*
-* @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
-* @license    This project is released under the MIT license.
-**/
-
-#ifndef SERIALNUMBERPROOF_H_
-#define SERIALNUMBERPROOF_H_
-
-#include <list>
-#include <vector>
-#include <bitset>
-#include "Params.h"
-#include "Coin.h"
-#include "Commitment.h"
-#include "../bignum.h"
-#include "../serialize.h"
-#include "Accumulator.h"
-#include "../util.h"
-
-using namespace std;
-namespace libzerocoin {
-
-/**A Signature of knowledge on the hash of metadata attesting that the signer knows the values
- *  necessary to open a commitment which contains a coin(which it self is of course a commitment)
- * with a given serial number.
- */
-class SerialNumberSignatureOfKnowledge {
-public:
-       SerialNumberSignatureOfKnowledge(const Params* p);
-       /** Creates a Signature of knowledge object that a commitment to a coin contains a coin with serial number x
-        *
-        * @param p params
-        * @param coin the coin we are going to prove the serial number of.
-        * @param commitmentToCoin the commitment to the coin
-        * @param msghash hash of meta data to create a signature of knowledge on.
-        */
-       SerialNumberSignatureOfKnowledge(const Params* p, const PrivateCoin& coin, const Commitment& commitmentToCoin, uint256 msghash);
-
-       /** Verifies the Signature of knowledge.
-        *
-        * @param msghash hash of meta data to create a signature of knowledge on.
-        * @return
-        */
-       bool Verify(const Bignum& coinSerialNumber, const Bignum& valueOfCommitmentToCoin,const uint256 msghash) const;
-
-       IMPLEMENT_SERIALIZE
-       (
-           READWRITE(s_notprime);
-           READWRITE(sprime);
-           READWRITE(hash);
-       )
-private:
-       const Params* params;
-       // challenge hash
-       uint256 hash; //TODO For efficiency, should this be a bitset where Templates define params?
-
-       // challenge response values
-       // this is s_notprime instead of s
-       // because the serialization macros
-       // define something named s and it conflicts
-       vector<Bignum> s_notprime;
-       vector<Bignum> sprime;
-       inline Bignum challengeCalculation(const Bignum& a_exp, const Bignum& b_exp,
-                                          const Bignum& h_exp) const;
-};
-
-} /* namespace libzerocoin */
-#endif /* SERIALNUMBERPROOF_H_ */
diff --git a/src/zerocoin/SpendMetaData.cpp b/src/zerocoin/SpendMetaData.cpp
deleted file mode 100644 (file)
index 83d5619..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
-* @file       SpendMetaData.cpp
-*
-* @brief      SpendMetaData class for the Zerocoin library.
-*
-* @author     Ian Miers, Christina Garman and Matthew Green
-* @date       June 2013
-*
-* @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
-* @license    This project is released under the MIT license.
-**/
-
-#include "Zerocoin.h"
-
-namespace libzerocoin {
-
-SpendMetaData::SpendMetaData(uint256 accumulatorId, uint256 txHash): accumulatorId(accumulatorId), txHash(txHash) {}
-
-} /* namespace libzerocoin */
diff --git a/src/zerocoin/SpendMetaData.h b/src/zerocoin/SpendMetaData.h
deleted file mode 100644 (file)
index 855d8f9..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
-* @file       SpendMetaData.h
-*
-* @brief      SpendMetaData class for the Zerocoin library.
-*
-* @author     Ian Miers, Christina Garman and Matthew Green
-* @date       June 2013
-*
-* @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
-* @license    This project is released under the MIT license.
-**/
-
-#ifndef SPENDMETADATA_H_
-#define SPENDMETADATA_H_
-
-#include "../uint256.h"
-#include "../serialize.h"
-
-using namespace std;
-namespace libzerocoin {
-
-/** Any meta data needed for actual bitcoin integration.
- * Can extended provided the getHash() function is updated
- */
-class SpendMetaData {
-public:
-       /**
-        * Creates meta data associated with a coin spend
-        * @param accumulatorId hash of block containing accumulator
-        * @param txHash hash of transaction
-        */
-       SpendMetaData(uint256 accumulatorId, uint256 txHash);
-
-       /**
-        * The hash of the block containing the accumulator CoinSpend
-        * proves membership in.
-        */
-       uint256 accumulatorId; // The block the accumulator is in
-       /**Contains the hash of the rest of transaction
-        * spending a zerocoin (excluding the coinspend proof)
-        */
-       uint256 txHash; // The Hash of the rest of the transaction the spend proof is n.
-       // Allows us to sign the transaction.
-       IMPLEMENT_SERIALIZE
-       (
-           READWRITE(accumulatorId);
-           READWRITE(txHash);
-       )
-};
-
-} /* namespace libzerocoin */
-#endif /* SPENDMETADATA_H_ */
diff --git a/src/zerocoin/ZeroTest.cpp b/src/zerocoin/ZeroTest.cpp
deleted file mode 100644 (file)
index f00f0c5..0000000
+++ /dev/null
@@ -1,421 +0,0 @@
-/**
-* @file       Tests.cpp
-*
-* @brief      Test routines for Zerocoin.
-*
-* @author     Ian Miers, Christina Garman and Matthew Green
-* @date       June 2013
-*
-* @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
-* @license    This project is released under the MIT license.
-**/
-
-using namespace std;
-
-#include <string>
-#include <iostream>
-#include <fstream>
-#include <exception>
-#include "Zerocoin.h"
-#include "../util.h"
-
-using namespace libzerocoin;
-extern Params* ZCParams;
-
-
-#define TESTS_COINS_TO_ACCUMULATE   10
-
-// Global test counters
-uint32_t    gNumTests        = 0;
-uint32_t    gSuccessfulTests = 0;
-
-// Proof size
-uint32_t    gProofSize                 = 0;
-uint32_t    gCoinSize                  = 0;
-uint32_t       gSerialNumberSize       = 0;
-
-// Global coin array
-PrivateCoin    *gCoins[TESTS_COINS_TO_ACCUMULATE];
-
-// Global params
-Params *g_Params;
-
-//////////
-// Utility routines
-//////////
-
-void
-LogTestResult(string testName, bool (*testPtr)())
-{
-       printf("Testing if %s ...\n", testName.c_str());
-
-       bool testResult = testPtr();
-
-       if (testResult == true) {
-               printf("\t[PASS]\n");
-               gSuccessfulTests++;
-       } else {
-               printf("\t[FAIL]\n");
-       }
-
-       gNumTests++;
-}
-
-Bignum
-GetTestModulus()
-{
-       static Bignum testModulus(0);
-
-       // TODO: should use a hard-coded RSA modulus for testing
-       if (!testModulus) {
-               Bignum p, q;
-
-               // Note: we are NOT using safe primes for testing because
-               // they take too long to generate. Don't do this in real
-               // usage. See the paramgen utility for better code.
-               p = Bignum::generatePrime(1024, false);
-               q = Bignum::generatePrime(1024, false);
-               testModulus = p * q;
-       }
-
-       return testModulus;
-}
-
-//////////
-// Test routines
-//////////
-
-bool
-Test_GenRSAModulus()
-{
-       Bignum result = GetTestModulus();
-
-       if (!result) {
-               return false;
-       }
-       else {
-               return true;
-       }
-}
-
-bool
-Test_CalcParamSizes()
-{
-       bool result = true;
-#if 0
-
-       uint32_t pLen, qLen;
-
-       try {
-               calculateGroupParamLengths(4000, 80, &pLen, &qLen);
-               if (pLen < 1024 || qLen < 256) {
-                       result = false;
-               }
-               calculateGroupParamLengths(4000, 96, &pLen, &qLen);
-               if (pLen < 2048 || qLen < 256) {
-                       result = false;
-               }
-               calculateGroupParamLengths(4000, 112, &pLen, &qLen);
-               if (pLen < 3072 || qLen < 320) {
-                       result = false;
-               }
-               calculateGroupParamLengths(4000, 120, &pLen, &qLen);
-               if (pLen < 3072 || qLen < 320) {
-                       result = false;
-               }
-               calculateGroupParamLengths(4000, 128, &pLen, &qLen);
-               if (pLen < 3072 || qLen < 320) {
-                       result = false;
-               }
-       } catch (exception &e) {
-               result = false;
-       }
-#endif
-
-       return result;
-}
-
-bool
-Test_GenerateGroupParams()
-{
-       int32_t pLen = 1024, qLen = 256, count;
-       IntegerGroupParams group;
-
-       for (count = 0; count < 1; count++) {
-
-               try {
-                       group = deriveIntegerGroupParams(calculateSeed(GetTestModulus(), "test", ZEROCOIN_DEFAULT_SECURITYLEVEL, "TEST GROUP"), pLen, qLen);
-               } catch (std::runtime_error e) {
-                       printf("Caught exception %s\n", e.what());
-                       return false;
-               }
-
-               // Now perform some simple tests on the resulting parameters
-               if (group.groupOrder.bitSize() < qLen || group.modulus.bitSize() < pLen) {
-                       return false;
-               }
-
-               Bignum c = group.g.pow_mod(group.groupOrder, group.modulus);
-               if (!(c.isOne())) return false;
-
-               // Try at multiple parameter sizes
-               pLen = pLen * 1.5;
-               qLen = qLen * 1.5;
-       }
-
-       return true;
-}
-
-bool
-Test_ParamGen()
-{
-       bool result = true;
-
-       try {
-               // Instantiating testParams runs the parameter generation code
-               Params testParams(GetTestModulus(),ZEROCOIN_DEFAULT_SECURITYLEVEL);
-       } catch (runtime_error e) {
-               printf("ParamGen exception %s\n", e.what());
-               result = false;
-       }
-
-       return result;
-}
-
-bool
-Test_Accumulator()
-{
-       // This test assumes a list of coins were generated during
-       // the Test_MintCoin() test.
-       if (gCoins[0] == NULL) {
-               return false;
-       }
-       try {
-               // Accumulate the coin list from first to last into one accumulator
-               Accumulator accOne(&g_Params->accumulatorParams);
-               Accumulator accTwo(&g_Params->accumulatorParams);
-               Accumulator accThree(&g_Params->accumulatorParams);
-               Accumulator accFour(&g_Params->accumulatorParams);
-               AccumulatorWitness wThree(g_Params, accThree, gCoins[0]->getPublicCoin());
-
-               for (uint32_t i = 0; i < TESTS_COINS_TO_ACCUMULATE; i++) {
-                       accOne += gCoins[i]->getPublicCoin();
-                       accTwo += gCoins[TESTS_COINS_TO_ACCUMULATE - (i+1)]->getPublicCoin();
-                       accThree += gCoins[i]->getPublicCoin();
-                       wThree += gCoins[i]->getPublicCoin();
-                       if(i != 0) {
-                               accFour += gCoins[i]->getPublicCoin();
-                       }
-               }
-
-               // Compare the accumulated results
-               if (accOne.getValue() != accTwo.getValue() || accOne.getValue() != accThree.getValue()) {
-                       printf("Accumulators don't match\n");
-                       return false;
-               }
-
-               if(accFour.getValue() != wThree.getValue()) {
-                       printf("Witness math not working,\n");
-                       return false;
-               }
-
-               // Verify that the witness is correct
-               if (!wThree.VerifyWitness(accThree, gCoins[0]->getPublicCoin()) ) {
-                       printf("Witness not valid\n");
-                       return false;
-               }
-
-               // Serialization test: see if we can serialize the accumulator
-               CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
-               ss << accOne;
-
-               // Deserialize it into a new object
-               Accumulator newAcc(g_Params, ss);
-
-               // Compare the results
-               if (accOne.getValue() != newAcc.getValue()) {
-                       return false;
-               }
-
-       } catch (runtime_error e) {
-               return false;
-       }
-
-       return true;
-}
-
-bool
-Test_EqualityPoK()
-{
-       // Run this test 10 times
-       for (uint32_t i = 0; i < 10; i++) {
-               try {
-                       // Generate a random integer "val"
-                       Bignum val = Bignum::randBignum(g_Params->coinCommitmentGroup.groupOrder);
-
-                       // Manufacture two commitments to "val", both
-                       // under different sets of parameters
-                       Commitment one(&g_Params->accumulatorParams.accumulatorPoKCommitmentGroup, val);
-
-                       Commitment two(&g_Params->serialNumberSoKCommitmentGroup, val);
-
-                       // Now generate a proof of knowledge that "one" and "two" are
-                       // both commitments to the same value
-                       CommitmentProofOfKnowledge pok(&g_Params->accumulatorParams.accumulatorPoKCommitmentGroup,
-                                                      &g_Params->serialNumberSoKCommitmentGroup,
-                                                      one, two);
-
-                       // Serialize the proof into a stream
-                       CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
-                       ss << pok;
-
-                       // Deserialize back into a PoK object
-                       CommitmentProofOfKnowledge newPok(&g_Params->accumulatorParams.accumulatorPoKCommitmentGroup,
-                                                         &g_Params->serialNumberSoKCommitmentGroup,
-                                                         ss);
-
-                       if (newPok.Verify(one.getCommitmentValue(), two.getCommitmentValue()) != true) {
-                               return false;
-                       }
-
-                       // Just for fun, deserialize the proof a second time
-                       CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION);
-                       ss2 << pok;
-
-                       // This time tamper with it, then deserialize it back into a PoK
-                       ss2[15] = 0;
-                       CommitmentProofOfKnowledge newPok2(&g_Params->accumulatorParams.accumulatorPoKCommitmentGroup,
-                                                          &g_Params->serialNumberSoKCommitmentGroup,
-                                                          ss2);
-
-                       // If the tampered proof verifies, that's a failure!
-                       if (newPok2.Verify(one.getCommitmentValue(), two.getCommitmentValue()) == true) {
-                               return false;
-                       }
-
-               } catch (runtime_error &e) {
-                       return false;
-               }
-       }
-
-       return true;
-}
-
-bool
-Test_MintCoin()
-{
-       gCoinSize = 0;
-
-       try {
-               // Generate a list of coins
-               for (uint32_t i = 0; i < TESTS_COINS_TO_ACCUMULATE; i++) {
-                       gCoins[i] = new PrivateCoin(g_Params);
-
-                       PublicCoin pc = gCoins[i]->getPublicCoin();
-                       CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
-                       ss << pc;
-                       gCoinSize += ss.size();
-               }
-
-               gCoinSize /= TESTS_COINS_TO_ACCUMULATE;
-
-       } catch (exception &e) {
-               return false;
-       }
-
-       return true;
-}
-
-bool
-Test_MintAndSpend()
-{
-       try {
-               // This test assumes a list of coins were generated in Test_MintCoin()
-               if (gCoins[0] == NULL)
-               {
-                       // No coins: mint some.
-                       Test_MintCoin();
-                       if (gCoins[0] == NULL) {
-                               return false;
-                       }
-               }
-
-               // Accumulate the list of generated coins into a fresh accumulator.
-               // The first one gets marked as accumulated for a witness, the
-               // others just get accumulated normally.
-               Accumulator acc(&g_Params->accumulatorParams);
-               AccumulatorWitness wAcc(g_Params, acc, gCoins[0]->getPublicCoin());
-
-               for (uint32_t i = 0; i < TESTS_COINS_TO_ACCUMULATE; i++) {
-                       acc += gCoins[i]->getPublicCoin();
-                       wAcc +=gCoins[i]->getPublicCoin();
-               }
-
-               // Now spend the coin
-               SpendMetaData m(1,1);
-
-               CoinSpend spend(g_Params, *(gCoins[0]), acc, wAcc, m);
-
-               // Serialize the proof and deserialize into newSpend
-               CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
-               ss << spend;
-               gProofSize = ss.size();
-               CoinSpend newSpend(g_Params, ss);
-
-               // See if we can verify the deserialized proof (return our result)
-               bool ret =  newSpend.Verify(acc, m);
-               
-               // Extract the serial number
-               Bignum serialNumber = newSpend.getCoinSerialNumber();
-               gSerialNumberSize = ceil((double)serialNumber.bitSize() / 8.0);
-               
-               return ret;
-       } catch (runtime_error &e) {
-               printf("MintAndSpend exception %s\n", e.what());
-               return false;
-       }
-
-       return false;
-}
-
-void
-Test_RunAllTests()
-{
-       printf("ZeroCoin v%s self-test routine\n", ZEROCOIN_VERSION_STRING);
-
-       // Make a new set of parameters from a random RSA modulus
-       //g_Params = new Params(GetTestModulus());
-       g_Params = ZCParams;
-
-       gNumTests = gSuccessfulTests = gProofSize = 0;
-       for (uint32_t i = 0; i < TESTS_COINS_TO_ACCUMULATE; i++) {
-               gCoins[i] = NULL;
-       }
-
-       // Run through all of the Zerocoin tests
-       LogTestResult("an RSA modulus can be generated", Test_GenRSAModulus);
-       LogTestResult("parameter sizes are correct", Test_CalcParamSizes);
-       LogTestResult("group/field parameters can be generated", Test_GenerateGroupParams);
-       LogTestResult("parameter generation is correct", Test_ParamGen);
-       LogTestResult("coins can be minted", Test_MintCoin);
-       LogTestResult("the accumulator works", Test_Accumulator);
-       LogTestResult("the commitment equality PoK works", Test_EqualityPoK);
-       LogTestResult("a minted coin can be spent", Test_MintAndSpend);
-
-       printf("\nAverage coin size is %d bytes.\n", gCoinSize);
-       printf("Serial number size is %d bytes.\n", gSerialNumberSize);
-       printf("Spend proof size is %d bytes.\n", gProofSize);
-
-       // Summarize test results
-       if (gSuccessfulTests < gNumTests) {
-               printf("\nERROR: SOME TESTS FAILED\n");
-       }
-
-       // Clear any generated coins
-       for (uint32_t i = 0; i < TESTS_COINS_TO_ACCUMULATE; i++) {
-               delete gCoins[i];
-       }
-
-       printf("\n%d out of %d tests passed.\n\n", gSuccessfulTests, gNumTests);
-       delete g_Params;
-}
diff --git a/src/zerocoin/ZeroTest.h b/src/zerocoin/ZeroTest.h
deleted file mode 100644 (file)
index 36ab6b7..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef ZEROTEST_H_
-#define ZEROTEST_H_
-
-void Test_RunAllTests();
-
-#endif
diff --git a/src/zerocoin/Zerocoin.h b/src/zerocoin/Zerocoin.h
deleted file mode 100644 (file)
index 326e143..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
-* @file       Zerocoin.h
-*
-* @brief      Exceptions and constants for Zerocoin
-*
-* @author     Ian Miers, Christina Garman and Matthew Green
-* @date       June 2013
-*
-* @copyright  Copyright 2013 Ian Miers, Christina Garman and Matthew Green
-* @license    This project is released under the MIT license.
-**/
-
-#ifndef ZEROCOIN_H_
-#define ZEROCOIN_H_
-
-#include <stdexcept>
-
-#define ZEROCOIN_DEFAULT_SECURITYLEVEL      80
-#define ZEROCOIN_MIN_SECURITY_LEVEL         80
-#define ZEROCOIN_MAX_SECURITY_LEVEL         80
-#define ACCPROOF_KPRIME                     160
-#define ACCPROOF_KDPRIME                    128
-#define MAX_COINMINT_ATTEMPTS               10000
-#define ZEROCOIN_MINT_PRIME_PARAM           20
-#define ZEROCOIN_VERSION_STRING             "0.11"
-#define ZEROCOIN_VERSION_INT                11
-#define ZEROCOIN_PROTOCOL_VERSION           "1"
-#define HASH_OUTPUT_BITS                    256
-#define ZEROCOIN_COMMITMENT_EQUALITY_PROOF  "COMMITMENT_EQUALITY_PROOF"
-#define ZEROCOIN_ACCUMULATOR_PROOF          "ACCUMULATOR_PROOF"
-#define ZEROCOIN_SERIALNUMBER_PROOF         "SERIALNUMBER_PROOF"
-
-// Activate multithreaded mode for proof verification
-
-//#define ZEROCOIN_THREADING 1
-
-// Uses a fast technique for coin generation. Could be more vulnerable
-// to timing attacks. Turn off if an attacker can measure coin minting time.
-#define ZEROCOIN_FAST_MINT 1
-
-// Errors thrown by the Zerocoin library
-
-class ZerocoinException : public std::runtime_error
-{
-public:
-   explicit ZerocoinException(const std::string& str) : std::runtime_error(str) {}
-};
-
-#include "../serialize.h"
-#include "../bignum.h"
-#include "../hash.h"
-#include "Params.h"
-#include "Coin.h"
-#include "Commitment.h"
-#include "Accumulator.h"
-#include "AccumulatorProofOfKnowledge.h"
-#include "CoinSpend.h"
-#include "SerialNumberSignatureOfKnowledge.h"
-#include "ParamGeneration.h"
-
-#endif /* ZEROCOIN_H_ */