]> Git Repo - VerusCoin.git/commitdiff
Initial merge
authorjl777 <[email protected]>
Thu, 30 Mar 2017 01:35:16 +0000 (04:35 +0300)
committerjl777 <[email protected]>
Thu, 30 Mar 2017 01:35:16 +0000 (04:35 +0300)
46 files changed:
1  2 
.gitignore
Makefile.am
README.md
configure.ac
depends/packages/packages.mk
src/Makefile.am
src/Makefile.gtest.include
src/bitcoin-cli.cpp
src/bitcoind.cpp
src/chainparams.cpp
src/chainparams.h
src/clientversion.h
src/coins.cpp
src/coins.h
src/crypto/equihash.cpp
src/gtest/test_foundersreward.cpp
src/init.cpp
src/komodo-tx.cpp
src/main.cpp
src/main.h
src/miner.cpp
src/net.cpp
src/netbase.cpp
src/pow.cpp
src/primitives/transaction.h
src/rest.cpp
src/rpcblockchain.cpp
src/rpcclient.cpp
src/rpcmining.cpp
src/rpcmisc.cpp
src/rpcnet.cpp
src/rpcrawtransaction.cpp
src/rpcserver.cpp
src/rpcserver.h
src/test/rpc_wallet_tests.cpp
src/test/transaction_tests.cpp
src/tinyformat.h
src/txdb.cpp
src/txmempool.cpp
src/util.cpp
src/util.h
src/wallet/asyncrpcoperation_sendmany.cpp
src/wallet/rpcdump.cpp
src/wallet/rpcwallet.cpp
src/wallet/wallet.cpp
src/wallet/wallet.h

diff --cc .gitignore
Simple merge
diff --cc Makefile.am
index 2eeb92ee85483886a613d8cf546985be085802f0,e3142b52aa565100ef71f9a856b7d54bd590a0d1..f580ccfc2983b0de3e2358e2b4d14b355454fac9
@@@ -33,20 -35,12 +35,20 @@@ WINDOWS_PACKAGING = $(top_srcdir)/share
    $(top_srcdir)/share/pixmaps/nsis-header.bmp \
    $(top_srcdir)/share/pixmaps/nsis-wizard.bmp
  
- OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) $(OSX_BASE_LPROJ_DIR) \
-   $(top_srcdir)/contrib/macdeploy/$(OSX_BACKGROUND_IMAGE) \
-   $(top_srcdir)/contrib/macdeploy/DS_Store \
-   $(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \
-   $(top_srcdir)/contrib/macdeploy/detached-sig-create.sh
##OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) $(OSX_BASE_LPROJ_DIR) \
##  $(top_srcdir)/contrib/macdeploy/$(OSX_BACKGROUND_IMAGE) \
##  $(top_srcdir)/contrib/macdeploy/DS_Store \
##  $(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \
##  $(top_srcdir)/contrib/macdeploy/detached-sig-create.sh
  
 +
 +if BUILD_DARWIN
 +COVERAGE_INFO = baseline_filtered_combined.info baseline.info block_test.info \
 +  leveldb_baseline.info test_bitcoin_filtered.info total_coverage.info \
 +  baseline_filtered.info block_test_filtered.info \
 +  leveldb_baseline_filtered.info test_bitcoin_coverage.info test_bitcoin.info
 +#  zcash-gtest.info zcash-gtest_filtered.info zcash-gtest_coverage.info
 +else
  COVERAGE_INFO = baseline_filtered_combined.info baseline.info block_test.info \
    leveldb_baseline.info test_bitcoin_filtered.info total_coverage.info \
    baseline_filtered.info block_test_filtered.info \
diff --cc README.md
Simple merge
diff --cc configure.ac
index 4f022fcc8bdf82991646d022a750e4e7b13f6e7c,e356b9e07b431725567fb4176e5040e4a909c214..2098dc683ab632c9074f11267b1e84125557411e
@@@ -282,24 -296,19 +296,24 @@@ dnl       if test x$BREW = xbrew; the
           dnl in expected paths because they may conflict with system files. Ask
           dnl Homebrew where each one is located, then adjust paths accordingly.
           dnl It's safe to add these paths even if the functionality is disabled by
-          dnl the user (--without-wallet or --without-gui for example).
+          dnl the user (--without-wallet for example).
  
 -         openssl_prefix=`$BREW --prefix openssl 2>/dev/null`
 -         bdb_prefix=`$BREW --prefix berkeley-db4 2>/dev/null`
 -         if test x$openssl_prefix != x; then
 -           PKG_CONFIG_PATH="$openssl_prefix/lib/pkgconfig:$PKG_CONFIG_PATH"
 -           export PKG_CONFIG_PATH
 -         fi
 -         if test x$bdb_prefix != x; then
 -           CPPFLAGS="$CPPFLAGS -I$bdb_prefix/include"
 -           LIBS="$LIBS -L$bdb_prefix/lib"
 -         fi
 -       fi
 +dnl         openssl_prefix=`$BREW --prefix openssl 2>/dev/null`
 +dnl         bdb_prefix=`$BREW --prefix berkeley-db4 2>/dev/null`
 +dnl         qt5_prefix=`$BREW --prefix qt5 2>/dev/null`
 +dnl         if test x$openssl_prefix != x; then
 +dnl           PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
 +dnl           export PKG_CONFIG_PATH
 +dnl         fi
 +dnl         if test x$bdb_prefix != x; then
 +dnl           CPPFLAGS="$CPPFLAGS -I$bdb_prefix/include"
 +dnl           LIBS="$LIBS -L$bdb_prefix/lib"
 +dnl         fi
 +dnl         if test x$qt5_prefix != x; then
 +dnl           PKG_CONFIG_PATH="$qt5_prefix/lib/pkgconfig:$PKG_CONFIG_PATH"
 +dnl           export PKG_CONFIG_PATH
 +dnl         fi
 +dnl       fi
       else
         case $build_os in
           *darwin*)
index 862ec6b136f0066086861ad2599f207804a28a6a,9d025a6b2a813ae2f9ed9ccdaf6d4470286a12d3..6fa8c0589ba634fc09c008663cc23ae67d990b35
@@@ -1,12 -1,6 +1,13 @@@
+ rust_packages := rust librustzcash
  zcash_packages := libsnark libgmp libsodium
- packages := boost openssl $(zcash_packages)
 +
 +ifeq ($(build_os),darwin)
- packages := boost openssl $(zcash_packages) googletest googlemock
++packages := boost openssl libevent zeromq $(zcash_packages)
 +else
+ packages := boost openssl libevent zeromq $(zcash_packages) googletest googlemock
 +endif
 +
 +
  native_packages := native_ccache
  
  wallet_packages=bdb
diff --cc src/Makefile.am
index 715f33fc7b3fcc2f77bb1be005a8a30fd317a916,9963f285852946baf1e2e50621987aa0ac27572d..7bb34f74005d83e3f2e1ceb930a99da1eb25549d
@@@ -28,10 -29,9 +29,9 @@@ LIBBITCOIN_COMMON=libbitcoin_common.
  LIBBITCOIN_CLI=libbitcoin_cli.a
  LIBBITCOIN_UTIL=libbitcoin_util.a
  LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
- LIBBITCOIN_UNIVALUE=univalue/libbitcoin_univalue.a
- LIBBITCOINQT=qt/libbitcoinqt.a
  LIBSECP256K1=secp256k1/libsecp256k1.la
 -LIBZCASH=libzcash.a
+ LIBUNIVALUE=univalue/libunivalue.la
 +LIBZCASH=libzcash.a -lcurl
  
  $(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*)
        $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)
@@@ -350,18 -364,18 +364,18 @@@ nodist_libbitcoin_util_a_SOURCES = $(sr
  #
  
  # bitcoind binary #
 -zcashd_SOURCES = bitcoind.cpp
 -zcashd_CPPFLAGS = $(BITCOIN_INCLUDES)
 -zcashd_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
 +komodod_SOURCES = bitcoind.cpp
 +komodod_CPPFLAGS = $(BITCOIN_INCLUDES)
 +komodod_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
  
  if TARGET_WINDOWS
 -zcashd_SOURCES += bitcoind-res.rc
 +komodod_SOURCES += bitcoind-res.rc
  endif
  
 -zcashd_LDADD = \
 +komodod_LDADD = \
    $(LIBBITCOIN_SERVER) \
    $(LIBBITCOIN_COMMON) \
-   $(LIBBITCOIN_UNIVALUE) \
+   $(LIBUNIVALUE) \
    $(LIBBITCOIN_UTIL) \
    $(LIBBITCOIN_CRYPTO) \
    $(LIBZCASH) \
    $(LIBMEMENV) \
    $(LIBSECP256K1)
  
+ if ENABLE_ZMQ
+ zcashd_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
+ endif
  if ENABLE_WALLET
 -zcashd_LDADD += libbitcoin_wallet.a
 +komodod_LDADD += libbitcoin_wallet.a
  endif
  
 -zcashd_LDADD += \
 +komodod_LDADD += \
    $(BOOST_LIBS) \
    $(BDB_LIBS) \
    $(SSL_LIBS) \
    $(LIBZCASH) \
    $(LIBBITCOIN_CRYPTO) \
    $(LIBZCASH_LIBS)
- #
  
  # bitcoin-cli binary #
 -zcash_cli_SOURCES = bitcoin-cli.cpp
 -zcash_cli_CPPFLAGS = $(BITCOIN_INCLUDES) $(EVENT_CFLAGS)
 -zcash_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
 +komodo_cli_SOURCES = bitcoin-cli.cpp
- komodo_cli_CPPFLAGS = $(BITCOIN_INCLUDES)
++komodo_cli_CPPFLAGS = $(BITCOIN_INCLUDES) $(EVENT_CFLAGS)
 +komodo_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
  
  if TARGET_WINDOWS
 -zcash_cli_SOURCES += bitcoin-cli-res.rc
 +komodo_cli_SOURCES += bitcoin-cli-res.rc
  endif
  
 -zcash_cli_LDADD = \
 +komodo_cli_LDADD = \
    $(LIBBITCOIN_CLI) \
+   $(LIBUNIVALUE) \
    $(LIBBITCOIN_UTIL) \
    $(BOOST_LIBS) \
    $(SSL_LIBS) \
@@@ -414,8 -435,8 +435,9 @@@ komodo_tx_SOURCES += bitcoin-tx-res.r
  endif
  
  # FIXME: Is libzcash needed for zcash_tx?
 -zcash_tx_LDADD = \
 +komodo_tx_LDADD = \
-   $(LIBBITCOIN_UNIVALUE) \
++#$(LIBBITCOIN_UNIVALUE) \
+   $(LIBUNIVALUE) \
    $(LIBBITCOIN_COMMON) \
    $(LIBBITCOIN_UTIL) \
    $(LIBSECP256K1) \
@@@ -519,17 -540,9 +541,9 @@@ endi
        @test -f $(PROTOC)
        $(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$(abspath $(<D) $<)
  
 -if ENABLE_TESTS
 -include Makefile.test.include
 -include Makefile.gtest.include
 -endif
 +#if ENABLE_TESTS
 +#include Makefile.test.include
 +#include Makefile.gtest.include
 +#endif
  
- if ENABLE_QT
- include Makefile.qt.include
- endif
- if ENABLE_QT_TESTS
- include Makefile.qttest.include
- endif
  include Makefile.zcash.include
index 5a46b1f0f7cb1e1d801c6510ff22c3298913cb82,3752e0d484912cdcb191fd0c564a5de035819bc2..ea71f19c36924499329a15702c01dd03a49a430b
@@@ -40,17 -40,23 +40,20 @@@ zcash_gtest_SOURCES += 
        wallet/gtest/test_wallet.cpp
  endif
  
 -zcash_gtest_CPPFLAGS = -DMULTICORE -fopenmp -DBINARY_OUTPUT -DCURVE_ALT_BN128 -DSTATIC $(BITCOIN_INCLUDES)
 +komodo_gtest_CPPFLAGS = -DMULTICORE -fopenmp -DBINARY_OUTPUT -DCURVE_ALT_BN128 -DSTATIC
  
 -zcash_gtest_LDADD = -lgtest -lgmock $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
 +komodo_gtest_LDADD = -lgtest -lgmock $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
    $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1)
+ if ENABLE_ZMQ
+ zcash_gtest_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
+ endif
  if ENABLE_WALLET
 -zcash_gtest_LDADD += $(LIBBITCOIN_WALLET)
 +komodo_gtest_LDADD += $(LIBBITCOIN_WALLET)
  endif
  
- komodo_gtest_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBZCASH) $(LIBZCASH_LIBS)
 -zcash_gtest_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(LIBZCASH) $(LIBZCASH_LIBS)
 -
 -zcash_gtest_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static
++komodo_gtest_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(LIBZCASH) $(LIBZCASH_LIBS)
  
 -zcash-gtest_check: zcash-gtest FORCE
 -      ./zcash-gtest
 +komodo_gtest_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static
  
 -zcash-gtest-expected-failures: zcash-gtest FORCE
 -      ./zcash-gtest --gtest_filter=*DISABLED_* --gtest_also_run_disabled_tests
 +komodo-gtest-expected-failures: komodo-gtest FORCE
 +      ./komodo-gtest --gtest_filter=*DISABLED_* --gtest_also_run_disabled_tests
index e000776e63eb6c2910ff50daa1a7ceb4594d851d,4cb66aedbdc401bc02032c4356b8b807d73bb7a0..17878aa1714997299ce74b74ddfd03d7892de1c1
  #include "utilstrencodings.h"
  
  #include <boost/filesystem/operations.hpp>
+ #include <stdio.h>
+ #include <event2/buffer.h>
+ #include <event2/keyvalq_struct.h>
+ #include "support/events.h"
+ #include <univalue.h>
  
  using namespace std;
 +using namespace json_spirit;
 +int64_t MAX_MONEY = 200000000 * 100000000LL;
 +uint64_t komodo_maxallowed(int32_t baseid) { return(100000000LL * 1000000); } // stub
  
+ static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900;
  std::string HelpMessageCli()
  {
      string strUsage;
@@@ -79,14 -68,13 +86,14 @@@ static bool AppInitRPC(int argc, char* 
      // Parameters
      //
      ParseParameters(argc, argv);
 +    komodo_args();
      if (argc<2 || mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) {
-         std::string strUsage = _("Komodo RPC client version") + " " + FormatFullVersion() + "\n";
 -        std::string strUsage = _("Zcash RPC client version") + " " + FormatFullVersion() + "\n" + PrivacyInfo();
++        std::string strUsage = _("Komodo RPC client version") + " " + FormatFullVersion() + "\n" + PrivacyInfo();
          if (!mapArgs.count("-version")) {
              strUsage += "\n" + _("Usage:") + "\n" +
 -                  "  zcash-cli [options] <command> [params]  " + _("Send command to Zcash") + "\n" +
 -                  "  zcash-cli [options] help                " + _("List commands") + "\n" +
 -                  "  zcash-cli [options] help <command>      " + _("Get help for a command") + "\n";
 +                  "  komodo-cli [options] <command> [params]  " + _("Send command to Komodo") + "\n" +
 +                  "  komodo-cli [options] help                " + _("List commands") + "\n" +
 +                  "  komodo-cli [options] help <command>      " + _("Get help for a command") + "\n";
  
              strUsage += "\n" + HelpMessageCli();
          } else {
index bb98da3d653d67707358b34e6eade8e6b9f4ed1b,6feee7e9054a102565a9be675e69d6f2463be2f3..ccdf93d9b9e9c7c55f1eafcb0675900636b2117c
@@@ -81,7 -73,7 +86,7 @@@ bool AppInit(int argc, char* argv[]
      // Process help and version before taking care about datadir
      if (mapArgs.count("-?") || mapArgs.count("-h") ||  mapArgs.count("-help") || mapArgs.count("-version"))
      {
-         std::string strUsage = _("Komodo Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n";
 -        std::string strUsage = _("Zcash Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n" + PrivacyInfo();
++        std::string strUsage = _("Komodo Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n" + PrivacyInfo();
  
          if (mapArgs.count("-version"))
          {
      } catch (...) {
          PrintExceptionContinue(NULL, "AppInit()");
      }
 -
      if (!fRet)
      {
-         threadGroup.interrupt_all();
+         Interrupt(threadGroup);
          // threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of
          // the startup-failure cases to make sure they don't result in a hang due to some
          // thread-blocking-waiting-for-another-thread-during-startup case
index 41e54d752a737bfd9bffde58695c28e117437cf7,ce71a3aaadafb00fcba3a17ac94f2c813f5aeb51..1c2ac625ef182290d0da61ee6d4f6fbed681f348
@@@ -117,23 -122,79 +116,23 @@@ public
          fRequireStandard = true;
          fMineBlocksOnDemand = false;
          fTestnetToBeDeprecatedFieldRPC = false;
 -
 -        checkpointData = (Checkpoints::CCheckpointData) {
 +        checkpointData = (Checkpoints::CCheckpointData)
 +        {
              boost::assign::map_list_of
 -            (0, consensus.hashGenesisBlock)
 -            (2500, uint256S("0x00000006dc968f600be11a86cbfbf7feb61c7577f45caced2e82b6d261d19744"))
 -            (15000, uint256S("0x00000000b6bc56656812a5b8dcad69d6ad4446dec23b5ec456c18641fb5381ba"))
 -            (67500, uint256S("0x000000006b366d2c1649a6ebb4787ac2b39c422f451880bc922e3a6fbd723616")),
 -            1487767578,     // * UNIX timestamp of last checkpoint block
 -            325430,         // * total number of transactions between genesis and last checkpoint
 +            (0, consensus.hashGenesisBlock),
 +            //(2500, uint256S("0x0e6a3d5a46eba97c4e7618d66a39f115729e1176433c98481124c2bf733aa54e"))
 +            //(15000, uint256S("0x00f0bd236790e903321a2d22f85bd6bf8a505f6ef4eddb20458a65d37e14d142")),
 +            //(100000, uint256S("0x0f02eb1f3a4b89df9909fec81a4bd7d023e32e24e1f5262d9fc2cc36a715be6f")),
 +            1481120910,     // * UNIX timestamp of last checkpoint block
 +            110415,         // * total number of transactions between genesis and last checkpoint
                              //   (the tx=... number in the SetBestChain debug.log lines)
-             4240            // * estimated number of transactions per day after checkpoint
+             2777            // * estimated number of transactions per day after checkpoint
                              //   total number of tx / (checkpoint block height / (24 * 24))
          };
 -
 -        // Founders reward script expects a vector of 2-of-3 multisig addresses
 -        vFoundersRewardAddress = {
 -            "t3Vz22vK5z2LcKEdg16Yv4FFneEL1zg9ojd", /* main-index: 0*/
 -            "t3cL9AucCajm3HXDhb5jBnJK2vapVoXsop3", /* main-index: 1*/
 -            "t3fqvkzrrNaMcamkQMwAyHRjfDdM2xQvDTR", /* main-index: 2*/
 -            "t3TgZ9ZT2CTSK44AnUPi6qeNaHa2eC7pUyF", /* main-index: 3*/
 -            "t3SpkcPQPfuRYHsP5vz3Pv86PgKo5m9KVmx", /* main-index: 4*/
 -            "t3Xt4oQMRPagwbpQqkgAViQgtST4VoSWR6S", /* main-index: 5*/
 -            "t3ayBkZ4w6kKXynwoHZFUSSgXRKtogTXNgb", /* main-index: 6*/
 -            "t3adJBQuaa21u7NxbR8YMzp3km3TbSZ4MGB", /* main-index: 7*/
 -            "t3K4aLYagSSBySdrfAGGeUd5H9z5Qvz88t2", /* main-index: 8*/
 -            "t3RYnsc5nhEvKiva3ZPhfRSk7eyh1CrA6Rk", /* main-index: 9*/
 -            "t3Ut4KUq2ZSMTPNE67pBU5LqYCi2q36KpXQ", /* main-index: 10*/
 -            "t3ZnCNAvgu6CSyHm1vWtrx3aiN98dSAGpnD", /* main-index: 11*/
 -            "t3fB9cB3eSYim64BS9xfwAHQUKLgQQroBDG", /* main-index: 12*/
 -            "t3cwZfKNNj2vXMAHBQeewm6pXhKFdhk18kD", /* main-index: 13*/
 -            "t3YcoujXfspWy7rbNUsGKxFEWZqNstGpeG4", /* main-index: 14*/
 -            "t3bLvCLigc6rbNrUTS5NwkgyVrZcZumTRa4", /* main-index: 15*/
 -            "t3VvHWa7r3oy67YtU4LZKGCWa2J6eGHvShi", /* main-index: 16*/
 -            "t3eF9X6X2dSo7MCvTjfZEzwWrVzquxRLNeY", /* main-index: 17*/
 -            "t3esCNwwmcyc8i9qQfyTbYhTqmYXZ9AwK3X", /* main-index: 18*/
 -            "t3M4jN7hYE2e27yLsuQPPjuVek81WV3VbBj", /* main-index: 19*/
 -            "t3gGWxdC67CYNoBbPjNvrrWLAWxPqZLxrVY", /* main-index: 20*/
 -            "t3LTWeoxeWPbmdkUD3NWBquk4WkazhFBmvU", /* main-index: 21*/
 -            "t3P5KKX97gXYFSaSjJPiruQEX84yF5z3Tjq", /* main-index: 22*/
 -            "t3f3T3nCWsEpzmD35VK62JgQfFig74dV8C9", /* main-index: 23*/
 -            "t3Rqonuzz7afkF7156ZA4vi4iimRSEn41hj", /* main-index: 24*/
 -            "t3fJZ5jYsyxDtvNrWBeoMbvJaQCj4JJgbgX", /* main-index: 25*/
 -            "t3Pnbg7XjP7FGPBUuz75H65aczphHgkpoJW", /* main-index: 26*/
 -            "t3WeKQDxCijL5X7rwFem1MTL9ZwVJkUFhpF", /* main-index: 27*/
 -            "t3Y9FNi26J7UtAUC4moaETLbMo8KS1Be6ME", /* main-index: 28*/
 -            "t3aNRLLsL2y8xcjPheZZwFy3Pcv7CsTwBec", /* main-index: 29*/
 -            "t3gQDEavk5VzAAHK8TrQu2BWDLxEiF1unBm", /* main-index: 30*/
 -            "t3Rbykhx1TUFrgXrmBYrAJe2STxRKFL7G9r", /* main-index: 31*/
 -            "t3aaW4aTdP7a8d1VTE1Bod2yhbeggHgMajR", /* main-index: 32*/
 -            "t3YEiAa6uEjXwFL2v5ztU1fn3yKgzMQqNyo", /* main-index: 33*/
 -            "t3g1yUUwt2PbmDvMDevTCPWUcbDatL2iQGP", /* main-index: 34*/
 -            "t3dPWnep6YqGPuY1CecgbeZrY9iUwH8Yd4z", /* main-index: 35*/
 -            "t3QRZXHDPh2hwU46iQs2776kRuuWfwFp4dV", /* main-index: 36*/
 -            "t3enhACRxi1ZD7e8ePomVGKn7wp7N9fFJ3r", /* main-index: 37*/
 -            "t3PkLgT71TnF112nSwBToXsD77yNbx2gJJY", /* main-index: 38*/
 -            "t3LQtHUDoe7ZhhvddRv4vnaoNAhCr2f4oFN", /* main-index: 39*/
 -            "t3fNcdBUbycvbCtsD2n9q3LuxG7jVPvFB8L", /* main-index: 40*/
 -            "t3dKojUU2EMjs28nHV84TvkVEUDu1M1FaEx", /* main-index: 41*/
 -            "t3aKH6NiWN1ofGd8c19rZiqgYpkJ3n679ME", /* main-index: 42*/
 -            "t3MEXDF9Wsi63KwpPuQdD6by32Mw2bNTbEa", /* main-index: 43*/
 -            "t3WDhPfik343yNmPTqtkZAoQZeqA83K7Y3f", /* main-index: 44*/
 -            "t3PSn5TbMMAEw7Eu36DYctFezRzpX1hzf3M", /* main-index: 45*/
 -            "t3R3Y5vnBLrEn8L6wFjPjBLnxSUQsKnmFpv", /* main-index: 46*/
 -            "t3Pcm737EsVkGTbhsu2NekKtJeG92mvYyoN", /* main-index: 47*/
 -//            "t3PZ9PPcLzgL57XRSG5ND4WNBC9UTFb8DXv", /* main-index: 48*/
 -//            "t3L1WgcyQ95vtpSgjHfgANHyVYvffJZ9iGb", /* main-index: 49*/
 -//            "t3JtoXqsv3FuS7SznYCd5pZJGU9di15mdd7", /* main-index: 50*/
 -//            "t3hLJHrHs3ytDgExxr1mD8DYSrk1TowGV25", /* main-index: 51*/
 -//            "t3fmYHU2DnVaQgPhDs6TMFVmyC3qbWEWgXN", /* main-index: 52*/
 -//            "t3T4WmAp6nrLkJ24iPpGeCe1fSWTPv47ASG", /* main-index: 53*/
 -//            "t3fP6GrDM4QVwdjFhmCxGNbe7jXXXSDQ5dv", /* main-index: 54*/
 -};
 -        assert(vFoundersRewardAddress.size() <= consensus.GetLastFoundersRewardBlockHeight());
 +        if ( pthread_create((pthread_t *)malloc(sizeof(pthread_t)),NULL,chainparams_commandline,(void *)&consensus) != 0 )
 +        {
 +            
 +        }
      }
  };
  static CMainParams mainParams;
@@@ -212,11 -258,30 +211,13 @@@ public
  
          checkpointData = (Checkpoints::CCheckpointData) {
              boost::assign::map_list_of
-             ( 0, consensus.hashGenesisBlock),
-             genesis.nTime,
-             0,
-             0
+             (0, consensus.hashGenesisBlock)
+             (38000, uint256S("0x001e9a2d2e2892b88e9998cf7b079b41d59dd085423a921fe8386cecc42287b8")),
+             1486897419,  // * UNIX timestamp of last checkpoint block
+             47163,       // * total number of transactions between genesis and last checkpoint
+                          //   (the tx=... number in the SetBestChain debug.log lines)
+             715          //   total number of tx / (checkpoint block height / (24 * 24))
          };
 -
 -        // Founders reward script expects a vector of 2-of-3 multisig addresses
 -        vFoundersRewardAddress = {
 -            "t2UNzUUx8mWBCRYPRezvA363EYXyEpHokyi", "t2N9PH9Wk9xjqYg9iin1Ua3aekJqfAtE543", "t2NGQjYMQhFndDHguvUw4wZdNdsssA6K7x2", "t2ENg7hHVqqs9JwU5cgjvSbxnT2a9USNfhy",
 -            "t2BkYdVCHzvTJJUTx4yZB8qeegD8QsPx8bo", "t2J8q1xH1EuigJ52MfExyyjYtN3VgvshKDf", "t2Crq9mydTm37kZokC68HzT6yez3t2FBnFj", "t2EaMPUiQ1kthqcP5UEkF42CAFKJqXCkXC9", 
 -            "t2F9dtQc63JDDyrhnfpzvVYTJcr57MkqA12", "t2LPirmnfYSZc481GgZBa6xUGcoovfytBnC", "t26xfxoSw2UV9Pe5o3C8V4YybQD4SESfxtp", "t2D3k4fNdErd66YxtvXEdft9xuLoKD7CcVo", 
 -            "t2DWYBkxKNivdmsMiivNJzutaQGqmoRjRnL", "t2C3kFF9iQRxfc4B9zgbWo4dQLLqzqjpuGQ", "t2MnT5tzu9HSKcppRyUNwoTp8MUueuSGNaB", "t2AREsWdoW1F8EQYsScsjkgqobmgrkKeUkK", 
 -            "t2Vf4wKcJ3ZFtLj4jezUUKkwYR92BLHn5UT", "t2K3fdViH6R5tRuXLphKyoYXyZhyWGghDNY", "t2VEn3KiKyHSGyzd3nDw6ESWtaCQHwuv9WC", "t2F8XouqdNMq6zzEvxQXHV1TjwZRHwRg8gC", 
 -            "t2BS7Mrbaef3fA4xrmkvDisFVXVrRBnZ6Qj", "t2FuSwoLCdBVPwdZuYoHrEzxAb9qy4qjbnL", "t2SX3U8NtrT6gz5Db1AtQCSGjrpptr8JC6h", "t2V51gZNSoJ5kRL74bf9YTtbZuv8Fcqx2FH", 
 -            "t2FyTsLjjdm4jeVwir4xzj7FAkUidbr1b4R", "t2EYbGLekmpqHyn8UBF6kqpahrYm7D6N1Le", "t2NQTrStZHtJECNFT3dUBLYA9AErxPCmkka", "t2GSWZZJzoesYxfPTWXkFn5UaxjiYxGBU2a", 
 -            "t2RpffkzyLRevGM3w9aWdqMX6bd8uuAK3vn", "t2JzjoQqnuXtTGSN7k7yk5keURBGvYofh1d", "t2AEefc72ieTnsXKmgK2bZNckiwvZe3oPNL", "t2NNs3ZGZFsNj2wvmVd8BSwSfvETgiLrD8J", 
 -            "t2ECCQPVcxUCSSQopdNquguEPE14HsVfcUn", "t2JabDUkG8TaqVKYfqDJ3rqkVdHKp6hwXvG", "t2FGzW5Zdc8Cy98ZKmRygsVGi6oKcmYir9n", "t2DUD8a21FtEFn42oVLp5NGbogY13uyjy9t", 
 -            "t2UjVSd3zheHPgAkuX8WQW2CiC9xHQ8EvWp", "t2TBUAhELyHUn8i6SXYsXz5Lmy7kDzA1uT5", "t2Tz3uCyhP6eizUWDc3bGH7XUC9GQsEyQNc", "t2NysJSZtLwMLWEJ6MH3BsxRh6h27mNcsSy", 
 -            "t2KXJVVyyrjVxxSeazbY9ksGyft4qsXUNm9", "t2J9YYtH31cveiLZzjaE4AcuwVho6qjTNzp", "t2QgvW4sP9zaGpPMH1GRzy7cpydmuRfB4AZ", "t2NDTJP9MosKpyFPHJmfjc5pGCvAU58XGa4", 
 -            "t29pHDBWq7qN4EjwSEHg8wEqYe9pkmVrtRP", "t2Ez9KM8VJLuArcxuEkNRAkhNvidKkzXcjJ", "t2D5y7J5fpXajLbGrMBQkFg2mFN8fo3n8cX", "t2UV2wr1PTaUiybpkV3FdSdGxUJeZdZztyt", 
 -            };
 -        assert(vFoundersRewardAddress.size() <= consensus.GetLastFoundersRewardBlockHeight());
      }
  };
  static CTestNetParams testNetParams;
Simple merge
index db38f0bf43861389682865cd1a2f2f37799ce76b,fb934ab2405aa4c4b68303cf4fc0fc65803b48a2..108c89b856f38ef970625e402de7df7d517547ef
@@@ -16,8 -17,8 +17,8 @@@
  //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it
  #define CLIENT_VERSION_MAJOR 1
  #define CLIENT_VERSION_MINOR 0
- #define CLIENT_VERSION_REVISION 5
- #define CLIENT_VERSION_BUILD 51
+ #define CLIENT_VERSION_REVISION 8
 -#define CLIENT_VERSION_BUILD 50
++#define CLIENT_VERSION_BUILD 52
  
  //! Set to true for release, false for prerelease or test build
  #define CLIENT_VERSION_IS_RELEASE true
diff --cc src/coins.cpp
Simple merge
diff --cc src/coins.h
index 34e3a89d7da0aa2510ae5859f14ad6d7321c16eb,ebc86188fef4144eaca0abc1af3443d959cc724e..e7a8a017a8e94386463780dd4ad3e60cdf7463b2
@@@ -6,9 -6,8 +6,10 @@@
  #ifndef BITCOIN_COINS_H
  #define BITCOIN_COINS_H
  
 +#define KOMODO_ENABLE_INTEREST //enabling this is a hardfork, activate with new RR method
 +
  #include "compressor.h"
+ #include "core_memusage.h"
  #include "memusage.h"
  #include "serialize.h"
  #include "uint256.h"
Simple merge
Simple merge
diff --cc src/init.cpp
index f7a58fa500fcefc4bd09289de19d7ae80f33e0c9,ec3553c463eb43ecf8e299f08b3611cda617a9be..d17f0a16e7555973171f29c4f45772d4b836dcd2
@@@ -960,8 -1047,10 +1052,11 @@@ bool AppInit2(boost::thread_group& thre
  #endif
      if (GetBoolArg("-shrinkdebugfile", !fDebug))
          ShrinkDebugFile();
 -
 +    LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
 +    LogPrintf("Komodo version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
+     if (fPrintToDebugLog)
+         OpenDebugLog();
      LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
  #ifdef ENABLE_WALLET
      LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
index 46004a92ed5e13298f4c90e92cb6e8c5ad96d554,0000000000000000000000000000000000000000..19d0440ddf2fa05c86f7481aa0099e490781985c
mode 100644,000000..100644
--- /dev/null
@@@ -1,651 -1,0 +1,651 @@@
- #include "univalue/univalue.h"
 +// Copyright (c) 2009-2014 The Bitcoin Core developers
 +// Distributed under the MIT software license, see the accompanying
 +// file COPYING or http://www.opensource.org/licenses/mit-license.php.
 +
 +#include "base58.h"
 +#include "clientversion.h"
 +#include "coins.h"
 +#include "consensus/consensus.h"
 +#include "core_io.h"
 +#include "keystore.h"
 +#include "primitives/transaction.h"
 +#include "script/script.h"
 +#include "script/sign.h"
-     for (unsigned int kidx = 0; kidx < keysObj.count(); kidx++) {
++#include <univalue.h>
 +#include "util.h"
 +#include "utilmoneystr.h"
 +#include "utilstrencodings.h"
 +
 +#include <stdio.h>
 +
 +#include <boost/algorithm/string.hpp>
 +#include <boost/assign/list_of.hpp>
 +
 +using namespace std;
 +
 +#include "uint256.h"
 +#include "arith_uint256.h"
 +#include "komodo_structs.h"
 +#include "komodo_globals.h"
 +
 +#include "komodo_interest.h"
 +
 +uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue)
 +{
 +    return(0);
 +}
 +
 +static bool fCreateBlank;
 +static map<string,UniValue> registers;
 +
 +static bool AppInitRawTx(int argc, char* argv[])
 +{
 +    //
 +    // Parameters
 +    //
 +    ParseParameters(argc, argv);
 +
 +    // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
 +    if (!SelectParamsFromCommandLine()) {
 +        fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
 +        return false;
 +    }
 +
 +    fCreateBlank = GetBoolArg("-create", false);
 +
 +    if (argc<2 || mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help"))
 +    {
 +        // First part of help message is specific to this utility
 +        std::string strUsage = _("Zcash zcash-tx utility version") + " " + FormatFullVersion() + "\n\n" +
 +            _("Usage:") + "\n" +
 +              "  zcash-tx [options] <hex-tx> [commands]  " + _("Update hex-encoded zcash transaction") + "\n" +
 +              "  zcash-tx [options] -create [commands]   " + _("Create hex-encoded zcash transaction") + "\n" +
 +              "\n";
 +
 +        fprintf(stdout, "%s", strUsage.c_str());
 +
 +        strUsage = HelpMessageGroup(_("Options:"));
 +        strUsage += HelpMessageOpt("-?", _("This help message"));
 +        strUsage += HelpMessageOpt("-create", _("Create new, empty TX."));
 +        strUsage += HelpMessageOpt("-json", _("Select JSON output"));
 +        strUsage += HelpMessageOpt("-txid", _("Output only the hex-encoded transaction id of the resultant transaction."));
 +        strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly."));
 +        strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
 +
 +        fprintf(stdout, "%s", strUsage.c_str());
 +
 +        strUsage = HelpMessageGroup(_("Commands:"));
 +        strUsage += HelpMessageOpt("delin=N", _("Delete input N from TX"));
 +        strUsage += HelpMessageOpt("delout=N", _("Delete output N from TX"));
 +        strUsage += HelpMessageOpt("in=TXID:VOUT", _("Add input to TX"));
 +        strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N"));
 +        strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N"));
 +        strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX"));
 +        strUsage += HelpMessageOpt("outscript=VALUE:SCRIPT", _("Add raw script output to TX"));
 +        strUsage += HelpMessageOpt("sign=SIGHASH-FLAGS", _("Add zero or more signatures to transaction") + ". " +
 +            _("This command requires JSON registers:") +
 +            _("prevtxs=JSON object") + ", " +
 +            _("privatekeys=JSON object") + ". " +
 +            _("See signrawtransaction docs for format of sighash flags, JSON objects."));
 +        fprintf(stdout, "%s", strUsage.c_str());
 +
 +        strUsage = HelpMessageGroup(_("Register Commands:"));
 +        strUsage += HelpMessageOpt("load=NAME:FILENAME", _("Load JSON file FILENAME into register NAME"));
 +        strUsage += HelpMessageOpt("set=NAME:JSON-STRING", _("Set register NAME to given JSON-STRING"));
 +        fprintf(stdout, "%s", strUsage.c_str());
 +
 +        return false;
 +    }
 +    return true;
 +}
 +
 +static void RegisterSetJson(const string& key, const string& rawJson)
 +{
 +    UniValue val;
 +    if (!val.read(rawJson)) {
 +        string strErr = "Cannot parse JSON for key " + key;
 +        throw runtime_error(strErr);
 +    }
 +
 +    registers[key] = val;
 +}
 +
 +static void RegisterSet(const string& strInput)
 +{
 +    // separate NAME:VALUE in string
 +    size_t pos = strInput.find(':');
 +    if ((pos == string::npos) ||
 +        (pos == 0) ||
 +        (pos == (strInput.size() - 1)))
 +        throw runtime_error("Register input requires NAME:VALUE");
 +
 +    string key = strInput.substr(0, pos);
 +    string valStr = strInput.substr(pos + 1, string::npos);
 +
 +    RegisterSetJson(key, valStr);
 +}
 +
 +static void RegisterLoad(const string& strInput)
 +{
 +    // separate NAME:FILENAME in string
 +    size_t pos = strInput.find(':');
 +    if ((pos == string::npos) ||
 +        (pos == 0) ||
 +        (pos == (strInput.size() - 1)))
 +        throw runtime_error("Register load requires NAME:FILENAME");
 +
 +    string key = strInput.substr(0, pos);
 +    string filename = strInput.substr(pos + 1, string::npos);
 +
 +    FILE *f = fopen(filename.c_str(), "r");
 +    if (!f) {
 +        string strErr = "Cannot open file " + filename;
 +        throw runtime_error(strErr);
 +    }
 +
 +    // load file chunks into one big buffer
 +    string valStr;
 +    while ((!feof(f)) && (!ferror(f))) {
 +        char buf[4096];
 +        int bread = fread(buf, 1, sizeof(buf), f);
 +        if (bread <= 0)
 +            break;
 +
 +        valStr.insert(valStr.size(), buf, bread);
 +    }
 +
 +    int error = ferror(f);
 +    fclose(f);
 +
 +    if (error) {
 +        string strErr = "Error reading file " + filename;
 +        throw runtime_error(strErr);
 +    }
 +
 +    // evaluate as JSON buffer register
 +    RegisterSetJson(key, valStr);
 +}
 +
 +static void MutateTxVersion(CMutableTransaction& tx, const string& cmdVal)
 +{
 +    int64_t newVersion = atoi64(cmdVal);
 +    if (newVersion < CTransaction::MIN_CURRENT_VERSION || newVersion > CTransaction::MAX_CURRENT_VERSION)
 +        throw runtime_error("Invalid TX version requested");
 +
 +    tx.nVersion = (int) newVersion;
 +}
 +
 +static void MutateTxLocktime(CMutableTransaction& tx, const string& cmdVal)
 +{
 +    int64_t newLocktime = atoi64(cmdVal);
 +    if (newLocktime < 0LL || newLocktime > 0xffffffffLL)
 +        throw runtime_error("Invalid TX locktime requested");
 +
 +    tx.nLockTime = (unsigned int) newLocktime;
 +}
 +
 +static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput)
 +{
 +    // separate TXID:VOUT in string
 +    size_t pos = strInput.find(':');
 +    if ((pos == string::npos) ||
 +        (pos == 0) ||
 +        (pos == (strInput.size() - 1)))
 +        throw runtime_error("TX input missing separator");
 +
 +    // extract and validate TXID
 +    string strTxid = strInput.substr(0, pos);
 +    if ((strTxid.size() != 64) || !IsHex(strTxid))
 +        throw runtime_error("invalid TX input txid");
 +    uint256 txid(uint256S(strTxid));
 +
 +    static const unsigned int minTxOutSz = 9;
 +    static const unsigned int maxVout = MAX_BLOCK_SIZE / minTxOutSz;
 +
 +    // extract and validate vout
 +    string strVout = strInput.substr(pos + 1, string::npos);
 +    int vout = atoi(strVout);
 +    if ((vout < 0) || (vout > (int)maxVout))
 +        throw runtime_error("invalid TX input vout");
 +
 +    // append to transaction input list
 +    CTxIn txin(txid, vout);
 +    tx.vin.push_back(txin);
 +}
 +
 +static void MutateTxAddOutAddr(CMutableTransaction& tx, const string& strInput)
 +{
 +    // separate VALUE:ADDRESS in string
 +    size_t pos = strInput.find(':');
 +    if ((pos == string::npos) ||
 +        (pos == 0) ||
 +        (pos == (strInput.size() - 1)))
 +        throw runtime_error("TX output missing separator");
 +
 +    // extract and validate VALUE
 +    string strValue = strInput.substr(0, pos);
 +    CAmount value;
 +    if (!ParseMoney(strValue, value))
 +        throw runtime_error("invalid TX output value");
 +
 +    // extract and validate ADDRESS
 +    string strAddr = strInput.substr(pos + 1, string::npos);
 +    CBitcoinAddress addr(strAddr);
 +    if (!addr.IsValid())
 +        throw runtime_error("invalid TX output address");
 +
 +    // build standard output script via GetScriptForDestination()
 +    CScript scriptPubKey = GetScriptForDestination(addr.Get());
 +
 +    // construct TxOut, append to transaction output list
 +    CTxOut txout(value, scriptPubKey);
 +    tx.vout.push_back(txout);
 +}
 +
 +static void MutateTxAddOutScript(CMutableTransaction& tx, const string& strInput)
 +{
 +    // separate VALUE:SCRIPT in string
 +    size_t pos = strInput.find(':');
 +    if ((pos == string::npos) ||
 +        (pos == 0))
 +        throw runtime_error("TX output missing separator");
 +
 +    // extract and validate VALUE
 +    string strValue = strInput.substr(0, pos);
 +    CAmount value;
 +    if (!ParseMoney(strValue, value))
 +        throw runtime_error("invalid TX output value");
 +
 +    // extract and validate script
 +    string strScript = strInput.substr(pos + 1, string::npos);
 +    CScript scriptPubKey = ParseScript(strScript); // throws on err
 +
 +    // construct TxOut, append to transaction output list
 +    CTxOut txout(value, scriptPubKey);
 +    tx.vout.push_back(txout);
 +}
 +
 +static void MutateTxDelInput(CMutableTransaction& tx, const string& strInIdx)
 +{
 +    // parse requested deletion index
 +    int inIdx = atoi(strInIdx);
 +    if (inIdx < 0 || inIdx >= (int)tx.vin.size()) {
 +        string strErr = "Invalid TX input index '" + strInIdx + "'";
 +        throw runtime_error(strErr.c_str());
 +    }
 +
 +    // delete input from transaction
 +    tx.vin.erase(tx.vin.begin() + inIdx);
 +}
 +
 +static void MutateTxDelOutput(CMutableTransaction& tx, const string& strOutIdx)
 +{
 +    // parse requested deletion index
 +    int outIdx = atoi(strOutIdx);
 +    if (outIdx < 0 || outIdx >= (int)tx.vout.size()) {
 +        string strErr = "Invalid TX output index '" + strOutIdx + "'";
 +        throw runtime_error(strErr.c_str());
 +    }
 +
 +    // delete output from transaction
 +    tx.vout.erase(tx.vout.begin() + outIdx);
 +}
 +
 +static const unsigned int N_SIGHASH_OPTS = 6;
 +static const struct {
 +    const char *flagStr;
 +    int flags;
 +} sighashOptions[N_SIGHASH_OPTS] = {
 +    {"ALL", SIGHASH_ALL},
 +    {"NONE", SIGHASH_NONE},
 +    {"SINGLE", SIGHASH_SINGLE},
 +    {"ALL|ANYONECANPAY", SIGHASH_ALL|SIGHASH_ANYONECANPAY},
 +    {"NONE|ANYONECANPAY", SIGHASH_NONE|SIGHASH_ANYONECANPAY},
 +    {"SINGLE|ANYONECANPAY", SIGHASH_SINGLE|SIGHASH_ANYONECANPAY},
 +};
 +
 +static bool findSighashFlags(int& flags, const string& flagStr)
 +{
 +    flags = 0;
 +
 +    for (unsigned int i = 0; i < N_SIGHASH_OPTS; i++) {
 +        if (flagStr == sighashOptions[i].flagStr) {
 +            flags = sighashOptions[i].flags;
 +            return true;
 +        }
 +    }
 +
 +    return false;
 +}
 +
 +uint256 ParseHashUO(map<string,UniValue>& o, string strKey)
 +{
 +    if (!o.count(strKey))
 +        return uint256();
 +    return ParseHashUV(o[strKey], strKey);
 +}
 +
 +vector<unsigned char> ParseHexUO(map<string,UniValue>& o, string strKey)
 +{
 +    if (!o.count(strKey)) {
 +        vector<unsigned char> emptyVec;
 +        return emptyVec;
 +    }
 +    return ParseHexUV(o[strKey], strKey);
 +}
 +
 +
 +static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
 +{
 +    int nHashType = SIGHASH_ALL;
 +
 +    if (flagStr.size() > 0)
 +        if (!findSighashFlags(nHashType, flagStr))
 +            throw runtime_error("unknown sighash flag/sign option");
 +
 +    vector<CTransaction> txVariants;
 +    txVariants.push_back(tx);
 +
 +    // mergedTx will end up with all the signatures; it
 +    // starts as a clone of the raw tx:
 +    CMutableTransaction mergedTx(txVariants[0]);
 +    bool fComplete = true;
 +    CCoinsView viewDummy;
 +    CCoinsViewCache view(&viewDummy);
 +
 +    if (!registers.count("privatekeys"))
 +        throw runtime_error("privatekeys register variable must be set.");
 +    bool fGivenKeys = false;
 +    CBasicKeyStore tempKeystore;
 +    UniValue keysObj = registers["privatekeys"];
 +    fGivenKeys = true;
 +
-         for (unsigned int previdx = 0; previdx < prevtxsObj.count(); previdx++) {
++    for (size_t kidx = 0; kidx < keysObj.size(); kidx++) {
 +        if (!keysObj[kidx].isStr())
 +            throw runtime_error("privatekey not a string");
 +        CBitcoinSecret vchSecret;
 +        bool fGood = vchSecret.SetString(keysObj[kidx].getValStr());
 +        if (!fGood)
 +            throw runtime_error("privatekey not valid");
 +
 +        CKey key = vchSecret.GetKey();
 +        tempKeystore.AddKey(key);
 +    }
 +
 +    // Add previous txouts given in the RPC call:
 +    if (!registers.count("prevtxs"))
 +        throw runtime_error("prevtxs register variable must be set.");
 +    UniValue prevtxsObj = registers["prevtxs"];
 +    {
++        for (size_t previdx = 0; previdx < prevtxsObj.size(); previdx++) {
 +            UniValue prevOut = prevtxsObj[previdx];
 +            if (!prevOut.isObject())
 +                throw runtime_error("expected prevtxs internal object");
 +
 +            map<string,UniValue::VType> types = boost::assign::map_list_of("txid", UniValue::VSTR)("vout",UniValue::VNUM)("scriptPubKey",UniValue::VSTR);
 +            if (!prevOut.checkObject(types))
 +                throw runtime_error("prevtxs internal object typecheck fail");
 +
 +            uint256 txid = ParseHashUV(prevOut["txid"], "txid");
 +
 +            int nOut = atoi(prevOut["vout"].getValStr());
 +            if (nOut < 0)
 +                throw runtime_error("vout must be positive");
 +
 +            vector<unsigned char> pkData(ParseHexUV(prevOut["scriptPubKey"], "scriptPubKey"));
 +            CScript scriptPubKey(pkData.begin(), pkData.end());
 +
 +            {
 +                CCoinsModifier coins = view.ModifyCoins(txid);
 +                if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
 +                    string err("Previous output scriptPubKey mismatch:\n");
 +                    err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+
 +                        scriptPubKey.ToString();
 +                    throw runtime_error(err);
 +                }
 +                if ((unsigned int)nOut >= coins->vout.size())
 +                    coins->vout.resize(nOut+1);
 +                coins->vout[nOut].scriptPubKey = scriptPubKey;
 +                coins->vout[nOut].nValue = 0; // we don't know the actual output value
 +            }
 +
 +            // if redeemScript given and private keys given,
 +            // add redeemScript to the tempKeystore so it can be signed:
 +            if (fGivenKeys && scriptPubKey.IsPayToScriptHash() &&
 +                prevOut.exists("redeemScript")) {
 +                UniValue v = prevOut["redeemScript"];
 +                vector<unsigned char> rsData(ParseHexUV(v, "redeemScript"));
 +                CScript redeemScript(rsData.begin(), rsData.end());
 +                tempKeystore.AddCScript(redeemScript);
 +            }
 +        }
 +    }
 +
 +    const CKeyStore& keystore = tempKeystore;
 +
 +    bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
 +
 +    // Sign what we can:
 +    for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
 +        CTxIn& txin = mergedTx.vin[i];
 +        const CCoins* coins = view.AccessCoins(txin.prevout.hash);
 +        if (!coins || !coins->IsAvailable(txin.prevout.n)) {
 +            fComplete = false;
 +            continue;
 +        }
 +        const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey;
 +
 +        txin.scriptSig.clear();
 +        // Only sign SIGHASH_SINGLE if there's a corresponding output:
 +        if (!fHashSingle || (i < mergedTx.vout.size()))
 +            SignSignature(keystore, prevPubKey, mergedTx, i, nHashType);
 +
 +        // ... and merge in other signatures:
 +        BOOST_FOREACH(const CTransaction& txv, txVariants) {
 +            txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
 +        }
 +        if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i)))
 +            fComplete = false;
 +    }
 +
 +    if (fComplete) {
 +        // do nothing... for now
 +        // perhaps store this for later optional JSON output
 +    }
 +
 +    tx = mergedTx;
 +}
 +
 +class Secp256k1Init
 +{
 +public:
 +    Secp256k1Init() { ECC_Start(); }
 +    ~Secp256k1Init() { ECC_Stop(); }
 +};
 +
 +static void MutateTx(CMutableTransaction& tx, const string& command,
 +                     const string& commandVal)
 +{
 +    boost::scoped_ptr<Secp256k1Init> ecc;
 +
 +    if (command == "nversion")
 +        MutateTxVersion(tx, commandVal);
 +    else if (command == "locktime")
 +        MutateTxLocktime(tx, commandVal);
 +
 +    else if (command == "delin")
 +        MutateTxDelInput(tx, commandVal);
 +    else if (command == "in")
 +        MutateTxAddInput(tx, commandVal);
 +
 +    else if (command == "delout")
 +        MutateTxDelOutput(tx, commandVal);
 +    else if (command == "outaddr")
 +        MutateTxAddOutAddr(tx, commandVal);
 +    else if (command == "outscript")
 +        MutateTxAddOutScript(tx, commandVal);
 +
 +    else if (command == "sign") {
 +        if (!ecc) { ecc.reset(new Secp256k1Init()); }
 +        MutateTxSign(tx, commandVal);
 +    }
 +
 +    else if (command == "load")
 +        RegisterLoad(commandVal);
 +
 +    else if (command == "set")
 +        RegisterSet(commandVal);
 +
 +    else
 +        throw runtime_error("unknown command");
 +}
 +
 +static void OutputTxJSON(const CTransaction& tx)
 +{
 +    UniValue entry(UniValue::VOBJ);
 +    TxToUniv(tx, uint256(), entry);
 +
 +    string jsonOutput = entry.write(4);
 +    fprintf(stdout, "%s\n", jsonOutput.c_str());
 +}
 +
 +static void OutputTxHash(const CTransaction& tx)
 +{
 +    string strHexHash = tx.GetHash().GetHex(); // the hex-encoded transaction hash (aka the transaction id)
 +
 +    fprintf(stdout, "%s\n", strHexHash.c_str());
 +}
 +
 +static void OutputTxHex(const CTransaction& tx)
 +{
 +    string strHex = EncodeHexTx(tx);
 +
 +    fprintf(stdout, "%s\n", strHex.c_str());
 +}
 +
 +static void OutputTx(const CTransaction& tx)
 +{
 +    if (GetBoolArg("-json", false))
 +        OutputTxJSON(tx);
 +    else if (GetBoolArg("-txid", false))
 +        OutputTxHash(tx);
 +    else
 +        OutputTxHex(tx);
 +}
 +
 +static string readStdin()
 +{
 +    char buf[4096];
 +    string ret;
 +
 +    while (!feof(stdin)) {
 +        size_t bread = fread(buf, 1, sizeof(buf), stdin);
 +        ret.append(buf, bread);
 +        if (bread < sizeof(buf))
 +            break;
 +    }
 +
 +    if (ferror(stdin))
 +        throw runtime_error("error reading stdin");
 +
 +    boost::algorithm::trim_right(ret);
 +
 +    return ret;
 +}
 +
 +static int CommandLineRawTx(int argc, char* argv[])
 +{
 +    string strPrint;
 +    int nRet = 0;
 +    try {
 +        // Skip switches; Permit common stdin convention "-"
 +        while (argc > 1 && IsSwitchChar(argv[1][0]) &&
 +               (argv[1][1] != 0)) {
 +            argc--;
 +            argv++;
 +        }
 +
 +        CTransaction txDecodeTmp;
 +        int startArg;
 +
 +        if (!fCreateBlank) {
 +            // require at least one param
 +            if (argc < 2)
 +                throw runtime_error("too few parameters");
 +
 +            // param: hex-encoded bitcoin transaction
 +            string strHexTx(argv[1]);
 +            if (strHexTx == "-")                 // "-" implies standard input
 +                strHexTx = readStdin();
 +
 +            if (!DecodeHexTx(txDecodeTmp, strHexTx))
 +                throw runtime_error("invalid transaction encoding");
 +
 +            startArg = 2;
 +        } else
 +            startArg = 1;
 +
 +        CMutableTransaction tx(txDecodeTmp);
 +
 +        for (int i = startArg; i < argc; i++) {
 +            string arg = argv[i];
 +            string key, value;
 +            size_t eqpos = arg.find('=');
 +            if (eqpos == string::npos)
 +                key = arg;
 +            else {
 +                key = arg.substr(0, eqpos);
 +                value = arg.substr(eqpos + 1);
 +            }
 +
 +            MutateTx(tx, key, value);
 +        }
 +
 +        OutputTx(tx);
 +    }
 +
 +    catch (const boost::thread_interrupted&) {
 +        throw;
 +    }
 +    catch (const std::exception& e) {
 +        strPrint = string("error: ") + e.what();
 +        nRet = EXIT_FAILURE;
 +    }
 +    catch (...) {
 +        PrintExceptionContinue(NULL, "CommandLineRawTx()");
 +        throw;
 +    }
 +
 +    if (strPrint != "") {
 +        fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
 +    }
 +    return nRet;
 +}
 +
 +int main(int argc, char* argv[])
 +{
 +    SetupEnvironment();
 +
 +    try {
 +        if(!AppInitRawTx(argc, argv))
 +            return EXIT_FAILURE;
 +    }
 +    catch (const std::exception& e) {
 +        PrintExceptionContinue(&e, "AppInitRawTx()");
 +        return EXIT_FAILURE;
 +    } catch (...) {
 +        PrintExceptionContinue(NULL, "AppInitRawTx()");
 +        return EXIT_FAILURE;
 +    }
 +
 +    int ret = EXIT_FAILURE;
 +    try {
 +        ret = CommandLineRawTx(argc, argv);
 +    }
 +    catch (const std::exception& e) {
 +        PrintExceptionContinue(&e, "CommandLineRawTx()");
 +    } catch (...) {
 +        PrintExceptionContinue(NULL, "CommandLineRawTx()");
 +    }
 +    return ret;
 +}
diff --cc src/main.cpp
index 43794cb94cf7cf2550355c074050751f557693b4,ab91ee41e71033a590b052543aa5f1138c101039..4ae36759cbe9de12e14f1a26ab9cbad1b3451789
@@@ -1878,44 -1741,6 +1902,46 @@@ bool ContextualCheckInputs(const CTrans
      return true;
  }
  
- }
 +bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, const Consensus::Params& consensusParams, std::vector<CScriptCheck> *pvChecks)
++
++/*bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, const Consensus::Params& consensusParams, std::vector<CScriptCheck> *pvChecks)
 +{
 +    if (!NonContextualCheckInputs(tx, state, inputs, fScriptChecks, flags, cacheStore, consensusParams, pvChecks)) {
 +        fprintf(stderr,"ContextualCheckInputs failure.0\n");
 +        return false;
 +    }
 +
 +    if (!tx.IsCoinBase())
 +    {
 +        // While checking, GetBestBlock() refers to the parent block.
 +        // This is also true for mempool checks.
 +        CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
 +        int nSpendHeight = pindexPrev->nHeight + 1;
 +        for (unsigned int i = 0; i < tx.vin.size(); i++)
 +        {
 +            const COutPoint &prevout = tx.vin[i].prevout;
 +            const CCoins *coins = inputs.AccessCoins(prevout.hash);
 +            // Assertion is okay because NonContextualCheckInputs ensures the inputs
 +            // are available.
 +            assert(coins);
 +
 +            // If prev is coinbase, check that it's matured
 +            if (coins->IsCoinBase()) {
 +                if ( ASSETCHAINS_SYMBOL[0] == 0 )
 +                    COINBASE_MATURITY = _COINBASE_MATURITY;
 +                if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
 +                    fprintf(stderr,"ContextualCheckInputs failure.1 i.%d of %d\n",i,(int32_t)tx.vin.size());
 +
 +                    return state.Invalid(
 +                        error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
 +                }
 +            }
 +        }
 +    }
 +
 +    return true;
++}*/
 +
  namespace {
  
  bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
@@@ -2207,8 -2032,16 +2233,20 @@@ bool ConnectBlock(const CBlock& block, 
  {
      const CChainParams& chainparams = Params();
      AssertLockHeld(cs_main);
 -
++/*<<<<<<< HEA
 +    // Check it again in case a previous version let a bad block in
 +    bool fExpensiveChecks = (!fCheckpointsEnabled || pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()));
++=======
++*/
+     bool fExpensiveChecks = true;
+     if (fCheckpointsEnabled) {
+         CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
+         if (pindexLastCheckpoint && pindexLastCheckpoint->GetAncestor(pindex->nHeight) == pindex) {
+             // This block is an ancestor of a checkpoint: disable script checks
+             fExpensiveChecks = false;
+         }
+     }
 -
++//>>>>>>> zcash/master
      auto verifier = libzcash::ProofVerifier::Strict();
      auto disabledVerifier = libzcash::ProofVerifier::Disabled();
  
@@@ -2893,8 -2709,9 +2935,9 @@@ bool ActivateBestChain(CValidationStat
                          pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
              }
              // Notify external listeners about the new tip.
+             GetMainSignals().UpdatedBlockTip(pindexNewTip);
              uiInterface.NotifyBlockTip(hashNewTip);
 -        }
 +        } //else fprintf(stderr,"initial download skips propagation\n");
      } while(pindexMostWork != chainActive.Tip());
      CheckBlockIndex();
  
@@@ -3275,20 -3067,14 +3318,20 @@@ bool ContextualCheckBlockHeader(const C
          return state.Invalid(error("%s: block's timestamp is too early", __func__),
                               REJECT_INVALID, "time-too-old");
  
-     if(fCheckpointsEnabled)
+     if (fCheckpointsEnabled)
      {
 +        // Check that the block chain matches the known block chain up to a checkpoint
 +        if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
 +            return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),REJECT_CHECKPOINT, "checkpoint mismatch");
 +
          // Don't accept any forks from the main chain prior to last checkpoint
          CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints());
 +        int32_t notarized_height;
          if (pcheckpoint && nHeight < pcheckpoint->nHeight)
 -            return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight));
 +            return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d) vs %d", __func__, nHeight,pcheckpoint->nHeight));
 +        else if ( komodo_checkpoint(&notarized_height,nHeight,hash) < 0 )
 +            return state.DoS(100, error("%s: forked chain %d older than last notarized (height %d) vs %d", __func__,nHeight, notarized_height));
      }
 -
      // Reject block.nVersion < 4 blocks
      if (block.nVersion < 4)
          return state.Invalid(error("%s : rejected nVersion<4 block", __func__),
diff --cc src/main.h
Simple merge
diff --cc src/miner.cpp
index 7c14b8d4e7841c39f4433c82db9bd931c7e5b281,e65b9c5f06f4fdf555b7b7bce711c056b2ea3692..78fe63a3959adfc4a393695d9856b748ad674bdb
@@@ -98,57 -106,15 +106,57 @@@ void UpdateTime(CBlockHeader* pblock, c
          pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams);
  }
  
 +#define ASSETCHAINS_MINHEIGHT 100
 +#define KOMODO_ELECTION_GAP 2000
 +#define ROUNDROBIN_DELAY 60
 +extern int32_t ASSETCHAINS_SEED,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAIN_INIT,KOMODO_INITDONE,KOMODO_ON_DEMAND,KOMODO_INITDONE,KOMODO_PASSPORT_INITDONE;
 +extern char ASSETCHAINS_SYMBOL[16];
 +extern std::string NOTARY_PUBKEY;
 +extern uint8_t NOTARY_PUBKEY33[33];
 +uint32_t Mining_start,Mining_height;
 +int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33);
 +int32_t komodo_is_special(int32_t height,uint8_t pubkey33[33]);
 +int32_t komodo_pax_opreturn(uint8_t *opret,int32_t maxsize);
 +uint64_t komodo_paxtotal();
 +int32_t komodo_baseid(char *origbase);
 +int32_t komodo_is_issuer();
 +int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *symbol,int32_t tokomodo);
 +int32_t komodo_isrealtime(int32_t *kmdheightp);
 +int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag);
 +
  CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
  {
 -    const CChainParams& chainparams = Params();
 +    uint64_t deposits; int32_t isrealtime,kmdheight; const CChainParams& chainparams = Params();
      // Create new block
-     unique_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate());
+     std::unique_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate());
      if(!pblocktemplate.get())
 +    {
 +        fprintf(stderr,"pblocktemplate.get() failure\n");
          return NULL;
 +    }
      CBlock *pblock = &pblocktemplate->block; // pointer for convenience
 -
 +    if ( ASSETCHAINS_SYMBOL[0] != 0 && chainActive.Tip()->nHeight >= ASSETCHAINS_MINHEIGHT )
 +    {
 +        isrealtime = komodo_isrealtime(&kmdheight);
 +        deposits = komodo_paxtotal();
 +        while ( KOMODO_ON_DEMAND == 0 && deposits == 0 && (int32_t)mempool.GetTotalTxSize() == 0 )
 +        {
 +            deposits = komodo_paxtotal();
 +            if ( KOMODO_PASSPORT_INITDONE == 0 || KOMODO_INITDONE == 0 || (komodo_baseid(ASSETCHAINS_SYMBOL) >= 0 && (isrealtime= komodo_isrealtime(&kmdheight)) == 0) )
 +            {
 +                //fprintf(stderr,"INITDONE.%d RT.%d deposits %.8f ht.%d\n",KOMODO_INITDONE,isrealtime,(double)deposits/COIN,kmdheight);
 +            }
 +            else if ( komodo_isrealtime(&kmdheight) != 0 && (deposits != 0 || (int32_t)mempool.GetTotalTxSize() > 0) )
 +            {
 +                fprintf(stderr,"start CreateNewBlock %s initdone.%d deposit %.8f mempool.%d RT.%u KOMODO_ON_DEMAND.%d\n",ASSETCHAINS_SYMBOL,KOMODO_INITDONE,(double)komodo_paxtotal()/COIN,(int32_t)mempool.GetTotalTxSize(),isrealtime,KOMODO_ON_DEMAND);
 +                break;
 +            }
 +            sleep(10);
 +        }
 +        KOMODO_ON_DEMAND = 0;
 +        if ( 0 && deposits != 0 )
 +            printf("miner KOMODO_DEPOSIT %llu pblock->nHeight %d mempool.GetTotalTxSize(%d)\n",(long long)komodo_paxtotal(),(int32_t)chainActive.Tip()->nHeight,(int32_t)mempool.GetTotalTxSize());
 +    }
      // -regtest only: allow overriding block.nVersion with
      // -blockversion=N to test forking scenarios
      if (Params().MineBlocksOnDemand())
      return pblocktemplate.release();
  }
  
 -#ifdef ENABLE_WALLET
+ #ifdef ENABLE_WALLET
+ boost::optional<CScript> GetMinerScriptPubKey(CReserveKey& reservekey)
+ #else
+ boost::optional<CScript> GetMinerScriptPubKey()
+ #endif
+ {
+     CKeyID keyID;
+     CBitcoinAddress addr;
+     if (addr.SetString(GetArg("-mineraddress", ""))) {
+         addr.GetKeyID(keyID);
+     } else {
+ #ifdef ENABLE_WALLET
+         CPubKey pubkey;
+         if (!reservekey.GetReservedKey(pubkey)) {
+             return boost::optional<CScript>();
+         }
+         keyID = pubkey.GetID();
+ #else
+         return boost::optional<CScript>();
+ #endif
+     }
+     CScript scriptPubKey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
+     return scriptPubKey;
+ }
 -}
++/*#ifdef ENABLE_WALLET
+ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey)
+ {
+     boost::optional<CScript> scriptPubKey = GetMinerScriptPubKey(reservekey);
+ #else
+ CBlockTemplate* CreateNewBlockWithKey()
+ {
+     boost::optional<CScript> scriptPubKey = GetMinerScriptPubKey();
+ #endif
+     if (!scriptPubKey) {
+         return NULL;
+     }
+     return CreateNewBlock(*scriptPubKey);
++}*/
+ //////////////////////////////////////////////////////////////////////////////
+ //
+ // Internal miner
+ //
+ #ifdef ENABLE_MINING
  void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
  {
      // Update nExtraNonce
  }
  
  #ifdef ENABLE_WALLET
 +//////////////////////////////////////////////////////////////////////////////
 +//
 +// Internal miner
 +//
 +int8_t komodo_minerid(int32_t height,uint8_t *pubkey33);
 +
 +CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey)
 +{
 +    CPubKey pubkey; CScript scriptPubKey; uint8_t *script,*ptr; int32_t i;
 +    if ( USE_EXTERNAL_PUBKEY != 0 )
 +    {
 +        //fprintf(stderr,"use notary pubkey\n");
 +        scriptPubKey = CScript() << ParseHex(NOTARY_PUBKEY) << OP_CHECKSIG;
 +    }
 +    else
 +    {
 +        if (!reservekey.GetReservedKey(pubkey))
 +        {
 +            return NULL;
 +        }
 +        scriptPubKey.resize(35);
 +        ptr = (uint8_t *)pubkey.begin();
 +        script = (uint8_t *)scriptPubKey.data();
 +        script[0] = 33;
 +        for (i=0; i<33; i++)
 +            script[i+1] = ptr[i];
 +        script[34] = OP_CHECKSIG;
 +        //scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
 +    }
 +    if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
 +    {
 +        for (i=0; i<65; i++)
 +            fprintf(stderr,"%d ",komodo_minerid(chainActive.Tip()->nHeight-i,0));
 +        fprintf(stderr," minerids.special %d from ht.%d\n",komodo_is_special(chainActive.Tip()->nHeight+1,NOTARY_PUBKEY33),chainActive.Tip()->nHeight);
 +    }
 +    return CreateNewBlock(scriptPubKey);
 +}
 +
++
  static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
+ #else
+ static bool ProcessBlockFound(CBlock* pblock)
+ #endif // ENABLE_WALLET
  {
      LogPrintf("%s\n", pblock->ToString());
 -    LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));
 +    LogPrintf("generated %s height.%d\n", FormatMoney(pblock->vtx[0].vout[0].nValue),chainActive.Tip()->nHeight+1);
  
      // Found a solution
      {
          LOCK(cs_main);
          if (pblock->hashPrevBlock != chainActive.Tip()->GetBlockHash())
 -            return error("ZcashMiner: generated block is stale");
 +        {
 +            uint256 hash; int32_t i;
 +            hash = pblock->hashPrevBlock;
 +            for (i=31; i>=0; i--)
 +                fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
 +            fprintf(stderr," <- prev (stale)\n");
 +            hash = chainActive.Tip()->GetBlockHash();
 +            for (i=31; i>=0; i--)
 +                fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
 +            fprintf(stderr," <- chainTip (stale)\n");
 +
 +            return error("KomodoMiner: generated block is stale");
 +        }
      }
  
 -    if (GetArg("-mineraddress", "").empty()) {
 -        // Remove key from key pool
 -        reservekey.KeepKey();
+ #ifdef ENABLE_WALLET
-         reservekey.KeepKey();
 +    // Remove key from key pool
 +    if ( IS_KOMODO_NOTARY == 0 )
 -
++    {
++        if (GetArg("-mineraddress", "").empty()) {
++            // Remove key from key pool
++            reservekey.KeepKey();
++        }
+     }
      // Track how many getdata requests this block gets
      {
          LOCK(wallet.cs_wallet);
      return true;
  }
  
 +int32_t komodo_baseid(char *origbase);
 +int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,int32_t *nonzpkeysp,int32_t height);
 +int32_t FOUND_BLOCK,KOMODO_MAYBEMINED;
 +extern int32_t KOMODO_LASTMINED;
 +int32_t roundrobin_delay;
 +
+ #ifdef ENABLE_WALLET
  void static BitcoinMiner(CWallet *pwallet)
+ #else
+ void static BitcoinMiner()
+ #endif
  {
 -    LogPrintf("ZcashMiner started\n");
 +    LogPrintf("KomodoMiner started\n");
      SetThreadPriority(THREAD_PRIORITY_LOWEST);
 -    RenameThread("zcash-miner");
 +    RenameThread("komodo-miner");
      const CChainParams& chainparams = Params();
  
-     // Each thread has its own key and counter
+ #ifdef ENABLE_WALLET
+     // Each thread has its own key
      CReserveKey reservekey(pwallet);
+ #endif
+     // Each thread has its own counter
      unsigned int nExtraNonce = 0;
  
      unsigned int n = chainparams.EquihashN();
              cancelSolver = true;
          }
      );
+     miningTimer.start();
  
      try {
 -        while (true) {
 -            if (chainparams.MiningRequiresPeers()) {
 +        if ( ASSETCHAINS_SYMBOL[0] != 0 )
 +            fprintf(stderr,"try %s Mining with %s\n",ASSETCHAINS_SYMBOL,solver.c_str());
 +        while (true)
 +        {
 +            if (chainparams.MiningRequiresPeers()) //chainActive.Tip()->nHeight != 235300 &&
 +            {
 +                //if ( ASSETCHAINS_SEED != 0 && chainActive.Tip()->nHeight < 100 )
 +                //    break;
                  // Busy-wait for the network to come online so we don't waste time mining
                  // on an obsolete chain. In regtest mode we expect to fly solo.
-                 //fprintf(stderr,"Wait for peers...\n");
+                 miningTimer.stop();
                  do {
                      bool fvNodesEmpty;
                      {
                          LOCK(cs_vNodes);
                          fvNodesEmpty = vNodes.empty();
                      }
 -                    if (!fvNodesEmpty && !IsInitialBlockDownload())
 +                    if (!fvNodesEmpty )//&& !IsInitialBlockDownload())
                          break;
 -                    MilliSleep(1000);
 +                    MilliSleep(5000);
 +                    //fprintf(stderr,"fvNodesEmpty %d IsInitialBlockDownload(%s) %d\n",(int32_t)fvNodesEmpty,ASSETCHAINS_SYMBOL,(int32_t)IsInitialBlockDownload());
 +
                  } while (true);
 +                //fprintf(stderr,"%s Found peers\n",ASSETCHAINS_SYMBOL);
+                 miningTimer.start();
              }
 -
 +            /*while ( ASSETCHAINS_SYMBOL[0] != 0 && chainActive.Tip()->nHeight < ASSETCHAINS_MINHEIGHT )
 +            {
 +                fprintf(stderr,"%s waiting for block 100, ht.%d\n",ASSETCHAINS_SYMBOL,chainActive.Tip()->nHeight);
 +                sleep(3);
 +            }*/
              //
              // Create new block
              //
              unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
              CBlockIndex* pindexPrev = chainActive.Tip();
 -
 +            if ( Mining_height != pindexPrev->nHeight+1 )
 +            {
 +                Mining_height = pindexPrev->nHeight+1;
 +                Mining_start = (uint32_t)time(NULL);
 +            }
 +            if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
 +                fprintf(stderr,"%s create new block ht.%d\n",ASSETCHAINS_SYMBOL,Mining_height);
+ #ifdef ENABLE_WALLET
 -            unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
 +            CBlockTemplate *ptr = CreateNewBlockWithKey(reservekey);
+ #else
 -            unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey());
++            CBlockTemplate *ptr = CreateNewBlockWithKey();
+ #endif
 +            if ( ptr == 0 )
 +            {
 +                static uint32_t counter;
 +                if ( counter++ < 100 )
 +                    fprintf(stderr,"created illegal block, retry\n");
 +                continue;
 +            }
 +            unique_ptr<CBlockTemplate> pblocktemplate(ptr);
              if (!pblocktemplate.get())
              {
-                 LogPrintf("Error in KomodoMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n");
+                 if (GetArg("-mineraddress", "").empty()) {
 -                    LogPrintf("Error in ZcashMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n");
++                    LogPrintf("Error in KomodoMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n");
+                 } else {
+                     // Should never reach here, because -mineraddress validity is checked in init.cpp
 -                    LogPrintf("Error in ZcashMiner: Invalid -mineraddress\n");
++                    LogPrintf("Error in KomodoMiner: Invalid -mineraddress\n");
+                 }
                  return;
              }
              CBlock *pblock = &pblocktemplate->block;
                  // H(I||V||...
                  crypto_generichash_blake2b_state curr_state;
                  curr_state = state;
 -                crypto_generichash_blake2b_update(&curr_state,
 -                                                  pblock->nNonce.begin(),
 -                                                  pblock->nNonce.size());
 -
 +                crypto_generichash_blake2b_update(&curr_state,pblock->nNonce.begin(),pblock->nNonce.size());
                  // (x_1, x_2, ...) = A(I, V, n, k)
 -                LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",
 -                         solver, pblock->nNonce.ToString());
 -
 +                LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",solver, pblock->nNonce.ToString());
 +                //fprintf(stderr,"running solver\n");
                  std::function<bool(std::vector<unsigned char>)> validBlock =
+ #ifdef ENABLE_WALLET
                          [&pblock, &hashTarget, &pwallet, &reservekey, &m_cs, &cancelSolver, &chainparams]
-                         (std::vector<unsigned char> soln)
-                 {
+ #else
+                         [&pblock, &hashTarget, &m_cs, &cancelSolver, &chainparams]
+ #endif
+                         (std::vector<unsigned char> soln) {
                      // Write the solution to the hash and compute the result.
                      LogPrint("pow", "- Checking solution against target\n");
                      pblock->nSolution = soln;
                      solutionTargetChecks.increment();
 -
 -                    if (UintToArith256(pblock->GetHash()) > hashTarget) {
 +                    if ( UintToArith256(pblock->GetHash()) > hashTarget )
 +                    {
 +                        //if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
 +                        //     fprintf(stderr," missed target\n");
                          return false;
                      }
 -
 +                    if ( ASSETCHAINS_SYMBOL[0] == 0 && Mining_start != 0 && time(NULL) < Mining_start+roundrobin_delay )
 +                    {
 +                        //printf("Round robin diff sleep %d\n",(int32_t)(Mining_start+roundrobin_delay-time(NULL)));
 +                        int32_t nseconds = Mining_start+roundrobin_delay-time(NULL);
 +                        if ( nseconds > 0 )
 +                            sleep(nseconds);
 +                        MilliSleep((rand() % 1700) + 1);
 +                    }
 +                    KOMODO_CHOSEN_ONE = 1;
                      // Found a solution
                      SetThreadPriority(THREAD_PRIORITY_NORMAL);
 -                    LogPrintf("ZcashMiner:\n");
 +                    LogPrintf("KomodoMiner:\n");
                      LogPrintf("proof-of-work found  \n  hash: %s  \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex());
+ #ifdef ENABLE_WALLET
                      if (ProcessBlockFound(pblock, *pwallet, reservekey)) {
+ #else
+                     if (ProcessBlockFound(pblock)) {
+ #endif
                          // Ignore chain updates caused by us
                          std::lock_guard<std::mutex> lock{m_cs};
                          cancelSolver = false;
      }
      catch (const boost::thread_interrupted&)
      {
+         miningTimer.stop();
          c.disconnect();
 -        LogPrintf("ZcashMiner terminated\n");
 +        LogPrintf("KomodoMiner terminated\n");
          throw;
      }
      catch (const std::runtime_error &e)
      {
+         miningTimer.stop();
          c.disconnect();
 -        LogPrintf("ZcashMiner runtime error: %s\n", e.what());
 +        LogPrintf("KomodoMiner runtime error: %s\n", e.what());
          return;
      }
+     miningTimer.stop();
      c.disconnect();
  }
  
diff --cc src/net.cpp
Simple merge
diff --cc src/netbase.cpp
Simple merge
diff --cc src/pow.cpp
Simple merge
Simple merge
diff --cc src/rest.cpp
index d278198b42cc87245cd4575178761783d9106345,b8cc5462b3f0d1123f39c82834bd81c427ab76b0..1a1e5268bd8448c34c9935600b3a078b49602b40
@@@ -506,10 -563,9 +563,10 @@@ static bool rest_getutxos(HTTPRequest* 
              utxo.push_back(Pair("txvers", (int32_t)coin.nTxVer));
              utxo.push_back(Pair("height", (int32_t)coin.nHeight));
              utxo.push_back(Pair("value", ValueFromAmount(coin.out.nValue)));
 +            //utxo.push_back(Pair("interest", ValueFromAmount(komodo_interest(coin.out.nValue,coin.nLockTime,chainActive.Tip()->nTime))));
  
              // include the script in a json output
-             Object o;
+             UniValue o(UniValue::VOBJ);
              ScriptPubKeyToJSON(coin.out.scriptPubKey, o, true);
              utxo.push_back(Pair("scriptPubKey", o));
              utxos.push_back(utxo);
index b1fa9d3d5a893600d4a2c57d567f611c9e3e7937,939430be2030b3d31083b00f78e4a6f0e129faa4..a825d1e8ac46c7e3ed26dc13aeaa59bce9a17897
@@@ -272,23 -309,7 +309,26 @@@ UniValue getblockhash(const UniValue& p
      return pblockindex->GetBlockHash().GetHex();
  }
  
- Value getblock(const Array& params, bool fHelp)
 +uint256 _komodo_getblockhash(int32_t nHeight)
 +{
 +    uint256 hash;
 +    LOCK(cs_main);
 +    if ( nHeight >= 0 && nHeight <= chainActive.Height() )
 +    {
 +        CBlockIndex* pblockindex = chainActive[nHeight];
 +        hash = pblockindex->GetBlockHash();
 +        int32_t i;
 +        for (i=0; i<32; i++)
 +            printf("%02x",((uint8_t *)&hash)[i]);
 +        printf(" blockhash.%d\n",nHeight);
 +    } else memset(&hash,0,sizeof(hash));
 +    return(hash);
 +}
 +
++//Value getblock(const Array& params, bool fHelp)
++//=======
+ UniValue getblockheader(const UniValue& params, bool fHelp)
++//>>>>>>> zcash/master
  {
      if (fHelp || params.size() < 1 || params.size() > 2)
          throw runtime_error(
@@@ -396,266 -496,7 +515,269 @@@ UniValue gettxoutsetinfo(const UniValue
      return ret;
  }
  
- Value gettxout(const Array& params, bool fHelp)
 +#define IGUANA_MAXSCRIPTSIZE 10001
 +#define KOMODO_KVDURATION 1440
 +#define KOMODO_KVBINARY 2
 +extern char ASSETCHAINS_SYMBOL[16];
 +uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime);
 +uint32_t komodo_txtime(uint256 hash);
 +uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uint64_t basevolume);
 +int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel);
 +int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height);
 +char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len);
 +//uint32_t komodo_interest_args(int32_t *txheightp,uint32_t *tiptimep,uint64_t *valuep,uint256 hash,int32_t n);
 +int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width);
 +int32_t komodo_kvsearch(uint256 *refpubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[IGUANA_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen);
 +
 +Value kvsearch(const Array& params, bool fHelp)
 +{
 +    Object ret; uint32_t flags; uint8_t value[IGUANA_MAXSCRIPTSIZE],key[IGUANA_MAXSCRIPTSIZE]; int32_t duration,j,height,valuesize,keylen; uint256 refpubkey; static uint256 zeroes;
 +    if (fHelp || params.size() != 1 )
 +        throw runtime_error("kvsearch key");
 +    LOCK(cs_main);
 +    if ( (keylen= (int32_t)strlen(params[0].get_str().c_str())) > 0 )
 +    {
 +        ret.push_back(Pair("coin",(char *)(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL)));
 +        ret.push_back(Pair("currentheight", (int64_t)chainActive.Tip()->nHeight));
 +        ret.push_back(Pair("key",params[0].get_str()));
 +        ret.push_back(Pair("keylen",keylen));
 +        if ( keylen < sizeof(key) )
 +        {
 +            memcpy(key,params[0].get_str().c_str(),keylen);
 +            if ( (valuesize= komodo_kvsearch(&refpubkey,chainActive.Tip()->nHeight,&flags,&height,value,key,keylen)) >= 0 )
 +            {
 +                std::string val; char *valuestr;
 +                val.resize(valuesize);
 +                valuestr = (char *)val.data();
 +                memcpy(valuestr,value,valuesize);
 +                if ( memcmp(&zeroes,&refpubkey,sizeof(refpubkey)) != 0 )
 +                    ret.push_back(Pair("owner",refpubkey.GetHex()));
 +                ret.push_back(Pair("height",height));
 +                duration = ((flags >> 2) + 1) * KOMODO_KVDURATION;
 +                ret.push_back(Pair("expiration", (int64_t)(height+duration)));
 +                ret.push_back(Pair("flags",(int64_t)flags));
 +                ret.push_back(Pair("value",val));
 +                ret.push_back(Pair("valuesize",valuesize));
 +            } else ret.push_back(Pair("error",(char *)"cant find key"));
 +        } else ret.push_back(Pair("error",(char *)"key too big"));
 +    } else ret.push_back(Pair("error",(char *)"null key"));
 +    return ret;
 +}
 +
 +Value minerids(const Array& params, bool fHelp)
 +{
 +    Object ret; Array a; uint8_t minerids[2000],pubkeys[65][33]; int32_t i,j,n,numnotaries,tally[129];
 +    if ( fHelp || params.size() != 1 )
 +        throw runtime_error("minerids needs height\n");
 +    LOCK(cs_main);
 +    int32_t height = atoi(params[0].get_str().c_str());
 +    if ( height <= 0 )
 +        height = chainActive.Tip()->nHeight;
 +    if ( (n= komodo_minerids(minerids,height,(int32_t)(sizeof(minerids)/sizeof(*minerids)))) > 0 )
 +    {
 +        memset(tally,0,sizeof(tally));
 +        numnotaries = komodo_notaries(pubkeys,height);
 +        if ( numnotaries > 0 )
 +        {
 +            for (i=0; i<n; i++)
 +            {
 +                if ( minerids[i] >= numnotaries )
 +                    tally[128]++;
 +                else tally[minerids[i]]++;
 +            }
 +            for (i=0; i<64; i++)
 +            {
 +                Object item; std::string hex,kmdaddress; char *hexstr,kmdaddr[64],*ptr; int32_t m;
 +                hex.resize(66);
 +                hexstr = (char *)hex.data();
 +                for (j=0; j<33; j++)
 +                    sprintf(&hexstr[j*2],"%02x",pubkeys[i][j]);
 +                item.push_back(Pair("notaryid", i));
 +                
 +                bitcoin_address(kmdaddr,60,pubkeys[i],33);
 +                m = (int32_t)strlen(kmdaddr);
 +                kmdaddress.resize(m);
 +                ptr = (char *)kmdaddress.data();
 +                memcpy(ptr,kmdaddr,m);
 +                item.push_back(Pair("KMDaddress", kmdaddress));
 +                
 +                item.push_back(Pair("pubkey", hex));
 +                item.push_back(Pair("blocks", tally[i]));
 +                a.push_back(item);
 +            }
 +            Object item;
 +            item.push_back(Pair("pubkey", (char *)"external miners"));
 +            item.push_back(Pair("blocks", tally[128]));
 +            a.push_back(item);
 +        }
 +        ret.push_back(Pair("mined", a));
 +    } else ret.push_back(Pair("error", (char *)"couldnt extract minerids"));
 +    return ret;
 +}
 +
 +Value notaries(const Array& params, bool fHelp)
 +{
 +    Array a; Object ret; int32_t i,j,n,m; char *hexstr;  uint8_t pubkeys[64][33]; char btcaddr[64],kmdaddr[64],*ptr;
 +    if ( fHelp || params.size() != 1 )
 +        throw runtime_error("notaries height\n");
 +    LOCK(cs_main);
 +    int32_t height = atoi(params[0].get_str().c_str());
 +    if ( height < 0 )
 +        height = chainActive.Tip()->nHeight;
 +    //fprintf(stderr,"notaries as of height.%d\n",height);
 +    //if ( height > chainActive.Height()+20000 )
 +    //    throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
 +    //else
 +    {
 +        if ( (n= komodo_notaries(pubkeys,height)) > 0 )
 +        {
 +            for (i=0; i<n; i++)
 +            {
 +                Object item;
 +                std::string btcaddress,kmdaddress,hex;
 +                hex.resize(66);
 +                hexstr = (char *)hex.data();
 +                for (j=0; j<33; j++)
 +                    sprintf(&hexstr[j*2],"%02x",pubkeys[i][j]);
 +                item.push_back(Pair("pubkey", hex));
 +
 +                bitcoin_address(btcaddr,0,pubkeys[i],33);
 +                m = (int32_t)strlen(btcaddr);
 +                btcaddress.resize(m);
 +                ptr = (char *)btcaddress.data();
 +                memcpy(ptr,btcaddr,m);
 +                item.push_back(Pair("BTCaddress", btcaddress));
 +
 +                bitcoin_address(kmdaddr,60,pubkeys[i],33);
 +                m = (int32_t)strlen(kmdaddr);
 +                kmdaddress.resize(m);
 +                ptr = (char *)kmdaddress.data();
 +                memcpy(ptr,kmdaddr,m);
 +                item.push_back(Pair("KMDaddress", kmdaddress));
 +                a.push_back(item);
 +            }
 +        }
 +        ret.push_back(Pair("notaries", a));
 +        ret.push_back(Pair("numnotaries", n));
 +    }
 +    return ret;
 +}
 +
 +int32_t komodo_pending_withdraws(char *opretstr);
 +int32_t pax_fiatstatus(uint64_t *available,uint64_t *deposited,uint64_t *issued,uint64_t *withdrawn,uint64_t *approved,uint64_t *redeemed,char *base);
 +extern char CURRENCIES[][8];
 +
 +Value paxpending(const Array& params, bool fHelp)
 +{
 +    Object ret; Array a; char opretbuf[10000*2]; int32_t opretlen,baseid; uint64_t available,deposited,issued,withdrawn,approved,redeemed;
 +    if ( fHelp || params.size() != 0 )
 +        throw runtime_error("paxpending needs no args\n");
 +    LOCK(cs_main);
 +    if ( (opretlen= komodo_pending_withdraws(opretbuf)) > 0 )
 +        ret.push_back(Pair("withdraws", opretbuf));
 +    else ret.push_back(Pair("withdraws", (char *)""));
 +    for (baseid=0; baseid<32; baseid++)
 +    {
 +        Object item,obj;
 +        if ( pax_fiatstatus(&available,&deposited,&issued,&withdrawn,&approved,&redeemed,CURRENCIES[baseid]) == 0 )
 +        {
 +            if ( deposited != 0 || issued != 0 || withdrawn != 0 || approved != 0 || redeemed != 0 )
 +            {
 +                item.push_back(Pair("available", ValueFromAmount(available)));
 +                item.push_back(Pair("deposited", ValueFromAmount(deposited)));
 +                item.push_back(Pair("issued", ValueFromAmount(issued)));
 +                item.push_back(Pair("withdrawn", ValueFromAmount(withdrawn)));
 +                item.push_back(Pair("approved", ValueFromAmount(approved)));
 +                item.push_back(Pair("redeemed", ValueFromAmount(redeemed)));
 +                obj.push_back(Pair(CURRENCIES[baseid],item));
 +                a.push_back(obj);
 +            }
 +        }
 +    }
 +    ret.push_back(Pair("fiatstatus", a));
 +    return ret;
 +}
 +
 +Value paxprice(const Array& params, bool fHelp)
 +{
 +    if ( fHelp || params.size() > 4 || params.size() < 2 )
 +        throw runtime_error("paxprice \"base\" \"rel\" height\n");
 +    LOCK(cs_main);
 +    Object ret; uint64_t basevolume=0,relvolume,seed;
 +    std::string base = params[0].get_str();
 +    std::string rel = params[1].get_str();
 +    int32_t height;
 +    if ( params.size() == 2 )
 +        height = chainActive.Tip()->nHeight;
 +    else height = atoi(params[2].get_str().c_str());
 +    //if ( params.size() == 3 || (basevolume= COIN * atof(params[3].get_str().c_str())) == 0 )
 +        basevolume = 1;
 +    relvolume = komodo_paxprice(&seed,height,(char *)base.c_str(),(char *)rel.c_str(),basevolume);
 +    ret.push_back(Pair("base", base));
 +    ret.push_back(Pair("rel", rel));
 +    ret.push_back(Pair("height", height));
 +    char seedstr[32];
 +    sprintf(seedstr,"%llu",(long long)seed);
 +    ret.push_back(Pair("seed", seedstr));
 +    if ( height < 0 || height > chainActive.Height() )
 +        throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
 +    else
 +    {
 +        CBlockIndex *pblockindex = chainActive[height];
 +        if ( pblockindex != 0 )
 +            ret.push_back(Pair("timestamp", (int64_t)pblockindex->nTime));
 +        if ( basevolume != 0 && relvolume != 0 )
 +        {
 +            ret.push_back(Pair("price",((double)relvolume / (double)basevolume)));
 +            ret.push_back(Pair("invprice",((double)basevolume / (double)relvolume)));
 +            ret.push_back(Pair("basevolume",ValueFromAmount(basevolume)));
 +            ret.push_back(Pair("relvolume",ValueFromAmount(relvolume)));
 +        } else ret.push_back(Pair("error", "overflow or error in one or more of parameters"));
 +    }
 +    return ret;
 +}
 +
 +Value paxprices(const Array& params, bool fHelp)
 +{
 +    if ( fHelp || params.size() != 3 )
 +        throw runtime_error("paxprices \"base\" \"rel\" maxsamples\n");
 +    LOCK(cs_main);
 +    Object ret; uint64_t relvolume,prices[4096]; uint32_t i,n; int32_t heights[sizeof(prices)/sizeof(*prices)];
 +    std::string base = params[0].get_str();
 +    std::string rel = params[1].get_str();
 +    int32_t maxsamples = atoi(params[2].get_str().c_str());
 +    if ( maxsamples < 1 )
 +        maxsamples = 1;
 +    else if ( maxsamples > sizeof(heights)/sizeof(*heights) )
 +        maxsamples = sizeof(heights)/sizeof(*heights);
 +    ret.push_back(Pair("base", base));
 +    ret.push_back(Pair("rel", rel));
 +    n = komodo_paxprices(heights,prices,maxsamples,(char *)base.c_str(),(char *)rel.c_str());
 +    Array a;
 +    for (i=0; i<n; i++)
 +    {
 +        Object item;
 +        if ( heights[i] < 0 || heights[i] > chainActive.Height() )
 +            throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
 +        else
 +        {
 +            CBlockIndex *pblockindex = chainActive[heights[i]];
 +            
 +            item.push_back(Pair("t", (int64_t)pblockindex->nTime));
 +            item.push_back(Pair("p", (double)prices[i] / COIN));
 +            a.push_back(item);
 +        }
 +    }
 +    ret.push_back(Pair("array", a));
 +    return ret;
 +}
 +
 +uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue);
 +
++//Value gettxout(const Array& params, bool fHelp)
++//=======
+ UniValue gettxout(const UniValue& params, bool fHelp)
++//>>>>>>> zcash/master
  {
      if (fHelp || params.size() < 2 || params.size() > 3)
          throw runtime_error(
      ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
      if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
          ret.push_back(Pair("confirmations", 0));
 -    else
 -        ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
 +    else ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
      ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
-     Object o;
 +    uint64_t interest; int32_t txheight; uint32_t locktime;
 +    if ( (interest= komodo_accrued_interest(&txheight,&locktime,hash,n,coins.nHeight,coins.vout[n].nValue)) != 0 )
 +        ret.push_back(Pair("interest", ValueFromAmount(interest)));
+     UniValue o(UniValue::VOBJ);
      ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true);
      ret.push_back(Pair("scriptPubKey", o));
      ret.push_back(Pair("version", coins.nVersion));
index 5b89b18c488e07e741b32cdbe4d5ab2b2f0c2c2e,07adf65fc38a35967d0043288320f7e69669d9a9..da8fdc4b65b418466d72861b132bd4a20ffafc69
@@@ -106,14 -111,7 +111,15 @@@ static const CRPCConvertParam vRPCConve
      { "z_sendmany", 3},
      { "z_getoperationstatus", 0},
      { "z_getoperationresult", 0},
 +    { "z_importkey", 1 },
 +    { "paxprice", 4 },
 +    { "paxprices", 3 },
 +    { "paxpending", 0 },
 +    { "notaries", 1 },
 +    { "minerids", 1 },
 +    { "kvsearch", 1 },
 +    { "kvupdate", 4 },
+     { "z_importkey", 2 },
  };
  
  class CRPCConvertTable
index 8dc4111a56415cab2bad49023ed938f8b94803ee,e4273e42bbd1ad91463b84163c4e03ba1fd6ae22..f2fdc1415777c5e82c935cad677f5d6b658db65d
@@@ -157,9 -157,7 +157,10 @@@ UniValue getgenerate(const UniValue& pa
      return GetBoolArg("-gen", false);
  }
  
- Value generate(const Array& params, bool fHelp)
 +extern uint8_t NOTARY_PUBKEY33[33];
 +
++//Value generate(const Array& params, bool fHelp)
+ UniValue generate(const UniValue& params, bool fHelp)
  {
      if (fHelp || params.size() < 1 || params.size() > 1)
          throw runtime_error(
@@@ -650,18 -678,18 +683,18 @@@ UniValue getblocktemplate(const UniValu
  
          if (tx.IsCoinBase()) {
              // Show founders' reward if it is required
 -            if (pblock->vtx[0].vout.size() > 1) {
 +            //if (pblock->vtx[0].vout.size() > 1) {
                  // Correct this if GetBlockTemplate changes the order
 -                entry.push_back(Pair("foundersreward", (int64_t)tx.vout[1].nValue));
 -            }
 +            //    entry.push_back(Pair("foundersreward", (int64_t)tx.vout[1].nValue));
 +            //}
 +            entry.push_back(Pair("coinbasevalue", 3*COIN));
              entry.push_back(Pair("required", true));
              txCoinbase = entry;
 -        } else {
 +        } else
              transactions.push_back(entry);
 -        }
      }
  
-     Object aux;
+     UniValue aux(UniValue::VOBJ);
      aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
  
      arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
      result.push_back(Pair("bits", strprintf("%08x", pblock->nBits)));
      result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1)));
  
 +    //fprintf(stderr,"return complete template\n");
      return result;
  }
- #endif
  
  class submitblock_StateCatcher : public CValidationInterface
  {
@@@ -864,8 -897,13 +902,8 @@@ UniValue getblocksubsidy(const UniValue
          throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
  
      CAmount nReward = GetBlockSubsidy(nHeight, Params().GetConsensus());
-     Object result;
 -    CAmount nFoundersReward = 0;
 -    if ((nHeight > 0) && (nHeight <= Params().GetConsensus().GetLastFoundersRewardBlockHeight())) {
 -        nFoundersReward = nReward/5;
 -        nReward -= nFoundersReward;
 -    }
+     UniValue result(UniValue::VOBJ);
      result.push_back(Pair("miner", ValueFromAmount(nReward)));
 -    result.push_back(Pair("founders", ValueFromAmount(nFoundersReward)));
 +    //result.push_back(Pair("founders", ValueFromAmount(nFoundersReward)));
      return result;
  }
diff --cc src/rpcmisc.cpp
index 9135cd812fd80d47868d15d1a01ae9211547f624,9eab8c21767f797a77a4b433c4b951c063cbc618..f6a78ce3dc47f39894350cbd0a134e7ffb28a1b4
@@@ -41,18 -40,8 +40,19 @@@ using namespace std
   *
   * Or alternatively, create a specific query method for the information.
   **/
- Value getinfo(const Array& params, bool fHelp)
++
 +uint64_t komodo_interestsum();
 +int32_t komodo_longestchain();
 +int32_t komodo_notarized_height(uint256 *hashp,uint256 *txidp);
 +int32_t komodo_whoami(char *pubkeystr,int32_t height);
 +extern int32_t KOMODO_LASTMINED;
 +extern char ASSETCHAINS_SYMBOL[];
 +int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp);
 +#define KOMODO_VERSION "0.1.0"
 +
+ UniValue getinfo(const UniValue& params, bool fHelp)
  {
 +    uint256 notarized_hash,notarized_desttxid; int32_t notarized_height,longestchain,kmdnotarized_height,txid_height;
      if (fHelp || params.size() != 0)
          throw runtime_error(
              "getinfo\n"
  
      proxyType proxy;
      GetProxy(NET_IPV4, proxy);
 +    notarized_height = komodo_notarized_height(&notarized_hash,&notarized_desttxid);
  
-     Object obj;
+     UniValue obj(UniValue::VOBJ);
      obj.push_back(Pair("version", CLIENT_VERSION));
      obj.push_back(Pair("protocolversion", PROTOCOL_VERSION));
 +    obj.push_back(Pair("KMDversion", KOMODO_VERSION));
 +    obj.push_back(Pair("notarized", notarized_height));
 +    obj.push_back(Pair("notarizedhash", notarized_hash.ToString()));
 +    obj.push_back(Pair("notarizedtxid", notarized_desttxid.ToString()));
 +    txid_height = notarizedtxid_height(ASSETCHAINS_SYMBOL[0] != 0 ? (char *)"KMD" : (char *)"BTC",(char *)notarized_desttxid.ToString().c_str(),&kmdnotarized_height);
 +    if ( txid_height > 0 )
 +        obj.push_back(Pair("notarizedtxid_height", txid_height));
 +    else obj.push_back(Pair("notarizedtxid_height", "mempool"));
 +    if ( ASSETCHAINS_SYMBOL[0] != 0 )
 +        obj.push_back(Pair("KMDnotarized_height", kmdnotarized_height));
 +    obj.push_back(Pair("notarized_confirms", txid_height < kmdnotarized_height ? (kmdnotarized_height - txid_height + 1) : 0));
  #ifdef ENABLE_WALLET
      if (pwalletMain) {
          obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
diff --cc src/rpcnet.cpp
index 7e05c6efd10738b9e080d07d711fb3b00f18fcd0,b68897d169a413240889824153d873dc939bc5b8..ee2c21d4d6ef19a4bb2c7b99b046a13af38f1e2d
@@@ -165,37 -164,7 +164,37 @@@ UniValue getpeerinfo(const UniValue& pa
      return ret;
  }
  
- Value addnode(const Array& params, bool fHelp)
 +int32_t komodo_longestchain()
 +{
 +    int32_t ht,n=0,num=0,maxheight=0,height = 0;
 +    LOCK(cs_main);
 +    vector<CNodeStats> vstats;
 +    CopyNodeStats(vstats);
 +    BOOST_FOREACH(const CNodeStats& stats, vstats)
 +    {
 +        CNodeStateStats statestats;
 +        bool fStateStats = GetNodeStateStats(stats.nodeid,statestats);
 +        ht = 0;
 +        if ( stats.nStartingHeight > ht )
 +            ht = stats.nStartingHeight;
 +        if ( statestats.nSyncHeight > ht )
 +            ht = statestats.nSyncHeight;
 +        if ( statestats.nCommonHeight > ht )
 +            ht = statestats.nCommonHeight;
 +        if ( maxheight == 0 || ht > maxheight*1.01 )
 +            maxheight = ht, num = 1;
 +        else if ( ht > maxheight*0.99 )
 +            num++;
 +        n++;
 +        if ( ht > height )
 +            height = ht;
 +    }
 +    if ( num > (n >> 1) )
 +        return(height);
 +    else return(0);
 +}
 +
+ UniValue addnode(const UniValue& params, bool fHelp)
  {
      string strCommand;
      if (params.size() == 2)
index 313cfea2c0671d38cbf0ccf070016720eabd565d,5ff035164981a33cc55f3a8ec720c9757c26dd61..2bda8df6d83c513b3b9b6ad676977a695c0124ec
@@@ -96,9 -110,7 +110,9 @@@ UniValue TxJoinSplitToJSON(const CTrans
      return vjoinsplit;
  }
  
- void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
 +uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime);
 +
+ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
  {
      entry.push_back(Pair("txid", tx.GetHash().GetHex()));
      entry.push_back(Pair("version", tx.nVersion));
          vin.push_back(in);
      }
      entry.push_back(Pair("vin", vin));
-     Array vout;
 -    UniValue vout(UniValue::VARR);
 +    BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
 +    CBlockIndex *tipindex,*pindex = it->second;
 +    uint64_t interest;
      for (unsigned int i = 0; i < tx.vout.size(); i++) {
          const CTxOut& txout = tx.vout[i];
-         Object out;
+         UniValue out(UniValue::VOBJ);
          out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
 +        if ( pindex != 0 && tx.nLockTime != 0 && (tipindex= chainActive.Tip()) != 0 )
 +        {
 +            extern char ASSETCHAINS_SYMBOL[16];
 +            interest = komodo_interest(pindex->nHeight,txout.nValue,tx.nLockTime,tipindex->nTime);
 +            if ( 0 && strcmp("REVS",ASSETCHAINS_SYMBOL) == 0 )
 +                fprintf(stderr,"TxtoJSON interest %llu %.8f (%d %llu %u %u)\n",(long long)interest,(double)interest/COIN,(int32_t)pindex->nHeight,(long long)txout.nValue,(uint32_t)tx.nLockTime,(int32_t)tipindex->nTime);
 +            out.push_back(Pair("interest", ValueFromAmount(interest)));
 +        }
          out.push_back(Pair("n", (int64_t)i));
-         Object o;
+         UniValue o(UniValue::VOBJ);
          ScriptPubKeyToJSON(txout.scriptPubKey, o, true);
          out.push_back(Pair("scriptPubKey", o));
          vout.push_back(out);
@@@ -253,57 -281,7 +293,57 @@@ UniValue getrawtransaction(const UniVal
      return result;
  }
  
- Value gettxoutproof(const Array& params, bool fHelp)
 +int32_t gettxout_scriptPubKey(uint8_t *scriptPubKey,int32_t maxsize,uint256 txid,int32_t n)
 +{
 +    int32_t i,m; uint8_t *ptr;
 +    LOCK(cs_main);
 +    /*CCoins coins;
 +     for (iter=0; iter<2; iter++)
 +     {
 +     if ( iter == 0 )
 +     {
 +     LOCK(mempool.cs);
 +     CCoinsViewMemPool view(pcoinsTip,mempool);
 +     if ( view.GetCoins(txid,coins) == 0 )
 +     {
 +     //fprintf(stderr,"cant get view\n");
 +     continue;
 +     }
 +     mempool.pruneSpent(txid, coins); // TODO: this should be done by the CCoinsViewMemPool
 +     }
 +     else if ( pcoinsTip->GetCoins(txid,coins) == 0 )
 +     {
 +     //fprintf(stderr,"cant get pcoinsTip->GetCoins\n");
 +     continue;
 +     }
 +     if ( n < 0 || (unsigned int)n >= coins.vout.size() || coins.vout[n].IsNull() )
 +     {
 +     fprintf(stderr,"iter.%d n.%d vs voutsize.%d\n",iter,n,(int32_t)coins.vout.size());
 +     continue;
 +     }
 +     ptr = (uint8_t *)coins.vout[n].scriptPubKey.data();
 +     m = coins.vout[n].scriptPubKey.size();
 +     for (i=0; i<maxsize&&i<m; i++)
 +     scriptPubKey[i] = ptr[i];
 +     return(i);
 +     }*/
 +    CTransaction tx;
 +    uint256 hashBlock;
 +    if ( GetTransaction(txid,tx,hashBlock,true) == 0 )
 +        return(-1);
 +    else if ( n <= tx.vout.size() ) // vout.size() seems off by 1
 +    {
 +        ptr = (uint8_t *)tx.vout[n].scriptPubKey.data();
 +        m = tx.vout[n].scriptPubKey.size();
 +        for (i=0; i<maxsize&&i<m; i++)
 +            scriptPubKey[i] = ptr[i];
 +        //fprintf(stderr,"got scriptPubKey via rawtransaction\n");
 +        return(i);
 +    }
 +    return(-1);
 +}
 +
+ UniValue gettxoutproof(const UniValue& params, bool fHelp)
  {
      if (fHelp || (params.size() != 1 && params.size() != 2))
          throw runtime_error(
index cde0ed095a14c0968a156feb81a00af153a6b6e8,2e8aa5aadde14db849aa5aa97b1ff5e9ce0ff8e9..4749cfdc4efc947c35b1f145f2085a83bfae5021
@@@ -251,20 -239,18 +239,18 @@@ UniValue help(const UniValue& params, b
  }
  
  
Value stop(const Array& params, bool fHelp)
UniValue stop(const UniValue& params, bool fHelp)
  {
 -    // Accept the deprecated and ignored 'detach' boolean argument
 +   // Accept the deprecated and ignored 'detach' boolean argument
      if (fHelp || params.size() > 1)
          throw runtime_error(
              "stop\n"
 -            "\nStop Zcash server.");
 +            "\nStop Komodo server.");
      // Shutdown will take long enough that the response should get back
      StartShutdown();
 -    return "Zcash server stopping";
 +    return "Komodo server stopping";
  }
  
  /**
   * Call Table
   */
@@@ -436,341 -420,9 +430,164 @@@ const CRPCCommand *CRPCTable::operator[
      return (*it).second;
  }
  
- bool HTTPAuthorized(map<string, string>& mapHeaders)
- {
-     string strAuth = mapHeaders["authorization"];
-     if (strAuth.substr(0,6) != "Basic ")
-         return false;
-     string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
-     string strUserPass = DecodeBase64(strUserPass64);
-     return TimingResistantEqual(strUserPass, strRPCUserColonPass);
- }
- void ErrorReply(std::ostream& stream, const Object& objError, const Value& id)
- {
-     // Send error reply from json-rpc error object
-     int nStatus = HTTP_INTERNAL_SERVER_ERROR;
-     int code = find_value(objError, "code").get_int();
-     if (code == RPC_INVALID_REQUEST) nStatus = HTTP_BAD_REQUEST;
-     else if (code == RPC_METHOD_NOT_FOUND) nStatus = HTTP_NOT_FOUND;
-     string strReply = JSONRPCReply(Value::null, objError, id);
-     stream << HTTPReply(nStatus, strReply, false) << std::flush;
- }
- CNetAddr BoostAsioToCNetAddr(boost::asio::ip::address address)
- {
-     CNetAddr netaddr;
-     // Make sure that IPv4-compatible and IPv4-mapped IPv6 addresses are treated as IPv4 addresses
-     if (address.is_v6()
-      && (address.to_v6().is_v4_compatible()
-       || address.to_v6().is_v4_mapped()))
-         address = address.to_v6().to_v4();
-     if(address.is_v4())
-     {
-         boost::asio::ip::address_v4::bytes_type bytes = address.to_v4().to_bytes();
-         netaddr.SetRaw(NET_IPV4, &bytes[0]);
-     }
-     else
-     {
-         boost::asio::ip::address_v6::bytes_type bytes = address.to_v6().to_bytes();
-         netaddr.SetRaw(NET_IPV6, &bytes[0]);
-     }
-     return netaddr;
- }
- bool ClientAllowed(const boost::asio::ip::address& address)
- {
-     CNetAddr netaddr = BoostAsioToCNetAddr(address);
-     BOOST_FOREACH(const CSubNet &subnet, rpc_allow_subnets)
-         if (subnet.Match(netaddr))
-             return true;
-     return false;
- }
- template <typename Protocol>
- class AcceptedConnectionImpl : public AcceptedConnection
- {
- public:
-     AcceptedConnectionImpl(
-             boost::asio::io_service& io_service,
-             ssl::context &context,
-             bool fUseSSL) :
-         sslStream(io_service, context),
-         _d(sslStream, fUseSSL),
-         _stream(_d)
-     {
-     }
-     virtual std::iostream& stream()
-     {
-         return _stream;
-     }
-     virtual std::string peer_address_to_string() const
-     {
-         return peer.address().to_string();
-     }
-     virtual void close()
-     {
-         _stream.close();
-     }
-     typename Protocol::endpoint peer;
-     boost::asio::ssl::stream<typename Protocol::socket> sslStream;
- private:
-     SSLIOStreamDevice<Protocol> _d;
-     boost::iostreams::stream< SSLIOStreamDevice<Protocol> > _stream;
- };
- void ServiceConnection(AcceptedConnection *conn);
- //! Forward declaration required for RPCListen
- template <typename Protocol, typename SocketAcceptorService>
- static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
-                              ssl::context& context,
-                              bool fUseSSL,
-                              boost::shared_ptr< AcceptedConnection > conn,
-                              const boost::system::error_code& error);
- /**
-  * Sets up I/O resources to accept and handle a new connection.
-  */
- template <typename Protocol, typename SocketAcceptorService>
- static void RPCListen(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
-                    ssl::context& context,
-                    const bool fUseSSL)
- {
-     // Accept connection
-     boost::shared_ptr< AcceptedConnectionImpl<Protocol> > conn(new AcceptedConnectionImpl<Protocol>(acceptor->get_io_service(), context, fUseSSL));
-     acceptor->async_accept(
-             conn->sslStream.lowest_layer(),
-             conn->peer,
-             boost::bind(&RPCAcceptHandler<Protocol, SocketAcceptorService>,
-                 acceptor,
-                 boost::ref(context),
-                 fUseSSL,
-                 conn,
-                 _1));
- }
- /**
-  * Accept and handle incoming connection.
-  */
- template <typename Protocol, typename SocketAcceptorService>
- static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
-                              ssl::context& context,
-                              const bool fUseSSL,
-                              boost::shared_ptr< AcceptedConnection > conn,
-                              const boost::system::error_code& error)
- {
-     // Immediately start accepting new connections, except when we're cancelled or our socket is closed.
-     if (error != boost::asio::error::operation_aborted && acceptor->is_open())
-         RPCListen(acceptor, context, fUseSSL);
-     AcceptedConnectionImpl<ip::tcp>* tcp_conn = dynamic_cast< AcceptedConnectionImpl<ip::tcp>* >(conn.get());
-     if (error)
-     {
-         // TODO: Actually handle errors
-         LogPrintf("%s: Error: %s\n", __func__, error.message());
-     }
-     // Restrict callers by IP.  It is important to
-     // do this before starting client thread, to filter out
-     // certain DoS and misbehaving clients.
-     else if (tcp_conn && !ClientAllowed(tcp_conn->peer.address()))
-     {
-         // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
-         if (!fUseSSL)
-             conn->stream() << HTTPError(HTTP_FORBIDDEN, false) << std::flush;
-         conn->close();
-     }
-     else {
-         ServiceConnection(conn.get());
-         conn->close();
-     }
- }
- static ip::tcp::endpoint ParseEndpoint(const std::string &strEndpoint, int defaultPort)
+ bool StartRPC()
  {
- /*<<<<<<< HEAD
-         unsigned char rand_pwd[32];
-         GetRandBytes(rand_pwd, 32);
-         uiInterface.ThreadSafeMessageBox(strprintf(
-             _("To use komodod you must set an rpcpassword in the configuration file:\n"
-               "%s\n"
-               "It is recommended you use the following random password:\n"
-               "rpcuser=zcashrpc\n"
-               "rpcpassword=%s\n"
-               "(you do not need to remember this password)\n"
-               "The username and password MUST NOT be the same.\n"
-               "If the file does not exist, create it with owner-readable-only file permissions.\n"
-               "It is also recommended to set alertnotify so you are notified of problems;\n"
-               "for example: alertnotify=echo %%s | mail -s \"Komodo Alert\" [email protected]\n"),
-                 GetConfigFile().string(),
-                 EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32)),
-                 "", CClientUIInterface::MSG_ERROR | CClientUIInterface::SECURE);
-         StartShutdown();
-         return;
- =======*/
++/*<<<<<<< HEA
 +    std::string addr;
 +    int port = defaultPort;
 +    SplitHostPort(strEndpoint, port, addr);
 +    return ip::tcp::endpoint(boost::asio::ip::address::from_string(addr), port);
 +}
 +
 +void StartRPCThreads()
 +{
 +    rpc_allow_subnets.clear();
 +    rpc_allow_subnets.push_back(CSubNet("127.0.0.0/8")); // always allow IPv4 local subnet
 +    rpc_allow_subnets.push_back(CSubNet("::1")); // always allow IPv6 localhost
 +    if (mapMultiArgs.count("-rpcallowip"))
 +    {
 +        const vector<string>& vAllow = mapMultiArgs["-rpcallowip"];
 +        BOOST_FOREACH(string strAllow, vAllow)
 +        {
 +            CSubNet subnet(strAllow);
 +            if(!subnet.IsValid())
 +            {
 +                uiInterface.ThreadSafeMessageBox(
 +                    strprintf("Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).", strAllow),
 +                    "", CClientUIInterface::MSG_ERROR);
 +                StartShutdown();
 +                return;
 +            }
 +            rpc_allow_subnets.push_back(subnet);
 +        }
 +    }
 +    std::string strAllowed;
 +    BOOST_FOREACH(const CSubNet &subnet, rpc_allow_subnets)
 +        strAllowed += subnet.ToString() + " ";
 +    LogPrint("rpc", "Allowing RPC connections from: %s\n", strAllowed);
 +
 +    if (mapArgs["-rpcpassword"] == "")
 +    {
- //>>>>>>> zcash/master
 +        LogPrintf("No rpcpassword set - using random cookie authentication\n");
 +        if (!GenerateAuthCookie(&strRPCUserColonPass)) {
 +            uiInterface.ThreadSafeMessageBox(
 +                _("Error: A fatal internal error occured, see debug.log for details"), // Same message as AbortNode
 +                "", CClientUIInterface::MSG_ERROR);
 +            StartShutdown();
 +            return;
 +        }
 +    } else {
 +        strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
 +    }
 +
 +    assert(rpc_io_service == NULL);
 +    rpc_io_service = new boost::asio::io_service();
 +    rpc_ssl_context = new ssl::context(*rpc_io_service, ssl::context::sslv23);
 +
 +    const bool fUseSSL = GetBoolArg("-rpcssl", false);
 +
 +    if (fUseSSL)
 +    {
 +        rpc_ssl_context->set_options(ssl::context::no_sslv2 | ssl::context::no_sslv3);
 +
 +        boost::filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert"));
 +        if (!pathCertFile.is_complete()) pathCertFile = boost::filesystem::path(GetDataDir()) / pathCertFile;
 +        if (boost::filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string());
 +        else LogPrintf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string());
 +
 +        boost::filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem"));
 +        if (!pathPKFile.is_complete()) pathPKFile = boost::filesystem::path(GetDataDir()) / pathPKFile;
 +        if (boost::filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem);
 +        else LogPrintf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string());
 +
 +        string strCiphers = GetArg("-rpcsslciphers", "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH");
 +        SSL_CTX_set_cipher_list(rpc_ssl_context->impl(), strCiphers.c_str());
 +    }
 +
 +    std::vector<ip::tcp::endpoint> vEndpoints;
 +    bool bBindAny = false;
 +    int defaultPort = GetArg("-rpcport", BaseParams().RPCPort());
 +    if (!mapArgs.count("-rpcallowip")) // Default to loopback if not allowing external IPs
 +    {
 +        vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::loopback(), defaultPort));
 +        vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::loopback(), defaultPort));
 +        if (mapArgs.count("-rpcbind"))
 +        {
 +            LogPrintf("WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n");
 +        }
 +    } else if (mapArgs.count("-rpcbind")) // Specific bind address
 +    {
 +        BOOST_FOREACH(const std::string &addr, mapMultiArgs["-rpcbind"])
 +        {
 +            try {
 +                vEndpoints.push_back(ParseEndpoint(addr, defaultPort));
 +            }
 +            catch (const boost::system::system_error&)
 +            {
 +                uiInterface.ThreadSafeMessageBox(
 +                    strprintf(_("Could not parse -rpcbind value %s as network address"), addr),
 +                    "", CClientUIInterface::MSG_ERROR);
 +                StartShutdown();
 +                return;
 +            }
 +        }
 +    } else { // No specific bind address specified, bind to any
 +        vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::any(), defaultPort));
 +        vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::any(), defaultPort));
 +        // Prefer making the socket dual IPv6/IPv4 instead of binding
 +        // to both addresses separately.
 +        bBindAny = true;
 +    }
 +
 +    bool fListening = false;
 +    std::string strerr;
 +    std::string straddress;
 +    BOOST_FOREACH(const ip::tcp::endpoint &endpoint, vEndpoints)
 +    {
 +        try {
 +            boost::asio::ip::address bindAddress = endpoint.address();
 +            straddress = bindAddress.to_string();
 +            LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", straddress, endpoint.port(), bBindAny);
 +            boost::system::error_code v6_only_error;
 +            boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service));
 +
 +            acceptor->open(endpoint.protocol());
 +            acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
 +
 +            // Try making the socket dual IPv6/IPv4 when listening on the IPv6 "any" address
 +            acceptor->set_option(boost::asio::ip::v6_only(
 +                !bBindAny || bindAddress != boost::asio::ip::address_v6::any()), v6_only_error);
 +
 +            acceptor->bind(endpoint);
 +            acceptor->listen(socket_base::max_connections);
 +
 +            RPCListen(acceptor, *rpc_ssl_context, fUseSSL);
 +
 +            fListening = true;
 +            rpc_acceptors.push_back(acceptor);
 +            // If dual IPv6/IPv4 bind successful, skip binding to IPv4 separately
 +            if(bBindAny && bindAddress == boost::asio::ip::address_v6::any() && !v6_only_error)
 +                break;
 +        }
 +        catch (const boost::system::system_error& e)
 +        {
 +            LogPrintf("ERROR: Binding RPC on address %s port %i failed: %s\n", straddress, endpoint.port(), e.what());
 +            strerr = strprintf(_("An error occurred while setting up the RPC address %s port %u for listening: %s"), straddress, endpoint.port(), e.what());
 +        }
 +    }
 +
 +    if (!fListening) {
 +        uiInterface.ThreadSafeMessageBox(strerr, "", CClientUIInterface::MSG_ERROR);
 +        StartShutdown();
 +        return;
 +    }
 +
 +    rpc_worker_group = new boost::thread_group();
 +    for (int i = 0; i < GetArg("-rpcthreads", 4); i++)
 +        rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service));
++=======
+     LogPrint("rpc", "Starting RPC\n");
++>>>>>>> zcash/master*/
      fRPCRunning = true;
      g_rpcSignals.Started();
  
@@@ -957,132 -541,24 +707,130 @@@ static UniValue JSONRPCExecOne(const Un
      return rpc_result;
  }
  
- static string JSONRPCExecBatch(const Array& vReq)
+ std::string JSONRPCExecBatch(const UniValue& vReq)
  {
-     Array ret;
-     for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++)
+     UniValue ret(UniValue::VARR);
+     for (size_t reqIdx = 0; reqIdx < vReq.size(); reqIdx++)
          ret.push_back(JSONRPCExecOne(vReq[reqIdx]));
  
-     return write_string(Value(ret), false) + "\n";
+     return ret.write() + "\n";
  }
  
- static bool HTTPReq_JSONRPC(AcceptedConnection *conn,
-                             string& strRequest,
-                             map<string, string>& mapHeaders,
-                             bool fRun)
+ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue &params) const
  {
-     // Check authorization
-     if (mapHeaders.count("authorization") == 0)
+     // Return immediately if in warmup
      {
-         conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush;
-         return false;
+         LOCK(cs_rpcWarmup);
+         if (fRPCInWarmup)
+             throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
      }
  
-         /* Deter brute-forcing
-            We don't support exposing the RPC port, so this shouldn't result
-            in a DoS. */
++/*<<<<<<< HEA
 +    if (!HTTPAuthorized(mapHeaders))
 +    {
 +        LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string());
-         /*
++        //Deter brute-forcing  We don't support exposing the RPC port, so this shouldn't result in a DoS.
 +        MilliSleep(250);
 +
 +        conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush;
 +        return false;
 +    }
 +    JSONRequest jreq;
 +    try
 +    {
 +        // Parse request
 +        Value valRequest;
 +        if (!read_string(strRequest, valRequest))
 +        {
 +            fprintf(stderr,"CANTPARSE.(%s)\n",strRequest.c_str());
 +            throw JSONRPCError(RPC_PARSE_ERROR, "Parse error");
 +        }
 +        // Return immediately if in warmup
 +        {
 +            LOCK(cs_rpcWarmup);
 +            if (fRPCInWarmup)
 +                throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
 +        }
 +
 +        string strReply;
 +
 +        // singleton request
 +        if (valRequest.type() == obj_type) {
 +            jreq.parse(valRequest);
 +
 +            Value result = tableRPC.execute(jreq.strMethod, jreq.params);
 +
 +            // Send reply
 +            strReply = JSONRPCReply(result, Value::null, jreq.id);
 +
 +        // array of requests
 +        } else if (valRequest.type() == array_type)
 +            strReply = JSONRPCExecBatch(valRequest.get_array());
 +        else
 +            throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error");
 +
 +        conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, strReply.size()) << strReply << std::flush;
 +    }
 +    catch (const Object& objError)
 +    {
 +        ErrorReply(conn->stream(), objError, jreq.id);
 +        return false;
 +    }
 +    catch (const std::exception& e)
 +    {
 +        ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
 +        return false;
 +    }
 +    return true;
 +}
 +
 +void ServiceConnection(AcceptedConnection *conn)
 +{
 +    bool fRun = true;
 +    while (fRun && !ShutdownRequested())
 +    {
 +        int nProto = 0;
 +        map<string, string> mapHeaders;
 +        string strRequest, strMethod, strURI;
 +
 +        // Read HTTP request line
 +        if (!ReadHTTPRequestLine(conn->stream(), nProto, strMethod, strURI))
 +            break;
 +
 +        // Read HTTP message headers and body
 +        ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto, MAX_SIZE);
 +
 +        // TODO #1856: Re-enable support for persistent connections.
 +        // We have disabled support for HTTP Keep-Alive until resolution of #1680, upstream rpc deadlock.
 +        // Close connection immediately.
 +        fRun = false;
-         if ((mapHeaders["connection"] == "close") || (!GetBoolArg("-rpckeepalive", true)))
-             fRun = false;
-         */
++ 
 +        // HTTP Keep-Alive is false; close connection immediately
++        //if ((mapHeaders["connection"] == "close") || (!GetBoolArg("-rpckeepalive", true)))
++        //    fRun = false;
++ 
 +
 +        // Process via JSON-RPC API
 +        if (strURI == "/") {
 +            if (!HTTPReq_JSONRPC(conn, strRequest, mapHeaders, fRun))
 +                break;
 +
 +        // Process via HTTP REST API
 +        } else if (strURI.substr(0, 6) == "/rest/" && GetBoolArg("-rest", false)) {
 +            if (!HTTPReq_REST(conn, strURI, strRequest, mapHeaders, fRun))
 +                break;
 +
 +        } else {
 +            conn->stream() << HTTPError(HTTP_NOT_FOUND, false) << std::flush;
 +            break;
 +        }
 +    }
 +}
 +
 +json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array &params) const
 +{
++=======
++>>>>>>> zcash/master*/
      // Find method
      const CRPCCommand *pcmd = tableRPC[strMethod];
      if (!pcmd)
diff --cc src/rpcserver.h
index 9a5c02dca5c49c5779f7521322a01d0cdf09b8bb,1124801c2e7adbfa0d151e0b55fa280563366c79..c94450609d8c03fdbdbd6c67bf1035755e1a1c0f
@@@ -153,135 -172,129 +172,139 @@@ extern std::string HelpExampleRpc(cons
  
  extern void EnsureWalletIsUnlocked();
  
- extern json_spirit::Value getconnectioncount(const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp
- extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value ping(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value addnode(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getaddednodeinfo(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getnettotals(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value dumpprivkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
- extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value importaddress(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value dumpwallet(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value importwallet(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp
- extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value generate(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getlocalsolps(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getnetworksolps(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value prioritisetransaction(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value estimatefee(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value estimatepriority(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
- extern json_spirit::Value getaccountaddress(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getrawchangeaddress(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value setaccount(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getaccount(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getaddressesbyaccount(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value sendtoaddress(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value signmessage(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value verifymessage(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getreceivedbyaddress(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getreceivedbyaccount(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getbalance(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getunconfirmedbalance(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value movecmd(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value sendfrom(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value sendmany(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value addmultisigaddress(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value createmultisig(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value listreceivedbyaddress(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value listreceivedbyaccount(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value listtransactions(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value listaddressgroupings(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value listaccounts(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value listsinceblock(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value gettransaction(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value backupwallet(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value keypoolrefill(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value walletpassphrase(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value walletpassphrasechange(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value walletlock(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value encryptwallet(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value validateaddress(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getinfo(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getwalletinfo(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getblockchaininfo(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getnetworkinfo(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value setmocktime(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value resendwallettransactions(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value zc_benchmark(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value zc_raw_keygen(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value zc_raw_joinsplit(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value zc_raw_receive(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value zc_sample_joinsplit(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp
- extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value lockunspent(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value listlockunspent(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value createrawtransaction(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value decoderawtransaction(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value decodescript(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value signrawtransaction(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value sendrawtransaction(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value gettxoutproof(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value verifytxoutproof(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getblockcount(const json_spirit::Array& params, bool fHelp); // in rpcblockchain.cpp
- extern json_spirit::Value getbestblockhash(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getdifficulty(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value settxfee(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getmempoolinfo(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getrawmempool(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value gettxoutsetinfo(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value gettxout(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value notaries(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value minerids(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value kvsearch(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value kvupdate(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value paxprice(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value paxpending(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value paxprices(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value paxdeposit(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value paxwithdraw(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHelp);
- //extern json_spirit::Value getchaintips(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value invalidateblock(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value reconsiderblock(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value getblocksubsidy(const json_spirit::Array& params, bool fHelp);
- extern json_spirit::Value z_exportkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
- extern json_spirit::Value z_importkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
- extern json_spirit::Value z_getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
- extern json_spirit::Value z_listaddresses(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
- extern json_spirit::Value z_exportwallet(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
- extern json_spirit::Value z_importwallet(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
- extern json_spirit::Value z_listreceivedbyaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
- extern json_spirit::Value z_getbalance(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
- extern json_spirit::Value z_gettotalbalance(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
- extern json_spirit::Value z_sendmany(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
- extern json_spirit::Value z_getoperationstatus(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
- extern json_spirit::Value z_getoperationresult(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
- extern json_spirit::Value z_listoperationids(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
- extern json_spirit::Value z_validateaddress(const json_spirit::Array& params, bool fHelp); // in rpcmisc.cpp
- // in rest.cpp
- extern bool HTTPReq_REST(AcceptedConnection *conn,
-                   const std::string& strURI,
-                   const std::string& strRequest,
-                   const std::map<std::string, std::string>& mapHeaders,
-                   bool fRun);
+ extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpcnet.cpp
+ extern UniValue getpeerinfo(const UniValue& params, bool fHelp);
+ extern UniValue ping(const UniValue& params, bool fHelp);
+ extern UniValue addnode(const UniValue& params, bool fHelp);
+ extern UniValue disconnectnode(const UniValue& params, bool fHelp);
+ extern UniValue getaddednodeinfo(const UniValue& params, bool fHelp);
+ extern UniValue getnettotals(const UniValue& params, bool fHelp);
+ extern UniValue setban(const UniValue& params, bool fHelp);
+ extern UniValue listbanned(const UniValue& params, bool fHelp);
+ extern UniValue clearbanned(const UniValue& params, bool fHelp);
+ extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp
+ extern UniValue importprivkey(const UniValue& params, bool fHelp);
+ extern UniValue importaddress(const UniValue& params, bool fHelp);
+ extern UniValue dumpwallet(const UniValue& params, bool fHelp);
+ extern UniValue importwallet(const UniValue& params, bool fHelp);
+ extern UniValue getgenerate(const UniValue& params, bool fHelp); // in rpcmining.cpp
+ extern UniValue setgenerate(const UniValue& params, bool fHelp);
+ extern UniValue generate(const UniValue& params, bool fHelp);
+ extern UniValue getlocalsolps(const UniValue& params, bool fHelp);
+ extern UniValue getnetworksolps(const UniValue& params, bool fHelp);
+ extern UniValue getnetworkhashps(const UniValue& params, bool fHelp);
+ extern UniValue getmininginfo(const UniValue& params, bool fHelp);
+ extern UniValue prioritisetransaction(const UniValue& params, bool fHelp);
+ extern UniValue getblocktemplate(const UniValue& params, bool fHelp);
+ extern UniValue submitblock(const UniValue& params, bool fHelp);
+ extern UniValue estimatefee(const UniValue& params, bool fHelp);
+ extern UniValue estimatepriority(const UniValue& params, bool fHelp);
+ extern UniValue getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp
+ extern UniValue getaccountaddress(const UniValue& params, bool fHelp);
+ extern UniValue getrawchangeaddress(const UniValue& params, bool fHelp);
+ extern UniValue setaccount(const UniValue& params, bool fHelp);
+ extern UniValue getaccount(const UniValue& params, bool fHelp);
+ extern UniValue getaddressesbyaccount(const UniValue& params, bool fHelp);
+ extern UniValue sendtoaddress(const UniValue& params, bool fHelp);
+ extern UniValue signmessage(const UniValue& params, bool fHelp);
+ extern UniValue verifymessage(const UniValue& params, bool fHelp);
+ extern UniValue getreceivedbyaddress(const UniValue& params, bool fHelp);
+ extern UniValue getreceivedbyaccount(const UniValue& params, bool fHelp);
+ extern UniValue getbalance(const UniValue& params, bool fHelp);
+ extern UniValue getunconfirmedbalance(const UniValue& params, bool fHelp);
+ extern UniValue movecmd(const UniValue& params, bool fHelp);
+ extern UniValue sendfrom(const UniValue& params, bool fHelp);
+ extern UniValue sendmany(const UniValue& params, bool fHelp);
+ extern UniValue addmultisigaddress(const UniValue& params, bool fHelp);
+ extern UniValue createmultisig(const UniValue& params, bool fHelp);
+ extern UniValue listreceivedbyaddress(const UniValue& params, bool fHelp);
+ extern UniValue listreceivedbyaccount(const UniValue& params, bool fHelp);
+ extern UniValue listtransactions(const UniValue& params, bool fHelp);
+ extern UniValue listaddressgroupings(const UniValue& params, bool fHelp);
+ extern UniValue listaccounts(const UniValue& params, bool fHelp);
+ extern UniValue listsinceblock(const UniValue& params, bool fHelp);
+ extern UniValue gettransaction(const UniValue& params, bool fHelp);
+ extern UniValue backupwallet(const UniValue& params, bool fHelp);
+ extern UniValue keypoolrefill(const UniValue& params, bool fHelp);
+ extern UniValue walletpassphrase(const UniValue& params, bool fHelp);
+ extern UniValue walletpassphrasechange(const UniValue& params, bool fHelp);
+ extern UniValue walletlock(const UniValue& params, bool fHelp);
+ extern UniValue encryptwallet(const UniValue& params, bool fHelp);
+ extern UniValue validateaddress(const UniValue& params, bool fHelp);
+ extern UniValue getinfo(const UniValue& params, bool fHelp);
+ extern UniValue getwalletinfo(const UniValue& params, bool fHelp);
+ extern UniValue getblockchaininfo(const UniValue& params, bool fHelp);
+ extern UniValue getnetworkinfo(const UniValue& params, bool fHelp);
+ extern UniValue setmocktime(const UniValue& params, bool fHelp);
+ extern UniValue resendwallettransactions(const UniValue& params, bool fHelp);
+ extern UniValue zc_benchmark(const UniValue& params, bool fHelp);
+ extern UniValue zc_raw_keygen(const UniValue& params, bool fHelp);
+ extern UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp);
+ extern UniValue zc_raw_receive(const UniValue& params, bool fHelp);
+ extern UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp);
+ extern UniValue getrawtransaction(const UniValue& params, bool fHelp); // in rcprawtransaction.cpp
+ extern UniValue listunspent(const UniValue& params, bool fHelp);
+ extern UniValue lockunspent(const UniValue& params, bool fHelp);
+ extern UniValue listlockunspent(const UniValue& params, bool fHelp);
+ extern UniValue createrawtransaction(const UniValue& params, bool fHelp);
+ extern UniValue decoderawtransaction(const UniValue& params, bool fHelp);
+ extern UniValue decodescript(const UniValue& params, bool fHelp);
+ extern UniValue fundrawtransaction(const UniValue& params, bool fHelp);
+ extern UniValue signrawtransaction(const UniValue& params, bool fHelp);
+ extern UniValue sendrawtransaction(const UniValue& params, bool fHelp);
+ extern UniValue gettxoutproof(const UniValue& params, bool fHelp);
+ extern UniValue verifytxoutproof(const UniValue& params, bool fHelp);
+ extern UniValue getblockcount(const UniValue& params, bool fHelp); // in rpcblockchain.cpp
+ extern UniValue getbestblockhash(const UniValue& params, bool fHelp);
+ extern UniValue getdifficulty(const UniValue& params, bool fHelp);
+ extern UniValue settxfee(const UniValue& params, bool fHelp);
+ extern UniValue getmempoolinfo(const UniValue& params, bool fHelp);
+ extern UniValue getrawmempool(const UniValue& params, bool fHelp);
+ extern UniValue getblockhash(const UniValue& params, bool fHelp);
+ extern UniValue getblockheader(const UniValue& params, bool fHelp);
+ extern UniValue getblock(const UniValue& params, bool fHelp);
+ extern UniValue gettxoutsetinfo(const UniValue& params, bool fHelp);
+ extern UniValue gettxout(const UniValue& params, bool fHelp);
+ extern UniValue verifychain(const UniValue& params, bool fHelp);
+ extern UniValue getchaintips(const UniValue& params, bool fHelp);
+ extern UniValue invalidateblock(const UniValue& params, bool fHelp);
+ extern UniValue reconsiderblock(const UniValue& params, bool fHelp);
+ extern UniValue getblocksubsidy(const UniValue& params, bool fHelp);
+ extern UniValue z_exportkey(const UniValue& params, bool fHelp); // in rpcdump.cpp
+ extern UniValue z_importkey(const UniValue& params, bool fHelp); // in rpcdump.cpp
+ extern UniValue z_getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp
+ extern UniValue z_listaddresses(const UniValue& params, bool fHelp); // in rpcwallet.cpp
+ extern UniValue z_exportwallet(const UniValue& params, bool fHelp); // in rpcdump.cpp
+ extern UniValue z_importwallet(const UniValue& params, bool fHelp); // in rpcdump.cpp
+ extern UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp
+ extern UniValue z_getbalance(const UniValue& params, bool fHelp); // in rpcwallet.cpp
+ extern UniValue z_gettotalbalance(const UniValue& params, bool fHelp); // in rpcwallet.cpp
+ extern UniValue z_sendmany(const UniValue& params, bool fHelp); // in rpcwallet.cpp
+ extern UniValue z_getoperationstatus(const UniValue& params, bool fHelp); // in rpcwallet.cpp
+ extern UniValue z_getoperationresult(const UniValue& params, bool fHelp); // in rpcwallet.cpp
+ extern UniValue z_listoperationids(const UniValue& params, bool fHelp); // in rpcwallet.cpp
+ extern UniValue z_validateaddress(const UniValue& params, bool fHelp); // in rpcmisc.cpp
++extern json_spirit::Value notaries(const UniValue& params, bool fHelp);
++extern json_spirit::Value minerids(const UniValue& params, bool fHelp);
++extern json_spirit::Value kvsearch(const UniValue& params, bool fHelp);
++extern json_spirit::Value kvupdate(const UniValue& params, bool fHelp);
++extern json_spirit::Value paxprice(const UniValue& params, bool fHelp);
++extern json_spirit::Value paxpending(const UniValue& params, bool fHelp);
++extern json_spirit::Value paxprices(const UniValue& params, bool fHelp);
++extern json_spirit::Value paxdeposit(const UniValue& params, bool fHelp);
++extern json_spirit::Value paxwithdraw(const UniValue& params, bool fHelp);
++
+ bool StartRPC();
+ void InterruptRPC();
+ void StopRPC();
+ std::string JSONRPCExecBatch(const UniValue& vReq);
  
  #endif // BITCOIN_RPCSERVER_H
Simple merge
Simple merge
index e0b5bde76c187399544c11b87ca48efe9dae684e,0236610e1ad17a932cee943e70f304e133953ba8..5971b7af8618524983c1faf85fad3e102cac79f7
@@@ -500,13 -500,6 +500,13 @@@ class FormatAr
          void format(std::ostream& out, const char* fmtBegin,
                      const char* fmtEnd, int ntrunc) const
          {
- /*<<<<<<< HEAD
++/*
 +            // It would be nice if we could do this from the destructor, but we
 +            // can't if TINYFORMAT_ERROR is used to throw an exception!
 +            m_fmt = printFormatStringLiteral(m_out, m_fmt);
 +            if(*m_fmt != '\0')
 +                TINYFORMAT_ERROR("tinyformat: Too many conversion specifiers in format string");
 +=======*/
              m_formatImpl(out, fmtBegin, fmtEnd, ntrunc, m_value);
          }
  
diff --cc src/txdb.cpp
Simple merge
Simple merge
diff --cc src/util.cpp
index 553aa32139efba60b78f9d573ef229413e9df8f9,420ce043c057317f6af51fb0b06aa9060a39d499..4c901d5862dfe3194da8515e3eb3863ecc79f3c0
@@@ -859,12 -888,19 +911,20 @@@ void SetThreadPriority(int nPriority
  #endif // WIN32
  }
  
+ std::string PrivacyInfo()
+ {
+     return "\n" +
+            FormatParagraph(strprintf(_("In order to ensure you are adequately protecting your privacy when using Zcash, please see <%s>."),
+                                      "https://z.cash/support/security/index.html")) + "\n";
+ }
  std::string LicenseInfo()
  {
-     return FormatParagraph(strprintf(_("Copyright (C) 2009-%i The Bitcoin Core Developers"), COPYRIGHT_YEAR)) + "\n" +
+     return "\n" +
+            FormatParagraph(strprintf(_("Copyright (C) 2009-%i The Bitcoin Core Developers"), COPYRIGHT_YEAR)) + "\n" +
             FormatParagraph(strprintf(_("Copyright (C) 2015-%i The Zcash Developers"), COPYRIGHT_YEAR)) + "\n" +
 -           "\n" +
 +        FormatParagraph(strprintf(_("Copyright (C) 2015-%i jl777 and SuperNET developers"), COPYRIGHT_YEAR)) + "\n" +
 +        "\n" +
             FormatParagraph(_("This is experimental software.")) + "\n" +
             "\n" +
             FormatParagraph(_("Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.")) + "\n" +
diff --cc src/util.h
Simple merge
index 704a448011c18e55e4390a1def0d6845aa90668c,1691452b892299b360b00d1378edfa6b8b2c6df2..18e25bc9759bcac0151488f53b0b9c23a8a82e1b
  #include "rpcprotocol.h"
  #include "zcash/IncrementalMerkleTree.hpp"
  #include "sodium.h"
+ #include "miner.h"
  
 +#include <stdint.h>
 +
  #include <iostream>
  #include <chrono>
  #include <thread>
Simple merge
index 819b5a8eccfa15f5e5132e1cb7ea42e1fe79b207,efa1a18a3e53b8fe24db6de300bd275136675587..0c3edfb2c6401316968a68427c08512ac2acd9ac
@@@ -74,12 -72,8 +72,12 @@@ void EnsureWalletIsUnlocked(
          throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
  }
  
- void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
 +uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue);
 +uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime);
 +
+ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
  {
 +    //int32_t i,n,txheight; uint32_t locktime; uint64_t interest = 0;
      int confirms = wtx.GetDepthInMainChain();
      entry.push_back(Pair("confirmations", confirms));
      if (wtx.IsCoinBase())
@@@ -1139,8 -905,10 +1136,10 @@@ UniValue sendfrom(const UniValue& param
      string strAccount = AccountFromValue(params[0]);
      CBitcoinAddress address(params[1].get_str());
      if (!address.IsValid())
 -        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
 +        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Komodo address");
      CAmount nAmount = AmountFromValue(params[2]);
+     if (nAmount <= 0)
+         throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
      int nMinDepth = 1;
      if (params.size() > 3)
          nMinDepth = params[3].get_int();
@@@ -1227,14 -995,15 +1226,15 @@@ UniValue sendmany(const UniValue& param
      vector<CRecipient> vecSend;
  
      CAmount totalAmount = 0;
-     BOOST_FOREACH(const Pair& s, sendTo)
+     vector<string> keys = sendTo.getKeys();
+     BOOST_FOREACH(const string& name_, keys)
      {
-         CBitcoinAddress address(s.name_);
+         CBitcoinAddress address(name_);
          if (!address.IsValid())
-             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Komodo address: ")+s.name_);
 -            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Zcash address: ")+name_);
++            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Komodo address: ")+name_);
  
          if (setAddress.count(address))
-             throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
+             throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_);
          setAddress.insert(address);
  
          CScript scriptPubKey = GetScriptForDestination(address.Get());
@@@ -2298,13 -2078,13 +2309,13 @@@ UniValue encryptwallet(const UniValue& 
      // slack space in .dat files; that is bad if the old data is
      // unencrypted private keys. So:
      StartShutdown();
 -    return "wallet encrypted; Zcash server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup.";
 +    return "wallet encrypted; Komodo server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup.";
  }
  
Value lockunspent(const Array& params, bool fHelp)
UniValue lockunspent(const UniValue& params, bool fHelp)
  {
      if (!EnsureWalletIsAvailable(fHelp))
-         return Value::null;
+         return NullUniValue;
      
      if (fHelp || params.size() < 1 || params.size() > 2)
          throw runtime_error(
@@@ -2528,12 -2308,10 +2539,12 @@@ UniValue resendwallettransactions(cons
      return result;
  }
  
- Value listunspent(const Array& params, bool fHelp)
 +uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime);
 +
+ UniValue listunspent(const UniValue& params, bool fHelp)
  {
      if (!EnsureWalletIsAvailable(fHelp))
-         return Value::null;
+         return NullUniValue;
      
      if (fHelp || params.size() > 3)
          throw runtime_error(
  
      set<CBitcoinAddress> setAddress;
      if (params.size() > 2) {
-         Array inputs = params[2].get_array();
-         BOOST_FOREACH(Value& input, inputs) {
+         UniValue inputs = params[2].get_array();
+         for (size_t idx = 0; idx < inputs.size(); idx++) {
+             const UniValue& input = inputs[idx];
              CBitcoinAddress address(input.get_str());
              if (!address.IsValid())
 -                throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Zcash address: ")+input.get_str());
 +                throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Komodo address: ")+input.get_str());
              if (setAddress.count(address))
                  throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str());
             setAddress.insert(address);
      return results;
  }
  
- Value zc_sample_joinsplit(const json_spirit::Array& params, bool fHelp)
 +uint64_t komodo_interestsum()
 +{
 +    uint64_t interest,sum = 0;
 +    vector<COutput> vecOutputs;
 +    assert(pwalletMain != NULL);
 +    LOCK2(cs_main, pwalletMain->cs_wallet);
 +    pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
 +    BOOST_FOREACH(const COutput& out,vecOutputs)
 +    {
 +        CAmount nValue = out.tx->vout[out.i].nValue;
 +        if ( out.tx->nLockTime != 0 && out.fSpendable != 0 )
 +        {
 +            BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
 +            CBlockIndex *tipindex,*pindex = it->second;
 +            if ( pindex != 0 && (tipindex= chainActive.Tip()) != 0 )
 +            {
 +                interest = komodo_interest(pindex->nHeight,nValue,out.tx->nLockTime,tipindex->nTime);
 +                sum += interest;
 +            }
 +        }
 +    }
 +    return(sum);
 +}
 +
+ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
+ {
+     if (!EnsureWalletIsAvailable(fHelp))
+         return NullUniValue;
+     if (fHelp || params.size() != 1)
+         throw runtime_error(
+                             "fundrawtransaction \"hexstring\"\n"
+                             "\nAdd inputs to a transaction until it has enough in value to meet its out value.\n"
+                             "This will not modify existing inputs, and will add one change output to the outputs.\n"
+                             "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n"
+                             "The inputs added will not be signed, use signrawtransaction for that.\n"
+                             "\nArguments:\n"
+                             "1. \"hexstring\"    (string, required) The hex string of the raw transaction\n"
+                             "\nResult:\n"
+                             "{\n"
+                             "  \"hex\":       \"value\", (string)  The resulting raw transaction (hex-encoded string)\n"
+                             "  \"fee\":       n,         (numeric) The fee added to the transaction\n"
+                             "  \"changepos\": n          (numeric) The position of the added change output, or -1\n"
+                             "}\n"
+                             "\"hex\"             \n"
+                             "\nExamples:\n"
+                             "\nCreate a transaction with no inputs\n"
+                             + HelpExampleCli("createrawtransaction", "\"[]\" \"{\\\"myaddress\\\":0.01}\"") +
+                             "\nAdd sufficient unsigned inputs to meet the output value\n"
+                             + HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") +
+                             "\nSign the transaction\n"
+                             + HelpExampleCli("signrawtransaction", "\"fundedtransactionhex\"") +
+                             "\nSend the transaction\n"
+                             + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"")
+                             );
+     RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR));
+     // parse hex string from parameter
+     CTransaction origTx;
+     if (!DecodeHexTx(origTx, params[0].get_str()))
+         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
+     CMutableTransaction tx(origTx);
+     CAmount nFee;
+     string strFailReason;
+     int nChangePos = -1;
+     if(!pwalletMain->FundTransaction(tx, nFee, nChangePos, strFailReason))
+         throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason);
+     UniValue result(UniValue::VOBJ);
+     result.push_back(Pair("hex", EncodeHexTx(tx)));
+     result.push_back(Pair("changepos", nChangePos));
+     result.push_back(Pair("fee", ValueFromAmount(nFee)));
+     return result;
+ }
+ UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp)
  {
      if (fHelp) {
          throw runtime_error(
@@@ -3388,13 -3184,11 +3454,13 @@@ UniValue z_gettotalbalance(const UniVal
      // so we use our own method to get balance of utxos.
      CAmount nBalance = getBalanceTaddr("", nMinDepth);
      CAmount nPrivateBalance = getBalanceZaddr("", nMinDepth);
 -    CAmount nTotalBalance = nBalance + nPrivateBalance;
 +    uint64_t interest = komodo_interestsum();
 +    CAmount nTotalBalance = nBalance + nPrivateBalance + interest;
-     Object result;
-     result.push_back(Pair("transparent", FormatMoney(nBalance, false)));
-     result.push_back(Pair("interest", FormatMoney(interest, false)));
-     result.push_back(Pair("private", FormatMoney(nPrivateBalance, false)));
-     result.push_back(Pair("total", FormatMoney(nTotalBalance, false)));
+     UniValue result(UniValue::VOBJ);
+     result.push_back(Pair("transparent", FormatMoney(nBalance)));
++    result.push_back(Pair("interest", FormatMoney(interest)));
+     result.push_back(Pair("private", FormatMoney(nPrivateBalance)));
+     result.push_back(Pair("total", FormatMoney(nTotalBalance)));
      return result;
  }
  
index 7fbdb237f995453b2b7efcd6ac21896296ddd733,98deedf64cac46e2db0f5ccec10d44cb3a4a3cb3..5f78be478d469f12437decf6fcf82fa7250401f9
@@@ -2460,15 -2373,9 +2453,15 @@@ bool CWallet::SelectCoinsMinConf(const 
      return true;
  }
  
 -bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet,  bool& fOnlyCoinbaseCoinsRet, bool& fNeedCoinbaseCoinsRet, const CCoinControl* coinControl) const
 +bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet,  bool& fOnlyCoinbaseCoinsRet, bool& fNeedCoinbaseCoinsRet, const CCoinControl* coinControl,uint64_t *interestp) const
  {
      // Output parameter fOnlyCoinbaseCoinsRet is set to true when the only available coins are coinbase utxos.
-     uint64_t tmp,interest = 0;
++    uint64_t tmp,interest = 0; int32_t retval;
 +    if ( interestp == 0 )
 +    {
 +        interestp = &tmp;
 +        *interestp = 0;
 +    }
      vector<COutput> vCoinsNoCoinbase, vCoinsWithCoinbase;
      AvailableCoins(vCoinsNoCoinbase, true, coinControl, false, false);
      AvailableCoins(vCoinsWithCoinbase, true, coinControl, false, true);
              fNeedCoinbaseCoinsRet = (valueWithCoinbase >= nTargetValue);
          }
      }
-     // coin control -> return all selected outputs (we want all to go into the transaction for sure)
-     if (coinControl && coinControl->HasSelected())
 -
+     // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
+     if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs)
      {
          BOOST_FOREACH(const COutput& out, vCoins)
          {
-             if(!out.fSpendable)
-                 continue;
+             if (!out.fSpendable)
+                  continue;
              nValueRet += out.tx->vout[out.i].nValue;
 +            if ( KOMODO_EXCHANGEWALLET == 0 )
 +                *interestp += out.tx->vout[out.i].interest;
              setCoinsRet.insert(make_pair(out.tx, out.i));
          }
          return (nValueRet >= nTargetValue);
      }
- //fprintf(stderr,"nValueRet %8f vs target %.8f\n",(double)nValueRet/COIN,(double)nTargetValue/COIN);
-     if ( SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet,&interest) != 0 )
 -
+     // calculate value from preset inputs and store them
+     set<pair<const CWalletTx*, uint32_t> > setPresetCoins;
+     CAmount nValueFromPresetInputs = 0;
+     std::vector<COutPoint> vPresetInputs;
+     if (coinControl)
+         coinControl->ListSelected(vPresetInputs);
+     BOOST_FOREACH(const COutPoint& outpoint, vPresetInputs)
+     {
+         map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
+         if (it != mapWallet.end())
+         {
+             const CWalletTx* pcoin = &it->second;
+             // Clearly invalid input, fail
+             if (pcoin->vout.size() <= outpoint.n)
+                 return false;
+             nValueFromPresetInputs += pcoin->vout[outpoint.n].nValue;
++            if ( KOMODO_EXCHANGEWALLET == 0 )
++                nValueFromPresetInputs += pcoin->vout[outpoint.n].interest;
+             setPresetCoins.insert(make_pair(pcoin, outpoint.n));
+         } else
+             return false; // TODO: Allow non-wallet inputs
+     }
+     // remove preset inputs from vCoins
+     for (vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coinControl && coinControl->HasSelected();)
+     {
+         if (setPresetCoins.count(make_pair(it->tx, it->i)))
+             it = vCoins.erase(it);
+         else
+             ++it;
+     }
++    retval = false;
++    if ( nTargetValue <= nValueFromPresetInputs )
++        retval = true;
++    else if ( SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet,&interest) != 0 )
 +    {
 +        *interestp += interest;
-         return(true);
++        retval = true;
 +    }
 +    else if ( SelectCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet,&interest) != 0 )
 +    {
 +        *interestp += interest;
-         return(true);
++        retval = true;
 +    }
 +    else if ( bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet,&interest) != 0 )
 +    {
 +        *interestp += interest;
-         return(true);
++        retval = true;
 +    }
-     return(false);
 -    bool res = nTargetValue <= nValueFromPresetInputs ||
 +    //return (SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet,interestp) ||
 +    //        SelectCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet,interestp) ||
 +    //        (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet,interestp)));
++    /*bool res = nTargetValue <= nValueFromPresetInputs ||
+         SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 6, vCoins, setCoinsRet, nValueRet) ||
+         SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 1, vCoins, setCoinsRet, nValueRet) ||
 -        (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, vCoins, setCoinsRet, nValueRet));
++        (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, vCoins, setCoinsRet, nValueRet));*/
+     // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
+     setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end());
+     // add preset inputs to the total value selected
+     nValueRet += nValueFromPresetInputs;
 -    return res;
++    return retval;
  }
  
- bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend,
-                                 CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl)
+ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosRet, std::string& strFailReason)
+ {
+     vector<CRecipient> vecSend;
+     // Turn the txout set into a CRecipient vector
+     BOOST_FOREACH(const CTxOut& txOut, tx.vout)
+     {
+         CRecipient recipient = {txOut.scriptPubKey, txOut.nValue, false};
+         vecSend.push_back(recipient);
+     }
+     CCoinControl coinControl;
+     coinControl.fAllowOtherInputs = true;
+     BOOST_FOREACH(const CTxIn& txin, tx.vin)
+         coinControl.Select(txin.prevout);
+     CReserveKey reservekey(this);
+     CWalletTx wtx;
+     if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosRet, strFailReason, &coinControl, false))
+         return false;
+     if (nChangePosRet != -1)
+         tx.vout.insert(tx.vout.begin() + nChangePosRet, wtx.vout[nChangePosRet]);
+     // Add new txins (keeping original txin scriptSig/order)
+     BOOST_FOREACH(const CTxIn& txin, wtx.vin)
+     {
+         bool found = false;
+         BOOST_FOREACH(const CTxIn& origTxIn, tx.vin)
+         {
+             if (txin.prevout.hash == origTxIn.prevout.hash && txin.prevout.n == origTxIn.prevout.n)
+             {
+                 found = true;
+                 break;
+             }
+         }
+         if (!found)
+             tx.vin.push_back(txin);
+     }
+     return true;
+ }
+ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet,
+                                 int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign)
  {
 -    CAmount nValue = 0;
 -    unsigned int nSubtractFeeFromAmount = 0;
 +    uint64_t interest2,interest = 0; CAmount nValue = 0; unsigned int nSubtractFeeFromAmount = 0;
      BOOST_FOREACH (const CRecipient& recipient, vecSend)
      {
          if (nValue < 0 || recipient.nAmount < 0)
Simple merge
This page took 0.20305 seconds and 4 git commands to generate.