aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcontrib/devtools/git-subtree-check.sh3
-rwxr-xr-xcontrib/devtools/optimize-pngs.py3
-rwxr-xr-xcontrib/devtools/security-check.py3
-rwxr-xr-xcontrib/devtools/test-security-check.py3
-rwxr-xr-xcontrib/gitian-build.sh4
-rwxr-xr-xcontrib/macdeploy/detached-sig-apply.sh4
-rwxr-xr-xcontrib/macdeploy/detached-sig-create.sh4
-rwxr-xr-xcontrib/macdeploy/extract-osx-sdk.sh4
-rw-r--r--contrib/qos/tc.sh4
-rwxr-xr-xcontrib/qt_translations.py3
-rwxr-xr-xcontrib/seeds/makeseeds.py3
-rw-r--r--contrib/spendfrom/setup.py3
-rwxr-xr-xcontrib/spendfrom/spendfrom.py3
-rw-r--r--contrib/testgen/base58.py3
-rwxr-xr-xcontrib/testgen/gen_base58_test_vectors.py3
-rwxr-xr-xcontrib/tidy_datadir.sh3
-rwxr-xr-xcontrib/verify-commits/gpg.sh4
-rwxr-xr-xcontrib/verify-commits/pre-push-hook.sh4
-rwxr-xr-xcontrib/verify-commits/verify-commits.sh4
-rwxr-xr-xcontrib/verifybinaries/verify.sh3
-rwxr-xr-xcontrib/zmq/zmq_sub.py3
-rw-r--r--doc/build-osx.md2
-rw-r--r--doc/gitian-building.md2
-rw-r--r--doc/translation_process.md2
-rwxr-xr-xqa/pull-tester/rpc-tests.py14
-rwxr-xr-xqa/rpc-tests/create_cache.py10
-rw-r--r--qa/rpc-tests/test_framework/blockstore.py3
-rwxr-xr-xqa/rpc-tests/wallet.py5
-rwxr-xr-xqa/rpc-tests/walletbackup.py7
-rwxr-xr-xshare/qt/extract_strings_qt.py3
-rw-r--r--src/Makefile.qttest.include6
-rw-r--r--src/init.cpp31
-rw-r--r--src/main.cpp8
-rw-r--r--src/net.cpp30
-rw-r--r--src/net.h17
-rw-r--r--src/primitives/transaction.cpp5
-rw-r--r--src/primitives/transaction.h7
-rw-r--r--src/qt/paymentrequest.proto2
-rwxr-xr-xsrc/qt/res/movies/makespinner.sh4
-rw-r--r--src/qt/rpcconsole.cpp229
-rw-r--r--src/qt/rpcconsole.h2
-rw-r--r--src/qt/test/rpcnestedtests.cpp93
-rw-r--r--src/qt/test/rpcnestedtests.h25
-rw-r--r--src/qt/test/test_main.cpp16
-rw-r--r--src/qt/transactiondesc.cpp1
-rw-r--r--src/test/DoS_tests.cpp8
-rw-r--r--src/test/net_tests.cpp4
-rw-r--r--src/test/test_bitcoin.cpp2
-rw-r--r--src/wallet/test/accounting_tests.cpp24
-rw-r--r--src/wallet/wallet.cpp35
-rw-r--r--src/wallet/wallet.h5
51 files changed, 524 insertions, 149 deletions
diff --git a/contrib/devtools/git-subtree-check.sh b/contrib/devtools/git-subtree-check.sh
index 1cb82fe682..2384d66cad 100755
--- a/contrib/devtools/git-subtree-check.sh
+++ b/contrib/devtools/git-subtree-check.sh
@@ -1,4 +1,7 @@
#!/bin/sh
+# Copyright (c) 2015 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
DIR="$1"
COMMIT="$2"
diff --git a/contrib/devtools/optimize-pngs.py b/contrib/devtools/optimize-pngs.py
index 799e0cc7d0..b7b8dc0082 100755
--- a/contrib/devtools/optimize-pngs.py
+++ b/contrib/devtools/optimize-pngs.py
@@ -1,4 +1,7 @@
#!/usr/bin/env python
+# Copyright (c) 2014-2015 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
Run this script every time you change one of the png files. Using pngcrush, it will optimize the png files, remove various color profiles, remove ancillary chunks (alla) and text chunks (text).
#pngcrush -brute -ow -rem gAMA -rem cHRM -rem iCCP -rem sRGB -rem alla -rem text
diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py
index c61d652641..b4b4b4603d 100755
--- a/contrib/devtools/security-check.py
+++ b/contrib/devtools/security-check.py
@@ -1,4 +1,7 @@
#!/usr/bin/env python
+# Copyright (c) 2015-2016 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
Perform basic ELF security checks on a series of executables.
Exit status will be 0 if successful, and the program will be silent.
diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py
index 324b7bcd85..c0f120392e 100755
--- a/contrib/devtools/test-security-check.py
+++ b/contrib/devtools/test-security-check.py
@@ -1,4 +1,7 @@
#!/usr/bin/env python2
+# Copyright (c) 2015-2016 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
Test script for security-check.py
'''
diff --git a/contrib/gitian-build.sh b/contrib/gitian-build.sh
index ee47d138f3..53c24e3a87 100755
--- a/contrib/gitian-build.sh
+++ b/contrib/gitian-build.sh
@@ -1,3 +1,7 @@
+# Copyright (c) 2016 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
# What to do
sign=false
verify=false
diff --git a/contrib/macdeploy/detached-sig-apply.sh b/contrib/macdeploy/detached-sig-apply.sh
index 781fe315ed..91674a92e6 100755
--- a/contrib/macdeploy/detached-sig-apply.sh
+++ b/contrib/macdeploy/detached-sig-apply.sh
@@ -1,4 +1,8 @@
#!/bin/sh
+# Copyright (c) 2014-2015 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
set -e
UNSIGNED="$1"
diff --git a/contrib/macdeploy/detached-sig-create.sh b/contrib/macdeploy/detached-sig-create.sh
index 89a2da32f7..5022ea88bc 100755
--- a/contrib/macdeploy/detached-sig-create.sh
+++ b/contrib/macdeploy/detached-sig-create.sh
@@ -1,4 +1,8 @@
#!/bin/sh
+# Copyright (c) 2014-2015 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
set -e
ROOTDIR=dist
diff --git a/contrib/macdeploy/extract-osx-sdk.sh b/contrib/macdeploy/extract-osx-sdk.sh
index 46d2d825d4..ff9fbd58df 100755
--- a/contrib/macdeploy/extract-osx-sdk.sh
+++ b/contrib/macdeploy/extract-osx-sdk.sh
@@ -1,4 +1,8 @@
#!/bin/bash
+# Copyright (c) 2016 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
set -e
INPUTFILE="Xcode_7.3.1.dmg"
diff --git a/contrib/qos/tc.sh b/contrib/qos/tc.sh
index f620604212..aaf5e1fa11 100644
--- a/contrib/qos/tc.sh
+++ b/contrib/qos/tc.sh
@@ -1,3 +1,7 @@
+# Copyright (c) 2013 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
#network interface on which to limit traffic
IF="eth0"
#limit of the network interface in question
diff --git a/contrib/qt_translations.py b/contrib/qt_translations.py
index fd8a8b7129..cfdeed41ab 100755
--- a/contrib/qt_translations.py
+++ b/contrib/qt_translations.py
@@ -1,4 +1,7 @@
#!/usr/bin/env python
+# Copyright (c) 2011 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
# Helpful little script that spits out a comma-separated list of
# language codes for Qt icons that should be included
diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py
index 4072405ef5..041f224f40 100755
--- a/contrib/seeds/makeseeds.py
+++ b/contrib/seeds/makeseeds.py
@@ -1,4 +1,7 @@
#!/usr/bin/env python
+# Copyright (c) 2013-2015 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
# Generate seeds.txt from Pieter's DNS seeder
#
diff --git a/contrib/spendfrom/setup.py b/contrib/spendfrom/setup.py
index 01b9768a5b..f80736752a 100644
--- a/contrib/spendfrom/setup.py
+++ b/contrib/spendfrom/setup.py
@@ -1,3 +1,6 @@
+# Copyright (c) 2013 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from distutils.core import setup
setup(name='btcspendfrom',
version='1.0',
diff --git a/contrib/spendfrom/spendfrom.py b/contrib/spendfrom/spendfrom.py
index 72ee0425eb..086b91b267 100755
--- a/contrib/spendfrom/spendfrom.py
+++ b/contrib/spendfrom/spendfrom.py
@@ -1,4 +1,7 @@
#!/usr/bin/env python
+# Copyright (c) 2013 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
# Use the raw transactions API to spend bitcoins received on particular addresses,
# and send any change back to that same address.
diff --git a/contrib/testgen/base58.py b/contrib/testgen/base58.py
index b716495145..72b288b2dc 100644
--- a/contrib/testgen/base58.py
+++ b/contrib/testgen/base58.py
@@ -1,3 +1,6 @@
+# Copyright (c) 2012 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
Bitcoin base58 encoding and decoding.
diff --git a/contrib/testgen/gen_base58_test_vectors.py b/contrib/testgen/gen_base58_test_vectors.py
index 1813436953..8518774db3 100755
--- a/contrib/testgen/gen_base58_test_vectors.py
+++ b/contrib/testgen/gen_base58_test_vectors.py
@@ -1,4 +1,7 @@
#!/usr/bin/env python
+# Copyright (c) 2012 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
Generate valid and invalid base58 address and private key test vectors.
diff --git a/contrib/tidy_datadir.sh b/contrib/tidy_datadir.sh
index 5d6d826444..8960f8811d 100755
--- a/contrib/tidy_datadir.sh
+++ b/contrib/tidy_datadir.sh
@@ -1,4 +1,7 @@
#!/bin/bash
+# Copyright (c) 2013 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
if [ -d "$1" ]; then
cd "$1"
diff --git a/contrib/verify-commits/gpg.sh b/contrib/verify-commits/gpg.sh
index 375d711725..09ff237544 100755
--- a/contrib/verify-commits/gpg.sh
+++ b/contrib/verify-commits/gpg.sh
@@ -1,4 +1,8 @@
#!/bin/sh
+# Copyright (c) 2014-2016 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
INPUT=$(cat /dev/stdin)
VALID=false
REVSIG=false
diff --git a/contrib/verify-commits/pre-push-hook.sh b/contrib/verify-commits/pre-push-hook.sh
index c57222818a..c21febb9e9 100755
--- a/contrib/verify-commits/pre-push-hook.sh
+++ b/contrib/verify-commits/pre-push-hook.sh
@@ -1,4 +1,8 @@
#!/bin/bash
+# Copyright (c) 2014-2015 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
if ! [[ "$2" =~ ^(git@)?(www.)?github.com(:|/)bitcoin/bitcoin(.git)?$ ]]; then
exit 0
fi
diff --git a/contrib/verify-commits/verify-commits.sh b/contrib/verify-commits/verify-commits.sh
index 5219331e2e..cfe4f11a0b 100755
--- a/contrib/verify-commits/verify-commits.sh
+++ b/contrib/verify-commits/verify-commits.sh
@@ -1,4 +1,8 @@
#!/bin/sh
+# Copyright (c) 2014-2016 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
# Not technically POSIX-compliant due to use of "local", but almost every
# shell anyone uses today supports it, so its probably fine
diff --git a/contrib/verifybinaries/verify.sh b/contrib/verifybinaries/verify.sh
index e22b911743..e20770c96a 100755
--- a/contrib/verifybinaries/verify.sh
+++ b/contrib/verifybinaries/verify.sh
@@ -1,4 +1,7 @@
#!/bin/bash
+# Copyright (c) 2016 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
### This script attempts to download the signature file SHA256SUMS.asc from bitcoin.org
### It first checks if the signature passes, and then downloads the files specified in
diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py
index 6268123dd8..3dea5e3c14 100755
--- a/contrib/zmq/zmq_sub.py
+++ b/contrib/zmq/zmq_sub.py
@@ -1,4 +1,7 @@
#!/usr/bin/env python2
+# Copyright (c) 2014-2016 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
import array
import binascii
diff --git a/doc/build-osx.md b/doc/build-osx.md
index c9eb4225ab..bc90a30562 100644
--- a/doc/build-osx.md
+++ b/doc/build-osx.md
@@ -16,7 +16,7 @@ Then install [Homebrew](http://brew.sh).
Dependencies
----------------------
- brew install automake berkeley-db4 libtool boost --c++11 miniupnpc openssl pkg-config protobuf --c++11 qt5 libevent
+ brew install automake berkeley-db4 libtool boost --c++11 miniupnpc openssl pkg-config homebrew/versions/protobuf260 --c++11 qt5 libevent
NOTE: Building with Qt4 is still supported, however, could result in a broken UI. Building with Qt5 is recommended.
diff --git a/doc/gitian-building.md b/doc/gitian-building.md
index 938f92ff12..84dce3f082 100644
--- a/doc/gitian-building.md
+++ b/doc/gitian-building.md
@@ -337,7 +337,7 @@ Getting and building the inputs
--------------------------------
Follow the instructions in [doc/release-process.md](release-process.md#fetch-and-build-inputs-first-time-or-when-dependency-versions-change)
-in the bitcoin repository under 'Fetch and build inputs' to install sources which require
+in the bitcoin repository under 'Fetch and create inputs' to install sources which require
manual intervention. Also optionally follow the next step: 'Seed the Gitian sources cache
and offline git repositories' which will fetch the remaining files required for building
offline.
diff --git a/doc/translation_process.md b/doc/translation_process.md
index a443a16fe2..9e9ced2457 100644
--- a/doc/translation_process.md
+++ b/doc/translation_process.md
@@ -6,7 +6,7 @@ The Bitcoin-Core project has been designed to support multiple localisations. Th
### Helping to translate (using Transifex)
Transifex is setup to monitor the Github repo for updates, and when code containing new translations is found, Transifex will process any changes. It may take several hours after a pull-request has been merged, to appear in the Transifex web interface.
-Multiple language support is critical in assisting Bitcoin’s global adoption, and growth. One of Bitcoin’s greatest strengths is cross-boarder money transfers, any help making that easier is greatly appreciated.
+Multiple language support is critical in assisting Bitcoin’s global adoption, and growth. One of Bitcoin’s greatest strengths is cross-border money transfers, any help making that easier is greatly appreciated.
See the [Transifex Bitcoin project](https://www.transifex.com/projects/p/bitcoin/) to assist in translations. You should also join the translation mailing list for announcements - see details below.
diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py
index 771f6c7a0f..9e187b019b 100755
--- a/qa/pull-tester/rpc-tests.py
+++ b/qa/pull-tester/rpc-tests.py
@@ -251,21 +251,27 @@ class RPCTestHandler:
self.num_running += 1
t = self.test_list.pop(0)
port_seed = ["--portseed=%s" % len(self.test_list)]
+ log_stdout = tempfile.SpooledTemporaryFile(max_size=2**16)
+ log_stderr = tempfile.SpooledTemporaryFile(max_size=2**16)
self.jobs.append((t,
time.time(),
subprocess.Popen((RPC_TESTS_DIR + t).split() + self.flags + port_seed,
universal_newlines=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)))
+ stdout=log_stdout,
+ stderr=log_stderr),
+ log_stdout,
+ log_stderr))
if not self.jobs:
raise IndexError('pop from empty list')
while True:
# Return first proc that finishes
time.sleep(.5)
for j in self.jobs:
- (name, time0, proc) = j
+ (name, time0, proc, log_out, log_err) = j
if proc.poll() is not None:
- (stdout, stderr) = proc.communicate(timeout=3)
+ log_out.seek(0), log_err.seek(0)
+ [stdout, stderr] = [l.read().decode('utf-8') for l in (log_out, log_err)]
+ log_out.close(), log_err.close()
passed = stderr == "" and proc.returncode == 0
self.num_running -= 1
self.jobs.remove(j)
diff --git a/qa/rpc-tests/create_cache.py b/qa/rpc-tests/create_cache.py
index b6161e0917..1ace6310d0 100755
--- a/qa/rpc-tests/create_cache.py
+++ b/qa/rpc-tests/create_cache.py
@@ -12,9 +12,15 @@ from test_framework.test_framework import BitcoinTestFramework
class CreateCache(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+
+ # Test network and test nodes are not required:
+ self.num_nodes = 0
+ self.nodes = []
+
def setup_network(self):
- # Don't setup any test nodes
- self.options.noshutdown = True
+ pass
def run_test(self):
pass
diff --git a/qa/rpc-tests/test_framework/blockstore.py b/qa/rpc-tests/test_framework/blockstore.py
index 6120dd574b..1e2bbb277a 100644
--- a/qa/rpc-tests/test_framework/blockstore.py
+++ b/qa/rpc-tests/test_framework/blockstore.py
@@ -1,4 +1,7 @@
#!/usr/bin/env python3
+# Copyright (c) 2015-2016 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
# BlockStore: a helper class that keeps a map of blocks and implements
# helper functions for responding to getheaders and getdata,
# and for constructing a getheaders message
diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py
index 5d96e7a6e5..3420be1a2e 100755
--- a/qa/rpc-tests/wallet.py
+++ b/qa/rpc-tests/wallet.py
@@ -18,9 +18,10 @@ class WalletTest (BitcoinTestFramework):
super().__init__()
self.setup_clean_chain = True
self.num_nodes = 4
+ self.extra_args = [['-usehd={:d}'.format(i%2==0)] for i in range(4)]
def setup_network(self, split=False):
- self.nodes = start_nodes(3, self.options.tmpdir)
+ self.nodes = start_nodes(3, self.options.tmpdir, self.extra_args[:3])
connect_nodes_bi(self.nodes,0,1)
connect_nodes_bi(self.nodes,1,2)
connect_nodes_bi(self.nodes,0,2)
@@ -154,7 +155,7 @@ class WalletTest (BitcoinTestFramework):
txid2 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1)
sync_mempools(self.nodes)
- self.nodes.append(start_node(3, self.options.tmpdir))
+ self.nodes.append(start_node(3, self.options.tmpdir, self.extra_args[3]))
connect_nodes_bi(self.nodes, 0, 3)
sync_blocks(self.nodes)
diff --git a/qa/rpc-tests/walletbackup.py b/qa/rpc-tests/walletbackup.py
index b991d5c761..e12cb10a50 100755
--- a/qa/rpc-tests/walletbackup.py
+++ b/qa/rpc-tests/walletbackup.py
@@ -45,12 +45,12 @@ class WalletBackupTest(BitcoinTestFramework):
super().__init__()
self.setup_clean_chain = True
self.num_nodes = 4
+ # nodes 1, 2,3 are spenders, let's give them a keypool=100
+ self.extra_args = [["-keypool=100"], ["-keypool=100"], ["-keypool=100"], []]
# This mirrors how the network was setup in the bash test
def setup_network(self, split=False):
- # nodes 1, 2,3 are spenders, let's give them a keypool=100
- extra_args = [["-keypool=100"], ["-keypool=100"], ["-keypool=100"], []]
- self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args)
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args)
connect_nodes(self.nodes[0], 3)
connect_nodes(self.nodes[1], 3)
connect_nodes(self.nodes[2], 3)
@@ -79,6 +79,7 @@ class WalletBackupTest(BitcoinTestFramework):
# Must sync mempools before mining.
sync_mempools(self.nodes)
self.nodes[3].generate(1)
+ sync_blocks(self.nodes)
# As above, this mirrors the original bash test.
def start_three(self):
diff --git a/share/qt/extract_strings_qt.py b/share/qt/extract_strings_qt.py
index 9624abf1fc..92e0df259e 100755
--- a/share/qt/extract_strings_qt.py
+++ b/share/qt/extract_strings_qt.py
@@ -1,4 +1,7 @@
#!/usr/bin/env python
+# Copyright (c) 2012-2016 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
Extract _("...") strings for translation and convert to Qt stringdefs so that
they can be picked up by Qt linguist.
diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include
index 813a343ffa..0a7efb5d5b 100644
--- a/src/Makefile.qttest.include
+++ b/src/Makefile.qttest.include
@@ -1,13 +1,16 @@
bin_PROGRAMS += qt/test/test_bitcoin-qt
TESTS += qt/test/test_bitcoin-qt
-TEST_QT_MOC_CPP = qt/test/moc_uritests.cpp
+TEST_QT_MOC_CPP = \
+ qt/test/moc_rpcnestedtests.cpp \
+ qt/test/moc_uritests.cpp
if ENABLE_WALLET
TEST_QT_MOC_CPP += qt/test/moc_paymentservertests.cpp
endif
TEST_QT_H = \
+ qt/test/rpcnestedtests.h \
qt/test/uritests.h \
qt/test/paymentrequestdata.h \
qt/test/paymentservertests.h
@@ -16,6 +19,7 @@ qt_test_test_bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_
$(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS)
qt_test_test_bitcoin_qt_SOURCES = \
+ qt/test/rpcnestedtests.cpp \
qt/test/test_main.cpp \
qt/test/uritests.cpp \
$(TEST_QT_H)
diff --git a/src/init.cpp b/src/init.cpp
index 8d1e330a05..a15f1f1a4f 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -759,10 +759,7 @@ void InitParameterInteraction()
if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) {
if (SoftSetBoolArg("-whitelistrelay", false))
LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistrelay=0\n", __func__);
-#ifdef ENABLE_WALLET
- if (SoftSetBoolArg("-walletbroadcast", false))
- LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__);
-#endif
+ // walletbroadcast is disabled in CWallet::ParameterInteraction()
}
// Forcing relay from whitelisted hosts implies we will accept relays from them in the first place.
@@ -821,12 +818,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
return InitError("Initializing networking failed");
#ifndef WIN32
- if (GetBoolArg("-sysperms", false)) {
-#ifdef ENABLE_WALLET
- if (!GetBoolArg("-disablewallet", false))
- return InitError("-sysperms is not allowed in combination with enabled wallet functionality");
-#endif
- } else {
+ if (!GetBoolArg("-sysperms", false)) {
umask(077);
}
@@ -854,15 +846,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// also see: InitParameterInteraction()
- // if using block pruning, then disable txindex
+ // if using block pruning, then disallow txindex
if (GetArg("-prune", 0)) {
if (GetBoolArg("-txindex", DEFAULT_TXINDEX))
return InitError(_("Prune mode is incompatible with -txindex."));
-#ifdef ENABLE_WALLET
- if (GetBoolArg("-rescan", false)) {
- return InitError(_("Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again."));
- }
-#endif
}
// Make sure enough file descriptors are available
@@ -978,7 +965,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
nBytesPerSigOp = GetArg("-bytespersigop", nBytesPerSigOp);
#ifdef ENABLE_WALLET
- if (!CWallet::ParameterInteraction())
+ if (!fDisableWallet && !CWallet::ParameterInteraction())
return false;
#endif // ENABLE_WALLET
@@ -1116,7 +1103,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// ********************************************************* Step 6: network initialization
assert(!g_connman);
- g_connman = std::unique_ptr<CConnman>(new CConnman());
+ g_connman = std::unique_ptr<CConnman>(new CConnman(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max())));
CConnman& connman = *g_connman;
RegisterNodeSignals(GetNodeSignals());
@@ -1249,8 +1236,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
RegisterValidationInterface(pzmqNotificationInterface);
}
#endif
+ uint64_t nMaxOutboundLimit = 0; //unlimited unless -maxuploadtarget is set
+ uint64_t nMaxOutboundTimeframe = MAX_UPLOAD_TIMEFRAME;
+
if (mapArgs.count("-maxuploadtarget")) {
- connman.SetMaxOutboundTarget(GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET)*1024*1024);
+ nMaxOutboundLimit = GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET)*1024*1024;
}
// ********************************************************* Step 7: load block chain
@@ -1533,6 +1523,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
connOptions.nSendBufferMaxSize = 1000*GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER);
connOptions.nReceiveFloodSize = 1000*GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER);
+ connOptions.nMaxOutboundTimeframe = nMaxOutboundTimeframe;
+ connOptions.nMaxOutboundLimit = nMaxOutboundLimit;
+
if(!connman.Start(threadGroup, scheduler, strNodeError, connOptions))
return InitError(strNodeError);
diff --git a/src/main.cpp b/src/main.cpp
index 593897f516..e5ddd31d0c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -113,6 +113,8 @@ CScript COINBASE_FLAGS;
const string strMessageMagic = "Bitcoin Signed Message:\n";
+static const uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL; // SHA256("main address relay")[0:8]
+
// Internal stuff
namespace {
@@ -2062,7 +2064,7 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin
// Open history file to read
CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
if (filein.IsNull())
- return error("%s: OpenBlockFile failed", __func__);
+ return error("%s: OpenUndoFile failed", __func__);
// Read block
uint256 hashChecksum;
@@ -4739,11 +4741,9 @@ static void RelayAddress(const CAddress& addr, bool fReachable, CConnman& connma
// Relay to a limited number of other nodes
// Use deterministic randomness to send to the same nodes for 24 hours
// at a time so the addrKnowns of the chosen nodes prevent repeats
- static const uint64_t salt0 = GetRand(std::numeric_limits<uint64_t>::max());
- static const uint64_t salt1 = GetRand(std::numeric_limits<uint64_t>::max());
uint64_t hashAddr = addr.GetHash();
std::multimap<uint64_t, CNode*> mapMix;
- const CSipHasher hasher = CSipHasher(salt0, salt1).Write(hashAddr << 32).Write((GetTime() + hashAddr) / (24*60*60));
+ const CSipHasher hasher = connman.GetDeterministicRandomizer(RANDOMIZER_ID_ADDRESS_RELAY).Write(hashAddr << 32).Write((GetTime() + hashAddr) / (24*60*60));
auto sortfunc = [&mapMix, &hasher](CNode* pnode) {
if (pnode->nVersion >= CADDR_TIME_VERSION) {
diff --git a/src/net.cpp b/src/net.cpp
index cc9728b853..cce06f2d64 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -63,6 +63,7 @@
const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
+static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL; // SHA256("netgroup")[0:8]
//
// Global state variables
//
@@ -387,7 +388,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
addrman.Attempt(addrConnect, fCountFailure);
// Add node
- CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addrConnect, pszDest ? pszDest : "", false);
+ CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), pszDest ? pszDest : "", false);
GetNodeSignals().InitializeNode(pnode->GetId(), pnode);
pnode->AddRef();
@@ -448,7 +449,7 @@ void CNode::PushVersion()
{
int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService(), addr.nServices));
- CAddress addrMe = GetLocalAddress(&addr, nLocalServices);
+ CAddress addrMe = CAddress(CService(), nLocalServices);
if (fLogIPs)
LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nMyStartingHeight, addrMe.ToString(), addrYou.ToString(), id);
else
@@ -1022,7 +1023,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
}
}
- CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addr, "", true);
+ CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), "", true);
GetNodeSignals().InitializeNode(pnode->GetId(), pnode);
pnode->AddRef();
pnode->fWhitelisted = whitelisted;
@@ -2023,7 +2024,7 @@ void Discover(boost::thread_group& threadGroup)
#endif
}
-CConnman::CConnman()
+CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In) : nSeed0(nSeed0In), nSeed1(nSeed1In)
{
setBannedIsDirty = false;
fAddressesInitialized = false;
@@ -2046,9 +2047,7 @@ bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, st
{
nTotalBytesRecv = 0;
nTotalBytesSent = 0;
- nMaxOutboundLimit = 0;
nMaxOutboundTotalBytesSentInCycle = 0;
- nMaxOutboundTimeframe = 60*60*24; //1 day
nMaxOutboundCycleStartTime = 0;
nRelevantServices = connOptions.nRelevantServices;
@@ -2060,6 +2059,9 @@ bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, st
nSendBufferMaxSize = connOptions.nSendBufferMaxSize;
nReceiveFloodSize = connOptions.nSendBufferMaxSize;
+ nMaxOutboundLimit = connOptions.nMaxOutboundLimit;
+ nMaxOutboundTimeframe = connOptions.nMaxOutboundTimeframe;
+
SetBestHeight(connOptions.nBestHeight);
clientInterface = connOptions.uiInterface;
@@ -2108,7 +2110,7 @@ bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, st
if (pnodeLocalHost == NULL) {
CNetAddr local;
LookupHost("127.0.0.1", local, false);
- pnodeLocalHost = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices));
+ pnodeLocalHost = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices), 0);
GetNodeSignals().InitializeNode(pnodeLocalHost->GetId(), pnodeLocalHost);
}
@@ -2498,10 +2500,10 @@ void CNode::Fuzz(int nChance)
unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
unsigned int CConnman::GetSendBufferSize() const{ return nSendBufferMaxSize; }
-CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) :
+CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, const std::string& addrNameIn, bool fInboundIn) :
ssSend(SER_NETWORK, INIT_PROTO_VERSION),
addr(addrIn),
- nKeyedNetGroup(CalculateKeyedNetGroup(addrIn)),
+ nKeyedNetGroup(nKeyedNetGroupIn),
addrKnown(5000, 0.001),
filterInventoryKnown(50000, 0.000001)
{
@@ -2694,12 +2696,14 @@ int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
}
-/* static */ uint64_t CNode::CalculateKeyedNetGroup(const CAddress& ad)
+CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id)
{
- static const uint64_t k0 = GetRand(std::numeric_limits<uint64_t>::max());
- static const uint64_t k1 = GetRand(std::numeric_limits<uint64_t>::max());
+ return CSipHasher(nSeed0, nSeed1).Write(id);
+}
+uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& ad)
+{
std::vector<unsigned char> vchNetGroup(ad.GetGroup());
- return CSipHasher(k0, k1).Write(&vchNetGroup[0], vchNetGroup.size()).Finalize();
+ return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(&vchNetGroup[0], vchNetGroup.size()).Finalize();
}
diff --git a/src/net.h b/src/net.h
index a48ee02c44..0173854669 100644
--- a/src/net.h
+++ b/src/net.h
@@ -11,6 +11,7 @@
#include "amount.h"
#include "bloom.h"
#include "compat.h"
+#include "hash.h"
#include "limitedmap.h"
#include "netaddress.h"
#include "protocol.h"
@@ -72,6 +73,8 @@ static const size_t SETASKFOR_MAX_SZ = 2 * MAX_INV_SZ;
static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
/** The default for -maxuploadtarget. 0 = Unlimited */
static const uint64_t DEFAULT_MAX_UPLOAD_TARGET = 0;
+/** The default timeframe for -maxuploadtarget. 1 day. */
+static const uint64_t MAX_UPLOAD_TIMEFRAME = 60 * 60 * 24;
/** Default for blocks only*/
static const bool DEFAULT_BLOCKSONLY = false;
@@ -120,8 +123,10 @@ public:
CClientUIInterface* uiInterface = nullptr;
unsigned int nSendBufferMaxSize = 0;
unsigned int nReceiveFloodSize = 0;
+ uint64_t nMaxOutboundTimeframe = 0;
+ uint64_t nMaxOutboundLimit = 0;
};
- CConnman();
+ CConnman(uint64_t seed0, uint64_t seed1);
~CConnman();
bool Start(boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError, Options options);
void Stop();
@@ -294,6 +299,8 @@ public:
void SetBestHeight(int height);
int GetBestHeight() const;
+ /** Get a unique deterministic randomizer. */
+ CSipHasher GetDeterministicRandomizer(uint64_t id);
private:
struct ListenSocket {
@@ -311,6 +318,8 @@ private:
void ThreadSocketHandler();
void ThreadDNSAddressSeed();
+ uint64_t CalculateKeyedNetGroup(const CAddress& ad);
+
CNode* FindNode(const CNetAddr& ip);
CNode* FindNode(const CSubNet& subNet);
CNode* FindNode(const std::string& addrName);
@@ -388,6 +397,9 @@ private:
int nMaxFeeler;
std::atomic<int> nBestHeight;
CClientUIInterface* clientInterface;
+
+ /** SipHasher seeds for deterministic randomness */
+ const uint64_t nSeed0, nSeed1;
};
extern std::unique_ptr<CConnman> g_connman;
void Discover(boost::thread_group& threadGroup);
@@ -656,14 +668,13 @@ public:
CAmount lastSentFeeFilter;
int64_t nextSendTimeFeeFilter;
- CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, const std::string &addrNameIn = "", bool fInboundIn = false);
+ CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, const std::string &addrNameIn = "", bool fInboundIn = false);
~CNode();
private:
CNode(const CNode&);
void operator=(const CNode&);
- static uint64_t CalculateKeyedNetGroup(const CAddress& ad);
uint64_t nLocalHostNonce;
ServiceFlags nLocalServices;
diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp
index 2fdc59ea07..4afbe99fd3 100644
--- a/src/primitives/transaction.cpp
+++ b/src/primitives/transaction.cpp
@@ -131,6 +131,11 @@ unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const
return nTxSize;
}
+unsigned int CTransaction::GetTotalSize() const
+{
+ return ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
+}
+
std::string CTransaction::ToString() const
{
std::string str;
diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h
index 5689d15bf7..16c2e5c454 100644
--- a/src/primitives/transaction.h
+++ b/src/primitives/transaction.h
@@ -415,6 +415,13 @@ public:
// Compute modified tx size for priority calculation (optionally given tx size)
unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const;
+
+ /**
+ * Get the total transaction size in bytes, including witness data.
+ * "Total Size" defined in BIP141 and BIP144.
+ * @return Total transaction size in bytes
+ */
+ unsigned int GetTotalSize() const;
bool IsCoinBase() const
{
diff --git a/src/qt/paymentrequest.proto b/src/qt/paymentrequest.proto
index b2281c4c7b..d2721a34bd 100644
--- a/src/qt/paymentrequest.proto
+++ b/src/qt/paymentrequest.proto
@@ -6,6 +6,8 @@
// https://en.bitcoin.it/wiki/Payment_Request
//
+syntax = "proto2";
+
package payments;
option java_package = "org.bitcoin.protocols.payments";
option java_outer_classname = "Protos";
diff --git a/src/qt/res/movies/makespinner.sh b/src/qt/res/movies/makespinner.sh
index a4c2fddbbf..d0deb1238c 100755
--- a/src/qt/res/movies/makespinner.sh
+++ b/src/qt/res/movies/makespinner.sh
@@ -1,3 +1,7 @@
+# Copyright (c) 2014-2015 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
FRAMEDIR=$(dirname $0)
for i in {0..35}
do
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index f35f401d06..a316b951c4 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -113,9 +113,11 @@ public:
#include "rpcconsole.moc"
/**
- * Split shell command line into a list of arguments. Aims to emulate \c bash and friends.
+ * Split shell command line into a list of arguments and execute the command(s).
+ * Aims to emulate \c bash and friends.
*
- * - Arguments are delimited with whitespace
+ * - Command nesting is possible with brackets [example: validateaddress(getnewaddress())]
+ * - Arguments are delimited with whitespace or comma
* - Extra whitespace at the beginning and end and between arguments will be ignored
* - Text can be "double" or 'single' quoted
* - The backslash \c \ is used as escape character
@@ -123,11 +125,15 @@ public:
* - Within double quotes, only escape \c " and backslashes before a \c " or another backslash
* - Within single quotes, no escaping is possible and no special interpretation takes place
*
- * @param[out] args Parsed arguments will be appended to this list
+ * @param[out] result stringified Result from the executed command(chain)
* @param[in] strCommand Command line to split
*/
-bool parseCommandLine(std::vector<std::string> &args, const std::string &strCommand)
+
+bool RPCConsole::RPCExecuteCommandLine(std::string &strResult, const std::string &strCommand)
{
+ std::vector< std::vector<std::string> > stack;
+ stack.push_back(std::vector<std::string>());
+
enum CmdParseState
{
STATE_EATING_SPACES,
@@ -135,95 +141,180 @@ bool parseCommandLine(std::vector<std::string> &args, const std::string &strComm
STATE_SINGLEQUOTED,
STATE_DOUBLEQUOTED,
STATE_ESCAPE_OUTER,
- STATE_ESCAPE_DOUBLEQUOTED
+ STATE_ESCAPE_DOUBLEQUOTED,
+ STATE_COMMAND_EXECUTED,
+ STATE_COMMAND_EXECUTED_INNER
} state = STATE_EATING_SPACES;
std::string curarg;
- Q_FOREACH(char ch, strCommand)
+ UniValue lastResult;
+
+ std::string strCommandTerminated = strCommand;
+ if (strCommandTerminated.back() != '\n')
+ strCommandTerminated += "\n";
+ for(char ch: strCommandTerminated)
{
switch(state)
{
- case STATE_ARGUMENT: // In or after argument
- case STATE_EATING_SPACES: // Handle runs of whitespace
- switch(ch)
+ case STATE_COMMAND_EXECUTED_INNER:
+ case STATE_COMMAND_EXECUTED:
{
- case '"': state = STATE_DOUBLEQUOTED; break;
- case '\'': state = STATE_SINGLEQUOTED; break;
- case '\\': state = STATE_ESCAPE_OUTER; break;
- case ' ': case '\n': case '\t':
- if(state == STATE_ARGUMENT) // Space ends argument
+ bool breakParsing = true;
+ switch(ch)
{
- args.push_back(curarg);
- curarg.clear();
+ case '[': curarg.clear(); state = STATE_COMMAND_EXECUTED_INNER; break;
+ default:
+ if (state == STATE_COMMAND_EXECUTED_INNER)
+ {
+ if (ch != ']')
+ {
+ // append char to the current argument (which is also used for the query command)
+ curarg += ch;
+ break;
+ }
+ if (curarg.size())
+ {
+ // if we have a value query, query arrays with index and objects with a string key
+ UniValue subelement;
+ if (lastResult.isArray())
+ {
+ for(char argch: curarg)
+ if (!std::isdigit(argch))
+ throw std::runtime_error("Invalid result query");
+ subelement = lastResult[atoi(curarg.c_str())];
+ }
+ else if (lastResult.isObject())
+ subelement = find_value(lastResult, curarg);
+ else
+ throw std::runtime_error("Invalid result query"); //no array or object: abort
+ lastResult = subelement;
+ }
+
+ state = STATE_COMMAND_EXECUTED;
+ break;
+ }
+ // don't break parsing when the char is required for the next argument
+ breakParsing = false;
+
+ // pop the stack and return the result to the current command arguments
+ stack.pop_back();
+
+ // don't stringify the json in case of a string to avoid doublequotes
+ if (lastResult.isStr())
+ curarg = lastResult.get_str();
+ else
+ curarg = lastResult.write(2);
+
+ // if we have a non empty result, use it as stack argument otherwise as general result
+ if (curarg.size())
+ {
+ if (stack.size())
+ stack.back().push_back(curarg);
+ else
+ strResult = curarg;
+ }
+ curarg.clear();
+ // assume eating space state
+ state = STATE_EATING_SPACES;
}
- state = STATE_EATING_SPACES;
- break;
- default: curarg += ch; state = STATE_ARGUMENT;
+ if (breakParsing)
+ break;
}
- break;
- case STATE_SINGLEQUOTED: // Single-quoted string
- switch(ch)
+ case STATE_ARGUMENT: // In or after argument
+ case STATE_EATING_SPACES: // Handle runs of whitespace
+ switch(ch)
{
- case '\'': state = STATE_ARGUMENT; break;
- default: curarg += ch;
+ case '"': state = STATE_DOUBLEQUOTED; break;
+ case '\'': state = STATE_SINGLEQUOTED; break;
+ case '\\': state = STATE_ESCAPE_OUTER; break;
+ case '(': case ')': case '\n':
+ if (state == STATE_ARGUMENT)
+ {
+ if (ch == '(' && stack.size() && stack.back().size() > 0)
+ stack.push_back(std::vector<std::string>());
+ if (curarg.size())
+ {
+ // don't allow commands after executed commands on baselevel
+ if (!stack.size())
+ throw std::runtime_error("Invalid Syntax");
+ stack.back().push_back(curarg);
+ }
+ curarg.clear();
+ state = STATE_EATING_SPACES;
+ }
+ if ((ch == ')' || ch == '\n') && stack.size() > 0)
+ {
+ std::string strPrint;
+ // Convert argument list to JSON objects in method-dependent way,
+ // and pass it along with the method name to the dispatcher.
+ lastResult = tableRPC.execute(stack.back()[0], RPCConvertValues(stack.back()[0], std::vector<std::string>(stack.back().begin() + 1, stack.back().end())));
+
+ state = STATE_COMMAND_EXECUTED;
+ curarg.clear();
+ }
+ break;
+ case ' ': case ',': case '\t':
+ if(state == STATE_ARGUMENT) // Space ends argument
+ {
+ if (curarg.size())
+ stack.back().push_back(curarg);
+ curarg.clear();
+ }
+ state = STATE_EATING_SPACES;
+ break;
+ default: curarg += ch; state = STATE_ARGUMENT;
}
- break;
- case STATE_DOUBLEQUOTED: // Double-quoted string
- switch(ch)
+ break;
+ case STATE_SINGLEQUOTED: // Single-quoted string
+ switch(ch)
{
- case '"': state = STATE_ARGUMENT; break;
- case '\\': state = STATE_ESCAPE_DOUBLEQUOTED; break;
- default: curarg += ch;
+ case '\'': state = STATE_ARGUMENT; break;
+ default: curarg += ch;
}
- break;
- case STATE_ESCAPE_OUTER: // '\' outside quotes
- curarg += ch; state = STATE_ARGUMENT;
- break;
- case STATE_ESCAPE_DOUBLEQUOTED: // '\' in double-quoted text
- if(ch != '"' && ch != '\\') curarg += '\\'; // keep '\' for everything but the quote and '\' itself
- curarg += ch; state = STATE_DOUBLEQUOTED;
- break;
+ break;
+ case STATE_DOUBLEQUOTED: // Double-quoted string
+ switch(ch)
+ {
+ case '"': state = STATE_ARGUMENT; break;
+ case '\\': state = STATE_ESCAPE_DOUBLEQUOTED; break;
+ default: curarg += ch;
+ }
+ break;
+ case STATE_ESCAPE_OUTER: // '\' outside quotes
+ curarg += ch; state = STATE_ARGUMENT;
+ break;
+ case STATE_ESCAPE_DOUBLEQUOTED: // '\' in double-quoted text
+ if(ch != '"' && ch != '\\') curarg += '\\'; // keep '\' for everything but the quote and '\' itself
+ curarg += ch; state = STATE_DOUBLEQUOTED;
+ break;
}
}
switch(state) // final state
{
- case STATE_EATING_SPACES:
- return true;
- case STATE_ARGUMENT:
- args.push_back(curarg);
- return true;
- default: // ERROR to end in one of the other states
- return false;
+ case STATE_COMMAND_EXECUTED:
+ if (lastResult.isStr())
+ strResult = lastResult.get_str();
+ else
+ strResult = lastResult.write(2);
+ case STATE_ARGUMENT:
+ case STATE_EATING_SPACES:
+ return true;
+ default: // ERROR to end in one of the other states
+ return false;
}
}
void RPCExecutor::request(const QString &command)
{
- std::vector<std::string> args;
- if(!parseCommandLine(args, command.toStdString()))
- {
- Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \""));
- return;
- }
- if(args.empty())
- return; // Nothing to do
try
{
- std::string strPrint;
- // Convert argument list to JSON objects in method-dependent way,
- // and pass it along with the method name to the dispatcher.
- UniValue result = tableRPC.execute(
- args[0],
- RPCConvertValues(args[0], std::vector<std::string>(args.begin() + 1, args.end())));
-
- // Format result reply
- if (result.isNull())
- strPrint = "";
- else if (result.isStr())
- strPrint = result.get_str();
- else
- strPrint = result.write(2);
-
- Q_EMIT reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint));
+ std::string result;
+ std::string executableCommand = command.toStdString() + "\n";
+ if(!RPCConsole::RPCExecuteCommandLine(result, executableCommand))
+ {
+ Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \""));
+ return;
+ }
+ Q_EMIT reply(RPCConsole::CMD_REPLY, QString::fromStdString(result));
}
catch (UniValue& objError)
{
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index 28affa954d..50224a1cc0 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -35,6 +35,8 @@ public:
explicit RPCConsole(const PlatformStyle *platformStyle, QWidget *parent);
~RPCConsole();
+ static bool RPCExecuteCommandLine(std::string &strResult, const std::string &strCommand);
+
void setClientModel(ClientModel *model);
enum MessageClass {
diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp
new file mode 100644
index 0000000000..3dae33bafb
--- /dev/null
+++ b/src/qt/test/rpcnestedtests.cpp
@@ -0,0 +1,93 @@
+// Copyright (c) 2016 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "rpcnestedtests.h"
+
+#include "chainparams.h"
+#include "consensus/validation.h"
+#include "main.h"
+#include "rpc/register.h"
+#include "rpc/server.h"
+#include "rpcconsole.h"
+#include "test/testutil.h"
+#include "univalue.h"
+#include "util.h"
+
+#include <QDir>
+
+#include <boost/filesystem.hpp>
+
+void RPCNestedTests::rpcNestedTests()
+{
+ UniValue jsonRPCError;
+
+ // do some test setup
+ // could be moved to a more generic place when we add more tests on QT level
+ const CChainParams& chainparams = Params();
+ RegisterAllCoreRPCCommands(tableRPC);
+ ClearDatadirCache();
+ std::string path = QDir::tempPath().toStdString() + "/" + strprintf("test_bitcoin_qt_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000)));
+ QDir dir(QString::fromStdString(path));
+ dir.mkpath(".");
+ mapArgs["-datadir"] = path;
+ //mempool.setSanityCheck(1.0);
+ pblocktree = new CBlockTreeDB(1 << 20, true);
+ pcoinsdbview = new CCoinsViewDB(1 << 23, true);
+ pcoinsTip = new CCoinsViewCache(pcoinsdbview);
+ InitBlockIndex(chainparams);
+ {
+ CValidationState state;
+ bool ok = ActivateBestChain(state, chainparams);
+ QVERIFY(ok);
+ }
+
+ SetRPCWarmupFinished();
+
+ std::string result;
+ std::string result2;
+ RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()[chain]"); //simple result filtering with path
+ QVERIFY(result=="main");
+
+ RPCConsole::RPCExecuteCommandLine(result, "getblock(getbestblockhash())"); //simple 2 level nesting
+ RPCConsole::RPCExecuteCommandLine(result, "getblock(getblock(getbestblockhash())[hash], true)");
+
+ RPCConsole::RPCExecuteCommandLine(result, "getblock( getblock( getblock(getbestblockhash())[hash] )[hash], true)"); //4 level nesting with whitespace, filtering path and boolean parameter
+
+ RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo");
+ QVERIFY(result.substr(0,1) == "{");
+
+ RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()");
+ QVERIFY(result.substr(0,1) == "{");
+
+ RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo "); //whitespace at the end will be tolerated
+ QVERIFY(result.substr(0,1) == "{");
+
+#if QT_VERSION >= 0x050300
+ // do the QVERIFY_EXCEPTION_THROWN checks only with Qt5.3 and higher (QVERIFY_EXCEPTION_THROWN was introduced in Qt5.3)
+ QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo() .\n"), std::runtime_error); //invalid syntax
+ QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo() getblockchaininfo()"), std::runtime_error); //invalid syntax
+ (RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo(")); //tolerate non closing brackets if we have no arguments
+ (RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()()()")); //tolerate non command brackts
+ QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo(True)"), UniValue); //invalid argument
+ QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "a(getblockchaininfo(True))"), UniValue); //method not found
+#endif
+
+ (RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()[\"chain\"]")); //Quote path identifier are allowed, but look after a child contaning the quotes in the key
+ QVERIFY(result == "null");
+
+ (RPCConsole::RPCExecuteCommandLine(result, "createrawtransaction [] {} 0")); //parameter not in brackets are allowed
+ (RPCConsole::RPCExecuteCommandLine(result2, "createrawtransaction([],{},0)")); //parameter in brackets are allowed
+ QVERIFY(result == result2);
+ (RPCConsole::RPCExecuteCommandLine(result2, "createrawtransaction( [], {} , 0 )")); //whitespace between parametres is allowed
+ QVERIFY(result == result2);
+
+ RPCConsole::RPCExecuteCommandLine(result, "getblock(getbestblockhash())[tx][0]");
+ QVERIFY(result == "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
+
+ delete pcoinsTip;
+ delete pcoinsdbview;
+ delete pblocktree;
+
+ boost::filesystem::remove_all(boost::filesystem::path(path));
+}
diff --git a/src/qt/test/rpcnestedtests.h b/src/qt/test/rpcnestedtests.h
new file mode 100644
index 0000000000..9ad409019f
--- /dev/null
+++ b/src/qt/test/rpcnestedtests.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2016 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_TEST_RPC_NESTED_TESTS_H
+#define BITCOIN_QT_TEST_RPC_NESTED_TESTS_H
+
+#include <QObject>
+#include <QTest>
+
+#include "txdb.h"
+#include "txmempool.h"
+
+class RPCNestedTests : public QObject
+{
+ Q_OBJECT
+
+ private Q_SLOTS:
+ void rpcNestedTests();
+
+private:
+ CCoinsViewDB *pcoinsdbview;
+};
+
+#endif // BITCOIN_QT_TEST_RPC_NESTED_TESTS_H
diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp
index db193420bf..dbaab54fb6 100644
--- a/src/qt/test/test_main.cpp
+++ b/src/qt/test/test_main.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2009-2015 The Bitcoin Core developers
+// Copyright (c) 2009-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -6,6 +6,9 @@
#include "config/bitcoin-config.h"
#endif
+#include "chainparams.h"
+#include "key.h"
+#include "rpcnestedtests.h"
#include "util.h"
#include "uritests.h"
@@ -27,10 +30,17 @@ Q_IMPORT_PLUGIN(qtwcodecs)
Q_IMPORT_PLUGIN(qkrcodecs)
#endif
+extern void noui_connect();
+
// This is all you need to run all the tests
int main(int argc, char *argv[])
{
+ ECC_Start();
SetupEnvironment();
+ SetupNetworking();
+ SelectParams(CBaseChainParams::MAIN);
+ noui_connect();
+
bool fInvalid = false;
// Don't remove this, it's needed to access
@@ -48,6 +58,10 @@ int main(int argc, char *argv[])
if (QTest::qExec(&test2) != 0)
fInvalid = true;
#endif
+ RPCNestedTests test3;
+ if (QTest::qExec(&test3) != 0)
+ fInvalid = true;
+ ECC_Stop();
return fInvalid;
}
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp
index bae0cbd1c8..65144e7865 100644
--- a/src/qt/transactiondesc.cpp
+++ b/src/qt/transactiondesc.cpp
@@ -241,6 +241,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco
strHTML += "<br><b>" + tr("Comment") + ":</b><br>" + GUIUtil::HtmlEscape(wtx.mapValue["comment"], true) + "<br>";
strHTML += "<b>" + tr("Transaction ID") + ":</b> " + rec->getTxID() + "<br>";
+ strHTML += "<b>" + tr("Transaction total size") + ":</b> " + QString::number(wtx.GetTotalSize()) + " bytes<br>";
strHTML += "<b>" + tr("Output index") + ":</b> " + QString::number(rec->getOutputIndex()) + "<br>";
// Message from normal bitcoin:URI (bitcoin:123...?message=example)
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp
index 33f107d84b..97abeb7211 100644
--- a/src/test/DoS_tests.cpp
+++ b/src/test/DoS_tests.cpp
@@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
{
connman->ClearBanned();
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
- CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, "", true);
+ CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 0, "", true);
GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1);
dummyNode1.nVersion = 1;
Misbehaving(dummyNode1.GetId(), 100); // Should get banned
@@ -57,7 +57,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
BOOST_CHECK(!connman->IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned
CAddress addr2(ip(0xa0b0c002), NODE_NONE);
- CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, "", true);
+ CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, 1, "", true);
GetNodeSignals().InitializeNode(dummyNode2.GetId(), &dummyNode2);
dummyNode2.nVersion = 1;
Misbehaving(dummyNode2.GetId(), 50);
@@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
connman->ClearBanned();
mapArgs["-banscore"] = "111"; // because 11 is my favorite number
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
- CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, "", true);
+ CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 3, "", true);
GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1);
dummyNode1.nVersion = 1;
Misbehaving(dummyNode1.GetId(), 100);
@@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
SetMockTime(nStartTime); // Overrides future calls to GetTime()
CAddress addr(ip(0xa0b0c001), NODE_NONE);
- CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, "", true);
+ CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, 4, "", true);
GetNodeSignals().InitializeNode(dummyNode.GetId(), &dummyNode);
dummyNode.nVersion = 1;
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index bc9a98ab04..680708533e 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -164,12 +164,12 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test)
bool fInboundIn = false;
// Test that fFeeler is false by default.
- CNode* pnode1 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, pszDest, fInboundIn);
+ CNode* pnode1 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 0, pszDest, fInboundIn);
BOOST_CHECK(pnode1->fInbound == false);
BOOST_CHECK(pnode1->fFeeler == false);
fInboundIn = true;
- CNode* pnode2 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, pszDest, fInboundIn);
+ CNode* pnode2 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 1, pszDest, fInboundIn);
BOOST_CHECK(pnode2->fInbound == true);
BOOST_CHECK(pnode2->fFeeler == false);
}
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index b1ceef4f64..02843d8525 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -72,7 +72,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
nScriptCheckThreads = 3;
for (int i=0; i < nScriptCheckThreads-1; i++)
threadGroup.create_thread(&ThreadScriptCheck);
- g_connman = std::unique_ptr<CConnman>(new CConnman());
+ g_connman = std::unique_ptr<CConnman>(new CConnman(0x1337, 0x1337)); // Deterministic randomness for tests.
connman = g_connman.get();
RegisterNodeSignals(GetNodeSignals());
}
diff --git a/src/wallet/test/accounting_tests.cpp b/src/wallet/test/accounting_tests.cpp
index a6cada46a2..a833be13d0 100644
--- a/src/wallet/test/accounting_tests.cpp
+++ b/src/wallet/test/accounting_tests.cpp
@@ -3,7 +3,6 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "wallet/wallet.h"
-#include "wallet/walletdb.h"
#include "wallet/test/wallet_test_fixture.h"
@@ -17,13 +16,13 @@ extern CWallet* pwalletMain;
BOOST_FIXTURE_TEST_SUITE(accounting_tests, WalletTestingSetup)
static void
-GetResults(CWalletDB& walletdb, std::map<CAmount, CAccountingEntry>& results)
+GetResults(std::map<CAmount, CAccountingEntry>& results)
{
std::list<CAccountingEntry> aes;
results.clear();
- BOOST_CHECK(walletdb.ReorderTransactions(pwalletMain) == DB_LOAD_OK);
- walletdb.ListAccountCreditDebit("", aes);
+ BOOST_CHECK(pwalletMain->ReorderTransactions() == DB_LOAD_OK);
+ pwalletMain->ListAccountCreditDebit("", aes);
BOOST_FOREACH(CAccountingEntry& ae, aes)
{
results[ae.nOrderPos] = ae;
@@ -32,7 +31,6 @@ GetResults(CWalletDB& walletdb, std::map<CAmount, CAccountingEntry>& results)
BOOST_AUTO_TEST_CASE(acc_orderupgrade)
{
- CWalletDB walletdb(pwalletMain->strWalletFile);
std::vector<CWalletTx*> vpwtx;
CWalletTx wtx;
CAccountingEntry ae;
@@ -45,7 +43,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade)
ae.nTime = 1333333333;
ae.strOtherAccount = "b";
ae.strComment = "";
- pwalletMain->AddAccountingEntry(ae, walletdb);
+ pwalletMain->AddAccountingEntry(ae);
wtx.mapValue["comment"] = "z";
pwalletMain->AddToWallet(wtx);
@@ -55,9 +53,9 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade)
ae.nTime = 1333333336;
ae.strOtherAccount = "c";
- pwalletMain->AddAccountingEntry(ae, walletdb);
+ pwalletMain->AddAccountingEntry(ae);
- GetResults(walletdb, results);
+ GetResults(results);
BOOST_CHECK(pwalletMain->nOrderPosNext == 3);
BOOST_CHECK(2 == results.size());
@@ -71,9 +69,9 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade)
ae.nTime = 1333333330;
ae.strOtherAccount = "d";
ae.nOrderPos = pwalletMain->IncOrderPosNext();
- pwalletMain->AddAccountingEntry(ae, walletdb);
+ pwalletMain->AddAccountingEntry(ae);
- GetResults(walletdb, results);
+ GetResults(results);
BOOST_CHECK(results.size() == 3);
BOOST_CHECK(pwalletMain->nOrderPosNext == 4);
@@ -105,7 +103,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade)
vpwtx[2]->nTimeReceived = (unsigned int)1333333329;
vpwtx[2]->nOrderPos = -1;
- GetResults(walletdb, results);
+ GetResults(results);
BOOST_CHECK(results.size() == 3);
BOOST_CHECK(pwalletMain->nOrderPosNext == 6);
@@ -121,9 +119,9 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade)
ae.nTime = 1333333334;
ae.strOtherAccount = "e";
ae.nOrderPos = -1;
- pwalletMain->AddAccountingEntry(ae, walletdb);
+ pwalletMain->AddAccountingEntry(ae);
- GetResults(walletdb, results);
+ GetResults(results);
BOOST_CHECK(results.size() == 4);
BOOST_CHECK(pwalletMain->nOrderPosNext == 7);
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 4c10ea0edb..7469fd7519 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -649,6 +649,12 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
return true;
}
+DBErrors CWallet::ReorderTransactions()
+{
+ CWalletDB walletdb(strWalletFile);
+ return walletdb.ReorderTransactions(this);
+}
+
int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
{
AssertLockHeld(cs_wallet); // nOrderPosNext
@@ -677,7 +683,7 @@ bool CWallet::AccountMove(std::string strFrom, std::string strTo, CAmount nAmoun
debit.nTime = nNow;
debit.strOtherAccount = strTo;
debit.strComment = strComment;
- AddAccountingEntry(debit, walletdb);
+ AddAccountingEntry(debit, &walletdb);
// Credit
CAccountingEntry credit;
@@ -687,7 +693,7 @@ bool CWallet::AccountMove(std::string strFrom, std::string strTo, CAmount nAmoun
credit.nTime = nNow;
credit.strOtherAccount = strFrom;
credit.strComment = strComment;
- AddAccountingEntry(credit, walletdb);
+ AddAccountingEntry(credit, &walletdb);
if (!walletdb.TxnCommit())
return false;
@@ -2501,9 +2507,21 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CCon
return true;
}
-bool CWallet::AddAccountingEntry(const CAccountingEntry& acentry, CWalletDB & pwalletdb)
+void CWallet::ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries) {
+ CWalletDB walletdb(strWalletFile);
+ return walletdb.ListAccountCreditDebit(strAccount, entries);
+}
+
+bool CWallet::AddAccountingEntry(const CAccountingEntry& acentry)
{
- if (!pwalletdb.WriteAccountingEntry_Backend(acentry))
+ CWalletDB walletdb(strWalletFile);
+
+ return AddAccountingEntry(acentry, &walletdb);
+}
+
+bool CWallet::AddAccountingEntry(const CAccountingEntry& acentry, CWalletDB *pwalletdb)
+{
+ if (!pwalletdb->WriteAccountingEntry_Backend(acentry))
return false;
laccentries.push_back(acentry);
@@ -3446,6 +3464,15 @@ bool CWallet::InitLoadWallet()
bool CWallet::ParameterInteraction()
{
+ if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && SoftSetBoolArg("-walletbroadcast", false)) {
+ LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__);
+ }
+
+ if (GetBoolArg("-sysperms", false))
+ return InitError("-sysperms is not allowed in combination with enabled wallet functionality");
+ if (GetArg("-prune", 0) && GetBoolArg("-rescan", false))
+ return InitError(_("Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again."));
+
if (mapArgs.count("-mintxfee"))
{
CAmount n = 0;
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 61aff6e45a..584f013204 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -741,6 +741,7 @@ public:
* @return next transaction order id
*/
int64_t IncOrderPosNext(CWalletDB *pwalletdb = NULL);
+ DBErrors ReorderTransactions();
bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment = "");
bool GetAccountPubkey(CPubKey &pubKey, std::string strAccount, bool bForceNew = false);
@@ -775,7 +776,9 @@ public:
std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true);
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman);
- bool AddAccountingEntry(const CAccountingEntry&, CWalletDB & pwalletdb);
+ void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries);
+ bool AddAccountingEntry(const CAccountingEntry&);
+ bool AddAccountingEntry(const CAccountingEntry&, CWalletDB *pwalletdb);
static CFeeRate minTxFee;
static CFeeRate fallbackFee;