diff --git a/.travis.yml b/.travis.yml index 63004c490129..78d3a83251d7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,9 @@ # replacing the "compilers" with a build name prefixed by the no-op ":" # command. See: https://github.com/travis-ci/casher/issues/6 +sudo: false +dist: precise + os: linux language: cpp compiler: gcc @@ -15,39 +18,76 @@ env: - CCACHE_TEMPDIR=/tmp/.ccache-temp - CCACHE_COMPRESS=1 - BASE_OUTDIR=$TRAVIS_BUILD_DIR/out - - SDK_URL=https://bitcoincore.org/depends-sources/sdks + - SDK_URL=https://dash.org/depends-sources/sdks cache: apt: true + ccache: true directories: - - depends/built - - depends/sdk-sources - - $HOME/.ccache + - depends/built + - depends/sdk-sources matrix: fast_finish: true include: - compiler: ": ARM" - env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" + env: HOST=arm-linux-gnueabihf DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" + addons: + apt: + packages: + - g++-arm-linux-gnueabihf - compiler: ": dashd" - env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat CPPFLAGS=-DDEBUG_LOCKORDER" - - compiler: ": No wallet" - env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" + env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat CPPFLAGS=-DDEBUG_LOCKORDER" + addons: + apt: + packages: + - bc - compiler: ": 32-bit + dash" - env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" USE_SHELL="/bin/dash" + env: HOST=i686-pc-linux-gnu RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" USE_SHELL="/bin/dash" + addons: + apt: + packages: + - g++-multilib + - bc - compiler: ": Cross-Mac" - env: HOST=x86_64-apple-darwin11 PACKAGES="gcc-multilib g++-multilib cmake libcap-dev libz-dev libbz2-dev" OSX_SDK=10.7 GOAL="deploy" + env: HOST=x86_64-apple-darwin11 OSX_SDK=10.7 GOAL="deploy" + addons: + apt: + packages: + - gcc-multilib + - g++-multilib + - cmake + - libcap-dev + - libbz2-dev - compiler: ": Win64" - env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2" + env: HOST=x86_64-w64-mingw32 RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2" WINE=true + addons: + apt: + packages: + - nsis + - gcc-mingw-w64-x86-64 + - g++-mingw-w64-x86-64 + - binutils-mingw-w64-x86-64 + - mingw-w64-dev + - wine + - bc - compiler: ": Win32" - env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2" + env: HOST=i686-w64-mingw32 RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2" WINE=true + addons: + apt: + packages: + - nsis + - gcc-mingw-w64-i686 + - g++-mingw-w64-i686 + - binutils-mingw-w64-i686 + - mingw-w64-dev + - wine + - bc exclude: - compiler: gcc install: - - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi - - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi before_script: - unset CC; unset CXX - mkdir -p depends/SDKs depends/sdk-sources - - if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then wget $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -O depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi + - if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS script: @@ -63,7 +103,8 @@ script: - ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false ) - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib - - if [ "$RUN_TESTS" = "true" ]; then make check; fi + - if [ "$RUN_TESTS" = "true" -a "$WINE" != "true" ]; then make check; fi + - if [ "$RUN_TESTS" = "true" -a "$WINE" = "true" ]; then wine src/test/test_dash.exe && wine src/qt/test/test_dash-qt.exe ; fi - if [ "$RUN_TESTS" = "true" ]; then qa/pull-tester/rpc-tests.sh; fi after_script: - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then (echo "Upload goes here. Something like: scp -r $BASE_OUTDIR server" || echo "upload failed"); fi diff --git a/COPYING b/COPYING index 5826391abf1c..30727c6ed10a 100644 --- a/COPYING +++ b/COPYING @@ -1,5 +1,5 @@ -Copyright (c) 2009-2015 Bitcoin Developers -Copyright (c) 2014-2015 Dash Developers +Copyright (c) 2009-2016 Bitcoin Developers +Copyright (c) 2014-2016 Dash Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile.am b/Makefile.am index e5de3ac81938..61d53e140ca1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -184,10 +184,12 @@ cov: test_dash.coverage/.dirstamp total.coverage/.dirstamp endif +# Dash: disable the test until upstream switches from convoluted comparison tool +# Ref https://github.com/bitcoin/bitcoin/issues/4545 if USE_COMPARISON_TOOL check-local: - $(MKDIR_P) qa/tmp - @qa/pull-tester/run-bitcoind-for-test.sh $(JAVA) -jar $(JAVA_COMPARISON_TOOL) qa/tmp/compTool $(COMPARISON_TOOL_REORG_TESTS) 2>&1 + ## $(MKDIR_P) qa/tmp + ## @qa/pull-tester/run-bitcoind-for-test.sh $(JAVA) -jar $(JAVA_COMPARISON_TOOL) qa/tmp/compTool $(COMPARISON_TOOL_REORG_TESTS) 2>&1 endif EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.sh qa/pull-tester/run-bitcoin-cli qa/rpc-tests $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) diff --git a/README.md b/README.md index 3178aa4849da..d96518bd67b1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ Dash Core staging tree 0.12 =============================== -https://www.dashpay.io +`master:` [![Build Status](https://travis-ci.org/dashpay/dash.svg?branch=master)](https://travis-ci.org/dashpay/dash) `v0.12.0.x:` [![Build Status](https://travis-ci.org/dashpay/dash.svg?branch=v0.12.0.x)](https://travis-ci.org/dashpay/dash/branches) `v0.12.1.x:` [![Build Status](https://travis-ci.org/dashpay/dash.svg?branch=v0.12.1.x)](https://travis-ci.org/dashpay/dash/branches) + +https://www.dash.org Copyright (c) 2009-2015 Bitcoin Core Developers @@ -18,7 +20,7 @@ are carried out collectively by the network. Dash Core is the name of open source software which enables the use of this currency. For more information, as well as an immediately useable, binary version of -the Dash Core software, see https://www.dashpay.io/downloads. +the Dash Core software, see https://www.dash.org/downloads. License @@ -27,27 +29,15 @@ License Dash Core is released under the terms of the MIT license. See [COPYING](COPYING) for more information or see http://opensource.org/licenses/MIT. -Development process +Development Process ------------------- -Developers work in their own trees, then submit pull requests when they think -their feature or bug fix is ready. - -If it is a simple/trivial/non-controversial change, then one of the Dash -development team members simply pulls it. - -If it is a *more complicated or potentially controversial* change, then the patch -submitter will be asked to start a discussion (if they haven't already) on the -[mailing list](https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev) +The `master` branch is meant to be stable. Development is normally done in separate branches. +[Tags](https://github.com/dashpay/dash/tags) are created to indicate new official, +stable release versions of Dash Core. -The patch will be accepted if there is broad consensus that it is a good thing. -Developers should expect to rework and resubmit patches if the code doesn't -match the project's coding conventions (see [doc/coding.md](doc/coding.md)) or are -controversial. +The contribution workflow is described in [CONTRIBUTING.md](CONTRIBUTING.md). -The `master` branch is regularly built and tested, but is not guaranteed to be -completely stable. [Tags](https://github.com/dashpay/dash/tags) are created -regularly to indicate new official, stable release versions of Dash. ***TODO*** Testing ------- diff --git a/configure.ac b/configure.ac index 1a98aaf6d6af..410003b1cfeb 100644 --- a/configure.ac +++ b/configure.ac @@ -3,9 +3,9 @@ AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MINOR, 12) define(_CLIENT_VERSION_REVISION, 0) -define(_CLIENT_VERSION_BUILD, 56) +define(_CLIENT_VERSION_BUILD, 59) define(_CLIENT_VERSION_IS_RELEASE, true) -define(_COPYRIGHT_YEAR, 2015) +define(_COPYRIGHT_YEAR, 2016) AC_INIT([Dash Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[info@dashpay.io],[dash]) AC_CONFIG_SRCDIR([src/main.cpp]) AC_CONFIG_HEADERS([src/config/dash-config.h]) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 5a7897ee3206..617822cd273b 100755 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -15,7 +15,7 @@ packages: - "faketime" - "bsdmainutils" - "binutils-gold" -reference_datetime: "2014-01-10 00:00:00" +reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/dashpay/dash.git" "dir": "dash" diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml index f3c78be5e8b6..d1feac4c60ed 100644 --- a/contrib/gitian-descriptors/gitian-osx-signer.yml +++ b/contrib/gitian-descriptors/gitian-osx-signer.yml @@ -7,7 +7,7 @@ architectures: packages: - "libc6:i386" - "faketime" -reference_datetime: "2013-06-01 00:00:00" +reference_datetime: "2016-01-01 00:00:00" remotes: [] files: - "dash-osx-unsigned.tar.gz" diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index f8cb34deef22..48d9023939fc 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -18,7 +18,7 @@ packages: - "libcap-dev" - "libz-dev" - "libbz2-dev" -reference_datetime: "2013-06-01 00:00:00" +reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/dashpay/dash.git" "dir": "dash" diff --git a/contrib/gitian-descriptors/gitian-rpi2.yml b/contrib/gitian-descriptors/gitian-rpi2.yml index 6bf051f8c21f..440ebc6a1295 100644 --- a/contrib/gitian-descriptors/gitian-rpi2.yml +++ b/contrib/gitian-descriptors/gitian-rpi2.yml @@ -15,7 +15,7 @@ packages: - "faketime" - "bsdmainutils" - "binutils-gold" -reference_datetime: "2014-01-10 00:00:00" +reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/dashpay/dash.git" "dir": "dash" diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 9ca5ab6e496d..0314de1467f4 100755 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -18,7 +18,7 @@ packages: - "g++-mingw-w64" - "nsis" - "zip" -reference_datetime: "2014-01-10 00:00:00" +reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/dashpay/dash.git" "dir": "dash" diff --git a/depends/builders/linux.mk b/depends/builders/linux.mk index 98d0e9de348f..75055e77e93c 100644 --- a/depends/builders/linux.mk +++ b/depends/builders/linux.mk @@ -1,2 +1,2 @@ build_linux_SHA256SUM = sha256sum -build_linux_DOWNLOAD = wget --timeout=$(DOWNLOAD_CONNECT_TIMEOUT) --tries=$(DOWNLOAD_RETRIES) -nv -O +build_linux_DOWNLOAD = curl --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -o diff --git a/qa/rpc-tests/mempool_coinbase_spends.py b/qa/rpc-tests/mempool_coinbase_spends.py index 7b43712768bf..b34c89bf38d1 100755 --- a/qa/rpc-tests/mempool_coinbase_spends.py +++ b/qa/rpc-tests/mempool_coinbase_spends.py @@ -55,9 +55,9 @@ def run_test(self): # and make sure the mempool code behaves correctly. b = [ self.nodes[0].getblockhash(n) for n in range(102, 105) ] coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] - spend_101_raw = self.create_tx(coinbase_txids[0], node1_address, 50) - spend_102_raw = self.create_tx(coinbase_txids[1], node0_address, 50) - spend_103_raw = self.create_tx(coinbase_txids[2], node0_address, 50) + spend_101_raw = self.create_tx(coinbase_txids[0], node1_address, 500) + spend_102_raw = self.create_tx(coinbase_txids[1], node0_address, 500) + spend_103_raw = self.create_tx(coinbase_txids[2], node0_address, 500) # Broadcast and mine spend_102 and 103: spend_102_id = self.nodes[0].sendrawtransaction(spend_102_raw) @@ -65,8 +65,8 @@ def run_test(self): self.nodes[0].setgenerate(True, 1) # Create 102_1 and 103_1: - spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 50) - spend_103_1_raw = self.create_tx(spend_103_id, node1_address, 50) + spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 500) + spend_103_1_raw = self.create_tx(spend_103_id, node1_address, 500) # Broadcast and mine 103_1: spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw) diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/qa/rpc-tests/mempool_resurrect_test.py index 81db812bfc38..12d9ae9cda09 100755 --- a/qa/rpc-tests/mempool_resurrect_test.py +++ b/qa/rpc-tests/mempool_resurrect_test.py @@ -47,13 +47,13 @@ def run_test(self): b = [ self.nodes[0].getblockhash(n) for n in range(1, 4) ] coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] - spends1_raw = [ self.create_tx(txid, node0_address, 50) for txid in coinbase_txids ] + spends1_raw = [ self.create_tx(txid, node0_address, 500) for txid in coinbase_txids ] spends1_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends1_raw ] blocks = [] blocks.extend(self.nodes[0].setgenerate(True, 1)) - spends2_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in spends1_id ] + spends2_raw = [ self.create_tx(txid, node0_address, 499.99) for txid in spends1_id ] spends2_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends2_raw ] blocks.extend(self.nodes[0].setgenerate(True, 1)) diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py index f0b34f2904f6..3dd825dab7d6 100755 --- a/qa/rpc-tests/mempool_spendcoinbase.py +++ b/qa/rpc-tests/mempool_spendcoinbase.py @@ -47,7 +47,7 @@ def run_test(self): # is too immature to spend. b = [ self.nodes[0].getblockhash(n) for n in range(101, 103) ] coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] - spends_raw = [ self.create_tx(txid, node0_address, 50) for txid in coinbase_txids ] + spends_raw = [ self.create_tx(txid, node0_address, 500) for txid in coinbase_txids ] spend_101_id = self.nodes[0].sendrawtransaction(spends_raw[0]) diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py index 0c07ef8a53d8..5629ca736955 100755 --- a/qa/rpc-tests/smartfees.py +++ b/qa/rpc-tests/smartfees.py @@ -40,7 +40,7 @@ def setup_network(self): def run_test(self): # Prime the memory pool with pairs of transactions # (high-priority, random fee and zero-priority, random fee) - min_fee = Decimal("0.001") + min_fee = Decimal("0.00010000") fees_per_kb = []; for i in range(12): (txid, txhex, fee) = random_zeropri_transaction(self.nodes, Decimal("1.1"), @@ -58,7 +58,7 @@ def run_test(self): print("Fee estimates, super-stingy miner: "+str([str(e) for e in all_estimates])) # Estimates should be within the bounds of what transactions fees actually were: - delta = 1.0e-6 # account for rounding error + delta = 1.0e-5 # account for rounding error for e in filter(lambda x: x >= 0, all_estimates): if float(e)+delta < min(fees_per_kb) or float(e)-delta > max(fees_per_kb): raise AssertionError("Estimated fee (%f) out of range (%f,%f)"%(float(e), min_fee_kb, max_fee_kb)) diff --git a/qa/rpc-tests/test_framework.py b/qa/rpc-tests/test_framework.py index 4c8a11b821d4..0205b0812185 100755 --- a/qa/rpc-tests/test_framework.py +++ b/qa/rpc-tests/test_framework.py @@ -24,7 +24,7 @@ class BitcoinTestFramework(object): def run_test(self): for node in self.nodes: assert_equal(node.getblockcount(), 200) - assert_equal(node.getbalance(), 25*50) + assert_equal(node.getbalance(), 25*500) def add_options(self, parser): pass diff --git a/qa/rpc-tests/txn_doublespend.py b/qa/rpc-tests/txn_doublespend.py index 942d9fc66c14..8bf6c9d94526 100755 --- a/qa/rpc-tests/txn_doublespend.py +++ b/qa/rpc-tests/txn_doublespend.py @@ -25,27 +25,27 @@ def setup_network(self): return super(TxnMallTest, self).setup_network(True) def run_test(self): - # All nodes should start with 1,250 BTC: - starting_balance = 1250 + # All nodes should start with 12,500 DASH: + starting_balance = 12500 for i in range(4): assert_equal(self.nodes[i].getbalance(), starting_balance) self.nodes[i].getnewaddress("") # bug workaround, coins generated assigned to first getnewaddress! # Assign coins to foo and bar accounts: - self.nodes[0].move("", "foo", 1220) + self.nodes[0].move("", "foo", 12470) self.nodes[0].move("", "bar", 30) assert_equal(self.nodes[0].getbalance(""), 0) # Coins are sent to node1_address node1_address = self.nodes[1].getnewaddress("from0") - # First: use raw transaction API to send 1210 BTC to node1_address, + # First: use raw transaction API to send 12460 BTC to node1_address, # but don't broadcast: - (total_in, inputs) = gather_inputs(self.nodes[0], 1210) + (total_in, inputs) = gather_inputs(self.nodes[0], 12460) change_address = self.nodes[0].getnewaddress("foo") outputs = {} outputs[change_address] = 40 - outputs[node1_address] = 1210 + outputs[node1_address] = 12460 rawtx = self.nodes[0].createrawtransaction(inputs, outputs) doublespend = self.nodes[0].signrawtransaction(rawtx) assert_equal(doublespend["complete"], True) @@ -53,7 +53,7 @@ def run_test(self): # Create two transaction from node[0] to node[1]; the # second must spend change from the first because the first # spends all mature inputs: - txid1 = self.nodes[0].sendfrom("foo", node1_address, 1210, 0) + txid1 = self.nodes[0].sendfrom("foo", node1_address, 12460, 0) txid2 = self.nodes[0].sendfrom("bar", node1_address, 20, 0) # Have node0 mine a block: @@ -64,16 +64,16 @@ def run_test(self): tx1 = self.nodes[0].gettransaction(txid1) tx2 = self.nodes[0].gettransaction(txid2) - # Node0's balance should be starting balance, plus 50BTC for another - # matured block, minus 1210, minus 20, and minus transaction fees: + # Node0's balance should be starting balance, plus 500 DASH for another + # matured block, minus 12460, minus 20, and minus transaction fees: expected = starting_balance - if self.options.mine_block: expected += 50 + if self.options.mine_block: expected += 500 expected += tx1["amount"] + tx1["fee"] expected += tx2["amount"] + tx2["fee"] assert_equal(self.nodes[0].getbalance(), expected) # foo and bar accounts should be debited: - assert_equal(self.nodes[0].getbalance("foo"), 1220+tx1["amount"]+tx1["fee"]) + assert_equal(self.nodes[0].getbalance("foo"), 12470+tx1["amount"]+tx1["fee"]) assert_equal(self.nodes[0].getbalance("bar"), 30+tx2["amount"]+tx2["fee"]) if self.options.mine_block: @@ -103,18 +103,18 @@ def run_test(self): assert_equal(tx1["confirmations"], -1) assert_equal(tx2["confirmations"], -1) - # Node0's total balance should be starting balance, plus 100BTC for - # two more matured blocks, minus 1210 for the double-spend: - expected = starting_balance + 100 - 1210 + # Node0's total balance should be starting balance, plus 1000 DASH for + # two more matured blocks, minus 12460 for the double-spend: + expected = starting_balance + 1000 - 12460 assert_equal(self.nodes[0].getbalance(), expected) assert_equal(self.nodes[0].getbalance("*"), expected) # foo account should be debited, but bar account should not: - assert_equal(self.nodes[0].getbalance("foo"), 1220-1210) + assert_equal(self.nodes[0].getbalance("foo"), 12470-12460) assert_equal(self.nodes[0].getbalance("bar"), 30) # Node1's "from" account balance should be just the mutated send: - assert_equal(self.nodes[1].getbalance("from0"), 1210) + assert_equal(self.nodes[1].getbalance("from0"), 12460) if __name__ == '__main__': TxnMallTest().main() diff --git a/qa/rpc-tests/util.py b/qa/rpc-tests/util.py index d40e3b1f78fa..deb21084a7e6 100644 --- a/qa/rpc-tests/util.py +++ b/qa/rpc-tests/util.py @@ -103,15 +103,15 @@ def initialize_chain(test_dir): # Create a 200-block-long chain; each of the 4 nodes # gets 25 mature blocks and 25 immature. - # blocks are created with timestamps 10 minutes apart, starting - # at 1 Jan 2014 - block_time = 1388534400 + # blocks are created with timestamps 156 seconds apart, starting + # at 1 Jan 2015 + block_time = 1420070400 for i in range(2): for peer in range(4): for j in range(25): set_node_times(rpcs, block_time) rpcs[peer].setgenerate(True, 1) - block_time += 10*60 + block_time += 156 # Must sync before next peer starts generating blocks sync_blocks(rpcs) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index bf71d5ebc517..ef4b2d9c2058 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -8,14 +8,14 @@ # Does the following: # a) creates 3 nodes, with an empty chain (no blocks). # b) node0 mines a block -# c) node1 mines 101 blocks, so now nodes 0 and 1 have 50btc, node2 has none. -# d) node0 sends 21 btc to node2, in two transactions (11 btc, then 10 btc). +# c) node1 mines 101 blocks, so now nodes 0 and 1 have 500 DASH, node2 has none. +# d) node0 sends 21 DASH to node2, in two transactions (11 DASH, then 10 DASH). # e) node0 mines a block, collects the fee on the second transaction # f) node1 mines 100 blocks, to mature node0's just-mined block -# g) check that node0 has 100-21, node2 has 21 +# g) check that node0 has 1000-21, node2 has 21 # h) node0 should now have 2 unspent outputs; send these to node2 via raw tx broadcast by node1 # i) have node1 mine a block -# j) check balances - node0 should have 0, node2 should have 100 +# j) check balances - node0 should have 0, node2 should have 1000 # from test_framework import BitcoinTestFramework @@ -45,11 +45,11 @@ def run_test (self): self.nodes[1].setgenerate(True, 101) self.sync_all() - assert_equal(self.nodes[0].getbalance(), 50) - assert_equal(self.nodes[1].getbalance(), 50) + assert_equal(self.nodes[0].getbalance(), 500) + assert_equal(self.nodes[1].getbalance(), 500) assert_equal(self.nodes[2].getbalance(), 0) - # Send 21 BTC from 0 to 2 using sendtoaddress call. + # Send 21 DASH from 0 to 2 using sendtoaddress call. # Second transaction will be child of first, and will require a fee self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10) @@ -62,9 +62,9 @@ def run_test (self): self.nodes[1].setgenerate(True, 100) self.sync_all() - # node0 should end up with 100 btc in block rewards plus fees, but + # node0 should end up with 1000 DASH in block rewards plus fees, but # minus the 21 plus fees sent to node2 - assert_equal(self.nodes[0].getbalance(), 100-21) + assert_equal(self.nodes[0].getbalance(), 1000-21) assert_equal(self.nodes[2].getbalance(), 21) # Node0 should have two unspent outputs. @@ -92,8 +92,8 @@ def run_test (self): self.sync_all() assert_equal(self.nodes[0].getbalance(), 0) - assert_equal(self.nodes[2].getbalance(), 100) - assert_equal(self.nodes[2].getbalance("from1"), 100-21) + assert_equal(self.nodes[2].getbalance(), 1000) + assert_equal(self.nodes[2].getbalance("from1"), 1000-21) if __name__ == '__main__': diff --git a/src/activemasternode.cpp b/src/activemasternode.cpp index e65725386ced..42214cae060c 100644 --- a/src/activemasternode.cpp +++ b/src/activemasternode.cpp @@ -64,8 +64,6 @@ void CActiveMasternode::ManageStatus() service = CService(strMasterNodeAddr); } - LogPrintf("CActiveMasternode::ManageStatus() - Checking inbound connection to '%s'\n", service.ToString()); - if(Params().NetworkID() == CBaseChainParams::MAIN) { if(service.GetPort() != 9999) { notCapableReason = strprintf("Invalid port: %u - only 9999 is supported on mainnet.", service.GetPort()); @@ -78,11 +76,15 @@ void CActiveMasternode::ManageStatus() return; } - if(!ConnectNode((CAddress)service, NULL, true)){ + LogPrintf("CActiveMasternode::ManageStatus() - Checking inbound connection to '%s'\n", service.ToString()); + + CNode *pnode = ConnectNode((CAddress)service, NULL, false); + if(!pnode){ notCapableReason = "Could not connect to " + service.ToString(); LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason); return; } + pnode->Release(); // Choose coins to use CPubKey pubKeyCollateralAddress; @@ -111,12 +113,17 @@ void CActiveMasternode::ManageStatus() return; } - if(!Register(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage)) { - notCapableReason = "Error on Register: " + errorMessage; + CMasternodeBroadcast mnb; + if(!CreateBroadcast(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage, mnb)) { + notCapableReason = "Error on CreateBroadcast: " + errorMessage; LogPrintf("Register::ManageStatus() - %s\n", notCapableReason); return; } + //send to all peers + LogPrintf("CActiveMasternode::ManageStatus() - Relay broadcast vin = %s\n", vin.ToString()); + mnb.Relay(); + LogPrintf("CActiveMasternode::ManageStatus() - Is capable master node!\n"); status = ACTIVE_MASTERNODE_STARTED; @@ -188,38 +195,6 @@ bool CActiveMasternode::SendMasternodePing(std::string& errorMessage) { mnp.Relay(); - /* - * IT'S SAFE TO REMOVE THIS IN FURTHER VERSIONS - * AFTER MIGRATION TO V12 IS DONE - */ - - if(IsSporkActive(SPORK_10_MASTERNODE_PAY_UPDATED_NODES)) return true; - // for migration purposes ping our node on old masternodes network too - std::string retErrorMessage; - std::vector vchMasterNodeSignature; - int64_t masterNodeSignatureTime = GetAdjustedTime(); - - std::string strMessage = service.ToString() + boost::lexical_cast(masterNodeSignatureTime) + boost::lexical_cast(false); - - if(!darkSendSigner.SignMessage(strMessage, retErrorMessage, vchMasterNodeSignature, keyMasternode)) { - errorMessage = "dseep sign message failed: " + retErrorMessage; - return false; - } - - if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchMasterNodeSignature, strMessage, retErrorMessage)) { - errorMessage = "dseep verify message failed: " + retErrorMessage; - return false; - } - - LogPrint("masternode", "dseep - relaying from active mn, %s \n", vin.ToString().c_str()); - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - pnode->PushMessage("dseep", vin, vchMasterNodeSignature, masterNodeSignatureTime, false); - - /* - * END OF "REMOVE" - */ - return true; } else @@ -233,7 +208,7 @@ bool CActiveMasternode::SendMasternodePing(std::string& errorMessage) { } -bool CActiveMasternode::Register(std::string strService, std::string strKeyMasternode, std::string strTxHash, std::string strOutputIndex, std::string& errorMessage) { +bool CActiveMasternode::CreateBroadcast(std::string strService, std::string strKeyMasternode, std::string strTxHash, std::string strOutputIndex, std::string& errorMessage, CMasternodeBroadcast &mnb, bool fOffline) { CTxIn vin; CPubKey pubKeyCollateralAddress; CKey keyCollateralAddress; @@ -241,22 +216,22 @@ bool CActiveMasternode::Register(std::string strService, std::string strKeyMaste CKey keyMasternode; //need correct blocks to send ping - if(!masternodeSync.IsBlockchainSynced()) { - errorMessage = GetStatus(); - LogPrintf("CActiveMasternode::Register() - %s\n", errorMessage); + if(!fOffline && !masternodeSync.IsBlockchainSynced()) { + errorMessage = "Sync in progress. Must wait until sync is complete to start Masternode"; + LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage); return false; } if(!darkSendSigner.SetKey(strKeyMasternode, errorMessage, keyMasternode, pubKeyMasternode)) { errorMessage = strprintf("Can't find keys for masternode %s - %s", strService, errorMessage); - LogPrintf("CActiveMasternode::Register() - %s\n", errorMessage); + LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage); return false; } if(!GetMasterNodeVin(vin, pubKeyCollateralAddress, keyCollateralAddress, strTxHash, strOutputIndex)) { errorMessage = strprintf("Could not allocate vin %s:%s for masternode %s", strTxHash, strOutputIndex, strService); - LogPrintf("CActiveMasternode::Register() - %s\n", errorMessage); + LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage); return false; } @@ -264,92 +239,41 @@ bool CActiveMasternode::Register(std::string strService, std::string strKeyMaste if(Params().NetworkID() == CBaseChainParams::MAIN) { if(service.GetPort() != 9999) { errorMessage = strprintf("Invalid port %u for masternode %s - only 9999 is supported on mainnet.", service.GetPort(), strService); - LogPrintf("CActiveMasternode::Register() - %s\n", errorMessage); + LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage); return false; } } else if(service.GetPort() == 9999) { errorMessage = strprintf("Invalid port %u for masternode %s - 9999 is only supported on mainnet.", service.GetPort(), strService); - LogPrintf("CActiveMasternode::Register() - %s\n", errorMessage); + LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage); return false; } addrman.Add(CAddress(service), CNetAddr("127.0.0.1"), 2*60*60); - return Register(vin, CService(strService), keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage); + return CreateBroadcast(vin, CService(strService), keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage, mnb); } -bool CActiveMasternode::Register(CTxIn vin, CService service, CKey keyCollateralAddress, CPubKey pubKeyCollateralAddress, CKey keyMasternode, CPubKey pubKeyMasternode, std::string &errorMessage) { - CMasternodeBroadcast mnb; +bool CActiveMasternode::CreateBroadcast(CTxIn vin, CService service, CKey keyCollateralAddress, CPubKey pubKeyCollateralAddress, CKey keyMasternode, CPubKey pubKeyMasternode, std::string &errorMessage, CMasternodeBroadcast &mnb) { + // wait for reindex and/or import to finish + if (fImporting || fReindex) return false; + CMasternodePing mnp(vin); if(!mnp.Sign(keyMasternode, pubKeyMasternode)){ errorMessage = strprintf("Failed to sign ping, vin: %s", vin.ToString()); - LogPrintf("CActiveMasternode::Register() - %s\n", errorMessage); + LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage); + mnb = CMasternodeBroadcast(); return false; } - mnodeman.mapSeenMasternodePing.insert(make_pair(mnp.GetHash(), mnp)); - LogPrintf("CActiveMasternode::Register() - Adding to Masternode list\n service: %s\n vin: %s\n", service.ToString(), vin.ToString()); mnb = CMasternodeBroadcast(service, vin, pubKeyCollateralAddress, pubKeyMasternode, PROTOCOL_VERSION); mnb.lastPing = mnp; if(!mnb.Sign(keyCollateralAddress)){ errorMessage = strprintf("Failed to sign broadcast, vin: %s", vin.ToString()); - LogPrintf("CActiveMasternode::Register() - %s\n", errorMessage); - return false; - } - mnodeman.mapSeenMasternodeBroadcast.insert(make_pair(mnb.GetHash(), mnb)); - masternodeSync.AddedMasternodeList(mnb.GetHash()); - - CMasternode* pmn = mnodeman.Find(vin); - if(pmn == NULL) - { - CMasternode mn(mnb); - mnodeman.Add(mn); - } else { - pmn->UpdateFromNewBroadcast(mnb); - } - - //send to all peers - LogPrintf("CActiveMasternode::Register() - RelayElectionEntry vin = %s\n", vin.ToString()); - mnb.Relay(); - - /* - * IT'S SAFE TO REMOVE THIS IN FURTHER VERSIONS - * AFTER MIGRATION TO V12 IS DONE - */ - - if(IsSporkActive(SPORK_10_MASTERNODE_PAY_UPDATED_NODES)) return true; - // for migration purposes inject our node in old masternodes' list too - std::string retErrorMessage; - std::vector vchMasterNodeSignature; - int64_t masterNodeSignatureTime = GetAdjustedTime(); - std::string donationAddress = ""; - int donationPercantage = 0; - - std::string vchPubKey(pubKeyCollateralAddress.begin(), pubKeyCollateralAddress.end()); - std::string vchPubKey2(pubKeyMasternode.begin(), pubKeyMasternode.end()); - - std::string strMessage = service.ToString() + boost::lexical_cast(masterNodeSignatureTime) + vchPubKey + vchPubKey2 + boost::lexical_cast(PROTOCOL_VERSION) + donationAddress + boost::lexical_cast(donationPercantage); - - if(!darkSendSigner.SignMessage(strMessage, retErrorMessage, vchMasterNodeSignature, keyCollateralAddress)) { - errorMessage = "dsee sign message failed: " + retErrorMessage; - LogPrintf("CActiveMasternode::Register() - Error: %s\n", errorMessage.c_str()); - return false; - } - - if(!darkSendSigner.VerifyMessage(pubKeyCollateralAddress, vchMasterNodeSignature, strMessage, retErrorMessage)) { - errorMessage = "dsee verify message failed: " + retErrorMessage; - LogPrintf("CActiveMasternode::Register() - Error: %s\n", errorMessage.c_str()); + LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage); + mnb = CMasternodeBroadcast(); return false; } - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - pnode->PushMessage("dsee", vin, service, vchMasterNodeSignature, masterNodeSignatureTime, pubKeyCollateralAddress, pubKeyMasternode, -1, -1, masterNodeSignatureTime, PROTOCOL_VERSION, donationAddress, donationPercantage); - - /* - * END OF "REMOVE" - */ - return true; } @@ -358,6 +282,9 @@ bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secr } bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex) { + // wait for reindex and/or import to finish + if (fImporting || fReindex) return false; + // Find possible candidates TRY_LOCK(pwalletMain->cs_wallet, fWallet); if(!fWallet) return false; @@ -400,6 +327,8 @@ bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secr // Extract Masternode vin information from output bool CActiveMasternode::GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubkey, CKey& secretKey) { + // wait for reindex and/or import to finish + if (fImporting || fReindex) return false; CScript pubScript; diff --git a/src/activemasternode.h b/src/activemasternode.h index 93a64eeab253..fa6a7c45f887 100644 --- a/src/activemasternode.h +++ b/src/activemasternode.h @@ -29,8 +29,8 @@ class CActiveMasternode /// Ping Masternode bool SendMasternodePing(std::string& errorMessage); - /// Register any Masternode - bool Register(CTxIn vin, CService service, CKey key, CPubKey pubKey, CKey keyMasternode, CPubKey pubKeyMasternode, std::string &errorMessage); + /// Create Masternode broadcast, needs to be relayed manually after that + bool CreateBroadcast(CTxIn vin, CService service, CKey key, CPubKey pubKey, CKey keyMasternode, CPubKey pubKeyMasternode, std::string &errorMessage, CMasternodeBroadcast &mnb); /// Get 1000DRK input that can be used for the Masternode bool GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex); @@ -57,8 +57,8 @@ class CActiveMasternode void ManageStatus(); std::string GetStatus(); - /// Register remote Masternode - bool Register(std::string strService, std::string strKey, std::string strTxHash, std::string strOutputIndex, std::string& errorMessage); + /// Create Masternode broadcast, needs to be relayed manually after that + bool CreateBroadcast(std::string strService, std::string strKey, std::string strTxHash, std::string strOutputIndex, std::string& errorMessage, CMasternodeBroadcast &mnb, bool fOffline = false); /// Get 1000DRK input that can be used for the Masternode bool GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey); diff --git a/src/chainparams.cpp b/src/chainparams.cpp index c59e2ac012e4..11cd694a4576 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -74,11 +74,14 @@ static Checkpoints::MapCheckpoints mapCheckpoints = ( 207992, uint256("0x00000000000d85c22be098f74576ef00b7aa00c05777e966aff68a270f1e01a5")) ( 312645, uint256("0x0000000000059dcb71ad35a9e40526c44e7aae6c99169a9e7017b7d84b1c2daf")) ( 407452, uint256("0x000000000003c6a87e73623b9d70af7cd908ae22fee466063e4ffc20be1d2dbc")) + ( 477481, uint256("0x0000000000083dbb96b0eb7d3ec9f2c43e015817332c757f8b5a794abf2fdffb")) + ( 523412, uint256("0x000000000000e54f036576a10597e0e42cc22a5159ce572f999c33975e121d4d")) + ( 523930, uint256("0x0000000000000bccdb11c2b1cfb0ecab452abf267d89b7f46eaf2d54ce6e652c")) ; static const Checkpoints::CCheckpointData data = { &mapCheckpoints, - 1423563332, // * UNIX timestamp of last checkpoint block - 853742, // * total number of transactions between genesis and last checkpoint + 1464498277, // * UNIX timestamp of last checkpoint block + 1832634, // * total number of transactions between genesis and last checkpoint // (the tx=... number in the SetBestChain debug.log lines) 2800 // * estimated number of transactions per day after checkpoint }; @@ -162,7 +165,6 @@ class CMainParams : public CChainParams { assert(genesis.hashMerkleRoot == uint256("0xe0028eb9648db56b1ac77cf090b99048a8007e2bb64b68f092c03c7f56a662c7")); vSeeds.push_back(CDNSSeedData("darkcoin.io", "dnsseed.darkcoin.io")); - vSeeds.push_back(CDNSSeedData("darkcoin.qa", "dnsseed.darkcoin.qa")); vSeeds.push_back(CDNSSeedData("masternode.io", "dnsseed.masternode.io")); vSeeds.push_back(CDNSSeedData("dashpay.io", "dnsseed.dashpay.io")); diff --git a/src/clientversion.h b/src/clientversion.h index 747f4afc3b1a..24243afd5f04 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -17,7 +17,7 @@ #define CLIENT_VERSION_MAJOR 0 #define CLIENT_VERSION_MINOR 12 #define CLIENT_VERSION_REVISION 0 -#define CLIENT_VERSION_BUILD 56 +#define CLIENT_VERSION_BUILD 59 //! Set to true for release, false for prerelease or test build #define CLIENT_VERSION_IS_RELEASE true @@ -26,7 +26,7 @@ * Copyright year (2009-this) * Todo: update this when changing our copyright comments in the source */ -#define COPYRIGHT_YEAR 2015 +#define COPYRIGHT_YEAR 2016 #endif //HAVE_CONFIG_H diff --git a/src/darksend-relay.cpp b/src/darksend-relay.cpp index 9ef77fafd31a..ec4da68ca810 100644 --- a/src/darksend-relay.cpp +++ b/src/darksend-relay.cpp @@ -105,10 +105,11 @@ void CDarkSendRelay::RelayThroughNode(int nRank) if(pmn != NULL){ //printf("RelayThroughNode %s\n", pmn->addr.ToString().c_str()); - CNode* pnode = ConnectNode((CAddress)pmn->addr, NULL, true); + CNode* pnode = ConnectNode((CAddress)pmn->addr, NULL, false); if(pnode){ //printf("Connected\n"); pnode->PushMessage("dsr", (*this)); + pnode->Release(); return; } } else { diff --git a/src/darksend.cpp b/src/darksend.cpp index ef2d7c39a859..14dfa7e8430d 100644 --- a/src/darksend.cpp +++ b/src/darksend.cpp @@ -1539,20 +1539,23 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun) std::vector vTempCoins2; // Try to match their denominations if possible if (!pwalletMain->SelectCoinsByDenominations(dsq.nDenom, nValueMin, nBalanceNeedsAnonymized, vTempCoins, vTempCoins2, nValueIn, 0, nDarksendRounds)){ - LogPrintf("DoAutomaticDenominating - Couldn't match denominations %d\n", dsq.nDenom); + LogPrintf("DoAutomaticDenominating --- Couldn't match denominations %d\n", dsq.nDenom); continue; } + CMasternode* pmn = mnodeman.Find(dsq.vin); + if(pmn == NULL) + { + LogPrintf("DoAutomaticDenominating --- dsq vin %s is not in masternode list!", dsq.vin.ToString()); + continue; + } + + LogPrintf("DoAutomaticDenominating --- attempt to connect to masternode from queue %s\n", pmn->addr.ToString()); + lastTimeChanged = GetTimeMillis(); // connect to Masternode and submit the queue request CNode* pnode = ConnectNode((CAddress)addr, NULL, true); if(pnode != NULL) { - CMasternode* pmn = mnodeman.Find(dsq.vin); - if(pmn == NULL) - { - LogPrintf("DoAutomaticDenominating --- dsq vin %s is not in masternode list!", dsq.vin.ToString()); - continue; - } pSubmittedToMasternode = pmn; vecMasternodesUsed.push_back(dsq.vin); sessionDenom = dsq.nDenom; @@ -1594,7 +1597,7 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun) } lastTimeChanged = GetTimeMillis(); - LogPrintf("DoAutomaticDenominating -- attempt %d connection to Masternode %s\n", i, pmn->addr.ToString()); + LogPrintf("DoAutomaticDenominating --- attempt %d connection to Masternode %s\n", i, pmn->addr.ToString()); CNode* pnode = ConnectNode((CAddress)pmn->addr, NULL, true); if(pnode != NULL){ pSubmittedToMasternode = pmn; @@ -2107,10 +2110,14 @@ bool CDarkSendSigner::VerifyMessage(CPubKey pubkey, vector& vchSi return false; } - if (fDebug && pubkey2.GetID() != pubkey.GetID()) - LogPrintf("CDarkSendSigner::VerifyMessage -- keys don't match: %s %s\n", pubkey2.GetID().ToString(), pubkey.GetID().ToString()); + if (pubkey2.GetID() != pubkey.GetID()) { + errorMessage = strprintf("keys don't match - input: %s, recovered: %s, message: %s, sig: %s\n", + pubkey.GetID().ToString(), pubkey2.GetID().ToString(), strMessage, + EncodeBase64(&vchSig[0], vchSig.size())); + return false; + } - return (pubkey2.GetID() == pubkey.GetID()); + return true; } bool CDarksendQueue::Sign() diff --git a/src/db.cpp b/src/db.cpp index b88b29f89fc6..3a60372c06f9 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -199,7 +199,7 @@ bool CDBEnv::Salvage(std::string strFile, bool fAggressive, std::vector 4500 || Params().NetworkID() == CBaseChainParams::TESTNET) dDiff = ConvertBitsToDouble(nBits); + if(nHeight > 4500 || Params().NetworkID() != CBaseChainParams::MAIN) dDiff = ConvertBitsToDouble(nBits); int64_t nSubsidy = 0; if(nHeight >= 5465) { diff --git a/src/masternode-budget.cpp b/src/masternode-budget.cpp index 4655e3e7cfb6..3f89a577fcac 100644 --- a/src/masternode-budget.cpp +++ b/src/masternode-budget.cpp @@ -64,6 +64,12 @@ bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, s return false; } + // RETRIEVE CONFIRMATIONS AND NTIME + /* + - nTime starts as zero and is passed-by-reference out of this function and stored in the external proposal + - nTime is never validated via the hashing mechanism and comes from a full-validated source (the blockchain) + */ + int conf = GetIXConfirmations(nTxCollateralHash); if (nBlockHash != uint256(0)) { BlockMap::iterator mi = mapBlockIndex.find(nBlockHash); @@ -392,15 +398,18 @@ bool CBudgetManager::AddProposal(CBudgetProposal& budgetProposal) void CBudgetManager::CheckAndRemove() { - LogPrintf("CBudgetManager::CheckAndRemove \n"); + LogPrintf("CBudgetManager::CheckAndRemove\n"); std::string strError = ""; + + LogPrintf("CBudgetManager::CheckAndRemove - mapFinalizedBudgets cleanup - size: %d\n", mapFinalizedBudgets.size()); std::map::iterator it = mapFinalizedBudgets.begin(); while(it != mapFinalizedBudgets.end()) { CFinalizedBudget* pfinalizedBudget = &((*it).second); pfinalizedBudget->fValid = pfinalizedBudget->IsValid(strError); + LogPrintf("CBudgetManager::CheckAndRemove - pfinalizedBudget->IsValid - strError: %s\n", strError); if(pfinalizedBudget->fValid) { pfinalizedBudget->AutoCheck(); } @@ -408,6 +417,7 @@ void CBudgetManager::CheckAndRemove() ++it; } + LogPrintf("CBudgetManager::CheckAndRemove - mapProposals cleanup - size: %d\n", mapProposals.size()); std::map::iterator it2 = mapProposals.begin(); while(it2 != mapProposals.end()) { @@ -415,6 +425,8 @@ void CBudgetManager::CheckAndRemove() pbudgetProposal->fValid = pbudgetProposal->IsValid(strError); ++it2; } + + LogPrintf("CBudgetManager::CheckAndRemove - PASSED\n"); } void CBudgetManager::FillBlockPayee(CMutableTransaction& txNew, CAmount nFees) @@ -804,6 +816,7 @@ void CBudgetManager::NewBlock() //remove invalid votes once in a while (we have to check the signatures and validity of every vote, somewhat CPU intensive) + LogPrintf("CBudgetManager::NewBlock - askedForSourceProposalOrBudget cleanup - size: %d\n", askedForSourceProposalOrBudget.size()); std::map::iterator it = askedForSourceProposalOrBudget.begin(); while(it != askedForSourceProposalOrBudget.end()){ if((*it).second > GetTime() - (60*60*24)){ @@ -813,18 +826,21 @@ void CBudgetManager::NewBlock() } } + LogPrintf("CBudgetManager::NewBlock - mapProposals cleanup - size: %d\n", mapProposals.size()); std::map::iterator it2 = mapProposals.begin(); while(it2 != mapProposals.end()){ (*it2).second.CleanAndRemove(false); ++it2; } + LogPrintf("CBudgetManager::NewBlock - mapFinalizedBudgets cleanup - size: %d\n", mapFinalizedBudgets.size()); std::map::iterator it3 = mapFinalizedBudgets.begin(); while(it3 != mapFinalizedBudgets.end()){ (*it3).second.CleanAndRemove(false); ++it3; } + LogPrintf("CBudgetManager::NewBlock - vecImmatureBudgetProposals cleanup - size: %d\n", vecImmatureBudgetProposals.size()); std::vector::iterator it4 = vecImmatureBudgetProposals.begin(); while(it4 != vecImmatureBudgetProposals.end()) { @@ -848,6 +864,7 @@ void CBudgetManager::NewBlock() it4 = vecImmatureBudgetProposals.erase(it4); } + LogPrintf("CBudgetManager::NewBlock - vecImmatureFinalizedBudgets cleanup - size: %d\n", vecImmatureFinalizedBudgets.size()); std::vector::iterator it5 = vecImmatureFinalizedBudgets.begin(); while(it5 != vecImmatureFinalizedBudgets.end()) { @@ -871,7 +888,7 @@ void CBudgetManager::NewBlock() it5 = vecImmatureFinalizedBudgets.erase(it5); } - + LogPrintf("CBudgetManager::NewBlock - PASSED\n"); } void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv) @@ -1572,7 +1589,7 @@ bool CBudgetVote::SignatureValid(bool fSignatureCheck) if(pmn == NULL) { - LogPrintf("CBudgetVote::SignatureValid() - Unknown Masternode - %s\n", vin.ToString()); + LogPrint("mnbudget", "CBudgetVote::SignatureValid() - Unknown Masternode - %s\n", vin.ToString()); return false; } @@ -1974,7 +1991,7 @@ bool CFinalizedBudgetVote::SignatureValid(bool fSignatureCheck) if(pmn == NULL) { - LogPrintf("CFinalizedBudgetVote::SignatureValid() - Unknown Masternode\n"); + LogPrint("mnbudget", "CFinalizedBudgetVote::SignatureValid() - Unknown Masternode\n"); return false; } diff --git a/src/masternode.cpp b/src/masternode.cpp index f65f052c1d26..07afa7c2fca0 100644 --- a/src/masternode.cpp +++ b/src/masternode.cpp @@ -73,8 +73,6 @@ CMasternode::CMasternode() nScanningErrorCount = 0; nLastScanningErrorBlockHeight = 0; lastTimeChecked = 0; - nLastDsee = 0;// temporary, do not save. Remove after migration to v12 - nLastDseep = 0;// temporary, do not save. Remove after migration to v12 } CMasternode::CMasternode(const CMasternode& other) @@ -97,8 +95,6 @@ CMasternode::CMasternode(const CMasternode& other) nScanningErrorCount = other.nScanningErrorCount; nLastScanningErrorBlockHeight = other.nLastScanningErrorBlockHeight; lastTimeChecked = 0; - nLastDsee = other.nLastDsee;// temporary, do not save. Remove after migration to v12 - nLastDseep = other.nLastDseep;// temporary, do not save. Remove after migration to v12 } CMasternode::CMasternode(const CMasternodeBroadcast& mnb) @@ -121,8 +117,6 @@ CMasternode::CMasternode(const CMasternodeBroadcast& mnb) nScanningErrorCount = 0; nLastScanningErrorBlockHeight = 0; lastTimeChecked = 0; - nLastDsee = 0;// temporary, do not save. Remove after migration to v12 - nLastDseep = 0;// temporary, do not save. Remove after migration to v12 } // @@ -345,6 +339,8 @@ CMasternodeBroadcast::CMasternodeBroadcast(const CMasternode& mn) bool CMasternodeBroadcast::CheckAndUpdate(int& nDos) { + nDos = 0; + // make sure signature isn't in the future (past is OK) if (sigTime > GetAdjustedTime() + 60 * 60) { LogPrintf("mnb - Signature rejected, too far into the future %s\n", vin.ToString()); @@ -352,10 +348,6 @@ bool CMasternodeBroadcast::CheckAndUpdate(int& nDos) return false; } - std::string vchPubKey(pubkey.begin(), pubkey.end()); - std::string vchPubKey2(pubkey2.begin(), pubkey2.end()); - std::string strMessage = addr.ToString() + boost::lexical_cast(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast(protocolVersion); - if(protocolVersion < masternodePayments.GetMinMasternodePaymentsProto()) { LogPrintf("mnb - ignoring outdated Masternode %s protocol version %d\n", vin.ToString(), protocolVersion); return false; @@ -384,11 +376,60 @@ bool CMasternodeBroadcast::CheckAndUpdate(int& nDos) return false; } - std::string errorMessage = ""; - if(!darkSendSigner.VerifyMessage(pubkey, sig, strMessage, errorMessage)){ - LogPrintf("mnb - Got bad Masternode address signature\n"); - nDos = 100; + // incorrect ping or its sigTime + if(lastPing == CMasternodePing() || !lastPing.CheckAndUpdate(nDos, false, true)) return false; + + std::string strMessage; + std::string errorMessage = ""; + + if(protocolVersion < 70201) { + std::string vchPubKey(pubkey.begin(), pubkey.end()); + std::string vchPubKey2(pubkey2.begin(), pubkey2.end()); + strMessage = addr.ToString(false) + boost::lexical_cast(sigTime) + + vchPubKey + vchPubKey2 + boost::lexical_cast(protocolVersion); + + LogPrint("masternode", "mnb - sanitized strMessage: %s, pubkey address: %s, sig: %s\n", + SanitizeString(strMessage), CBitcoinAddress(pubkey.GetID()).ToString(), + EncodeBase64(&sig[0], sig.size())); + + if(!darkSendSigner.VerifyMessage(pubkey, sig, strMessage, errorMessage)){ + if (addr.ToString() != addr.ToString(false)) + { + // maybe it's wrong format, try again with the old one + strMessage = addr.ToString() + boost::lexical_cast(sigTime) + + vchPubKey + vchPubKey2 + boost::lexical_cast(protocolVersion); + + LogPrint("masternode", "mnb - sanitized strMessage: %s, pubkey address: %s, sig: %s\n", + SanitizeString(strMessage), CBitcoinAddress(pubkey.GetID()).ToString(), + EncodeBase64(&sig[0], sig.size())); + + if(!darkSendSigner.VerifyMessage(pubkey, sig, strMessage, errorMessage)){ + // didn't work either + LogPrintf("mnb - Got bad Masternode address signature, sanitized error: %s\n", SanitizeString(errorMessage)); + // there is a bug in old MN signatures, ignore such MN but do not ban the peer we got this from + return false; + } + } else { + // nope, sig is actually wrong + LogPrintf("mnb - Got bad Masternode address signature, sanitized error: %s\n", SanitizeString(errorMessage)); + // there is a bug in old MN signatures, ignore such MN but do not ban the peer we got this from + return false; + } + } + } else { + strMessage = addr.ToString(false) + boost::lexical_cast(sigTime) + + pubkey.GetID().ToString() + pubkey2.GetID().ToString() + + boost::lexical_cast(protocolVersion); + + LogPrint("masternode", "mnb - strMessage: %s, pubkey address: %s, sig: %s\n", + strMessage, CBitcoinAddress(pubkey.GetID()).ToString(), EncodeBase64(&sig[0], sig.size())); + + if(!darkSendSigner.VerifyMessage(pubkey, sig, strMessage, errorMessage)){ + LogPrintf("mnb - Got bad Masternode address signature, error: %s\n", errorMessage); + nDos = 100; + return false; + } } if(Params().NetworkID() == CBaseChainParams::MAIN) { @@ -398,8 +439,20 @@ bool CMasternodeBroadcast::CheckAndUpdate(int& nDos) //search existing Masternode list, this is where we update existing Masternodes with new mnb broadcasts CMasternode* pmn = mnodeman.Find(vin); - // no such masternode or it's not enabled already, nothing to update - if(pmn == NULL || (pmn != NULL && !pmn->IsEnabled())) return true; + // no such masternode, nothing to update + if(pmn == NULL) return true; + + // this broadcast is older or equal than the one that we already have - it's bad and should never happen + // unless someone is doing something fishy + // (mapSeenMasternodeBroadcast in CMasternodeMan::ProcessMessage should filter legit duplicates) + if(pmn->sigTime >= sigTime) { + LogPrintf("CMasternodeBroadcast::CheckAndUpdate - Bad sigTime %d for Masternode %20s %105s (existing broadcast is at %d)\n", + sigTime, addr.ToString(), vin.ToString(), pmn->sigTime); + return false; + } + + // masternode is not enabled yet/already, nothing to update + if(!pmn->IsEnabled()) return true; // mn.pubkey = pubkey, IsVinAssociatedWithPubkey is validated once below, // after that they just need to match @@ -423,6 +476,10 @@ bool CMasternodeBroadcast::CheckInputsAndAdd(int& nDoS) if(fMasterNode && vin.prevout == activeMasternode.vin.prevout && pubkey2 == activeMasternode.pubKeyMasternode) return true; + // incorrect ping or its sigTime + if(lastPing == CMasternodePing() || !lastPing.CheckAndUpdate(nDoS, false, true)) + return false; + // search existing Masternode list CMasternode* pmn = mnodeman.Find(vin); @@ -515,15 +572,27 @@ bool CMasternodeBroadcast::Sign(CKey& keyCollateralAddress) sigTime = GetAdjustedTime(); - std::string strMessage = addr.ToString() + boost::lexical_cast(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast(protocolVersion); + std::string strMessage = addr.ToString(false) + boost::lexical_cast(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast(protocolVersion); if(!darkSendSigner.SignMessage(strMessage, errorMessage, sig, keyCollateralAddress)) { LogPrintf("CMasternodeBroadcast::Sign() - Error: %s\n", errorMessage); return false; } + return true; +} + +bool CMasternodeBroadcast::VerifySignature() +{ + std::string errorMessage; + + std::string vchPubKey(pubkey.begin(), pubkey.end()); + std::string vchPubKey2(pubkey2.begin(), pubkey2.end()); + + std::string strMessage = addr.ToString() + boost::lexical_cast(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast(protocolVersion); + if(!darkSendSigner.VerifyMessage(pubkey, sig, strMessage, errorMessage)) { - LogPrintf("CMasternodeBroadcast::Sign() - Error: %s\n", errorMessage); + LogPrintf("CMasternodeBroadcast::VerifySignature() - Error: %s\n", errorMessage); return false; } @@ -568,7 +637,20 @@ bool CMasternodePing::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode) return true; } -bool CMasternodePing::CheckAndUpdate(int& nDos, bool fRequireEnabled) +bool CMasternodePing::VerifySignature(CPubKey& pubKeyMasternode, int &nDos) { + std::string strMessage = vin.ToString() + blockHash.ToString() + boost::lexical_cast(sigTime); + std::string errorMessage = ""; + + if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchSig, strMessage, errorMessage)) + { + LogPrintf("CMasternodePing::VerifySignature - Got bad Masternode ping signature %s Error: %s\n", vin.ToString(), errorMessage); + nDos = 33; + return false; + } + return true; +} + +bool CMasternodePing::CheckAndUpdate(int& nDos, bool fRequireEnabled, bool fCheckSigTimeOnly) { if (sigTime > GetAdjustedTime() + 60 * 60) { LogPrintf("CMasternodePing::CheckAndUpdate - Signature rejected, too far into the future %s\n", vin.ToString()); @@ -582,6 +664,12 @@ bool CMasternodePing::CheckAndUpdate(int& nDos, bool fRequireEnabled) return false; } + if(fCheckSigTimeOnly) { + CMasternode* pmn = mnodeman.Find(vin); + if(pmn) return VerifySignature(pmn->pubkey2, nDos); + return true; + } + LogPrint("masternode", "CMasternodePing::CheckAndUpdate - New Ping - %s - %s - %lli\n", GetHash().ToString(), blockHash.ToString(), sigTime); // see if we have this Masternode @@ -595,15 +683,8 @@ bool CMasternodePing::CheckAndUpdate(int& nDos, bool fRequireEnabled) // last ping was more then MASTERNODE_MIN_MNP_SECONDS-60 ago comparing to this one if(!pmn->IsPingedWithin(MASTERNODE_MIN_MNP_SECONDS - 60, sigTime)) { - std::string strMessage = vin.ToString() + blockHash.ToString() + boost::lexical_cast(sigTime); - - std::string errorMessage = ""; - if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage)) - { - LogPrintf("CMasternodePing::CheckAndUpdate - Got bad Masternode address signature %s\n", vin.ToString()); - nDos = 33; + if(!VerifySignature(pmn->pubkey2, nDos)) return false; - } BlockMap::iterator mi = mapBlockIndex.find(blockHash); if (mi != mapBlockIndex.end() && (*mi).second) diff --git a/src/masternode.h b/src/masternode.h index 0bdf396691a4..7219ea0a5014 100644 --- a/src/masternode.h +++ b/src/masternode.h @@ -58,8 +58,9 @@ class CMasternodePing READWRITE(vchSig); } - bool CheckAndUpdate(int& nDos, bool fRequireEnabled = true); + bool CheckAndUpdate(int& nDos, bool fRequireEnabled = true, bool fCheckSigTimeOnly = false); bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode); + bool VerifySignature(CPubKey& pubKeyMasternode, int &nDos); void Relay(); uint256 GetHash(){ @@ -135,9 +136,6 @@ class CMasternode int nLastScanningErrorBlockHeight; CMasternodePing lastPing; - int64_t nLastDsee;// temporary, do not save. Remove after migration to v12 - int64_t nLastDseep;// temporary, do not save. Remove after migration to v12 - CMasternode(); CMasternode(const CMasternode& other); CMasternode(const CMasternodeBroadcast& mnb); @@ -289,6 +287,7 @@ class CMasternodeBroadcast : public CMasternode bool CheckAndUpdate(int& nDoS); bool CheckInputsAndAdd(int& nDos); bool Sign(CKey& keyCollateralAddress); + bool VerifySignature(); void Relay(); ADD_SERIALIZE_METHODS; diff --git a/src/masternodeman.cpp b/src/masternodeman.cpp index 429df7d002b5..580cac75a9a2 100644 --- a/src/masternodeman.cpp +++ b/src/masternodeman.cpp @@ -324,17 +324,18 @@ void CMasternodeMan::CheckAndRemove(bool forceExpiredRemoval) } } - // remove expired mapSeenMasternodeBroadcast - map::iterator it3 = mapSeenMasternodeBroadcast.begin(); - while(it3 != mapSeenMasternodeBroadcast.end()){ - if((*it3).second.lastPing.sigTime < GetTime()-(MASTERNODE_REMOVAL_SECONDS*2)){ - mapSeenMasternodeBroadcast.erase(it3++); - masternodeSync.mapSeenSyncMNB.erase((*it3).second.GetHash()); - } else { - ++it3; - } - } - + // remove expired mapSeenMasternodeBroadcast + map::iterator it3 = mapSeenMasternodeBroadcast.begin(); + while(it3 != mapSeenMasternodeBroadcast.end()){ + if((*it3).second.lastPing.sigTime < GetTime() - MASTERNODE_REMOVAL_SECONDS*2){ + LogPrint("masternode", "CMasternodeMan::CheckAndRemove - Removing expired Masternode broadcast %s\n", (*it3).second.GetHash().ToString()); + masternodeSync.mapSeenSyncMNB.erase((*it3).second.GetHash()); + mapSeenMasternodeBroadcast.erase(it3++); + } else { + ++it3; + } + } + // remove expired mapSeenMasternodePing map::iterator it4 = mapSeenMasternodePing.begin(); while(it4 != mapSeenMasternodePing.end()){ @@ -667,7 +668,8 @@ void CMasternodeMan::ProcessMasternodeConnections() if(pnode->fDarkSendMaster){ if(darkSendPool.pSubmittedToMasternode != NULL && pnode->addr == darkSendPool.pSubmittedToMasternode->addr) continue; LogPrintf("Closing Masternode connection %s \n", pnode->addr.ToString()); - pnode->fDisconnect = true; + pnode->fDarkSendMaster = false; + pnode->Release(); } } } @@ -684,41 +686,12 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData CMasternodeBroadcast mnb; vRecv >> mnb; - if(mapSeenMasternodeBroadcast.count(mnb.GetHash())) { //seen - masternodeSync.AddedMasternodeList(mnb.GetHash()); - return; - } - mapSeenMasternodeBroadcast.insert(make_pair(mnb.GetHash(), mnb)); - int nDoS = 0; - if(!mnb.CheckAndUpdate(nDoS)){ - - if(nDoS > 0) - Misbehaving(pfrom->GetId(), nDoS); - - //failed - return; - } - - // make sure the vout that was signed is related to the transaction that spawned the Masternode - // - this is expensive, so it's only done once per Masternode - if(!darkSendSigner.IsVinAssociatedWithPubkey(mnb.vin, mnb.pubkey)) { - LogPrintf("mnb - Got mismatched pubkey and vin\n"); - Misbehaving(pfrom->GetId(), 33); - return; - } - - // make sure it's still unspent - // - this is checked later by .check() in many places and by ThreadCheckDarkSendPool() - if(mnb.CheckInputsAndAdd(nDoS)) { - // use this as a peer - addrman.Add(CAddress(mnb.addr), pfrom->addr, 2*60*60); - masternodeSync.AddedMasternodeList(mnb.GetHash()); + if (CheckMnbAndUpdateMasternodeList(mnb, nDoS)) { + // use announced Masternode as a peer + addrman.Add(CAddress(mnb.addr), pfrom->addr, 2*60*60); } else { - LogPrintf("mnb - Rejected Masternode entry %s\n", mnb.addr.ToString()); - - if (nDoS > 0) - Misbehaving(pfrom->GetId(), nDoS); + if(nDoS > 0) Misbehaving(pfrom->GetId(), nDoS); } } @@ -801,293 +774,6 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData LogPrintf("dseg - Sent %d Masternode entries to %s\n", nInvCount, pfrom->addr.ToString()); } } - /* - * IT'S SAFE TO REMOVE THIS IN FURTHER VERSIONS - * AFTER MIGRATION TO V12 IS DONE - */ - - // Light version for OLD MASSTERNODES - fake pings, no self-activation - else if (strCommand == "dsee") { //DarkSend Election Entry - - if(IsSporkActive(SPORK_10_MASTERNODE_PAY_UPDATED_NODES)) return; - - CTxIn vin; - CService addr; - CPubKey pubkey; - CPubKey pubkey2; - vector vchSig; - int64_t sigTime; - int count; - int current; - int64_t lastUpdated; - int protocolVersion; - CScript donationAddress; - int donationPercentage; - std::string strMessage; - - vRecv >> vin >> addr >> vchSig >> sigTime >> pubkey >> pubkey2 >> count >> current >> lastUpdated >> protocolVersion >> donationAddress >> donationPercentage; - - // make sure signature isn't in the future (past is OK) - if (sigTime > GetAdjustedTime() + 60 * 60) { - LogPrintf("dsee - Signature rejected, too far into the future %s\n", vin.ToString().c_str()); - Misbehaving(pfrom->GetId(), 1); - return; - } - - std::string vchPubKey(pubkey.begin(), pubkey.end()); - std::string vchPubKey2(pubkey2.begin(), pubkey2.end()); - - strMessage = addr.ToString() + boost::lexical_cast(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast(protocolVersion) + donationAddress.ToString() + boost::lexical_cast(donationPercentage); - - if(protocolVersion < masternodePayments.GetMinMasternodePaymentsProto()) { - LogPrintf("dsee - ignoring outdated Masternode %s protocol version %d < %d\n", vin.ToString().c_str(), protocolVersion, masternodePayments.GetMinMasternodePaymentsProto()); - Misbehaving(pfrom->GetId(), 1); - return; - } - - CScript pubkeyScript; - pubkeyScript = GetScriptForDestination(pubkey.GetID()); - - if(pubkeyScript.size() != 25) { - LogPrintf("dsee - pubkey the wrong size\n"); - Misbehaving(pfrom->GetId(), 100); - return; - } - - CScript pubkeyScript2; - pubkeyScript2 = GetScriptForDestination(pubkey2.GetID()); - - if(pubkeyScript2.size() != 25) { - LogPrintf("dsee - pubkey2 the wrong size\n"); - Misbehaving(pfrom->GetId(), 100); - return; - } - - if(!vin.scriptSig.empty()) { - LogPrintf("dsee - Ignore Not Empty ScriptSig %s\n",vin.ToString()); - Misbehaving(pfrom->GetId(), 100); - return; - } - - std::string errorMessage = ""; - if(!darkSendSigner.VerifyMessage(pubkey, vchSig, strMessage, errorMessage)){ - LogPrintf("dsee - Got bad Masternode address signature\n"); - Misbehaving(pfrom->GetId(), 100); - return; - } - - if(Params().NetworkID() == CBaseChainParams::MAIN){ - if(addr.GetPort() != 9999) return; - } else if(addr.GetPort() == 9999) return; - - //search existing Masternode list, this is where we update existing Masternodes with new dsee broadcasts - CMasternode* pmn = this->Find(vin); - if(pmn != NULL) - { - // count == -1 when it's a new entry - // e.g. We don't want the entry relayed/time updated when we're syncing the list - // mn.pubkey = pubkey, IsVinAssociatedWithPubkey is validated once below, - // after that they just need to match - if(count == -1 && pmn->pubkey == pubkey && (GetAdjustedTime() - pmn->nLastDsee > MASTERNODE_MIN_MNB_SECONDS)){ - if(pmn->protocolVersion > GETHEADERS_VERSION && sigTime - pmn->lastPing.sigTime < MASTERNODE_MIN_MNB_SECONDS) return; - if(pmn->nLastDsee < sigTime){ //take the newest entry - LogPrintf("dsee - Got updated entry for %s\n", addr.ToString().c_str()); - if(pmn->protocolVersion < GETHEADERS_VERSION) { - pmn->pubkey2 = pubkey2; - pmn->sigTime = sigTime; - pmn->sig = vchSig; - pmn->protocolVersion = protocolVersion; - pmn->addr = addr; - //fake ping - pmn->lastPing = CMasternodePing(vin); - } - pmn->nLastDsee = sigTime; - pmn->Check(); - if(pmn->IsEnabled()) { - TRY_LOCK(cs_vNodes, lockNodes); - if(!lockNodes) return; - BOOST_FOREACH(CNode* pnode, vNodes) - if(pnode->nVersion >= masternodePayments.GetMinMasternodePaymentsProto()) - pnode->PushMessage("dsee", vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion, donationAddress, donationPercentage); - } - } - } - - return; - } - - static std::map mapSeenDsee; - if(mapSeenDsee.count(vin.prevout) && mapSeenDsee[vin.prevout] == pubkey) { - LogPrint("mastenrode", "dsee - already seen this vin %s\n", vin.prevout.ToString()); - return; - } - mapSeenDsee.insert(make_pair(vin.prevout, pubkey)); - // make sure the vout that was signed is related to the transaction that spawned the Masternode - // - this is expensive, so it's only done once per Masternode - if(!darkSendSigner.IsVinAssociatedWithPubkey(vin, pubkey)) { - LogPrintf("dsee - Got mismatched pubkey and vin\n"); - Misbehaving(pfrom->GetId(), 100); - return; - } - - - LogPrint("masternode", "dsee - Got NEW OLD Masternode entry %s\n", addr.ToString().c_str()); - - // make sure it's still unspent - // - this is checked later by .check() in many places and by ThreadCheckDarkSendPool() - - CValidationState state; - CMutableTransaction tx = CMutableTransaction(); - CTxOut vout = CTxOut(999.99*COIN, darkSendPool.collateralPubKey); - tx.vin.push_back(vin); - tx.vout.push_back(vout); - - bool fAcceptable = false; - { - TRY_LOCK(cs_main, lockMain); - if(!lockMain) return; - fAcceptable = AcceptableInputs(mempool, state, CTransaction(tx), false, NULL); - } - - if(fAcceptable){ - if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){ - LogPrintf("dsee - Input must have least %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS); - Misbehaving(pfrom->GetId(), 20); - return; - } - - // verify that sig time is legit in past - // should be at least not earlier than block when 1000 DASH tx got MASTERNODE_MIN_CONFIRMATIONS - uint256 hashBlock = 0; - CTransaction tx2; - GetTransaction(vin.prevout.hash, tx2, hashBlock, true); - BlockMap::iterator mi = mapBlockIndex.find(hashBlock); - if (mi != mapBlockIndex.end() && (*mi).second) - { - CBlockIndex* pMNIndex = (*mi).second; // block for 1000 DASH tx -> 1 confirmation - CBlockIndex* pConfIndex = chainActive[pMNIndex->nHeight + MASTERNODE_MIN_CONFIRMATIONS - 1]; // block where tx got MASTERNODE_MIN_CONFIRMATIONS - if(pConfIndex->GetBlockTime() > sigTime) - { - LogPrintf("mnb - Bad sigTime %d for Masternode %20s %105s (%i conf block is at %d)\n", - sigTime, addr.ToString(), vin.ToString(), MASTERNODE_MIN_CONFIRMATIONS, pConfIndex->GetBlockTime()); - return; - } - } - - // use this as a peer - addrman.Add(CAddress(addr), pfrom->addr, 2*60*60); - - // add Masternode - CMasternode mn = CMasternode(); - mn.addr = addr; - mn.vin = vin; - mn.pubkey = pubkey; - mn.sig = vchSig; - mn.sigTime = sigTime; - mn.pubkey2 = pubkey2; - mn.protocolVersion = protocolVersion; - // fake ping - mn.lastPing = CMasternodePing(vin); - mn.Check(true); - // add v11 masternodes, v12 should be added by mnb only - if(protocolVersion < GETHEADERS_VERSION) { - LogPrint("masternode", "dsee - Accepted OLD Masternode entry %i %i\n", count, current); - Add(mn); - } - if(mn.IsEnabled()) { - TRY_LOCK(cs_vNodes, lockNodes); - if(!lockNodes) return; - BOOST_FOREACH(CNode* pnode, vNodes) - if(pnode->nVersion >= masternodePayments.GetMinMasternodePaymentsProto()) - pnode->PushMessage("dsee", vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion, donationAddress, donationPercentage); - } - } else { - LogPrintf("dsee - Rejected Masternode entry %s\n", addr.ToString().c_str()); - - int nDoS = 0; - if (state.IsInvalid(nDoS)) - { - LogPrintf("dsee - %s from %s %s was not accepted into the memory pool\n", tx.GetHash().ToString().c_str(), - pfrom->addr.ToString().c_str(), pfrom->cleanSubVer.c_str()); - if (nDoS > 0) - Misbehaving(pfrom->GetId(), nDoS); - } - } - } - - else if (strCommand == "dseep") { //DarkSend Election Entry Ping - - if(IsSporkActive(SPORK_10_MASTERNODE_PAY_UPDATED_NODES)) return; - - CTxIn vin; - vector vchSig; - int64_t sigTime; - bool stop; - vRecv >> vin >> vchSig >> sigTime >> stop; - - //LogPrintf("dseep - Received: vin: %s sigTime: %lld stop: %s\n", vin.ToString().c_str(), sigTime, stop ? "true" : "false"); - - if (sigTime > GetAdjustedTime() + 60 * 60) { - LogPrintf("dseep - Signature rejected, too far into the future %s\n", vin.ToString().c_str()); - Misbehaving(pfrom->GetId(), 1); - return; - } - - if (sigTime <= GetAdjustedTime() - 60 * 60) { - LogPrintf("dseep - Signature rejected, too far into the past %s - %d %d \n", vin.ToString().c_str(), sigTime, GetAdjustedTime()); - Misbehaving(pfrom->GetId(), 1); - return; - } - - std::map::iterator i = mWeAskedForMasternodeListEntry.find(vin.prevout); - if (i != mWeAskedForMasternodeListEntry.end()) - { - int64_t t = (*i).second; - if (GetTime() < t) return; // we've asked recently - } - - // see if we have this Masternode - CMasternode* pmn = this->Find(vin); - if(pmn != NULL && pmn->protocolVersion >= masternodePayments.GetMinMasternodePaymentsProto()) - { - // LogPrintf("dseep - Found corresponding mn for vin: %s\n", vin.ToString().c_str()); - // take this only if it's newer - if(sigTime - pmn->nLastDseep > MASTERNODE_MIN_MNP_SECONDS) - { - std::string strMessage = pmn->addr.ToString() + boost::lexical_cast(sigTime) + boost::lexical_cast(stop); - - std::string errorMessage = ""; - if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage)) - { - LogPrintf("dseep - Got bad Masternode address signature %s \n", vin.ToString().c_str()); - //Misbehaving(pfrom->GetId(), 100); - return; - } - - // fake ping for v11 masternodes, ignore for v12 - if(pmn->protocolVersion < GETHEADERS_VERSION) pmn->lastPing = CMasternodePing(vin); - pmn->nLastDseep = sigTime; - pmn->Check(); - if(pmn->IsEnabled()) { - TRY_LOCK(cs_vNodes, lockNodes); - if(!lockNodes) return; - LogPrint("masternode", "dseep - relaying %s \n", vin.ToString().c_str()); - BOOST_FOREACH(CNode* pnode, vNodes) - if(pnode->nVersion >= masternodePayments.GetMinMasternodePaymentsProto()) - pnode->PushMessage("dseep", vin, vchSig, sigTime, stop); - } - } - return; - } - - LogPrint("masternode", "dseep - Couldn't find Masternode entry %s %s\n", vin.ToString(), pfrom->addr.ToString()); - - AskForMN(pfrom, vin); - } - - /* - * END OF "REMOVE" - */ } @@ -1118,3 +804,57 @@ std::string CMasternodeMan::ToString() const return info.str(); } + +void CMasternodeMan::UpdateMasternodeList(CMasternodeBroadcast mnb) { + mapSeenMasternodePing.insert(make_pair(mnb.lastPing.GetHash(), mnb.lastPing)); + mapSeenMasternodeBroadcast.insert(make_pair(mnb.GetHash(), mnb)); + masternodeSync.AddedMasternodeList(mnb.GetHash()); + + LogPrintf("CMasternodeMan::UpdateMasternodeList() - addr: %s\n vin: %s\n", mnb.addr.ToString(), mnb.vin.ToString()); + + CMasternode* pmn = Find(mnb.vin); + if(pmn == NULL) + { + CMasternode mn(mnb); + Add(mn); + } else { + pmn->UpdateFromNewBroadcast(mnb); + } +} + +bool CMasternodeMan::CheckMnbAndUpdateMasternodeList(CMasternodeBroadcast mnb, int& nDos) { + nDos = 0; + LogPrint("masternode", "CMasternodeMan::CheckMnbAndUpdateMasternodeList - Masternode broadcast, vin: %s\n", mnb.vin.ToString()); + + if(mapSeenMasternodeBroadcast.count(mnb.GetHash())) { //seen + masternodeSync.AddedMasternodeList(mnb.GetHash()); + return true; + } + mapSeenMasternodeBroadcast.insert(make_pair(mnb.GetHash(), mnb)); + + LogPrint("masternode", "CMasternodeMan::CheckMnbAndUpdateMasternodeList - Masternode broadcast, vin: %s new\n", mnb.vin.ToString()); + + if(!mnb.CheckAndUpdate(nDos)){ + LogPrint("masternode", "CMasternodeMan::CheckMnbAndUpdateMasternodeList - Masternode broadcast, vin: %s CheckAndUpdate failed\n", mnb.vin.ToString()); + return false; + } + + // make sure the vout that was signed is related to the transaction that spawned the Masternode + // - this is expensive, so it's only done once per Masternode + if(!darkSendSigner.IsVinAssociatedWithPubkey(mnb.vin, mnb.pubkey)) { + LogPrintf("CMasternodeMan::CheckMnbAndUpdateMasternodeList - Got mismatched pubkey and vin\n"); + nDos = 33; + return false; + } + + // make sure it's still unspent + // - this is checked later by .check() in many places and by ThreadCheckDarkSendPool() + if(mnb.CheckInputsAndAdd(nDos)) { + masternodeSync.AddedMasternodeList(mnb.GetHash()); + } else { + LogPrintf("CMasternodeMan::CheckMnbAndUpdateMasternodeList - Rejected Masternode entry %s\n", mnb.addr.ToString()); + return false; + } + + return true; +} \ No newline at end of file diff --git a/src/masternodeman.h b/src/masternodeman.h index 033f197c9200..b743af1c1f1d 100644 --- a/src/masternodeman.h +++ b/src/masternodeman.h @@ -141,6 +141,11 @@ class CMasternodeMan void Remove(CTxIn vin); + /// Update masternode list and maps using provided CMasternodeBroadcast + void UpdateMasternodeList(CMasternodeBroadcast mnb); + /// Perform complete check and only then update list and maps + bool CheckMnbAndUpdateMasternodeList(CMasternodeBroadcast mnb, int& nDos); + }; #endif diff --git a/src/net.cpp b/src/net.cpp index 3f39f399c5d9..be7ba92a92bc 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1050,10 +1050,14 @@ void ThreadMapPort() #ifndef UPNPDISCOVER_SUCCESS /* miniupnpc 1.5 */ devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0); -#else +#elif MINIUPNPC_API_VERSION < 14 /* miniupnpc 1.6 */ int error = 0; devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error); +#else + /* miniupnpc 1.9.20150730 */ + int error = 0; + devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error); #endif struct UPNPUrls urls; diff --git a/src/net.h b/src/net.h index 0ff51d922c3b..3080fae4d571 100644 --- a/src/net.h +++ b/src/net.h @@ -258,6 +258,11 @@ class CNode // b) the peer may tell us in their version message that we should not relay tx invs // until they have initialized their bloom filter. bool fRelayTxes; + // Should be 'true' only if we connected to this node to actually mix funds. + // In this case node will be released automatically via CMasternodeMan::ProcessMasternodeConnections(). + // Connecting to verify connectability/status or connecting for sending/relaying single message + // (even if it's relative to mixing e.g. for blinding) should NOT set this to 'true'. + // For such cases node should be released manually (preferably right after corresponding code). bool fDarkSendMaster; CSemaphoreGrant grantOutbound; CCriticalSection cs_filter; diff --git a/src/netbase.cpp b/src/netbase.cpp index 5436d2dca0a0..cb657c9005eb 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -827,17 +827,20 @@ enum Network CNetAddr::GetNetwork() const return NET_IPV6; } -std::string CNetAddr::ToStringIP() const +std::string CNetAddr::ToStringIP(bool fUseGetnameinfo) const { if (IsTor()) return EncodeBase32(&ip[6], 10) + ".onion"; - CService serv(*this, 0); - struct sockaddr_storage sockaddr; - socklen_t socklen = sizeof(sockaddr); - if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) { - char name[1025] = ""; - if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), NULL, 0, NI_NUMERICHOST)) - return std::string(name); + if (fUseGetnameinfo) + { + CService serv(*this, 0); + struct sockaddr_storage sockaddr; + socklen_t socklen = sizeof(sockaddr); + if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) { + char name[1025] = ""; + if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), NULL, 0, NI_NUMERICHOST)) + return std::string(name); + } } if (IsIPv4()) return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); @@ -1174,18 +1177,18 @@ std::string CService::ToStringPort() const return strprintf("%u", port); } -std::string CService::ToStringIPPort() const +std::string CService::ToStringIPPort(bool fUseGetnameinfo) const { if (IsIPv4() || IsTor()) { - return ToStringIP() + ":" + ToStringPort(); + return ToStringIP(fUseGetnameinfo) + ":" + ToStringPort(); } else { - return "[" + ToStringIP() + "]:" + ToStringPort(); + return "[" + ToStringIP(fUseGetnameinfo) + "]:" + ToStringPort(); } } -std::string CService::ToString() const +std::string CService::ToString(bool fUseGetnameinfo) const { - return ToStringIPPort(); + return ToStringIPPort(fUseGetnameinfo); } void CService::SetPort(unsigned short portIn) diff --git a/src/netbase.h b/src/netbase.h index 2a2f150c073a..065df799b36c 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -80,7 +80,7 @@ class CNetAddr bool IsMulticast() const; enum Network GetNetwork() const; std::string ToString() const; - std::string ToStringIP() const; + std::string ToStringIP(bool fUseGetnameinfo = true) const; unsigned int GetByte(int n) const; uint64_t GetHash() const; bool GetInAddr(struct in_addr* pipv4Addr) const; @@ -151,9 +151,9 @@ class CService : public CNetAddr friend bool operator!=(const CService& a, const CService& b); friend bool operator<(const CService& a, const CService& b); std::vector GetKey() const; - std::string ToString() const; + std::string ToString(bool fUseGetnameinfo = true) const; std::string ToStringPort() const; - std::string ToStringIPPort() const; + std::string ToStringIPPort(bool fUseGetnameinfo = true) const; CService(const struct in6_addr& ipv6Addr, unsigned short port); CService(const struct sockaddr_in6& addr); diff --git a/src/qt/res/images/splash.png b/src/qt/res/images/splash.png index c81fd7794ada..79451d9e8e78 100644 Binary files a/src/qt/res/images/splash.png and b/src/qt/res/images/splash.png differ diff --git a/src/rpcmasternode.cpp b/src/rpcmasternode.cpp index d59abb77416d..348e4105f77e 100644 --- a/src/rpcmasternode.cpp +++ b/src/rpcmasternode.cpp @@ -172,7 +172,9 @@ Value masternode(const Array& params, bool fHelp) CService addr = CService(strAddress); - if(ConnectNode((CAddress)addr, NULL, true)){ + CNode *pnode = ConnectNode((CAddress)addr, NULL, false); + if(pnode){ + pnode->Release(); return "successfully connected"; } else { throw runtime_error("error connecting\n"); @@ -304,11 +306,15 @@ Value masternode(const Array& params, bool fHelp) if(mne.getAlias() == alias) { found = true; std::string errorMessage; + CMasternodeBroadcast mnb; - bool result = activeMasternode.Register(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), errorMessage); + bool result = activeMasternode.CreateBroadcast(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), errorMessage, mnb); statusObj.push_back(Pair("result", result ? "successful" : "failed")); - if(!result) { + if(result) { + mnodeman.UpdateMasternodeList(mnb); + mnb.Relay(); + } else { statusObj.push_back(Pair("errorMessage", errorMessage)); } break; @@ -361,11 +367,12 @@ Value masternode(const Array& params, bool fHelp) CTxIn vin = CTxIn(uint256(mne.getTxHash()), uint32_t(atoi(mne.getOutputIndex().c_str()))); CMasternode *pmn = mnodeman.Find(vin); + CMasternodeBroadcast mnb; if(strCommand == "start-missing" && pmn) continue; if(strCommand == "start-disabled" && pmn && pmn->IsEnabled()) continue; - bool result = activeMasternode.Register(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), errorMessage); + bool result = activeMasternode.CreateBroadcast(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), errorMessage, mnb); Object statusObj; statusObj.push_back(Pair("alias", mne.getAlias())); @@ -373,6 +380,8 @@ Value masternode(const Array& params, bool fHelp) if(result) { successful++; + mnodeman.UpdateMasternodeList(mnb); + mnb.Relay(); } else { failed++; statusObj.push_back(Pair("errorMessage", errorMessage)); @@ -608,3 +617,275 @@ Value masternodelist(const Array& params, bool fHelp) return obj; } + +bool DecodeHexVecMnb(std::vector& vecMnb, std::string strHexMnb) { + + if (!IsHex(strHexMnb)) + return false; + + vector mnbData(ParseHex(strHexMnb)); + CDataStream ssData(mnbData, SER_NETWORK, PROTOCOL_VERSION); + try { + ssData >> vecMnb; + } + catch (const std::exception&) { + return false; + } + + return true; +} + +Value masternodebroadcast(const Array& params, bool fHelp) +{ + string strCommand; + if (params.size() >= 1) + strCommand = params[0].get_str(); + + if (fHelp || + (strCommand != "create-alias" && strCommand != "create-all" && strCommand != "decode" && strCommand != "relay")) + throw runtime_error( + "masternodebroadcast \"command\"... ( \"passphrase\" )\n" + "Set of commands to create and relay masternode broadcast messages\n" + "\nArguments:\n" + "1. \"command\" (string or set of strings, required) The command to execute\n" + "2. \"passphrase\" (string, optional) The wallet passphrase\n" + "\nAvailable commands:\n" + " create-alias - Create single remote masternode broadcast message by assigned alias configured in masternode.conf\n" + " create-all - Create remote masternode broadcast messages for all masternodes configured in masternode.conf\n" + " decode - Decode masternode broadcast message\n" + " relay - Relay masternode broadcast message to the network\n" + + HelpRequiringPassphrase()); + + if (strCommand == "create-alias") + { + // wait for reindex and/or import to finish + if (fImporting || fReindex) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Wait for reindex and/or import to finish"); + + if (params.size() < 2) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Command needs at least 2 parameters"); + + std::string alias = params[1].get_str(); + + if(pwalletMain->IsLocked()) { + SecureString strWalletPass; + strWalletPass.reserve(100); + + if (params.size() == 3){ + strWalletPass = params[2].get_str().c_str(); + } else { + throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Your wallet is locked, passphrase is required"); + } + + if(!pwalletMain->Unlock(strWalletPass)){ + throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "The wallet passphrase entered was incorrect"); + } + } + + bool found = false; + + Object statusObj; + std::vector vecMnb; + + statusObj.push_back(Pair("alias", alias)); + + BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) { + if(mne.getAlias() == alias) { + found = true; + std::string errorMessage; + CMasternodeBroadcast mnb; + + bool result = activeMasternode.CreateBroadcast(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), errorMessage, mnb, true); + + statusObj.push_back(Pair("result", result ? "successful" : "failed")); + if(result) { + vecMnb.push_back(mnb); + CDataStream ssVecMnb(SER_NETWORK, PROTOCOL_VERSION); + ssVecMnb << vecMnb; + statusObj.push_back(Pair("hex", HexStr(ssVecMnb.begin(), ssVecMnb.end()))); + } else { + statusObj.push_back(Pair("errorMessage", errorMessage)); + } + break; + } + } + + if(!found) { + statusObj.push_back(Pair("result", "not found")); + statusObj.push_back(Pair("errorMessage", "Could not find alias in config. Verify with list-conf.")); + } + + pwalletMain->Lock(); + return statusObj; + + } + + if (strCommand == "create-all") + { + // wait for reindex and/or import to finish + if (fImporting || fReindex) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Wait for reindex and/or import to finish"); + + if(pwalletMain->IsLocked()) { + SecureString strWalletPass; + strWalletPass.reserve(100); + + if (params.size() == 2){ + strWalletPass = params[1].get_str().c_str(); + } else { + throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Your wallet is locked, passphrase is required"); + } + + if(!pwalletMain->Unlock(strWalletPass)){ + throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "The wallet passphrase entered was incorrect"); + } + } + + std::vector mnEntries; + mnEntries = masternodeConfig.getEntries(); + + int successful = 0; + int failed = 0; + + Object resultsObj; + std::vector vecMnb; + + BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) { + std::string errorMessage; + + CTxIn vin = CTxIn(uint256(mne.getTxHash()), uint32_t(atoi(mne.getOutputIndex().c_str()))); + CMasternodeBroadcast mnb; + + bool result = activeMasternode.CreateBroadcast(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), errorMessage, mnb, true); + + Object statusObj; + statusObj.push_back(Pair("alias", mne.getAlias())); + statusObj.push_back(Pair("result", result ? "successful" : "failed")); + + if(result) { + successful++; + vecMnb.push_back(mnb); + } else { + failed++; + statusObj.push_back(Pair("errorMessage", errorMessage)); + } + + resultsObj.push_back(Pair("status", statusObj)); + } + pwalletMain->Lock(); + + CDataStream ssVecMnb(SER_NETWORK, PROTOCOL_VERSION); + ssVecMnb << vecMnb; + Object returnObj; + returnObj.push_back(Pair("overall", strprintf("Successfully created broadcast messages for %d masternodes, failed to create %d, total %d", successful, failed, successful + failed))); + returnObj.push_back(Pair("detail", resultsObj)); + returnObj.push_back(Pair("hex", HexStr(ssVecMnb.begin(), ssVecMnb.end()))); + + return returnObj; + } + + if (strCommand == "decode") + { + if (params.size() != 2) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'masternodebroadcast decode \"hexstring\"'"); + + int successful = 0; + int failed = 0; + + std::vector vecMnb; + Object returnObj; + + if (!DecodeHexVecMnb(vecMnb, params[1].get_str())) + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Masternode broadcast message decode failed"); + + BOOST_FOREACH(CMasternodeBroadcast& mnb, vecMnb) { + Object resultObj; + + if(mnb.VerifySignature()) { + successful++; + resultObj.push_back(Pair("vin", mnb.vin.ToString())); + resultObj.push_back(Pair("addr", mnb.addr.ToString())); + resultObj.push_back(Pair("pubkey", CBitcoinAddress(mnb.pubkey.GetID()).ToString())); + resultObj.push_back(Pair("pubkey2", CBitcoinAddress(mnb.pubkey2.GetID()).ToString())); + resultObj.push_back(Pair("vchSig", EncodeBase64(&mnb.sig[0], mnb.sig.size()))); + resultObj.push_back(Pair("sigTime", mnb.sigTime)); + resultObj.push_back(Pair("protocolVersion", mnb.protocolVersion)); + resultObj.push_back(Pair("nLastDsq", mnb.nLastDsq)); + + Object lastPingObj; + lastPingObj.push_back(Pair("vin", mnb.lastPing.vin.ToString())); + lastPingObj.push_back(Pair("blockHash", mnb.lastPing.blockHash.ToString())); + lastPingObj.push_back(Pair("sigTime", mnb.lastPing.sigTime)); + lastPingObj.push_back(Pair("vchSig", EncodeBase64(&mnb.lastPing.vchSig[0], mnb.lastPing.vchSig.size()))); + + resultObj.push_back(Pair("lastPing", lastPingObj)); + } else { + failed++; + resultObj.push_back(Pair("errorMessage", "Masternode broadcast signature verification failed")); + } + + returnObj.push_back(Pair(mnb.GetHash().ToString(), resultObj)); + } + + returnObj.push_back(Pair("overall", strprintf("Successfully decoded broadcast messages for %d masternodes, failed to decode %d, total %d", successful, failed, successful + failed))); + + return returnObj; + } + + if (strCommand == "relay") + { + if (params.size() < 2 || params.size() > 3) + throw JSONRPCError(RPC_INVALID_PARAMETER, "masternodebroadcast relay \"hexstring\" ( fast )\n" + "\nArguments:\n" + "1. \"hex\" (string, required) Broadcast messages hex string\n" + "2. fast (string, optional) If none, using safe method\n"); + + int successful = 0; + int failed = 0; + bool fSafe = params.size() == 2; + + std::vector vecMnb; + Object returnObj; + + if (!DecodeHexVecMnb(vecMnb, params[1].get_str())) + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Masternode broadcast message decode failed"); + + // verify all signatures first, bailout if any of them broken + BOOST_FOREACH(CMasternodeBroadcast& mnb, vecMnb) { + Object resultObj; + + resultObj.push_back(Pair("vin", mnb.vin.ToString())); + resultObj.push_back(Pair("addr", mnb.addr.ToString())); + + int nDos = 0; + bool fResult; + if (mnb.VerifySignature()) { + if (fSafe) { + fResult = mnodeman.CheckMnbAndUpdateMasternodeList(mnb, nDos); + } else { + mnodeman.UpdateMasternodeList(mnb); + mnb.Relay(); + fResult = true; + } + } else fResult = false; + + if(fResult) { + successful++; + mnodeman.UpdateMasternodeList(mnb); + mnb.Relay(); + resultObj.push_back(Pair(mnb.GetHash().ToString(), "successful")); + } else { + failed++; + resultObj.push_back(Pair("errorMessage", "Masternode broadcast signature verification failed")); + } + + returnObj.push_back(Pair(mnb.GetHash().ToString(), resultObj)); + } + + returnObj.push_back(Pair("overall", strprintf("Successfully relayed broadcast messages for %d masternodes, failed to relay %d, total %d", successful, failed, successful + failed))); + + return returnObj; + } + + return Value::null; +} diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index d5eb1efd3346..9df0f1fad338 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -311,6 +311,7 @@ static const CRPCCommand vRPCCommands[] = /* Dash features */ { "dash", "masternode", &masternode, true, true, false }, { "dash", "masternodelist", &masternodelist, true, true, false }, + { "dash", "masternodebroadcast", &masternodebroadcast, true, true, false }, { "dash", "mnbudget", &mnbudget, true, true, false }, { "dash", "mnbudgetvoteraw", &mnbudgetvoteraw, true, true, false }, { "dash", "mnfinalbudget", &mnfinalbudget, true, true, false }, diff --git a/src/rpcserver.h b/src/rpcserver.h index ff8d556173f6..228fd1875ed7 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -231,6 +231,7 @@ extern json_spirit::Value darksend(const json_spirit::Array& params, bool fHelp) extern json_spirit::Value spork(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value masternode(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value masternodelist(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value masternodebroadcast(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value mnbudget(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value mnbudgetvoteraw(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value mnfinalbudget(const json_spirit::Array& params, bool fHelp); diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp index 9a2bdbde1d8a..db3d653d1819 100644 --- a/src/test/Checkpoints_tests.cpp +++ b/src/test/Checkpoints_tests.cpp @@ -19,20 +19,20 @@ BOOST_AUTO_TEST_SUITE(Checkpoints_tests) BOOST_AUTO_TEST_CASE(sanity) { uint256 p88805 = uint256("0x00000000001392f1652e9bf45cd8bc79dc60fe935277cd11538565b4a94fa85f"); - uint256 p217752 = uint256("0x00000000000a7baeb2148272a7e14edf5af99a64af456c0afc23d15a0918b704"); + uint256 p107996 = uint256("0x00000000000a23840ac16115407488267aa3da2b9bc843e301185b7d17e4dc40"); BOOST_CHECK(Checkpoints::CheckBlock(88805, p88805)); - BOOST_CHECK(Checkpoints::CheckBlock(217752, p217752)); + BOOST_CHECK(Checkpoints::CheckBlock(107996, p107996)); // Wrong hashes at checkpoints should fail: - BOOST_CHECK(!Checkpoints::CheckBlock(88805, p217752)); - BOOST_CHECK(!Checkpoints::CheckBlock(217752, p88805)); + BOOST_CHECK(!Checkpoints::CheckBlock(88805, p107996)); + BOOST_CHECK(!Checkpoints::CheckBlock(107996, p88805)); // ... but any hash not at a checkpoint should succeed: - BOOST_CHECK(Checkpoints::CheckBlock(88805+1, p217752)); - BOOST_CHECK(Checkpoints::CheckBlock(217752+1, p88805)); + BOOST_CHECK(Checkpoints::CheckBlock(88805+1, p107996)); + BOOST_CHECK(Checkpoints::CheckBlock(107996+1, p88805)); - BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate() >= 217752); + BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate() >= 107996); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 5c15cc9c6980..6d0b1ac12715 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -85,7 +85,7 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize_with_tweak) BOOST_AUTO_TEST_CASE(bloom_create_insert_key) { - string strSecret = string("5Kg1gnAjaLfKiwhhPpGS3QfRg2m6awQvaj98JCZBZQ5SuS2F15C"); + string strSecret = string("7sQb6QHALg4XyHsJHsSNXnEHGhZfzTTUPJXJqaqK7CavQkiL9Ms"); CBitcoinSecret vchSecret; BOOST_CHECK(vchSecret.SetString(strSecret)); @@ -271,7 +271,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2) BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256("0x6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df21bea5f4e27e2")); BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 2); - BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007763ace63cddb23")); + BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23")); BOOST_CHECK(merkleBlock.vMatchedTxn[3].first == 3); BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); @@ -322,7 +322,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none) BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f")); BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1); - BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007763ace63cddb23")); + BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23")); BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 3); BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); diff --git a/src/test/data/alertTests.raw b/src/test/data/alertTests.raw index 01f50680b95a..f58df4f18b19 100644 Binary files a/src/test/data/alertTests.raw and b/src/test/data/alertTests.raw differ diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json index 6090421cb66f..c10c1d21bad8 100644 --- a/src/test/data/bitcoin-util-test.json +++ b/src/test/data/bitcoin-util-test.json @@ -1,60 +1,60 @@ [ - { "exec": "././bitcoin-tx", + { "exec": "././dash-tx", "args": ["-create"], "output_cmp": "blanktx.hex" }, - { "exec": "./bitcoin-tx", + { "exec": "./dash-tx", "args": ["-"], "input": "blanktx.hex", "output_cmp": "blanktx.hex" }, - { "exec": "./bitcoin-tx", + { "exec": "./dash-tx", "args": ["-", "delin=1"], "input": "tx394b54bb.hex", "output_cmp": "tt-delin1-out.hex" }, - { "exec": "./bitcoin-tx", + { "exec": "./dash-tx", "args": ["-", "delin=31"], "input": "tx394b54bb.hex", "return_code": 1 }, - { "exec": "./bitcoin-tx", + { "exec": "./dash-tx", "args": ["-", "delout=1"], "input": "tx394b54bb.hex", "output_cmp": "tt-delout1-out.hex" }, - { "exec": "./bitcoin-tx", + { "exec": "./dash-tx", "args": ["-", "delout=2"], "input": "tx394b54bb.hex", "return_code": 1 }, - { "exec": "./bitcoin-tx", + { "exec": "./dash-tx", "args": ["-", "locktime=317000"], "input": "tx394b54bb.hex", "output_cmp": "tt-locktime317000-out.hex" }, - { "exec": "./bitcoin-tx", + { "exec": "./dash-tx", "args": ["-create", "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", "in=bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c:18", "in=22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc:1", - "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o", - "outaddr=4:1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46"], + "outaddr=0.18:Xdak8YsJz8tm1iHFmycfTyKeUvHgfbdpyw", + "outaddr=4:XxppMBDQ6SiJrKcBrAy4WkkNdrxDBfzFdZ"], "output_cmp": "txcreate1.hex" }, - { "exec": "./bitcoin-tx", + { "exec": "./dash-tx", "args": ["-create", "outscript=0:"], "output_cmp": "txcreate2.hex" }, - { "exec": "./bitcoin-tx", + { "exec": "./dash-tx", "args": ["-create", "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0", - "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]", + "set=privatekeys:[\"7qYrzJZWqnyCWMYswFcqaRJypGdVceudXPSxmZKsngN7fyo7aAV\"]", "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\"}]", "sign=ALL", - "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"], + "outaddr=0.001:XijDvbYpPmznwgpWD3DkdYNfGmRP2KoVSk"], "output_cmp": "txcreatesign.hex" } ] diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 13ee05cfa697..e63018051dd2 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -511,10 +511,6 @@ ], ["Increase DERSIG test coverage"], - -["0 0x01 0x50", "HASH160 0x14 0xece424a6bb6ddf4db592c0faed60685047a361b1 EQUAL", "OP_RESERVED in P2SH should fail"], -["0 0x01 VER", "HASH160 0x14 0x0f4d7845db968f2a81b530b6f3c1d6246d4c7e01 EQUAL", "OP_VER in P2SH should fail"], - ["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Overly long signature is incorrectly encoded for DERSIG"], ["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Missing S is incorrectly encoded for DERSIG"], ["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "S with invalid S length is incorrectly encoded for DERSIG"], diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index c23cdb931d04..42e9edbd3730 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -137,9 +137,6 @@ ["'abcdefghijklmnopqrstuvwxyz'", "SIZE 26 EQUAL", "P2SH,STRICTENC"], ["42", "SIZE 1 EQUALVERIFY 42 EQUAL", "P2SH,STRICTENC", "SIZE does not consume argument"], -["-549755813887", "SIZE 5 EQUAL"], -["-549755813888", "SIZE 6 EQUAL"], -["-9223372036854775807", "SIZE 8 EQUAL"], ["2 -2 ADD", "0 EQUAL", "P2SH,STRICTENC"], ["2147483647 -2147483647 ADD", "0 EQUAL", "P2SH,STRICTENC"], @@ -698,53 +695,9 @@ ["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Non-integer R is correctly encoded"], ["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Non-integer S is correctly encoded"], ["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Zero-length R is correctly encoded"], -["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "Zero-length S is correctly encoded"], ["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "Zero-length S is correctly encoded for DERSIG"], ["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Negative S is correctly encoded"], -[ - "0x47 0x30440220003040725f724b0e2142fc44ac71f6e13161f6410aeb6dee477952ede3b6a6ca022041ff4940ee3d88116ad281d7cc556e1f2c9427d82290bd7974a25addbcd5bede01", - "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", - "", - "P2PK NOT with bad sig with too much R padding but no DERSIG" -], -[ - "0", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", - "", - "BIP66 example 4, without DERSIG" -], -[ - "0", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", - "DERSIG", - "BIP66 example 4, with DERSIG" -], -[ - "1", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", - "", - "BIP66 example 6, without DERSIG" -], -[ - "0 0 0x47 0x30440220afa76a8f60622f813b05711f051c6c3407e32d1b1b70b0576c1f01b54e4c05c702200d58e9df044fd1845cabfbeef6e624ba0401daf7d7e084736f9ff601c3783bf501", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", - "", - "BIP66 example 10, without DERSIG" -], -[ - "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", - "", - "BIP66 example 12, without DERSIG" -], -[ - "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", - "DERSIG", - "BIP66 example 12, with DERSIG" -], - ["Automatically generated test cases"], [ "0x47 0x3044022053205076a7bb13d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801", diff --git a/src/test/data/sighash.json b/src/test/data/sighash.json index 5954cef9acfb..d66a56ac35bd 100644 --- a/src/test/data/sighash.json +++ b/src/test/data/sighash.json @@ -413,7 +413,7 @@ ["6f62138301436f33a00b84a26a0457ccbfc0f82403288b9cbae39986b34357cb2ff9b889b302000000045253655335a7ff6701bac9960400000000086552ab656352635200000000", "6aac51", 0, 1444414211, "502a2435fd02898d2ff3ab08a3c19078414b32ec9b73d64a944834efc9dae10c"], ["9981143a040a88c2484ac3abe053849e72d04862120f424f373753161997dd40505dcb4783030000000700536365536565a2e10da3f4b1c1ad049d97b33f0ae0ea48c5d7c30cc8810e144ad93be97789706a5ead180100000003636a00ffffffffbdcbac84c4bcc87f03d0ad83fbe13b369d7e42ddb3aecf40870a37e814ad8bb5010000000963536a5100636a53abffffffff883609905a80e34202101544f69b58a0b4576fb7391e12a769f890eef90ffb72020000000651656352526affffffff04243660000000000004ab5352534a9ce001000000000863656363ab6a53652df19d030000000003ac65acedc51700000000000000000000", "ac6300acac", 2, 293672388, "7ba99b289c04718a7283f150d831175ed6303081e191a0608ea81f78926c5bdf"], ["a2bb630b01989bc5d643f2da4fb9b55c0cdf846ba06d1dbe372893024dbbe5b9b8a1900af802000000055265ac63aca7a68d2f04916c74010000000003abac007077f0040000000001007d4127010000000005ac516aac000f31e8030000000000571079c9", "65ab0051ac", 0, -1103627693, "92d53b4390262e6b288e8a32e0cfc36cd5adfdfabfe96c7bfd4a19d65e233761"], - ["49f7d0b6037bba276e910ad3cd74966c7b3bc197ffbcfefd6108d6587007047e97789835ea0300000008526a52006a650053ffffffff8d7b6c07cd10f4c4010eac7946f61aff7fb5f3920bdf3467e939e58a1d4100ab03000000076aac63ac535351ffffffff8f48c3ba2d52ad67fbcdc90d8778f3c8a3894e3c35b9730562d7176b81af23c80100000003ab5265ffffffff0301e3ef0300000000046a525353e899ac0500000000075153ab6a65abac259bea0400000000007b739972", "53516aacac6aac", 1, 955403557, "5d366a7f4346ae18aeb7c9fc4dab5af71173184aa20ed22fcb4ea8511ad25449"], + ["49f7d0b6037bba276e910ad3cd74966c7b3bc197ffbcfefd6108d6587006947e97789835ea0300000008526a52006a650053ffffffff8d7b6c07cd10f4c4010eac7946f61aff7fb5f3920bdf3467e939e58a1d4100ab03000000076aac63ac535351ffffffff8f48c3ba2d52ad67fbcdc90d8778f3c8a3894e3c35b9730562d7176b81af23c80100000003ab5265ffffffff0301e3ef0300000000046a525353e899ac0500000000075153ab6a65abac259bea0400000000007b739972", "53516aacac6aac", 1, 955403557, "5d366a7f4346ae18aeb7c9fc4dab5af71173184aa20ed22fcb4ea8511ad25449"], ["58a4fed801fbd8d92db9dfcb2e26b6ff10b120204243fee954d7dcb3b4b9b53380e7bb8fb60100000003006351ffffffff02a0795b050000000006536351ac6aac2718d00200000000075151acabac515354d21ba1", "005363515351", 0, -1322430665, "bbee941bbad950424bf40e3623457db47f60ed29deaa43c99dec702317cb3326"], ["32765a0b02e455793d9ce530e9f6a44bcbc612e893a875b5da61d822dc56d8245166c398b403000000085353abac6300006a6bdee2a78d0d0b6a5ea666eed70b9bfea99d1d612ba3878f615c4da10d4a521cba27155002000000035363abffffffff043cd42401000000000551656a53653685320100000000030000511881bc0500000000065165abab636a20169f010000000007acab656aac63acdb0706a8", "65ac53ab53", 0, 1936499176, "5c5a9c3a5de7dc7a82bc171c9d3505913b8bcc450bc8b2d11772c1a1d781210b"], ["17fad0d303da0d764fedf9f2887a91ea625331b28704940f41e39adf3903d8e75683ef6d46020000000151ffffffffff376eea4e880bcf0f03d33999104aafed2b3daf4907950bb06496af6b51720a020000000900636a63525253525196521684f3b08497bad2c660b00b43a6a517edc58217876eb5e478aa3b5fda0f29ee1bea00000000046aacab6affffffff03dde8e2050000000007ac5365ac51516a14772e000000000005630000abacbbb360010000000006ab5251ab656a50f180f0", "0053", 0, -1043701251, "a3bdf8771c8990971bff9b4e7d59b7829b067ed0b8d3ac1ec203429811384668"], diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index a7f12e31f591..10cdfde4785c 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -17,14 +17,14 @@ using namespace std; -static const string strSecret1 ("7qqrxbWBT6v8LTABNae6j9Je9wGagQy6qjjRU3ApBqUQ78HULDy"); -static const string strSecret2 ("7r41KxLVNTZA3bYj5FjiAC58GkTENKM6XV9MAxnzSmywcsswtjv"); -static const string strSecret1C ("XCafWPHo8D7VNrTWnFUkH1erzSXmexncn7cEzLaKGpwvyuTpyo6r"); -static const string strSecret2C ("XDWGSfF2DiCvvTV2hn3WfZsD6Wnn15yhPZDr2yFzYmYL5EC78XhR"); -static const CBitcoinAddress addr1 ("Xjn3e3Xy1TXnthGp4iAUh8no3wLPVcxZyk"); -static const CBitcoinAddress addr2 ("XcSKA3pffkLSZN5HjKF2bcpq4UXRkqXmi1"); -static const CBitcoinAddress addr1C("Xmgi9Tn6PyZKwPHWhGmMwAEam61T4wMDWz"); -static const CBitcoinAddress addr2C("Xta1praZQjyELweyMByXyiREw1ZRsjXzVp"); +static const string strSecret1 ("7qh6LYnLN2w2ntz2wwUhRUEgkQ2j8XB16FGw77ZRDZmC29bn7cD"); +static const string strSecret2 ("7rve4MxeWFQHGbSYH6J2yaaZd3MBUqoDEwN6ZAZ6ZHmhTT4r3hW"); +static const string strSecret1C ("XBuxZHH6TqXUuaSjbVTFR1DQSYecxCB9QA1Koyx5tTc3ddhqEnhm"); +static const string strSecret2C ("XHMkZqWcY6Zkoq1j42NBijD8z5N5FtNy2Wx7WyAfXX2HZgxry8cr"); +static const CBitcoinAddress addr1 ("Xywgfc872nn5CKtpATCoAjZCc4v96pJczy"); +static const CBitcoinAddress addr2 ("XpmouUj9KKJ99ZuU331ZS1KqsboeFnLGgK"); +static const CBitcoinAddress addr1C("XxV9h4Xmv6Pup8tVAQmH97K6grzvDwMG9F"); +static const CBitcoinAddress addr2C("Xn7ZrYdExuk79Dm7CJCw7sfUWi2qWJSbRy"); static const string strAddressBad("Xta1praZQjyELweyMByXyiREw1ZRsjXzVP"); diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp index 3de8c91044f4..9b0247c3ce88 100644 --- a/src/test/main_tests.cpp +++ b/src/test/main_tests.cpp @@ -16,11 +16,11 @@ BOOST_AUTO_TEST_CASE(subsidy_limit_test) for (int nHeight = 0; nHeight < 14000000; nHeight += 1000) { /* @TODO fix subsidity, add nBits */ CAmount nSubsidy = GetBlockValue(0, nHeight, 0); - BOOST_CHECK(nSubsidy <= 50 * COIN); + BOOST_CHECK(nSubsidy <= 25 * COIN); nSum += nSubsidy * 1000; BOOST_CHECK(MoneyRange(nSum)); } - BOOST_CHECK(nSum == 2099999997690000ULL); + BOOST_CHECK(nSum == 1350824726649000ULL); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 53c2e7b2619b..04d3b5957400 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -17,34 +17,34 @@ struct { unsigned char extranonce; unsigned int nonce; } blockinfo[] = { - {4, 0xa4a3e223}, {2, 0x15c32f9e}, {1, 0x0375b547}, {1, 0x7004a8a5}, - {2, 0xce440296}, {2, 0x52cfe198}, {1, 0x77a72cd0}, {2, 0xbb5d6f84}, - {2, 0x83f30c2c}, {1, 0x48a73d5b}, {1, 0xef7dcd01}, {2, 0x6809c6c4}, - {2, 0x0883ab3c}, {1, 0x087bbbe2}, {2, 0x2104a814}, {2, 0xdffb6daa}, - {1, 0xee8a0a08}, {2, 0xba4237c1}, {1, 0xa70349dc}, {1, 0x344722bb}, - {3, 0xd6294733}, {2, 0xec9f5c94}, {2, 0xca2fbc28}, {1, 0x6ba4f406}, - {2, 0x015d4532}, {1, 0x6e119b7c}, {2, 0x43e8f314}, {2, 0x27962f38}, - {2, 0xb571b51b}, {2, 0xb36bee23}, {2, 0xd17924a8}, {2, 0x6bc212d9}, - {1, 0x630d4948}, {2, 0x9a4c4ebb}, {2, 0x554be537}, {1, 0xd63ddfc7}, - {2, 0xa10acc11}, {1, 0x759a8363}, {2, 0xfb73090d}, {1, 0xe82c6a34}, - {1, 0xe33e92d7}, {3, 0x658ef5cb}, {2, 0xba32ff22}, {5, 0x0227a10c}, - {1, 0xa9a70155}, {5, 0xd096d809}, {1, 0x37176174}, {1, 0x830b8d0f}, - {1, 0xc6e3910e}, {2, 0x823f3ca8}, {1, 0x99850849}, {1, 0x7521fb81}, - {1, 0xaacaabab}, {1, 0xd645a2eb}, {5, 0x7aea1781}, {5, 0x9d6e4b78}, - {1, 0x4ce90fd8}, {1, 0xabdc832d}, {6, 0x4a34f32a}, {2, 0xf2524c1c}, - {2, 0x1bbeb08a}, {1, 0xad47f480}, {1, 0x9f026aeb}, {1, 0x15a95049}, - {2, 0xd1cb95b2}, {2, 0xf84bbda5}, {1, 0x0fa62cd1}, {1, 0xe05f9169}, - {1, 0x78d194a9}, {5, 0x3e38147b}, {5, 0x737ba0d4}, {1, 0x63378e10}, - {1, 0x6d5f91cf}, {2, 0x88612eb8}, {2, 0xe9639484}, {1, 0xb7fabc9d}, - {2, 0x19b01592}, {1, 0x5a90dd31}, {2, 0x5bd7e028}, {2, 0x94d00323}, - {1, 0xa9b9c01a}, {1, 0x3a40de61}, {1, 0x56e7eec7}, {5, 0x859f7ef6}, - {1, 0xfd8e5630}, {1, 0x2b0c9f7f}, {1, 0xba700e26}, {1, 0x7170a408}, - {1, 0x70de86a8}, {1, 0x74d64cd5}, {1, 0x49e738a1}, {2, 0x6910b602}, - {0, 0x643c565f}, {1, 0x54264b3f}, {2, 0x97ea6396}, {2, 0x55174459}, - {2, 0x03e8779a}, {1, 0x98f34d8f}, {1, 0xc07b2b07}, {1, 0xdfe29668}, - {1, 0x3141c7c1}, {1, 0xb3b595f4}, {1, 0x735abf08}, {5, 0x623bfbce}, - {2, 0xd351e722}, {1, 0xf4ca48c9}, {1, 0x5b19c670}, {1, 0xa164bf0e}, - {2, 0xbbbeb305}, {2, 0xfe1c810a}, + {0, 0x009c5477}, {0, 0x00a94582}, {0, 0x00af3d7f}, {0, 0x00d0b721}, + {0, 0x00d53e10}, {0, 0x00f52f0f}, {0, 0x00fb5876}, {0, 0x0117fb12}, + {0, 0x011f930b}, {0, 0x013365d2}, {0, 0x0151737e}, {0, 0x0152cdd0}, + {0, 0x01758d20}, {0, 0x0178d509}, {0, 0x0192103c}, {0, 0x01a3f1b8}, + {0, 0x01abc9c7}, {0, 0x01d2f50c}, {0, 0x01eebad1}, {0, 0x01ef3419}, + {0, 0x01f3f154}, {0, 0x01fa6245}, {0, 0x0224e780}, {0, 0x02281625}, + {0, 0x023a4d10}, {0, 0x0251d3cf}, {0, 0x02555277}, {0, 0x02648a41}, + {0, 0x0280795e}, {0, 0x02a3a585}, {0, 0x02ade34a}, {0, 0x02b02b02}, + {0, 0x02c9dc32}, {0, 0x02da9867}, {0, 0x02e4126e}, {0, 0x02e738c7}, + {0, 0x02f5c6a9}, {0, 0x0307bb0f}, {0, 0x0328ea58}, {0, 0x034fe819}, + {0, 0x036c6fcb}, {0, 0x039b8e11}, {0, 0x039fec90}, {0, 0x03a268ff}, + {0, 0x03d37583}, {0, 0x03d6a9a7}, {0, 0x03e7a013}, {0, 0x03f01ebe}, + {0, 0x0437104d}, {0, 0x043d0af7}, {0, 0x043d824d}, {0, 0x043f50fc}, + {0, 0x044def8c}, {0, 0x0452309a}, {0, 0x04538bd3}, {0, 0x0459286b}, + {0, 0x045bc734}, {0, 0x045c878a}, {0, 0x0485d3ba}, {0, 0x048a64e5}, + {0, 0x048d6ae1}, {0, 0x048dcfec}, {0, 0x049d2c79}, {0, 0x04ade791}, + {0, 0x04b75856}, {0, 0x04c1f89e}, {0, 0x04c2f731}, {0, 0x04ca0376}, + {0, 0x04ca102a}, {0, 0x04cbdfe5}, {0, 0x04cbe35a}, {0, 0x04ccfa95}, + {0, 0x04dcd6e4}, {0, 0x05066d8b}, {0, 0x05150274}, {0, 0x051dcfa0}, + {0, 0x052a4c40}, {0, 0x05310c4e}, {0, 0x05452f69}, {0, 0x05517592}, + {0, 0x05543eb8}, {0, 0x05549dc7}, {0, 0x05732695}, {0, 0x057b00d3}, + {0, 0x0584760d}, {0, 0x059ca419}, {0, 0x05b23b58}, {0, 0x05c69745}, + {0, 0x05e31a12}, {0, 0x05e932d5}, {0, 0x05ef8400}, {0, 0x05f0bdf6}, + {0, 0x05f93997}, {0, 0x05ff2978}, {0, 0x06030233}, {0, 0x0627d615}, + {0, 0x0644a441}, {0, 0x06518661}, {0, 0x06805ef2}, {0, 0x068c43dd}, + {0, 0x069cca16}, {0, 0x06acbf10}, {0, 0x06c2d607}, {0, 0x06d9ea08}, + {0, 0x0700d639}, {0, 0x07083d86}, {0, 0x071cc39d}, {0, 0x072c3cb8}, + {0, 0x07665a0f}, {0, 0x07741214}, }; // NOTE: These tests rely on CreateNewBlock doing its own self-validation! diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index aed6e3ac2150..2944c024fc7a 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -98,10 +98,10 @@ BOOST_AUTO_TEST_CASE(rpc_rawsign) "\"vout\":1,\"scriptPubKey\":\"a914b10c9df5f7edf436c697f02f1efdba4cf399615187\"," "\"redeemScript\":\"512103debedc17b3df2badbcdd86d5feb4562b86fe182e5998abd8bcd4f122c6155b1b21027e940bb73ab8732bfdf7f9216ecefca5b94d6df834e77e108f68e66f126044c052ae\"}]"; r = CallRPC(string("createrawtransaction ")+prevout+" "+ - "{\"3HqAe9LtNBjnsfM4CyYaWTnvCaUYT7v4oZ\":11}"); + "{\"7iYoULd4BAqRsRt1UbD5qqna88JvKRU3SL\":11}"); string notsigned = r.get_str(); - string privkey1 = "\"KzsXybp9jX64P5ekX1KUxRQ79Jht9uzW7LorgwE65i5rWACL6LQe\""; - string privkey2 = "\"Kyhdf5LuKTRx4ge69ybABsiUAWjVRK4XGxAKk2FQLp2HjGMy87Z4\""; + string privkey1 = "\"XEwTRsCX3CiWSQf8YmKMTeb84KyTbibkUv9mDTZHQ5MwuKG2ZzES\""; + string privkey2 = "\"XDmZ7LjGd94Q81eUBjb2h6uV5Y14s7fmeXWEGYabfBJP8RVpprBu\""; r = CallRPC(string("signrawtransaction ")+notsigned+" "+prevout+" "+"[]"); BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == false); r = CallRPC(string("signrawtransaction ")+notsigned+" "+prevout+" "+"["+privkey1+","+privkey2+"]"); diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 91da0c4420d5..6917092b41d6 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -88,10 +88,10 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) *********************************/ BOOST_CHECK_NO_THROW(CallRPC("setaccount " + setaccountDemoAddress.ToString() + " nullaccount")); /* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ is not owned by the test wallet. */ - BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ nullaccount"), runtime_error); + BOOST_CHECK_THROW(CallRPC("setaccount XnhQgp2Y11hPGWaCB7rdGF5xLxjf2kBZCb nullaccount"), runtime_error); BOOST_CHECK_THROW(CallRPC("setaccount"), runtime_error); /* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X (33 chars) is an illegal address (should be 34 chars) */ - BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X nullaccount"), runtime_error); + BOOST_CHECK_THROW(CallRPC("setaccount XnhQgp2Y11hPGWaCB7rdGF5xLxjf2kBZC nullaccount"), runtime_error); /********************************* * listunspent @@ -155,15 +155,15 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) BOOST_CHECK_NO_THROW(retValue = CallRPC("signmessage " + demoAddress.ToString() + " mymessage")); BOOST_CHECK_THROW(CallRPC("signmessage"), runtime_error); /* Should throw error because this address is not loaded in the wallet */ - BOOST_CHECK_THROW(CallRPC("signmessage 1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ mymessage"), runtime_error); + BOOST_CHECK_THROW(CallRPC("signmessage Xywgfc872nn5CKtpATCoAjZCc4v96pJczy mymessage"), runtime_error); /* missing arguments */ BOOST_CHECK_THROW(CallRPC("verifymessage " + demoAddress.ToString()), runtime_error); BOOST_CHECK_THROW(CallRPC("verifymessage " + demoAddress.ToString() + " " + retValue.get_str()), runtime_error); /* Illegal address */ - BOOST_CHECK_THROW(CallRPC("verifymessage 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X " + retValue.get_str() + " mymessage"), runtime_error); + BOOST_CHECK_THROW(CallRPC("verifymessage XnhQgp2Y11hPGWaCB7rdGF5xLxjf2kBZC " + retValue.get_str() + " mymessage"), runtime_error); /* wrong address */ - BOOST_CHECK(CallRPC("verifymessage 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ " + retValue.get_str() + " mymessage").get_bool() == false); + BOOST_CHECK(CallRPC("verifymessage XnhQgp2Y11hPGWaCB7rdGF5xLxjf2kBZCb " + retValue.get_str() + " mymessage").get_bool() == false); /* Correct address and signature but wrong message */ BOOST_CHECK(CallRPC("verifymessage " + demoAddress.ToString() + " " + retValue.get_str() + " wrongmessage").get_bool() == false); /* Correct address, message and signature*/ diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 519ce6c31940..4c50328c3b53 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -338,10 +338,12 @@ BOOST_AUTO_TEST_CASE(test_IsStandard) string reason; BOOST_CHECK(IsStandardTx(t, reason)); - t.vout[0].nValue = 501; // dust + // Dash minRelayTxFee is 10000, typical tx is dust below 5460 sat + t.vout[0].nValue = 5010; // dust BOOST_CHECK(!IsStandardTx(t, reason)); - t.vout[0].nValue = 601; // not dust + // Dash minRelayTxFee is 10000, typical tx is dust below 5460 sat + t.vout[0].nValue = 6010; // not dust BOOST_CHECK(IsStandardTx(t, reason)); t.vout[0].scriptPubKey = CScript() << OP_1; diff --git a/src/txmempool.h b/src/txmempool.h index bb6f7443d562..d5a4955f3887 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -17,7 +17,7 @@ class CAutoFile; inline double AllowFreeThreshold() { - return COIN * 576 / 250; + return COIN * 144 / 250; } inline bool AllowFree(double dPriority) diff --git a/src/wallet.h b/src/wallet.h index 069b50520e98..080f813a0290 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -43,7 +43,7 @@ static const CAmount DEFAULT_TRANSACTION_FEE = 0; //! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB static const CAmount nHighTransactionFeeWarning = 0.01 * COIN; //! -maxtxfee default -static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN; +static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.2 * COIN; // "smallest denom" + X * "denom tails" //! -maxtxfee will warn if called with a higher fee than this amount (in satoshis) static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWarning; //! Largest (in bytes) free transaction we're willing to create