diff --git a/.gitignore b/.gitignore index 3e53adf643a7..2bd43116f242 100644 --- a/.gitignore +++ b/.gitignore @@ -110,10 +110,7 @@ linux-build win32-build qa/pull-tester/run-bitcoind-for-test.sh qa/pull-tester/tests_config.py -qa/pull-tester/test.*/* -qa/tmp qa/cache/* -share/BitcoindComparisonTool.jar !src/leveldb*/Makefile diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b229c7509fee..63df1610305b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -87,6 +87,15 @@ before it will be merged. The basic squashing workflow is shown below. # save and quit git push -f # (force push to GitHub) +If you have problems with squashing (or other workflows with `git`), you can +alternatively enable "Allow edits from maintainers" in the right GitHub +sidebar and ask for help in the pull request. + +Please refrain from creating several pull requests for the same change. +Use the pull request that is already open (or was created earlier) to amend +changes. This preserves the discussion and review that happened earlier for +the respective change set. + The length of time required for peer review is unpredictable and will vary from pull request to pull request. @@ -198,3 +207,11 @@ Release Policy -------------- The project leader is the release manager for each Dash Core release. + +Copyright +--------- + +By contributing to this repository, you agree to license your work under the +MIT license unless specified otherwise in `contrib/debian/copyright` or at +the top of the file itself. Any work contributed where you are not the original +author must contain its license header with the original author(s) and source. diff --git a/configure.ac b/configure.ac index ab4fcd429751..12bee5b187c0 100644 --- a/configure.ac +++ b/configure.ac @@ -491,6 +491,7 @@ if test x$use_hardening != xno; then AX_CHECK_LINK_FLAG([[-Wl,--dynamicbase]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--dynamicbase"]) AX_CHECK_LINK_FLAG([[-Wl,--nxcompat]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--nxcompat"]) + AX_CHECK_LINK_FLAG([[-Wl,--high-entropy-va]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--high-entropy-va"]) AX_CHECK_LINK_FLAG([[-Wl,-z,relro]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,relro"]) AX_CHECK_LINK_FLAG([[-Wl,-z,now]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,now"]) diff --git a/contrib/README.md b/contrib/README.md index 3a1c906d4017..1e515a77d2c7 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -1,11 +1,3 @@ -Wallet Tools ---------------------- - -### [SpendFrom](/contrib/spendfrom) ### - -Use the raw transactions API to send coins received on a particular -address (or addresses). - Repository Tools --------------------- diff --git a/contrib/devtools/git-subtree-check.sh b/contrib/devtools/git-subtree-check.sh index 1cb82fe6826c..2384d66cad2a 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 e760b57d7a4d..be43ac8eea3f 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 c61d65264176..c90541e27119 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. @@ -12,6 +15,7 @@ READELF_CMD = os.getenv('READELF', '/usr/bin/readelf') OBJDUMP_CMD = os.getenv('OBJDUMP', '/usr/bin/objdump') +NONFATAL = {'HIGH_ENTROPY_VA'} # checks which are non-fatal for now but only generate a warning def check_ELF_PIE(executable): ''' @@ -114,26 +118,50 @@ def check_ELF_Canary(executable): def get_PE_dll_characteristics(executable): ''' - Get PE DllCharacteristics bits + Get PE DllCharacteristics bits. + Returns a tuple (arch,bits) where arch is 'i386:x86-64' or 'i386' + and bits is the DllCharacteristics value. ''' p = subprocess.Popen([OBJDUMP_CMD, '-x', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) (stdout, stderr) = p.communicate() if p.returncode: raise IOError('Error opening file') + arch = '' + bits = 0 for line in stdout.split('\n'): tokens = line.split() + if len(tokens)>=2 and tokens[0] == 'architecture:': + arch = tokens[1].rstrip(',') if len(tokens)>=2 and tokens[0] == 'DllCharacteristics': - return int(tokens[1],16) - return 0 + bits = int(tokens[1],16) + return (arch,bits) +IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020 +IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040 +IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100 -def check_PE_PIE(executable): +def check_PE_DYNAMIC_BASE(executable): '''PIE: DllCharacteristics bit 0x40 signifies dynamicbase (ASLR)''' - return bool(get_PE_dll_characteristics(executable) & 0x40) + (arch,bits) = get_PE_dll_characteristics(executable) + reqbits = IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE + return (bits & reqbits) == reqbits + +# On 64 bit, must support high-entropy 64-bit address space layout randomization in addition to DYNAMIC_BASE +# to have secure ASLR. +def check_PE_HIGH_ENTROPY_VA(executable): + '''PIE: DllCharacteristics bit 0x20 signifies high-entropy ASLR''' + (arch,bits) = get_PE_dll_characteristics(executable) + if arch == 'i386:x86-64': + reqbits = IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA + else: # Unnecessary on 32-bit + assert(arch == 'i386') + reqbits = 0 + return (bits & reqbits) == reqbits def check_PE_NX(executable): '''NX: DllCharacteristics bit 0x100 signifies nxcompat (DEP)''' - return bool(get_PE_dll_characteristics(executable) & 0x100) + (arch,bits) = get_PE_dll_characteristics(executable) + return (bits & IMAGE_DLL_CHARACTERISTICS_NX_COMPAT) == IMAGE_DLL_CHARACTERISTICS_NX_COMPAT CHECKS = { 'ELF': [ @@ -143,7 +171,8 @@ def check_PE_NX(executable): ('Canary', check_ELF_Canary) ], 'PE': [ - ('PIE', check_PE_PIE), + ('DYNAMIC_BASE', check_PE_DYNAMIC_BASE), + ('HIGH_ENTROPY_VA', check_PE_HIGH_ENTROPY_VA), ('NX', check_PE_NX) ] } @@ -168,12 +197,18 @@ def identify_executable(executable): continue failed = [] + warning = [] for (name, func) in CHECKS[etype]: if not func(filename): - failed.append(name) + if name in NONFATAL: + warning.append(name) + else: + failed.append(name) if failed: print('%s: failed %s' % (filename, ' '.join(failed))) retval = 1 + if warning: + print('%s: warning %s' % (filename, ' '.join(warning))) except IOError: print('%s: cannot open' % filename) retval = 1 diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py index 324b7bcd85ae..c0f120392e62 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 057fca72f6b3..2f9d8cf68ac7 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 781fe315edab..91674a92e6fa 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 b3e27d91c658..2d553d266654 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 46d2d825d452..ff9fbd58df07 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 8ead5789a2aa..e615ce12fe17 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 deleted file mode 100755 index 515d3daabc82..000000000000 --- a/contrib/qt_translations.py +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env python - -# Helpful little script that spits out a comma-separated list of -# language codes for Qt icons that should be included -# in binary Dash Core distributions - -import glob -import os -import re -import sys - -if len(sys.argv) != 3: - sys.exit("Usage: %s $QTDIR/translations $BITCOINDIR/src/qt/locale"%sys.argv[0]) - -d1 = sys.argv[1] -d2 = sys.argv[2] - -l1 = set([ re.search(r'qt_(.*).qm', f).group(1) for f in glob.glob(os.path.join(d1, 'qt_*.qm')) ]) -l2 = set([ re.search(r'dash_(.*).qm', f).group(1) for f in glob.glob(os.path.join(d2, 'dash_*.qm')) ]) - -print ",".join(sorted(l1.intersection(l2))) - diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py index 2dfb30d9d41f..820ca94a4b3c 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/README.md b/contrib/spendfrom/README.md deleted file mode 100644 index a51c9ce216b7..000000000000 --- a/contrib/spendfrom/README.md +++ /dev/null @@ -1,35 +0,0 @@ -### SpendFrom ### - -Use the raw transactions API to send coins received on a particular -address (or addresses). - -### Usage: ### -Depends on [jsonrpc](http://json-rpc.org/). - - spendfrom.py --from=FROMADDRESS1[,FROMADDRESS2] --to=TOADDRESS --amount=amount \ - --fee=fee --datadir=/path/to/.dashcore --testnet --dry_run - -With no arguments, outputs a list of amounts associated with addresses. - -With arguments, sends coins received by the `FROMADDRESS` addresses to the `TOADDRESS`. - -### Notes ### - -- You may explicitly specify how much fee to pay (a fee more than 1% of the amount -will fail, though, to prevent dash-losing accidents). Spendfrom may fail if -it thinks the transaction would never be confirmed (if the amount being sent is -too small, or if the transaction is too many bytes for the fee). - -- If a change output needs to be created, the change will be sent to the last -`FROMADDRESS` (if you specify just one `FROMADDRESS`, change will go back to it). - -- If `--datadir` is not specified, the default datadir is used. - -- The `--dry_run` option will just create and sign the transaction and print -the transaction data (as hexadecimal), instead of broadcasting it. - -- If the transaction is created and broadcast successfully, a transaction id -is printed. - -- If this was a tool for end-users and not programmers, it would have much friendlier -error-handling. diff --git a/contrib/spendfrom/setup.py b/contrib/spendfrom/setup.py deleted file mode 100644 index 01b9768a5b06..000000000000 --- a/contrib/spendfrom/setup.py +++ /dev/null @@ -1,9 +0,0 @@ -from distutils.core import setup -setup(name='btcspendfrom', - version='1.0', - description='Command-line utility for bitcoin "coin control"', - author='Gavin Andresen', - author_email='gavin@bitcoinfoundation.org', - requires=['jsonrpc'], - scripts=['spendfrom.py'], - ) diff --git a/contrib/spendfrom/spendfrom.py b/contrib/spendfrom/spendfrom.py deleted file mode 100755 index 51a8422c38c5..000000000000 --- a/contrib/spendfrom/spendfrom.py +++ /dev/null @@ -1,267 +0,0 @@ -#!/usr/bin/env python -# -# Use the raw transactions API to spend dashs received on particular addresses, -# and send any change back to that same address. -# -# Example usage: -# spendfrom.py # Lists available funds -# spendfrom.py --from=ADDRESS --to=ADDRESS --amount=11.00 -# -# Assumes it will talk to a dashd or Dash-Qt running -# on localhost. -# -# Depends on jsonrpc -# - -from decimal import * -import getpass -import math -import os -import os.path -import platform -import sys -import time -from jsonrpc import ServiceProxy, json - -BASE_FEE=Decimal("0.001") - -def check_json_precision(): - """Make sure json library being used does not lose precision converting BTC values""" - n = Decimal("20000000.00000003") - satoshis = int(json.loads(json.dumps(float(n)))*1.0e8) - if satoshis != 2000000000000003: - raise RuntimeError("JSON encode/decode loses precision") - -def determine_db_dir(): - """Return the default location of the Dash Core data directory""" - if platform.system() == "Darwin": - return os.path.expanduser("~/Library/Application Support/DashCore/") - elif platform.system() == "Windows": - return os.path.join(os.environ['APPDATA'], "DashCore") - return os.path.expanduser("~/.dashcore") - -def read_bitcoin_config(dbdir): - """Read the dash.conf file from dbdir, returns dictionary of settings""" - from ConfigParser import SafeConfigParser - - class FakeSecHead(object): - def __init__(self, fp): - self.fp = fp - self.sechead = '[all]\n' - def readline(self): - if self.sechead: - try: return self.sechead - finally: self.sechead = None - else: - s = self.fp.readline() - if s.find('#') != -1: - s = s[0:s.find('#')].strip() +"\n" - return s - - config_parser = SafeConfigParser() - config_parser.readfp(FakeSecHead(open(os.path.join(dbdir, "dash.conf")))) - return dict(config_parser.items("all")) - -def connect_JSON(config): - """Connect to a Dash Core JSON-RPC server""" - testnet = config.get('testnet', '0') - testnet = (int(testnet) > 0) # 0/1 in config file, convert to True/False - if not 'rpcport' in config: - config['rpcport'] = 19998 if testnet else 9998 - connect = "http://%s:%s@127.0.0.1:%s"%(config['rpcuser'], config['rpcpassword'], config['rpcport']) - try: - result = ServiceProxy(connect) - # ServiceProxy is lazy-connect, so send an RPC command mostly to catch connection errors, - # but also make sure the dashd we're talking to is/isn't testnet: - if result.getmininginfo()['testnet'] != testnet: - sys.stderr.write("RPC server at "+connect+" testnet setting mismatch\n") - sys.exit(1) - return result - except: - sys.stderr.write("Error connecting to RPC server at "+connect+"\n") - sys.exit(1) - -def unlock_wallet(dashd): - info = dashd.getinfo() - if 'unlocked_until' not in info: - return True # wallet is not encrypted - t = int(info['unlocked_until']) - if t <= time.time(): - try: - passphrase = getpass.getpass("Wallet is locked; enter passphrase: ") - dashd.walletpassphrase(passphrase, 5) - except: - sys.stderr.write("Wrong passphrase\n") - - info = dashd.getinfo() - return int(info['unlocked_until']) > time.time() - -def list_available(dashd): - address_summary = dict() - - address_to_account = dict() - for info in dashd.listreceivedbyaddress(0): - address_to_account[info["address"]] = info["account"] - - unspent = dashd.listunspent(0) - for output in unspent: - # listunspent doesn't give addresses, so: - rawtx = dashd.getrawtransaction(output['txid'], 1) - vout = rawtx["vout"][output['vout']] - pk = vout["scriptPubKey"] - - # This code only deals with ordinary pay-to-dash-address - # or pay-to-script-hash outputs right now; anything exotic is ignored. - if pk["type"] != "pubkeyhash" and pk["type"] != "scripthash": - continue - - address = pk["addresses"][0] - if address in address_summary: - address_summary[address]["total"] += vout["value"] - address_summary[address]["outputs"].append(output) - else: - address_summary[address] = { - "total" : vout["value"], - "outputs" : [output], - "account" : address_to_account.get(address, "") - } - - return address_summary - -def select_coins(needed, inputs): - # Feel free to improve this, this is good enough for my simple needs: - outputs = [] - have = Decimal("0.0") - n = 0 - while have < needed and n < len(inputs): - outputs.append({ "txid":inputs[n]["txid"], "vout":inputs[n]["vout"]}) - have += inputs[n]["amount"] - n += 1 - return (outputs, have-needed) - -def create_tx(dashd, fromaddresses, toaddress, amount, fee): - all_coins = list_available(dashd) - - total_available = Decimal("0.0") - needed = amount+fee - potential_inputs = [] - for addr in fromaddresses: - if addr not in all_coins: - continue - potential_inputs.extend(all_coins[addr]["outputs"]) - total_available += all_coins[addr]["total"] - - if total_available < needed: - sys.stderr.write("Error, only %f BTC available, need %f\n"%(total_available, needed)); - sys.exit(1) - - # - # Note: - # Python's json/jsonrpc modules have inconsistent support for Decimal numbers. - # Instead of wrestling with getting json.dumps() (used by jsonrpc) to encode - # Decimals, I'm casting amounts to float before sending them to dashd. - # - outputs = { toaddress : float(amount) } - (inputs, change_amount) = select_coins(needed, potential_inputs) - if change_amount > BASE_FEE: # don't bother with zero or tiny change - change_address = fromaddresses[-1] - if change_address in outputs: - outputs[change_address] += float(change_amount) - else: - outputs[change_address] = float(change_amount) - - rawtx = dashd.createrawtransaction(inputs, outputs) - signed_rawtx = dashd.signrawtransaction(rawtx) - if not signed_rawtx["complete"]: - sys.stderr.write("signrawtransaction failed\n") - sys.exit(1) - txdata = signed_rawtx["hex"] - - return txdata - -def compute_amount_in(dashd, txinfo): - result = Decimal("0.0") - for vin in txinfo['vin']: - in_info = dashd.getrawtransaction(vin['txid'], 1) - vout = in_info['vout'][vin['vout']] - result = result + vout['value'] - return result - -def compute_amount_out(txinfo): - result = Decimal("0.0") - for vout in txinfo['vout']: - result = result + vout['value'] - return result - -def sanity_test_fee(dashd, txdata_hex, max_fee): - class FeeError(RuntimeError): - pass - try: - txinfo = dashd.decoderawtransaction(txdata_hex) - total_in = compute_amount_in(dashd, txinfo) - total_out = compute_amount_out(txinfo) - if total_in-total_out > max_fee: - raise FeeError("Rejecting transaction, unreasonable fee of "+str(total_in-total_out)) - - tx_size = len(txdata_hex)/2 - kb = tx_size/1000 # integer division rounds down - if kb > 1 and fee < BASE_FEE: - raise FeeError("Rejecting no-fee transaction, larger than 1000 bytes") - if total_in < 0.01 and fee < BASE_FEE: - raise FeeError("Rejecting no-fee, tiny-amount transaction") - # Exercise for the reader: compute transaction priority, and - # warn if this is a very-low-priority transaction - - except FeeError as err: - sys.stderr.write((str(err)+"\n")) - sys.exit(1) - -def main(): - import optparse - - parser = optparse.OptionParser(usage="%prog [options]") - parser.add_option("--from", dest="fromaddresses", default=None, - help="addresses to get dashs from") - parser.add_option("--to", dest="to", default=None, - help="address to get send dashs to") - parser.add_option("--amount", dest="amount", default=None, - help="amount to send") - parser.add_option("--fee", dest="fee", default="0.0", - help="fee to include") - parser.add_option("--datadir", dest="datadir", default=determine_db_dir(), - help="location of dash.conf file with RPC username/password (default: %default)") - parser.add_option("--testnet", dest="testnet", default=False, action="store_true", - help="Use the test network") - parser.add_option("--dry_run", dest="dry_run", default=False, action="store_true", - help="Don't broadcast the transaction, just create and print the transaction data") - - (options, args) = parser.parse_args() - - check_json_precision() - config = read_bitcoin_config(options.datadir) - if options.testnet: config['testnet'] = True - dashd = connect_JSON(config) - - if options.amount is None: - address_summary = list_available(dashd) - for address,info in address_summary.iteritems(): - n_transactions = len(info['outputs']) - if n_transactions > 1: - print("%s %.8f %s (%d transactions)"%(address, info['total'], info['account'], n_transactions)) - else: - print("%s %.8f %s"%(address, info['total'], info['account'])) - else: - fee = Decimal(options.fee) - amount = Decimal(options.amount) - while unlock_wallet(dashd) == False: - pass # Keep asking for passphrase until they get it right - txdata = create_tx(dashd, options.fromaddresses.split(","), options.to, amount, fee) - sanity_test_fee(dashd, txdata, amount*Decimal("0.01")) - if options.dry_run: - print(txdata) - else: - txid = dashd.sendrawtransaction(txdata) - print(txid) - -if __name__ == '__main__': - main() diff --git a/contrib/testgen/base58.py b/contrib/testgen/base58.py index b716495145f7..72b288b2dc9f 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 a2d5dbe93eb2..2f53a316104b 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 d1b2d13fd4a9..101c9687a821 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 375d71172570..09ff23754473 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 be65ad24f318..20e13e8480cf 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(:|/)dashpay/dash(.git)?$ ]]; then exit 0 fi diff --git a/contrib/verify-commits/verify-commits.sh b/contrib/verify-commits/verify-commits.sh index 5219331e2e5b..cfe4f11a0b7a 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 e22b911743b8..e20770c96a96 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 62c3d34fb793..bf6c4dd00099 100755 --- a/contrib/zmq/zmq_sub.py +++ b/contrib/zmq/zmq_sub.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +# 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/depends/packages/expat.mk b/depends/packages/expat.mk index bd2927563850..81a660e83a55 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -1,8 +1,8 @@ package=expat -$(package)_version=2.1.1 +$(package)_version=2.2.0 $(package)_download_path=https://downloads.sourceforge.net/project/expat/expat/$($(package)_version) $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=aff584e5a2f759dcfc6d48671e9529f6afe1e30b0cd6a4cec200cbe3f793de67 +$(package)_sha256_hash=d9e50ff2d19b3538bd2127902a89987474e1a4db8e43a66a4d1a712ab9a504ff define $(package)_set_vars $(package)_config_opts=--disable-static diff --git a/depends/packages/fontconfig.mk b/depends/packages/fontconfig.mk index 2cf553ed9657..fb97e0b9ec1b 100644 --- a/depends/packages/fontconfig.mk +++ b/depends/packages/fontconfig.mk @@ -1,8 +1,8 @@ package=fontconfig -$(package)_version=2.11.1 +$(package)_version=2.12.1 $(package)_download_path=http://www.freedesktop.org/software/fontconfig/release/ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=dc62447533bca844463a3c3fd4083b57c90f18a70506e7a9f4936b5a1e516a99 +$(package)_sha256_hash=b449a3e10c47e1d1c7a6ec6e2016cca73d3bd68fbbd4f0ae5cc6b573f7d6c7f3 $(package)_dependencies=freetype expat define $(package)_set_vars diff --git a/depends/packages/native_ccache.mk b/depends/packages/native_ccache.mk index cd20fbe1e12b..a3a58604e583 100644 --- a/depends/packages/native_ccache.mk +++ b/depends/packages/native_ccache.mk @@ -1,8 +1,8 @@ package=native_ccache -$(package)_version=3.2.5 +$(package)_version=3.3.1 $(package)_download_path=https://samba.org/ftp/ccache $(package)_file_name=ccache-$($(package)_version).tar.bz2 -$(package)_sha256_hash=7a553809e90faf9de3a23ee9c5b5f786cfd4836bf502744bedb824a24bee1097 +$(package)_sha256_hash=cb6e4bafbb19ba0a2ec43386b123a5f92a20e1e3384c071d5d13e0cb3c84bf73 define $(package)_set_vars $(package)_config_opts= diff --git a/doc/build-osx.md b/doc/build-osx.md index e6b52c6e5573..3a4a399ddb8a 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, doing so could result in a broken UI. Therefore, building with Qt5 is recommended. diff --git a/doc/build-windows.md b/doc/build-windows.md index aaffe3051f14..0c561bf29479 100644 --- a/doc/build-windows.md +++ b/doc/build-windows.md @@ -27,6 +27,7 @@ To build executables for Windows 32-bit: cd depends make HOST=i686-w64-mingw32 -j4 cd .. + ./autogen.sh # not required when building from tarball ./configure --prefix=`pwd`/depends/i686-w64-mingw32 make @@ -35,6 +36,7 @@ To build executables for Windows 64-bit: cd depends make HOST=x86_64-w64-mingw32 -j4 cd .. + ./autogen.sh # not required when building from tarball ./configure --prefix=`pwd`/depends/x86_64-w64-mingw32 make diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 67252e5bb7eb..b67f1f6811d0 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -95,14 +95,14 @@ After creating the VM, we need to configure it. - Click `Ok` twice to save. -Get the [Debian 8.x net installer](http://cdimage.debian.org/debian-cd/8.5.0/amd64/iso-cd/debian-8.5.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). -This DVD image can be validated using a SHA256 hashing tool, for example on +Get the [Debian 8.x net installer](http://cdimage.debian.org/mirror/cdimage/archive/8.5.0/amd64/iso-cd/debian-8.5.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). +This DVD image can be [validated](https://www.debian.org/CD/verify) using a SHA256 hashing tool, for example on Unixy OSes by entering the following in a terminal: echo "ad4e8c27c561ad8248d5ebc1d36eb172f884057bfeb2c22ead823f59fa8c3dff debian-8.5.0-amd64-netinst.iso" | sha256sum -c # (must return OK) -Then start the VM. On the first launch you will be asked for a CD or DVD image. Choose the downloaded iso. +Then start the VM. On the first launch you will be asked for a CD or DVD image. Choose the downloaded ISO. ![](gitian-building/select_startup_disk.png) @@ -344,8 +344,8 @@ There will be a lot of warnings printed during the build of the image. These can 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 Dash Core repository under 'Fetch and build inputs' to install sources which require +Follow the instructions in [doc/release-process.md](release-process.md#fetch-and-create-inputs-first-time-or-when-dependency-versions-change) +in the Dash Core 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/reduce-traffic.md b/doc/reduce-traffic.md index a5b232541ab1..caeb28ef2f5b 100644 --- a/doc/reduce-traffic.md +++ b/doc/reduce-traffic.md @@ -19,8 +19,7 @@ This is *not* a hard limit; only a threshold to minimize the outbound traffic. When the limit is about to be reached, the uploaded data is cut by no longer serving historic blocks (blocks older than one week). Keep in mind that new nodes require other nodes that are willing to serve -historic blocks. **The recommended minimum is 144 blocks per day (max. 144MB -per day)** +historic blocks. Whitelisted peers will never be disconnected, although their traffic counts for calculating the target. diff --git a/doc/translation_process.md b/doc/translation_process.md index 2052f783260a..e90f0798cb7d 100644 --- a/doc/translation_process.md +++ b/doc/translation_process.md @@ -6,7 +6,7 @@ The Dash Core project has been designed to support multiple localisations. This ### 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 Dash’s global adoption, and growth. One of Dash’s greatest strengths is cross-boarder money transfers, any help making that easier is greatly appreciated. +Multiple language support is critical in assisting Dash’s global adoption, and growth. One of Dash’s greatest strengths is cross-border money transfers, any help making that easier is greatly appreciated. See the [Transifex Dash project](https://www.transifex.com/projects/p/dash/) 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 a5eb36566f10..ee1a9fbacafd 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -225,8 +225,8 @@ def runtests(): time_sum += duration print('\n' + BOLD[1] + name + BOLD[0] + ":") - print(stdout) - print('stderr:\n' if not stderr == '' else '', stderr) + print('' if passed else stdout + '\n', end='') + print('' if stderr == '' else 'stderr:\n' + stderr + '\n', end='') results += "%s | %s | %s s\n" % (name.ljust(max_len_name), str(passed).ljust(6), duration) print("Pass: %s%s%s, Duration: %s s\n" % (BOLD[1], passed, BOLD[0], duration)) results += BOLD[1] + "\n%s | %s | %s s (accumulated)" % ("ALL".ljust(max_len_name), str(all_passed).ljust(6), time_sum) + BOLD[0] diff --git a/qa/rpc-tests/create_cache.py b/qa/rpc-tests/create_cache.py index b6161e0917d0..1ace6310d0d0 100755 --- a/qa/rpc-tests/create_cache.py +++ b/qa/rpc-tests/create_cache.py @@ -12,9 +12,15 @@ 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/p2p-versionbits-warning.py b/qa/rpc-tests/p2p-versionbits-warning.py index 962cafef0b17..00dbbc02cf3c 100755 --- a/qa/rpc-tests/p2p-versionbits-warning.py +++ b/qa/rpc-tests/p2p-versionbits-warning.py @@ -6,6 +6,7 @@ from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * +import re import time from test_framework.blocktools import create_block, create_coinbase @@ -21,6 +22,10 @@ VB_TOP_BITS = 0x20000000 VB_UNKNOWN_BIT = 27 # Choose a bit unassigned to any deployment +WARN_UNKNOWN_RULES_MINED = "Unknown block versions being mined! It's possible unknown rules are in effect" +WARN_UNKNOWN_RULES_ACTIVE = "unknown new rules activated (versionbit {})".format(VB_UNKNOWN_BIT) +VB_PATTERN = re.compile("^Warning.*versionbit") + # TestNode: bare-bones "peer". Used mostly as a conduit for a test to sending # p2p messages to a node, generating the messages in the main testing logic. class TestNode(NodeConnCB): @@ -65,16 +70,12 @@ def __init__(self): self.num_nodes = 1 def setup_network(self): - self.nodes = [] self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") # Open and close to create zero-length file - with open(self.alert_filename, 'w') as f: + with open(self.alert_filename, 'w') as _: pass - self.node_options = ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""] - self.nodes.append(start_node(0, self.options.tmpdir, self.node_options)) - - import re - self.vb_pattern = re.compile("^Warning.*versionbit") + self.extra_args = [["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args) # Send numblocks blocks via peer with nVersionToUse set. def send_blocks_with_version(self, peer, numblocks, nVersionToUse): @@ -83,7 +84,7 @@ def send_blocks_with_version(self, peer, numblocks, nVersionToUse): block_time = self.nodes[0].getblockheader(tip)["time"]+1 tip = int(tip, 16) - for i in range(numblocks): + for _ in range(numblocks): block = create_block(tip, create_coinbase(height+1), block_time) block.nVersion = nVersionToUse block.solve() @@ -96,7 +97,7 @@ def send_blocks_with_version(self, peer, numblocks, nVersionToUse): def test_versionbits_in_alert_file(self): with open(self.alert_filename, 'r') as f: alert_text = f.read() - assert(self.vb_pattern.match(alert_text)) + assert(VB_PATTERN.match(alert_text)) def run_test(self): # Setup the p2p connection and start up the network thread. @@ -122,8 +123,10 @@ def run_test(self): # Fill rest of period with regular version blocks self.nodes[0].generate(VB_PERIOD - VB_THRESHOLD + 1) # Check that we're not getting any versionbit-related errors in - # getinfo() - assert(not self.vb_pattern.match(self.nodes[0].getinfo()["errors"])) + # get*info() + assert(not VB_PATTERN.match(self.nodes[0].getinfo()["errors"])) + assert(not VB_PATTERN.match(self.nodes[0].getmininginfo()["errors"])) + assert(not VB_PATTERN.match(self.nodes[0].getnetworkinfo()["warnings"])) # 3. Now build one period of blocks with >= VB_THRESHOLD blocks signaling # some unknown bit @@ -132,8 +135,10 @@ def run_test(self): # Might not get a versionbits-related alert yet, as we should # have gotten a different alert due to more than 51/100 blocks # being of unexpected version. - # Check that getinfo() shows some kind of error. - assert(len(self.nodes[0].getinfo()["errors"]) != 0) + # Check that get*info() shows some kind of error. + assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getinfo()["errors"]) + assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getmininginfo()["errors"]) + assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getnetworkinfo()["warnings"]) # Mine a period worth of expected blocks so the generic block-version warning # is cleared, and restart the node. This should move the versionbit state @@ -142,20 +147,21 @@ def run_test(self): stop_node(self.nodes[0], 0) wait_bitcoinds() # Empty out the alert file - with open(self.alert_filename, 'w') as f: + with open(self.alert_filename, 'w') as _: pass - self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args) # Connecting one block should be enough to generate an error. self.nodes[0].generate(1) - assert(len(self.nodes[0].getinfo()["errors"]) != 0) + assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getinfo()["errors"]) + assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getmininginfo()["errors"]) + assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getnetworkinfo()["warnings"]) stop_node(self.nodes[0], 0) wait_bitcoinds() self.test_versionbits_in_alert_file() # Test framework expects the node to still be running... - self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]) - + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args) if __name__ == '__main__': VersionBitsWarningTest().main() diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py index 3ac32140ba89..085024e26838 100755 --- a/qa/rpc-tests/rpcbind_test.py +++ b/qa/rpc-tests/rpcbind_test.py @@ -44,7 +44,7 @@ def run_bind_test(self, allow_ips, connect_to, addresses, expected): def run_allowip_test(self, allow_ips, rpchost, rpcport): ''' - Start a node with rpcwallow IP, and request getinfo + Start a node with rpcallow IP, and request getnetworkinfo at a non-localhost IP. ''' base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips] @@ -52,7 +52,7 @@ def run_allowip_test(self, allow_ips, rpchost, rpcport): try: # connect to node through non-loopback interface node = get_rpc_proxy(rpc_url(0, "%s:%d" % (rpchost, rpcport)), 0) - node.getinfo() + node.getnetworkinfo() finally: node = None # make sure connection will be garbage collected and closed stop_nodes(self.nodes) diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index d095a56ce75e..f5e0be20d1ec 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -55,7 +55,11 @@ class JSONRPCException(Exception): def __init__(self, rpc_error): - Exception.__init__(self) + try: + errmsg = '%(message)s (%(code)i)' % rpc_error + except (KeyError, TypeError): + errmsg = '' + Exception.__init__(self, errmsg) self.error = rpc_error diff --git a/qa/rpc-tests/test_framework/blockstore.py b/qa/rpc-tests/test_framework/blockstore.py index 6120dd574b5d..1e2bbb277ac5 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/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index d7a7c9cc50f3..ec3442870665 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -121,7 +121,8 @@ def main(self): self.add_options(parser) (self.options, self.args) = parser.parse_args() - self.options.tmpdir += '/' + str(self.options.port_seed) + # backup dir variable for removal at cleanup + self.options.root, self.options.tmpdir = self.options.tmpdir, self.options.tmpdir + '/' + str(self.options.port_seed) if self.options.trace_rpc: logging.basicConfig(level=logging.DEBUG, stream=sys.stdout) @@ -172,6 +173,8 @@ def main(self): if not self.options.nocleanup and not self.options.noshutdown and success: print("Cleaning up") shutil.rmtree(self.options.tmpdir) + if not os.listdir(self.options.root): + os.rmdir(self.options.root) else: print("Not cleaning up dir %s" % self.options.tmpdir) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 83b1d6200b73..f100037e1dd2 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -18,9 +18,10 @@ def __init__(self): 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], redirect_stderr=True) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) connect_nodes_bi(self.nodes,0,2) @@ -155,7 +156,7 @@ def run_test (self): 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], redirect_stderr=True)) 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 6db1eff671a6..a8d28ed234ed 100755 --- a/qa/rpc-tests/walletbackup.py +++ b/qa/rpc-tests/walletbackup.py @@ -45,12 +45,12 @@ def __init__(self): 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 @@ def do_one_round(self): # 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 ed98254aba34..ff96c02ff09c 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/share/qt/protobuf.pri b/share/qt/protobuf.pri deleted file mode 100644 index 865fe865550a..000000000000 --- a/share/qt/protobuf.pri +++ /dev/null @@ -1,35 +0,0 @@ -# Based on: http://code.google.com/p/ostinato/source/browse/protobuf.pri -# -# Qt qmake integration with Google Protocol Buffers compiler protoc -# -# To compile protocol buffers with qt qmake, specify PROTOS variable and -# include this file -# -# Example: -# PROTOS = a.proto b.proto -# include(protobuf.pri) -# -# Set PROTO_PATH if you need to set the protoc --proto_path search path -# Set PROTOC to the path to the protoc compiler if it is not in your $PATH -# - -isEmpty(PROTO_DIR):PROTO_DIR = . -isEmpty(PROTOC):PROTOC = protoc - -PROTOPATHS = -for(p, PROTO_PATH):PROTOPATHS += --proto_path=$${p} - -protobuf_decl.name = protobuf header -protobuf_decl.input = PROTOS -protobuf_decl.output = $${PROTO_DIR}/${QMAKE_FILE_BASE}.pb.h -protobuf_decl.commands = $${PROTOC} --cpp_out="$${PROTO_DIR}" $${PROTOPATHS} --proto_path=${QMAKE_FILE_IN_PATH} ${QMAKE_FILE_NAME} -protobuf_decl.variable_out = GENERATED_FILES -QMAKE_EXTRA_COMPILERS += protobuf_decl - -protobuf_impl.name = protobuf implementation -protobuf_impl.input = PROTOS -protobuf_impl.output = $${PROTO_DIR}/${QMAKE_FILE_BASE}.pb.cc -protobuf_impl.depends = $${PROTO_DIR}/${QMAKE_FILE_BASE}.pb.h -protobuf_impl.commands = $$escape_expand(\\n) -protobuf_impl.variable_out = GENERATED_SOURCES -QMAKE_EXTRA_COMPILERS += protobuf_impl diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index a2a8ab48f68f..cb5c90ed866a 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -3,6 +3,7 @@ TESTS += qt/test/test_dash-qt TEST_QT_MOC_CPP = \ qt/test/moc_compattests.cpp \ + qt/test/moc_rpcnestedtests.cpp \ qt/test/moc_trafficgraphdatatests.cpp \ qt/test/moc_uritests.cpp @@ -12,6 +13,7 @@ endif TEST_QT_H = \ qt/test/compattests.h \ + qt/test/rpcnestedtests.h \ qt/test/uritests.h \ qt/test/paymentrequestdata.h \ qt/test/paymentservertests.h \ @@ -22,6 +24,7 @@ qt_test_test_dash_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_ qt_test_test_dash_qt_SOURCES = \ qt/test/compattests.cpp \ + qt/test/rpcnestedtests.cpp \ qt/test/test_main.cpp \ qt/test/uritests.cpp \ qt/test/trafficgraphdatatests.cpp \ diff --git a/src/addrman.cpp b/src/addrman.cpp index ee6bd5bda9a8..1d587440cf37 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -255,6 +255,11 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP int nId; CAddrInfo* pinfo = Find(addr, &nId); + // Do not set a penality for a source's self-announcement + if (addr == source) { + nTimePenalty = 0; + } + if (pinfo) { // periodically update nTime bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60); diff --git a/src/bloom.cpp b/src/bloom.cpp index 5285684d7e6f..d00befc61ca6 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -280,8 +280,8 @@ void CRollingBloomFilter::insert(const std::vector& vKey) void CRollingBloomFilter::insert(const uint256& hash) { - vector data(hash.begin(), hash.end()); - insert(data); + vector vData(hash.begin(), hash.end()); + insert(vData); } bool CRollingBloomFilter::contains(const std::vector& vKey) const @@ -300,8 +300,8 @@ bool CRollingBloomFilter::contains(const std::vector& vKey) const bool CRollingBloomFilter::contains(const uint256& hash) const { - vector data(hash.begin(), hash.end()); - return contains(data); + vector vData(hash.begin(), hash.end()); + return contains(vData); } void CRollingBloomFilter::reset() diff --git a/src/dash-cli.cpp b/src/dash-cli.cpp index 668208a090fe..b4a5e3b7e31c 100644 --- a/src/dash-cli.cpp +++ b/src/dash-cli.cpp @@ -131,17 +131,42 @@ static int AppInitRPC(int argc, char* argv[]) /** Reply structure for request_done to fill in */ struct HTTPReply { + HTTPReply(): status(0), error(-1) {} + int status; + int error; std::string body; }; +const char *http_errorstring(int code) +{ + switch(code) { +#if LIBEVENT_VERSION_NUMBER >= 0x02010300 + case EVREQ_HTTP_TIMEOUT: + return "timeout reached"; + case EVREQ_HTTP_EOF: + return "EOF reached"; + case EVREQ_HTTP_INVALID_HEADER: + return "error while reading header, or invalid header"; + case EVREQ_HTTP_BUFFER_ERROR: + return "error encountered while reading or writing"; + case EVREQ_HTTP_REQUEST_CANCEL: + return "request was canceled"; + case EVREQ_HTTP_DATA_TOO_LONG: + return "response body is larger than allowed"; +#endif + default: + return "unknown"; + } +} + static void http_request_done(struct evhttp_request *req, void *ctx) { HTTPReply *reply = static_cast(ctx); if (req == NULL) { - /* If req is NULL, it means an error occurred while connecting, but - * I'm not sure how to find out which one. We also don't really care. + /* If req is NULL, it means an error occurred while connecting: the + * error code will have been passed to http_error_cb. */ reply->status = 0; return; @@ -160,6 +185,14 @@ static void http_request_done(struct evhttp_request *req, void *ctx) } } +#if LIBEVENT_VERSION_NUMBER >= 0x02010300 +static void http_error_cb(enum evhttp_request_error err, void *ctx) +{ + HTTPReply *reply = static_cast(ctx); + reply->error = err; +} +#endif + UniValue CallRPC(const string& strMethod, const UniValue& params) { std::string host = GetArg("-rpcconnect", DEFAULT_RPCCONNECT); @@ -180,6 +213,9 @@ UniValue CallRPC(const string& strMethod, const UniValue& params) struct evhttp_request *req = evhttp_request_new(http_request_done, (void*)&response); // TODO RAII if (req == NULL) throw runtime_error("create http request failed"); +#if LIBEVENT_VERSION_NUMBER >= 0x02010300 + evhttp_request_set_error_cb(req, http_error_cb); +#endif // Get credentials std::string strRPCUserColonPass; @@ -219,7 +255,7 @@ UniValue CallRPC(const string& strMethod, const UniValue& params) event_base_free(base); if (response.status == 0) - throw CConnectionFailed("couldn't connect to server"); + throw CConnectionFailed(strprintf("couldn't connect to server (%d %s)", response.error, http_errorstring(response.error))); else if (response.status == HTTP_UNAUTHORIZED) throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)"); else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR) diff --git a/src/init.cpp b/src/init.cpp index 838e9e435f58..16f5ac4e49ad 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -869,10 +869,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. @@ -970,12 +967,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); } @@ -1003,15 +995,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 } if (mapArgs.count("-devnet")) { @@ -1116,9 +1103,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) RegisterAllCoreRPCCommands(tableRPC); #ifdef ENABLE_WALLET - bool fDisableWallet = GetBoolArg("-disablewallet", false); - if (!fDisableWallet) - RegisterWalletRPCCommands(tableRPC); + RegisterWalletRPCCommands(tableRPC); #endif nConnectTimeout = GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT); @@ -1134,10 +1119,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (mapArgs.count("-minrelaytxfee")) { CAmount n = 0; - if (ParseMoney(mapArgs["-minrelaytxfee"], n) && n > 0) - ::minRelayTxFee = CFeeRate(n); - else + if (!ParseMoney(mapArgs["-minrelaytxfee"], n)) return InitError(AmountErrMsg("minrelaytxfee", mapArgs["-minrelaytxfee"])); + // High fee check is done afterward in CWallet::ParameterInteraction() + ::minRelayTxFee = CFeeRate(n); } fRequireStandard = !GetBoolArg("-acceptnonstdtxn", !Params().RequireStandard()); @@ -1256,29 +1241,14 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 5: Backup wallet and verify wallet database integrity #ifdef ENABLE_WALLET - if (!fDisableWallet) { - std::string strWarning; - std::string strError; - - nWalletBackups = GetArg("-createwalletbackups", 10); - nWalletBackups = std::max(0, std::min(10, nWalletBackups)); - - std::string strWalletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); - - if(!AutoBackupWallet(NULL, strWalletFile, strWarning, strError)) { - if (!strWarning.empty()) - InitWarning(strWarning); - if (!strError.empty()) - return InitError(strError); - } - - if (!CWallet::Verify()) - return false; + if (!CWallet::InitAutoBackup()) + return false; - // Initialize KeePass Integration - keePassInt.init(); + if (!CWallet::Verify()) + return false; - } // (!fDisableWallet) + // Initialize KeePass Integration + keePassInt.init(); #endif // ENABLE_WALLET // ********************************************************* Step 6: network initialization // Note that we absolutely cannot open any actual connections @@ -1287,7 +1257,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // need to reindex later. assert(!g_connman); - g_connman = std::unique_ptr(new CConnman()); + g_connman = std::unique_ptr(new CConnman(GetRand(std::numeric_limits::max()), GetRand(std::numeric_limits::max()))); CConnman& connman = *g_connman; peerLogic.reset(new PeerLogicValidation(&connman)); @@ -1432,8 +1402,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) pdsNotificationInterface = new CDSNotificationInterface(connman); RegisterValidationInterface(pdsNotificationInterface); + 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 @@ -1623,17 +1596,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 8: load wallet #ifdef ENABLE_WALLET - if (fDisableWallet) { - pwalletMain = NULL; - LogPrintf("Wallet disabled!\n"); - } else { - CWallet::InitLoadWallet(); - if (!pwalletMain) - return false; - } -#else // ENABLE_WALLET + if (!CWallet::InitLoadWallet()) + return false; +#else LogPrintf("No wallet support compiled in!\n"); -#endif // !ENABLE_WALLET +#endif // ********************************************************* Step 9: data directory maintenance @@ -1847,6 +1814,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(scheduler, strNodeError, connOptions)) return InitError(strNodeError); diff --git a/src/key.cpp b/src/key.cpp index 79023566c3e6..aae9b042ac6d 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -243,12 +243,12 @@ bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const return ret; } -bool CExtKey::Derive(CExtKey &out, unsigned int nChild) const { +bool CExtKey::Derive(CExtKey &out, unsigned int _nChild) const { out.nDepth = nDepth + 1; CKeyID id = key.GetPubKey().GetID(); memcpy(&out.vchFingerprint[0], &id, 4); - out.nChild = nChild; - return key.Derive(out.key, out.chaincode, nChild, chaincode); + out.nChild = _nChild; + return key.Derive(out.key, out.chaincode, _nChild, chaincode); } void CExtKey::SetMaster(const unsigned char *seed, unsigned int nSeedLen) { diff --git a/src/net.cpp b/src/net.cpp index 853d57f12a93..4f3375712abb 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -70,6 +70,7 @@ const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*"; constexpr const CConnman::CFullyConnectedOnly CConnman::FullyConnectedOnly; constexpr const CConnman::CAllNodes CConnman::AllNodes; +static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL; // SHA256("netgroup")[0:8] // // Global state variables // @@ -411,7 +412,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, true); + CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), pszDest ? pszDest : "", false, true); pnode->nServicesExpected = ServiceFlags(addrConnect.nServices & nRelevantServices); pnode->nTimeConnected = GetSystemTimeInSeconds(); @@ -1077,7 +1078,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) { return; } - CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addr, "", true); + CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), "", true); pnode->fWhitelisted = whitelisted; GetNodeSignals().InitializeNode(pnode, *this); @@ -2127,7 +2128,7 @@ void CConnman::SetNetworkActive(bool active) uiInterface.NotifyNetworkActiveChanged(fNetworkActive); } -CConnman::CConnman() +CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In) : nSeed0(nSeed0In), nSeed1(nSeed1In) { fNetworkActive = true; setBannedIsDirty = false; @@ -2153,9 +2154,7 @@ bool CConnman::Start(CScheduler& scheduler, std::string& strNodeError, Options c { nTotalBytesRecv = 0; nTotalBytesSent = 0; - nMaxOutboundLimit = 0; nMaxOutboundTotalBytesSentInCycle = 0; - nMaxOutboundTimeframe = 60*60*24; //1 day nMaxOutboundCycleStartTime = 0; nRelevantServices = connOptions.nRelevantServices; @@ -2167,6 +2166,9 @@ bool CConnman::Start(CScheduler& scheduler, std::string& strNodeError, Options c nSendBufferMaxSize = connOptions.nSendBufferMaxSize; nReceiveFloodSize = connOptions.nReceiveFloodSize; + nMaxOutboundLimit = connOptions.nMaxOutboundLimit; + nMaxOutboundTimeframe = connOptions.nMaxOutboundTimeframe; + SetBestHeight(connOptions.nBestHeight); clientInterface = connOptions.uiInterface; @@ -2220,7 +2222,7 @@ bool CConnman::Start(CScheduler& scheduler, std::string& strNodeError, Options c 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, *this); } @@ -2518,11 +2520,7 @@ void CConnman::RecordBytesSent(uint64_t bytes) void CConnman::SetMaxOutboundTarget(uint64_t limit) { LOCK(cs_totalBytesSent); - uint64_t recommendedMinimum = (nMaxOutboundTimeframe / 600) * MaxBlockSize(true); nMaxOutboundLimit = limit; - - if (limit > 0 && limit < recommendedMinimum) - LogPrintf("Max outbound target is very small (%s bytes) and will be overshot. Recommended minimum is %s bytes.\n", nMaxOutboundLimit, recommendedMinimum); } uint64_t CConnman::GetMaxOutboundTarget() @@ -2622,9 +2620,9 @@ int CConnman::GetBestHeight() const 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, bool fNetworkNodeIn) : +CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, const std::string& addrNameIn, bool fInboundIn, bool fNetworkNodeIn) : addr(addrIn), - nKeyedNetGroup(CalculateKeyedNetGroup(addrIn)), + nKeyedNetGroup(nKeyedNetGroupIn), addrKnown(5000, 0.001), filterInventoryKnown(50000, 0.000001), nSendVersion(0) @@ -2859,12 +2857,14 @@ void CConnman::ReleaseNodeVector(const std::vector& vecNodes) } } -/* static */ uint64_t CNode::CalculateKeyedNetGroup(const CAddress& ad) +CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id) { - static const uint64_t k0 = GetRand(std::numeric_limits::max()); - static const uint64_t k1 = GetRand(std::numeric_limits::max()); + return CSipHasher(nSeed0, nSeed1).Write(id); +} +uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& ad) +{ std::vector 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 70ef33868855..fb9cd261f526 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" @@ -80,6 +81,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; @@ -128,8 +131,10 @@ class CConnman 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(CScheduler& scheduler, std::string& strNodeError, Options options); void Stop(); @@ -386,6 +391,8 @@ class CConnman void SetBestHeight(int height); int GetBestHeight() const; + /** Get a unique deterministic randomizer. */ + CSipHasher GetDeterministicRandomizer(uint64_t id); unsigned int GetReceiveFloodSize() const; private: @@ -405,6 +412,8 @@ class CConnman void ThreadDNSAddressSeed(); void ThreadMnbRequestConnections(); + uint64_t CalculateKeyedNetGroup(const CAddress& ad); + void WakeMessageHandler(); CNode* FindNode(const CNetAddr& ip); @@ -491,6 +500,9 @@ class CConnman std::atomic nBestHeight; CClientUIInterface* clientInterface; + /** SipHasher seeds for deterministic randomness */ + const uint64_t nSeed0, nSeed1; + /** flag for waking the message processor. */ bool fMsgProcWake; @@ -784,7 +796,7 @@ class CNode CAmount lastSentFeeFilter; int64_t nextSendTimeFeeFilter; - CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, const std::string &addrNameIn = "", bool fInboundIn = false, bool fNetworkNodeIn = false); + CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, const std::string &addrNameIn = "", bool fInboundIn = false, bool fNetworkNodeIn = false); ~CNode(); private: @@ -793,9 +805,9 @@ class CNode CNode(const CNode&); void operator=(const CNode&); - static uint64_t CalculateKeyedNetGroup(const CAddress& ad); uint64_t nLocalHostNonce; + // Services offered to this peer ServiceFlags nLocalServices; int nMyStartingHeight; int nSendVersion; diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 1594f4d0b063..3cb154f76bd7 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -70,6 +70,8 @@ map mapOrphanTransactions GUARDED_BY(cs_main); map::iterator, IteratorComparator>> mapOrphanTransactionsByPrev GUARDED_BY(cs_main); void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main); +static const uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL; // SHA256("main address relay")[0:8] + // Internal stuff namespace { /** Number of nodes with fSyncStarted. */ @@ -815,11 +817,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::max()); - static const uint64_t salt1 = GetRand(std::numeric_limits::max()); uint64_t hashAddr = addr.GetHash(); multimap 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) { @@ -1754,9 +1754,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } if (!fRejectedParents) { BOOST_FOREACH(const CTxIn& txin, tx.vin) { - CInv inv(MSG_TX, txin.prevout.hash); - pfrom->AddInventoryKnown(inv); - if (!AlreadyHave(inv)) pfrom->AskFor(inv); + CInv _inv(MSG_TX, txin.prevout.hash); + pfrom->AddInventoryKnown(_inv); + if (!AlreadyHave(_inv)) pfrom->AskFor(_inv); } AddOrphanTx(tx, pfrom->GetId()); @@ -2402,9 +2402,9 @@ class CompareInvMempoolOrder { CTxMemPool *mp; public: - CompareInvMempoolOrder(CTxMemPool *mempool) + CompareInvMempoolOrder(CTxMemPool *_mempool) { - mp = mempool; + mp = _mempool; } bool operator()(std::set::iterator a, std::set::iterator b) diff --git a/src/pubkey.cpp b/src/pubkey.cpp index be4ee27cd48d..91a657593a4a 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -264,12 +264,12 @@ void CExtPubKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) { pubkey.Set(code+41, code+BIP32_EXTKEY_SIZE); } -bool CExtPubKey::Derive(CExtPubKey &out, unsigned int nChild) const { +bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const { out.nDepth = nDepth + 1; CKeyID id = pubkey.GetID(); memcpy(&out.vchFingerprint[0], &id, 4); - out.nChild = nChild; - return pubkey.Derive(out.pubkey, out.chaincode, nChild, chaincode); + out.nChild = _nChild; + return pubkey.Derive(out.pubkey, out.chaincode, _nChild, chaincode); } /* static */ bool CPubKey::CheckLowS(const std::vector& vchSig) { diff --git a/src/pubkey.h b/src/pubkey.h index aebfdbc82662..3a554877f800 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -88,9 +88,9 @@ class CPubKey } //! Construct a public key from a byte vector. - CPubKey(const std::vector& vch) + CPubKey(const std::vector& _vch) { - Set(vch.begin(), vch.end()); + Set(_vch.begin(), _vch.end()); } //! Simple read-only vector-like interface to the pubkey data. diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 728eca6126f9..0cf52891449b 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -22,12 +22,12 @@ #include #include -AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode mode, Tabs tab, QWidget *parent) : +AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode _mode, Tabs _tab, QWidget *parent) : QDialog(parent), ui(new Ui::AddressBookPage), model(0), - mode(mode), - tab(tab) + mode(_mode), + tab(_tab) { QString theme = GUIUtil::getThemeName(); ui->setupUi(this); @@ -108,14 +108,14 @@ AddressBookPage::~AddressBookPage() delete ui; } -void AddressBookPage::setModel(AddressTableModel *model) +void AddressBookPage::setModel(AddressTableModel *_model) { - this->model = model; - if(!model) + this->model = _model; + if(!_model) return; proxyModel = new QSortFilterProxyModel(this); - proxyModel->setSourceModel(model); + proxyModel->setSourceModel(_model); proxyModel->setDynamicSortFilter(true); proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); @@ -148,7 +148,7 @@ void AddressBookPage::setModel(AddressTableModel *model) this, SLOT(selectionChanged())); // Select row for newly created address - connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(selectNewAddress(QModelIndex,int,int))); + connect(_model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(selectNewAddress(QModelIndex,int,int))); selectionChanged(); } diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 3339abf83db9..61a024ded318 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -32,8 +32,8 @@ struct AddressTableEntry QString address; AddressTableEntry() {} - AddressTableEntry(Type type, const QString &label, const QString &address): - type(type), label(label), address(address) {} + AddressTableEntry(Type _type, const QString &_label, const QString &_address): + type(_type), label(_label), address(_address) {} }; struct AddressTableEntryLessThan @@ -74,8 +74,8 @@ class AddressTablePriv QList cachedAddressTable; AddressTableModel *parent; - AddressTablePriv(CWallet *wallet, AddressTableModel *parent): - wallet(wallet), parent(parent) {} + AddressTablePriv(CWallet *_wallet, AddressTableModel *_parent): + wallet(_wallet), parent(_parent) {} void refreshAddressTable() { @@ -165,8 +165,8 @@ class AddressTablePriv } }; -AddressTableModel::AddressTableModel(CWallet *wallet, WalletModel *parent) : - QAbstractTableModel(parent),walletModel(parent),wallet(wallet),priv(0) +AddressTableModel::AddressTableModel(CWallet *_wallet, WalletModel *parent) : + QAbstractTableModel(parent),walletModel(parent),wallet(_wallet),priv(0) { columns << tr("Label") << tr("Address"); priv = new AddressTablePriv(wallet, this); diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 32a9409fdfe8..4032e1728e01 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -19,10 +19,10 @@ #include #include -AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : +AskPassphraseDialog::AskPassphraseDialog(Mode _mode, QWidget *parent) : QDialog(parent), ui(new Ui::AskPassphraseDialog), - mode(mode), + mode(_mode), model(0), fCapsLock(false) { @@ -85,9 +85,9 @@ AskPassphraseDialog::~AskPassphraseDialog() delete ui; } -void AskPassphraseDialog::setModel(WalletModel *model) +void AskPassphraseDialog::setModel(WalletModel *_model) { - this->model = model; + this->model = _model; } void AskPassphraseDialog::accept() diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index cc5d2ed381e5..8e377b0e29d2 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -79,8 +79,9 @@ const std::string BitcoinGUI::DEFAULT_UIPLATFORM = const QString BitcoinGUI::DEFAULT_WALLET = "~Default"; -BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent) : +BitcoinGUI::BitcoinGUI(const PlatformStyle *_platformStyle, const NetworkStyle *networkStyle, QWidget *parent) : QMainWindow(parent), + enableWallet(false), clientModel(0), walletFrame(0), unitDisplayControl(0), @@ -124,7 +125,7 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *n modalOverlay(0), prevBlocks(0), spinnerFrame(0), - platformStyle(platformStyle) + platformStyle(_platformStyle) { /* Open CSS when configured */ this->setStyleSheet(GUIUtil::loadStyleSheet()); @@ -133,10 +134,7 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *n QString windowTitle = tr(PACKAGE_NAME) + " - "; #ifdef ENABLE_WALLET - /* if compiled with wallet support, -disablewallet can still disable the wallet */ - enableWallet = !GetBoolArg("-disablewallet", false); -#else - enableWallet = false; + enableWallet = WalletModel::isWalletEnabled(); #endif // ENABLE_WALLET if(enableWallet) { @@ -161,13 +159,13 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *n setUnifiedTitleAndToolBarOnMac(true); #endif - rpcConsole = new RPCConsole(platformStyle, 0); + rpcConsole = new RPCConsole(_platformStyle, 0); helpMessageDialog = new HelpMessageDialog(this, HelpMessageDialog::cmdline); #ifdef ENABLE_WALLET if(enableWallet) { /** Create wallet frame*/ - walletFrame = new WalletFrame(platformStyle, this); + walletFrame = new WalletFrame(_platformStyle, this); } else #endif // ENABLE_WALLET { @@ -587,10 +585,10 @@ void BitcoinGUI::createToolBars() #endif // ENABLE_WALLET } -void BitcoinGUI::setClientModel(ClientModel *clientModel) +void BitcoinGUI::setClientModel(ClientModel *_clientModel) { - this->clientModel = clientModel; - if(clientModel) + this->clientModel = _clientModel; + if(_clientModel) { // Create system tray menu (or setup the dock menu) that late to prevent users from calling actions, // while the client has not yet fully loaded @@ -618,31 +616,32 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) // Keep up to date with client updateNetworkState(); - connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); - connect(clientModel, SIGNAL(networkActiveChanged(bool)), this, SLOT(setNetworkActive(bool))); + setNumConnections(_clientModel->getNumConnections()); + connect(_clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); + connect(_clientModel, SIGNAL(networkActiveChanged(bool)), this, SLOT(setNetworkActive(bool))); - modalOverlay->setKnownBestHeight(clientModel->getHeaderTipHeight(), QDateTime::fromTime_t(clientModel->getHeaderTipTime())); - setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate(), clientModel->getVerificationProgress(NULL), false); - connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool))); + modalOverlay->setKnownBestHeight(_clientModel->getHeaderTipHeight(), QDateTime::fromTime_t(_clientModel->getHeaderTipTime())); + setNumBlocks(_clientModel->getNumBlocks(), _clientModel->getLastBlockDate(), _clientModel->getVerificationProgress(NULL), false); + connect(_clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool))); - connect(clientModel, SIGNAL(additionalDataSyncProgressChanged(double)), this, SLOT(setAdditionalDataSyncProgress(double))); + connect(_clientModel, SIGNAL(additionalDataSyncProgressChanged(double)), this, SLOT(setAdditionalDataSyncProgress(double))); // Receive and report messages from client model - connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int))); + connect(_clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int))); // Show progress dialog - connect(clientModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int))); + connect(_clientModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int))); - rpcConsole->setClientModel(clientModel); + rpcConsole->setClientModel(_clientModel); #ifdef ENABLE_WALLET if(walletFrame) { - walletFrame->setClientModel(clientModel); + walletFrame->setClientModel(_clientModel); } #endif // ENABLE_WALLET - unitDisplayControl->setOptionsModel(clientModel->getOptionsModel()); + unitDisplayControl->setOptionsModel(_clientModel->getOptionsModel()); - OptionsModel* optionsModel = clientModel->getOptionsModel(); + OptionsModel* optionsModel = _clientModel->getOptionsModel(); if(optionsModel) { // be aware of the tray icon disable state change reported by the OptionsModel object. @@ -1509,17 +1508,17 @@ void UnitDisplayStatusBarControl::createContextMenu() } /** Lets the control know about the Options Model (and its signals) */ -void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *optionsModel) +void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *_optionsModel) { - if (optionsModel) + if (_optionsModel) { - this->optionsModel = optionsModel; + this->optionsModel = _optionsModel; // be aware of a display unit change reported by the OptionsModel object. - connect(optionsModel,SIGNAL(displayUnitChanged(int)),this,SLOT(updateDisplayUnit(int))); + connect(_optionsModel,SIGNAL(displayUnitChanged(int)),this,SLOT(updateDisplayUnit(int))); // initialize the display units label with the current value in the model. - updateDisplayUnit(optionsModel->getDisplayUnit()); + updateDisplayUnit(_optionsModel->getDisplayUnit()); } } diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 48f38f0fd144..041857369673 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -34,9 +34,9 @@ static const int64_t nClientStartupTime = GetTime(); static int64_t nLastHeaderTipUpdateNotification = 0; static int64_t nLastBlockTipUpdateNotification = 0; -ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : +ClientModel::ClientModel(OptionsModel *_optionsModel, QObject *parent) : QObject(parent), - optionsModel(optionsModel), + optionsModel(_optionsModel), peerTableModel(0), cachedMasternodeCountString(""), banTableModel(0), diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 7caf1376a915..0bd4a42ac867 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -39,11 +39,11 @@ QList CoinControlDialog::payAmounts; CCoinControl* CoinControlDialog::coinControl = new CCoinControl(); bool CoinControlDialog::fSubtractFeeFromAmount = false; -CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent) : +CoinControlDialog::CoinControlDialog(const PlatformStyle *_platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::CoinControlDialog), model(0), - platformStyle(platformStyle) + platformStyle(_platformStyle) { ui->setupUi(this); @@ -163,15 +163,15 @@ CoinControlDialog::~CoinControlDialog() delete ui; } -void CoinControlDialog::setModel(WalletModel *model) +void CoinControlDialog::setModel(WalletModel *_model) { - this->model = model; + this->model = _model; - if(model && model->getOptionsModel() && model->getAddressTableModel()) + if(_model && _model->getOptionsModel() && _model->getAddressTableModel()) { updateView(); updateLabelLocked(); - CoinControlDialog::updateLabels(model, this); + CoinControlDialog::updateLabels(_model, this); } } diff --git a/src/qt/csvmodelwriter.cpp b/src/qt/csvmodelwriter.cpp index 8a1a49bb06c5..f424e6cd9824 100644 --- a/src/qt/csvmodelwriter.cpp +++ b/src/qt/csvmodelwriter.cpp @@ -8,15 +8,15 @@ #include #include -CSVModelWriter::CSVModelWriter(const QString &filename, QObject *parent) : +CSVModelWriter::CSVModelWriter(const QString &_filename, QObject *parent) : QObject(parent), - filename(filename), model(0) + filename(_filename), model(0) { } -void CSVModelWriter::setModel(const QAbstractItemModel *model) +void CSVModelWriter::setModel(const QAbstractItemModel *_model) { - this->model = model; + this->model = _model; } void CSVModelWriter::addColumn(const QString &title, int column, int role) diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp index 521246b794e4..5f05e50349e7 100644 --- a/src/qt/editaddressdialog.cpp +++ b/src/qt/editaddressdialog.cpp @@ -12,11 +12,11 @@ #include #include -EditAddressDialog::EditAddressDialog(Mode mode, QWidget *parent) : +EditAddressDialog::EditAddressDialog(Mode _mode, QWidget *parent) : QDialog(parent), ui(new Ui::EditAddressDialog), mapper(0), - mode(mode), + mode(_mode), model(0) { ui->setupUi(this); @@ -50,13 +50,13 @@ EditAddressDialog::~EditAddressDialog() delete ui; } -void EditAddressDialog::setModel(AddressTableModel *model) +void EditAddressDialog::setModel(AddressTableModel *_model) { - this->model = model; - if(!model) + this->model = _model; + if(!_model) return; - mapper->setModel(model); + mapper->setModel(_model); mapper->addMapping(ui->labelEdit, AddressTableModel::Label); mapper->addMapping(ui->addressEdit, AddressTableModel::Address); } @@ -138,8 +138,8 @@ QString EditAddressDialog::getAddress() const return address; } -void EditAddressDialog::setAddress(const QString &address) +void EditAddressDialog::setAddress(const QString &_address) { - this->address = address; - ui->addressEdit->setText(address); + this->address = _address; + ui->addressEdit->setText(_address); } diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 3b842e519360..371c9ce4556f 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -501,9 +501,9 @@ void SubstituteFonts(const QString& language) #endif } -ToolTipToRichTextFilter::ToolTipToRichTextFilter(int size_threshold, QObject *parent) : +ToolTipToRichTextFilter::ToolTipToRichTextFilter(int _size_threshold, QObject *parent) : QObject(parent), - size_threshold(size_threshold) + size_threshold(_size_threshold) { } diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index b9bc470c9790..63c7b38dc611 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -64,9 +64,9 @@ public Q_SLOTS: #include "intro.moc" -FreespaceChecker::FreespaceChecker(Intro *intro) +FreespaceChecker::FreespaceChecker(Intro *_intro) { - this->intro = intro; + this->intro = _intro; } void FreespaceChecker::check() diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp index c77e70c3094a..d45320c5b5ab 100644 --- a/src/qt/modaloverlay.cpp +++ b/src/qt/modaloverlay.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017 The Bitcoin Core developers +// 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. diff --git a/src/qt/modaloverlay.h b/src/qt/modaloverlay.h index ea9abec476e0..d82983ea7dd4 100644 --- a/src/qt/modaloverlay.h +++ b/src/qt/modaloverlay.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017 The Bitcoin Core developers +// 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. diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index 5a299ca49a89..a10a930aca40 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -62,9 +62,9 @@ void NetworkStyle::rotateColors(QImage& img, const int iconColorHueShift, const } // titleAddText needs to be const char* for tr() -NetworkStyle::NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText): - appName(appName), - titleAddText(qApp->translate("SplashScreen", titleAddText)) +NetworkStyle::NetworkStyle(const QString &_appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *_titleAddText): + appName(_appName), + titleAddText(qApp->translate("SplashScreen", _titleAddText)) { // Allow for separate UI settings for testnets QApplication::setApplicationName(appName); diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp index a45afde5660d..8277e20c909b 100644 --- a/src/qt/notificator.cpp +++ b/src/qt/notificator.cpp @@ -33,17 +33,17 @@ const int FREEDESKTOP_NOTIFICATION_ICON_SIZE = 128; #endif -Notificator::Notificator(const QString &programName, QSystemTrayIcon *trayicon, QWidget *parent) : - QObject(parent), - parent(parent), - programName(programName), +Notificator::Notificator(const QString &_programName, QSystemTrayIcon *_trayIcon, QWidget *_parent) : + QObject(_parent), + parent(_parent), + programName(_programName), mode(None), - trayIcon(trayicon) + trayIcon(_trayIcon) #ifdef USE_DBUS ,interface(0) #endif { - if(trayicon && trayicon->supportsMessages()) + if(_trayIcon && _trayIcon->supportsMessages()) { mode = QSystemTray; } diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 337a476cee5b..0e06634c304b 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -157,22 +157,22 @@ OptionsDialog::~OptionsDialog() delete ui; } -void OptionsDialog::setModel(OptionsModel *model) +void OptionsDialog::setModel(OptionsModel *_model) { - this->model = model; + this->model = _model; - if(model) + if(_model) { /* check if client restart is needed and show persistent message */ - if (model->isRestartRequired()) + if (_model->isRestartRequired()) showRestartWarning(true); - QString strLabel = model->getOverriddenByCommandLine(); + QString strLabel = _model->getOverriddenByCommandLine(); if (strLabel.isEmpty()) strLabel = tr("none"); ui->overriddenByCommandLineLabel->setText(strLabel); - mapper->setModel(model); + mapper->setModel(_model); setMapper(); mapper->toFirst(); diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 9ee16b17568e..51a6964dcd98 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -38,7 +38,7 @@ class TxViewDelegate : public QAbstractItemDelegate Q_OBJECT public: TxViewDelegate(const PlatformStyle *_platformStyle, QObject *parent=nullptr): - QAbstractItemDelegate(parent), unit(BitcoinUnits::DASH), + QAbstractItemDelegate(), unit(BitcoinUnits::DASH), platformStyle(_platformStyle) { diff --git a/src/qt/paymentrequest.proto b/src/qt/paymentrequest.proto index b2281c4c7b34..d2721a34bde8 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/paymentserver.cpp b/src/qt/paymentserver.cpp index 0502e4c325fe..82fdcc7f164d 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -750,9 +750,9 @@ void PaymentServer::reportSslErrors(QNetworkReply* reply, const QList Q_EMIT message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR); } -void PaymentServer::setOptionsModel(OptionsModel *optionsModel) +void PaymentServer::setOptionsModel(OptionsModel *_optionsModel) { - this->optionsModel = optionsModel; + this->optionsModel = _optionsModel; } void PaymentServer::handlePaymentACK(const QString& paymentACKMsg) diff --git a/src/qt/platformstyle.cpp b/src/qt/platformstyle.cpp index 16b79c939908..06ecd38d260a 100644 --- a/src/qt/platformstyle.cpp +++ b/src/qt/platformstyle.cpp @@ -73,11 +73,11 @@ QIcon ColorizeIcon(const QString& filename, const QColor& colorbase) } -PlatformStyle::PlatformStyle(const QString &name, bool imagesOnButtons, bool colorizeIcons, bool useExtraSpacing): - name(name), - imagesOnButtons(imagesOnButtons), - colorizeIcons(colorizeIcons), - useExtraSpacing(useExtraSpacing), +PlatformStyle::PlatformStyle(const QString &_name, bool _imagesOnButtons, bool _colorizeIcons, bool _useExtraSpacing): + name(_name), + imagesOnButtons(_imagesOnButtons), + colorizeIcons(_colorizeIcons), + useExtraSpacing(_useExtraSpacing), singleColor(0,0,0), textColor(0,0,0) { diff --git a/src/qt/qvalidatedlineedit.cpp b/src/qt/qvalidatedlineedit.cpp index baa2eb67f762..492b96ff09b6 100644 --- a/src/qt/qvalidatedlineedit.cpp +++ b/src/qt/qvalidatedlineedit.cpp @@ -15,14 +15,14 @@ QValidatedLineEdit::QValidatedLineEdit(QWidget *parent) : connect(this, SIGNAL(textChanged(QString)), this, SLOT(markValid())); } -void QValidatedLineEdit::setValid(bool valid) +void QValidatedLineEdit::setValid(bool _valid) { - if(valid == this->valid) + if(_valid == this->valid) { return; } - if(valid) + if(_valid) { setStyleSheet(""); } @@ -30,7 +30,7 @@ void QValidatedLineEdit::setValid(bool valid) { setStyleSheet(STYLE_INVALID); } - this->valid = valid; + this->valid = _valid; } void QValidatedLineEdit::focusInEvent(QFocusEvent *evt) diff --git a/src/qt/qvaluecombobox.cpp b/src/qt/qvaluecombobox.cpp index 146f3dd57850..2f2478783c02 100644 --- a/src/qt/qvaluecombobox.cpp +++ b/src/qt/qvaluecombobox.cpp @@ -20,9 +20,9 @@ void QValueComboBox::setValue(const QVariant &value) setCurrentIndex(findData(value, role)); } -void QValueComboBox::setRole(int role) +void QValueComboBox::setRole(int _role) { - this->role = role; + this->role = _role; } void QValueComboBox::handleSelectionChanged(int idx) diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index a42090af2e79..1d087aec74c8 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -22,17 +22,17 @@ #include #include -ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) : +ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::ReceiveCoinsDialog), columnResizingFixer(0), model(0), - platformStyle(platformStyle) + platformStyle(_platformStyle) { ui->setupUi(this); QString theme = GUIUtil::getThemeName(); - if (!platformStyle->getImagesOnButtons()) { + if (!_platformStyle->getImagesOnButtons()) { ui->clearButton->setIcon(QIcon()); ui->receiveButton->setIcon(QIcon()); ui->showRequestButton->setIcon(QIcon()); @@ -67,21 +67,21 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidg connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear())); } -void ReceiveCoinsDialog::setModel(WalletModel *model) +void ReceiveCoinsDialog::setModel(WalletModel *_model) { - this->model = model; + this->model = _model; - if(model && model->getOptionsModel()) + if(_model && _model->getOptionsModel()) { - model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder); - connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + _model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder); + connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); updateDisplayUnit(); QTableView* tableView = ui->recentRequestsView; tableView->verticalHeader()->hide(); tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - tableView->setModel(model->getRecentRequestsTableModel()); + tableView->setModel(_model->getRecentRequestsTableModel()); tableView->setAlternatingRowColors(true); tableView->setSelectionBehavior(QAbstractItemView::SelectRows); tableView->setSelectionMode(QAbstractItemView::ContiguousSelection); diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index be4ae56c4025..25461f1bab43 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -109,20 +109,20 @@ ReceiveRequestDialog::~ReceiveRequestDialog() delete ui; } -void ReceiveRequestDialog::setModel(OptionsModel *model) +void ReceiveRequestDialog::setModel(OptionsModel *_model) { - this->model = model; + this->model = _model; - if (model) - connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(update())); + if (_model) + connect(_model, SIGNAL(displayUnitChanged(int)), this, SLOT(update())); // update the display unit if necessary update(); } -void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &info) +void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &_info) { - this->info = info; + this->info = _info; update(); } diff --git a/src/qt/res/movies/makespinner.sh b/src/qt/res/movies/makespinner.sh index a4c2fddbbfe5..d0deb1238c2b 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 12039b4e612c..417216ad9740 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -93,8 +93,8 @@ class QtRPCTimerBase: public QObject, public RPCTimerBase { Q_OBJECT public: - QtRPCTimerBase(boost::function& func, int64_t millis): - func(func) + QtRPCTimerBase(boost::function& _func, int64_t millis): + func(_func) { timer.setSingleShot(true); connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); @@ -123,9 +123,11 @@ class QtRPCTimerInterface: public RPCTimerInterface #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 @@ -133,11 +135,15 @@ class QtRPCTimerInterface: public RPCTimerInterface * - 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 &args, const std::string &strCommand) + +bool RPCConsole::RPCExecuteCommandLine(std::string &strResult, const std::string &strCommand) { + std::vector< std::vector > stack; + stack.push_back(std::vector()); + enum CmdParseState { STATE_EATING_SPACES, @@ -145,95 +151,180 @@ bool parseCommandLine(std::vector &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()); + 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(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 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(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) { @@ -254,12 +345,12 @@ void RPCExecutor::request(const QString &command) } } -RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : +RPCConsole::RPCConsole(const PlatformStyle *_platformStyle, QWidget *parent) : QWidget(parent), ui(new Ui::RPCConsole), clientModel(0), historyPtr(0), - platformStyle(platformStyle), + platformStyle(_platformStyle), peersTableContextMenu(0), banTableContextMenu(0), consoleFontSize(0) diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 0658c9526d9e..83e4f7558f57 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -37,6 +37,8 @@ class RPCConsole: public QWidget 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/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 2d394c0452e4..626ef31db23b 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -33,19 +33,19 @@ #define SEND_CONFIRM_DELAY 3 -SendCoinsDialog::SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) : +SendCoinsDialog::SendCoinsDialog(const PlatformStyle *_platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::SendCoinsDialog), clientModel(0), model(0), fNewRecipientAllowed(true), fFeeMinimized(true), - platformStyle(platformStyle) + platformStyle(_platformStyle) { ui->setupUi(this); QString theme = GUIUtil::getThemeName(); - if (!platformStyle->getImagesOnButtons()) { + if (!_platformStyle->getImagesOnButtons()) { ui->addButton->setIcon(QIcon()); ui->clearButton->setIcon(QIcon()); ui->sendButton->setIcon(QIcon()); @@ -146,40 +146,40 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *pa minimizeFeeSection(settings.value("fFeeSectionMinimized").toBool()); } -void SendCoinsDialog::setClientModel(ClientModel *clientModel) +void SendCoinsDialog::setClientModel(ClientModel *_clientModel) { - this->clientModel = clientModel; + this->clientModel = _clientModel; - if (clientModel) { - connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(updateSmartFeeLabel())); + if (_clientModel) { + connect(_clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(updateSmartFeeLabel())); } } -void SendCoinsDialog::setModel(WalletModel *model) +void SendCoinsDialog::setModel(WalletModel *_model) { - this->model = model; + this->model = _model; - if(model && model->getOptionsModel()) + if(_model && _model->getOptionsModel()) { for(int i = 0; i < ui->entries->count(); ++i) { SendCoinsEntry *entry = qobject_cast(ui->entries->itemAt(i)->widget()); if(entry) { - entry->setModel(model); + entry->setModel(_model); } } - setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(), model->getAnonymizedBalance(), - model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance()); - connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount,CAmount))); - connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + setBalance(_model->getBalance(), _model->getUnconfirmedBalance(), _model->getImmatureBalance(), _model->getAnonymizedBalance(), + _model->getWatchBalance(), _model->getWatchUnconfirmedBalance(), _model->getWatchImmatureBalance()); + connect(_model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount,CAmount))); + connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); updateDisplayUnit(); // Coin Control - connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(coinControlUpdateLabels())); - connect(model->getOptionsModel(), SIGNAL(coinControlFeaturesChanged(bool)), this, SLOT(coinControlFeatureChanged(bool))); - ui->frameCoinControl->setVisible(model->getOptionsModel()->getCoinControlFeatures()); + connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(coinControlUpdateLabels())); + connect(_model->getOptionsModel(), SIGNAL(coinControlFeaturesChanged(bool)), this, SLOT(coinControlFeatureChanged(bool))); + ui->frameCoinControl->setVisible(_model->getOptionsModel()->getCoinControlFeatures()); coinControlUpdateLabels(); // fee section @@ -941,9 +941,9 @@ void SendCoinsDialog::coinControlUpdateLabels() } } -SendConfirmationDialog::SendConfirmationDialog(const QString &title, const QString &text, int secDelay, +SendConfirmationDialog::SendConfirmationDialog(const QString &title, const QString &text, int _secDelay, QWidget *parent) : - QMessageBox(QMessageBox::Question, title, text, QMessageBox::Yes | QMessageBox::Cancel, parent), secDelay(secDelay) + QMessageBox(QMessageBox::Question, title, text, QMessageBox::Yes | QMessageBox::Cancel, parent), secDelay(_secDelay) { setDefaultButton(QMessageBox::Cancel); yesButton = button(QMessageBox::Yes); diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 4fb43bcd6b90..c4fe9a44cc32 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -16,11 +16,11 @@ #include #include -SendCoinsEntry::SendCoinsEntry(const PlatformStyle *platformStyle, QWidget *parent) : +SendCoinsEntry::SendCoinsEntry(const PlatformStyle *_platformStyle, QWidget *parent) : QStackedWidget(parent), ui(new Ui::SendCoinsEntry), model(0), - platformStyle(platformStyle) + platformStyle(_platformStyle) { ui->setupUi(this); @@ -83,12 +83,12 @@ void SendCoinsEntry::on_payTo_textChanged(const QString &address) updateLabel(address); } -void SendCoinsEntry::setModel(WalletModel *model) +void SendCoinsEntry::setModel(WalletModel *_model) { - this->model = model; + this->model = _model; - if (model && model->getOptionsModel()) - connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + if (_model && _model->getOptionsModel()) + connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); clear(); } diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index eb95f1272326..7a2c6018f579 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -21,11 +21,11 @@ #include -SignVerifyMessageDialog::SignVerifyMessageDialog(const PlatformStyle *platformStyle, QWidget *parent) : +SignVerifyMessageDialog::SignVerifyMessageDialog(const PlatformStyle *_platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::SignVerifyMessageDialog), model(0), - platformStyle(platformStyle) + platformStyle(_platformStyle) { ui->setupUi(this); @@ -73,9 +73,9 @@ SignVerifyMessageDialog::~SignVerifyMessageDialog() delete ui; } -void SignVerifyMessageDialog::setModel(WalletModel *model) +void SignVerifyMessageDialog::setModel(WalletModel *_model) { - this->model = model; + this->model = _model; } void SignVerifyMessageDialog::setAddress_SM(const QString &address) diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp new file mode 100644 index 000000000000..c9a155345811 --- /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 "validation.h" +#include "rpc/register.h" +#include "rpc/server.h" +#include "rpcconsole.h" +#include "test/testutil.h" +#include "univalue.h" +#include "util.h" + +#include + +#include + +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 == "e0028eb9648db56b1ac77cf090b99048a8007e2bb64b68f092c03c7f56a662c7"); + + 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 000000000000..9ad409019f28 --- /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 +#include + +#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 00adddc04ee4..3bc073b13d7c 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 // Copyright (c) 2014-2017 The Dash Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,6 +7,9 @@ #include "config/dash-config.h" #endif +#include "chainparams.h" +#include "key.h" +#include "rpcnestedtests.h" #include "util.h" #include "uritests.h" #include "compattests.h" @@ -30,10 +33,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 @@ -51,6 +61,10 @@ int main(int argc, char *argv[]) if (QTest::qExec(&test2) != 0) fInvalid = true; #endif + RPCNestedTests test3; + if (QTest::qExec(&test3) != 0) + fInvalid = true; + CompatTests test4; if (QTest::qExec(&test4) != 0) fInvalid = true; @@ -58,6 +72,6 @@ int main(int argc, char *argv[]) TrafficGraphDataTests test5; if (QTest::qExec(&test5) != 0) fInvalid = true; - + ECC_Stop(); return fInvalid; } diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp index 149aeabe83a0..76ca8e00e97f 100644 --- a/src/qt/transactionfilterproxy.cpp +++ b/src/qt/transactionfilterproxy.cpp @@ -66,9 +66,9 @@ void TransactionFilterProxy::setDateRange(const QDateTime &from, const QDateTime invalidateFilter(); } -void TransactionFilterProxy::setAddressPrefix(const QString &addrPrefix) +void TransactionFilterProxy::setAddressPrefix(const QString &_addrPrefix) { - this->addrPrefix = addrPrefix; + this->addrPrefix = _addrPrefix; invalidateFilter(); } @@ -95,9 +95,9 @@ void TransactionFilterProxy::setLimit(int limit) this->limitRows = limit; } -void TransactionFilterProxy::setShowInactive(bool showInactive) +void TransactionFilterProxy::setShowInactive(bool _showInactive) { - this->showInactive = showInactive; + this->showInactive = _showInactive; invalidateFilter(); } diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index 37b1a0c6cae6..673b01736836 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -97,16 +97,16 @@ class TransactionRecord { } - TransactionRecord(uint256 hash, qint64 time): - hash(hash), time(time), type(Other), address(""), debit(0), + TransactionRecord(uint256 _hash, qint64 _time): + hash(_hash), time(_time), type(Other), address(""), debit(0), credit(0), idx(0) { } - TransactionRecord(uint256 hash, qint64 time, - Type type, const std::string &address, - const CAmount& debit, const CAmount& credit): - hash(hash), time(time), type(type), address(address), debit(debit), credit(credit), + TransactionRecord(uint256 _hash, qint64 _time, + Type _type, const std::string &_address, + const CAmount& _debit, const CAmount& _credit): + hash(_hash), time(_time), type(_type), address(_address), debit(_debit), credit(_credit), idx(0) { } diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 5ba8e02229e7..d24087aca6de 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -59,9 +59,9 @@ struct TxLessThan class TransactionTablePriv { public: - TransactionTablePriv(CWallet *wallet, TransactionTableModel *parent) : - wallet(wallet), - parent(parent) + TransactionTablePriv(CWallet *_wallet, TransactionTableModel *_parent) : + wallet(_wallet), + parent(_parent) { } @@ -235,13 +235,13 @@ class TransactionTablePriv } }; -TransactionTableModel::TransactionTableModel(const PlatformStyle *platformStyle, CWallet* wallet, WalletModel *parent): +TransactionTableModel::TransactionTableModel(const PlatformStyle *_platformStyle, CWallet* _wallet, WalletModel *parent): QAbstractTableModel(parent), - wallet(wallet), + wallet(_wallet), walletModel(parent), - priv(new TransactionTablePriv(wallet, this)), + priv(new TransactionTablePriv(_wallet, this)), fProcessingQueuedTransactions(false), - platformStyle(platformStyle) + platformStyle(_platformStyle) { columns << QString() << QString() << tr("Date") << tr("Type") << tr("Address / Label") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit()); priv->refreshWallet(); @@ -738,8 +738,8 @@ struct TransactionNotification { public: TransactionNotification() {} - TransactionNotification(uint256 hash, ChangeType status, bool showTransaction): - hash(hash), status(status), showTransaction(showTransaction) {} + TransactionNotification(uint256 _hash, ChangeType _status, bool _showTransaction): + hash(_hash), status(_status), showTransaction(_showTransaction) {} void invoke(QObject *ttm) { diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 44a1b74f2676..b64f217c8ae3 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -199,14 +199,14 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa connect(showDetailsAction, SIGNAL(triggered()), this, SLOT(showDetails())); } -void TransactionView::setModel(WalletModel *model) +void TransactionView::setModel(WalletModel *_model) { QSettings settings; - this->model = model; - if(model) + this->model = _model; + if(_model) { transactionProxyModel = new TransactionFilterProxy(this); - transactionProxyModel->setSourceModel(model->getTransactionTableModel()); + transactionProxyModel->setSourceModel(_model->getTransactionTableModel()); transactionProxyModel->setDynamicSortFilter(true); transactionProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); transactionProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); @@ -233,10 +233,10 @@ void TransactionView::setModel(WalletModel *model) columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(transactionView, AMOUNT_MINIMUM_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH, this); - if (model->getOptionsModel()) + if (_model->getOptionsModel()) { // Add third party transaction URLs to context menu - QStringList listUrls = model->getOptionsModel()->getThirdPartyTxUrls().split("|", QString::SkipEmptyParts); + QStringList listUrls = _model->getOptionsModel()->getThirdPartyTxUrls().split("|", QString::SkipEmptyParts); for (int i = 0; i < listUrls.size(); ++i) { QString host = QUrl(listUrls[i].trimmed(), QUrl::StrictMode).host(); @@ -253,10 +253,10 @@ void TransactionView::setModel(WalletModel *model) } // show/hide column Watch-only - updateWatchOnlyColumn(model->haveWatchOnly()); + updateWatchOnlyColumn(_model->haveWatchOnly()); // Watch-only signal - connect(model, SIGNAL(notifyWatchonlyChanged(bool)), this, SLOT(updateWatchOnlyColumn(bool))); + connect(_model, SIGNAL(notifyWatchonlyChanged(bool)), this, SLOT(updateWatchOnlyColumn(bool))); // Update transaction list with persisted settings chooseType(settings.value("transactionType").toInt()); diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index fcc34683f824..0eca28ddebf7 100644 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -12,10 +12,10 @@ #include #include -WalletFrame::WalletFrame(const PlatformStyle *platformStyle, BitcoinGUI *_gui) : +WalletFrame::WalletFrame(const PlatformStyle *_platformStyle, BitcoinGUI *_gui) : QFrame(_gui), gui(_gui), - platformStyle(platformStyle) + platformStyle(_platformStyle) { // Leave HBox hook for adding a list view later QHBoxLayout *walletFrameLayout = new QHBoxLayout(this); @@ -33,9 +33,9 @@ WalletFrame::~WalletFrame() { } -void WalletFrame::setClientModel(ClientModel *clientModel) +void WalletFrame::setClientModel(ClientModel *_clientModel) { - this->clientModel = clientModel; + this->clientModel = _clientModel; } bool WalletFrame::addWallet(const QString& name, WalletModel *walletModel) diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index f878c2cbcf64..444ede7194dd 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -34,8 +34,8 @@ #include -WalletModel::WalletModel(const PlatformStyle *platformStyle, CWallet *wallet, OptionsModel *optionsModel, QObject *parent) : - QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0), +WalletModel::WalletModel(const PlatformStyle *platformStyle, CWallet *_wallet, OptionsModel *_optionsModel, QObject *parent) : + QObject(parent), wallet(_wallet), optionsModel(_optionsModel), addressTableModel(0), transactionTableModel(0), recentRequestsTableModel(0), cachedBalance(0), @@ -605,11 +605,11 @@ WalletModel::UnlockContext WalletModel::requestUnlock(bool fForMixingOnly) return UnlockContext(this, !fInvalid, !fKeepUnlocked, was_mixing); } -WalletModel::UnlockContext::UnlockContext(WalletModel *wallet, bool valid, bool was_locked, bool was_mixing): - wallet(wallet), - valid(valid), - was_locked(was_locked), - was_mixing(was_mixing) +WalletModel::UnlockContext::UnlockContext(WalletModel *_wallet, bool _valid, bool _was_locked, bool _was_mixing): + wallet(_wallet), + valid(_valid), + was_locked(_was_locked), + was_mixing(_was_mixing) { } @@ -760,6 +760,11 @@ bool WalletModel::abandonTransaction(uint256 hash) const return wallet->AbandonTransaction(hash); } +bool WalletModel::isWalletEnabled() +{ + return !GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET); +} + bool WalletModel::hdEnabled() const { return wallet->IsHDEnabled(); diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 87522d40c74f..01d9052f986d 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -41,8 +41,8 @@ class SendCoinsRecipient { public: explicit SendCoinsRecipient() : amount(0), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) { } - explicit SendCoinsRecipient(const QString &addr, const QString &label, const CAmount& amount, const QString &message): - address(addr), label(label), amount(amount), message(message), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) {} + explicit SendCoinsRecipient(const QString &addr, const QString &_label, const CAmount& _amount, const QString &_message): + address(addr), label(_label), amount(_amount), message(_message), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) {} // If from an unauthenticated payment request, this is used for storing // the addresses, e.g. address-A
address-B
address-C. @@ -154,8 +154,8 @@ class WalletModel : public QObject // Return status record for SendCoins, contains error id + information struct SendCoinsReturn { - SendCoinsReturn(StatusCode status = OK): - status(status) {} + SendCoinsReturn(StatusCode _status = OK): + status(_status) {} StatusCode status; }; @@ -214,6 +214,8 @@ class WalletModel : public QObject bool transactionCanBeAbandoned(uint256 hash) const; bool abandonTransaction(uint256 hash) const; + static bool isWalletEnabled(); + bool hdEnabled() const; private: diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index 8c970ee8aabe..2db2ff3318e5 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -6,8 +6,8 @@ #include "wallet/wallet.h" -WalletModelTransaction::WalletModelTransaction(const QList &recipients) : - recipients(recipients), +WalletModelTransaction::WalletModelTransaction(const QList &_recipients) : + recipients(_recipients), walletTransaction(0), keyChange(0), fee(0) diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index b42573cc734f..14b69e41c2ab 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -32,11 +32,11 @@ #include #include -WalletView::WalletView(const PlatformStyle *platformStyle, QWidget *parent): +WalletView::WalletView(const PlatformStyle *_platformStyle, QWidget *parent): QStackedWidget(parent), clientModel(0), walletModel(0), - platformStyle(platformStyle) + platformStyle(_platformStyle) { // Create tabs overviewPage = new OverviewPage(platformStyle); @@ -132,55 +132,55 @@ void WalletView::setBitcoinGUI(BitcoinGUI *gui) } } -void WalletView::setClientModel(ClientModel *clientModel) +void WalletView::setClientModel(ClientModel *_clientModel) { - this->clientModel = clientModel; + this->clientModel = _clientModel; - overviewPage->setClientModel(clientModel); - sendCoinsPage->setClientModel(clientModel); + overviewPage->setClientModel(_clientModel); + sendCoinsPage->setClientModel(_clientModel); QSettings settings; if (settings.value("fShowMasternodesTab").toBool()) { - masternodeListPage->setClientModel(clientModel); + masternodeListPage->setClientModel(_clientModel); } } -void WalletView::setWalletModel(WalletModel *walletModel) +void WalletView::setWalletModel(WalletModel *_walletModel) { - this->walletModel = walletModel; + this->walletModel = _walletModel; // Put transaction list in tabs - transactionView->setModel(walletModel); - overviewPage->setWalletModel(walletModel); + transactionView->setModel(_walletModel); + overviewPage->setWalletModel(_walletModel); QSettings settings; if (settings.value("fShowMasternodesTab").toBool()) { - masternodeListPage->setWalletModel(walletModel); + masternodeListPage->setWalletModel(_walletModel); } - receiveCoinsPage->setModel(walletModel); - sendCoinsPage->setModel(walletModel); - usedReceivingAddressesPage->setModel(walletModel->getAddressTableModel()); - usedSendingAddressesPage->setModel(walletModel->getAddressTableModel()); + receiveCoinsPage->setModel(_walletModel); + sendCoinsPage->setModel(_walletModel); + usedReceivingAddressesPage->setModel(_walletModel->getAddressTableModel()); + usedSendingAddressesPage->setModel(_walletModel->getAddressTableModel()); - if (walletModel) + if (_walletModel) { // Receive and pass through messages from wallet model - connect(walletModel, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int))); + connect(_walletModel, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int))); // Handle changes in encryption status - connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SIGNAL(encryptionStatusChanged(int))); + connect(_walletModel, SIGNAL(encryptionStatusChanged(int)), this, SIGNAL(encryptionStatusChanged(int))); updateEncryptionStatus(); // update HD status - Q_EMIT hdEnabledStatusChanged(walletModel->hdEnabled()); + Q_EMIT hdEnabledStatusChanged(_walletModel->hdEnabled()); // Balloon pop-up for new transaction - connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), + connect(_walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(processNewTransaction(QModelIndex,int,int))); // Ask for passphrase if needed - connect(walletModel, SIGNAL(requireUnlock(bool)), this, SLOT(unlockWallet(bool))); + connect(_walletModel, SIGNAL(requireUnlock(bool)), this, SLOT(unlockWallet(bool))); // Show progress dialog - connect(walletModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int))); + connect(_walletModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int))); } } diff --git a/src/reverselock.h b/src/reverselock.h index fac1ccb7931a..1fd8de5d8074 100644 --- a/src/reverselock.h +++ b/src/reverselock.h @@ -13,9 +13,9 @@ class reverse_lock { public: - explicit reverse_lock(Lock& lock) : lock(lock) { - lock.unlock(); - lock.swap(templock); + explicit reverse_lock(Lock& _lock) : lock(_lock) { + _lock.unlock(); + _lock.swap(templock); } ~reverse_lock() { diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 930ea4f107c2..d9d90f1b0004 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -497,10 +497,10 @@ UniValue getmempoolancestors(const UniValue& params, bool fHelp) UniValue o(UniValue::VOBJ); BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) { const CTxMemPoolEntry &e = *ancestorIt; - const uint256& hash = e.GetTx().GetHash(); + const uint256& _hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); entryToJSON(info, e); - o.push_back(Pair(hash.ToString(), info)); + o.push_back(Pair(_hash.ToString(), info)); } return o; } @@ -561,10 +561,10 @@ UniValue getmempooldescendants(const UniValue& params, bool fHelp) UniValue o(UniValue::VOBJ); BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) { const CTxMemPoolEntry &e = *descendantIt; - const uint256& hash = e.GetTx().GetHash(); + const uint256& _hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); entryToJSON(info, e); - o.push_back(Pair(hash.ToString(), info)); + o.push_back(Pair(_hash.ToString(), info)); } return o; } diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index ee240cf3fdd2..5a0ec9265438 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -630,8 +630,8 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) UniValue aRules(UniValue::VARR); UniValue vbavailable(UniValue::VOBJ); - for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) { - Consensus::DeploymentPos pos = Consensus::DeploymentPos(i); + for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) { + Consensus::DeploymentPos pos = Consensus::DeploymentPos(j); ThresholdState state = VersionBitsState(pindexPrev, consensusParams, pos, versionbitscache); switch (state) { case THRESHOLD_DEFINED: diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 96af8bc87b3b..325e02782d7b 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -50,7 +50,7 @@ UniValue getinfo(const UniValue& params, bool fHelp) if (fHelp || params.size() != 0) throw runtime_error( "getinfo\n" - "Returns an object containing various state info.\n" + "\nDEPRECATED. Returns an object containing various state info.\n" "\nResult:\n" "{\n" " \"version\": xxxxx, (numeric) the server version\n" diff --git a/src/support/pagelocker.h b/src/support/pagelocker.h index 6b3979e5513b..538bf39453e3 100644 --- a/src/support/pagelocker.h +++ b/src/support/pagelocker.h @@ -28,11 +28,11 @@ template class LockedPageManagerBase { public: - LockedPageManagerBase(size_t page_size) : page_size(page_size) + LockedPageManagerBase(size_t _page_size) : page_size(_page_size) { // Determine bitmask for extracting page from address - assert(!(page_size & (page_size - 1))); // size must be power of two - page_mask = ~(page_size - 1); + assert(!(_page_size & (_page_size - 1))); // size must be power of two + page_mask = ~(_page_size - 1); } ~LockedPageManagerBase() diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index fb3ff06f478a..8ecc067f65f5 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -50,7 +50,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); dummyNode1.SetSendVersion(PROTOCOL_VERSION); GetNodeSignals().InitializeNode(&dummyNode1, *connman); dummyNode1.nVersion = 1; @@ -61,7 +61,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); dummyNode2.SetSendVersion(PROTOCOL_VERSION); GetNodeSignals().InitializeNode(&dummyNode2, *connman); dummyNode2.nVersion = 1; @@ -82,7 +82,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); dummyNode1.SetSendVersion(PROTOCOL_VERSION); GetNodeSignals().InitializeNode(&dummyNode1, *connman); dummyNode1.nVersion = 1; @@ -108,7 +108,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); dummyNode.SetSendVersion(PROTOCOL_VERSION); GetNodeSignals().InitializeNode(&dummyNode, *connman); dummyNode.nVersion = 1; diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index 5055977e86b8..60d610c5de69 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -257,8 +257,7 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) addrman.Good(CAddress(addr, NODE_NONE)); //Test 15: No collision in tried table yet. - BOOST_TEST_MESSAGE(addrman.size()); - BOOST_CHECK(addrman.size() == i); + BOOST_CHECK_EQUAL(addrman.size(), i); } //Test 16: tried table collision! @@ -543,4 +542,4 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) // than 64 buckets. BOOST_CHECK(buckets.size() > 64); } -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index d8be94870e05..f3cb3d0077c9 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -133,13 +133,13 @@ void TestAES128CBC(const std::string &hexkey, const std::string &hexiv, bool pad { std::vector sub(i, in.end()); std::vector subout(sub.size() + AES_BLOCKSIZE); - int size = enc.Encrypt(&sub[0], sub.size(), &subout[0]); - if (size != 0) + int _size = enc.Encrypt(&sub[0], sub.size(), &subout[0]); + if (_size != 0) { - subout.resize(size); + subout.resize(_size); std::vector subdecrypted(subout.size()); - size = dec.Decrypt(&subout[0], subout.size(), &subdecrypted[0]); - subdecrypted.resize(size); + _size = dec.Decrypt(&subout[0], subout.size(), &subdecrypted[0]); + subdecrypted.resize(_size); BOOST_CHECK(decrypted.size() == in.size()); BOOST_CHECK_MESSAGE(subdecrypted == sub, HexStr(subdecrypted) + std::string(" != ") + HexStr(sub)); } @@ -174,13 +174,13 @@ void TestAES256CBC(const std::string &hexkey, const std::string &hexiv, bool pad { std::vector sub(i, in.end()); std::vector subout(sub.size() + AES_BLOCKSIZE); - int size = enc.Encrypt(&sub[0], sub.size(), &subout[0]); - if (size != 0) + int _size = enc.Encrypt(&sub[0], sub.size(), &subout[0]); + if (_size != 0) { - subout.resize(size); + subout.resize(_size); std::vector subdecrypted(subout.size()); - size = dec.Decrypt(&subout[0], subout.size(), &subdecrypted[0]); - subdecrypted.resize(size); + _size = dec.Decrypt(&subout[0], subout.size(), &subdecrypted[0]); + subdecrypted.resize(_size); BOOST_CHECK(decrypted.size() == in.size()); BOOST_CHECK_MESSAGE(subdecrypted == sub, HexStr(subdecrypted) + std::string(" != ") + HexStr(sub)); } diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 3a29f1aa997d..919e38d83bc5 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -62,11 +62,11 @@ class CAddrManCorrupted : public CAddrManSerializationMock } }; -CDataStream AddrmanToStream(CAddrManSerializationMock& addrman) +CDataStream AddrmanToStream(CAddrManSerializationMock& _addrman) { CDataStream ssPeersIn(SER_DISK, CLIENT_VERSION); ssPeersIn << FLATDATA(Params().MessageStart()); - ssPeersIn << addrman; + ssPeersIn << _addrman; std::string str = ssPeersIn.str(); vector vchData(str.begin(), str.end()); return CDataStream(vchData, SER_DISK, CLIENT_VERSION); @@ -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/script_tests.cpp b/src/test/script_tests.cpp index eed13a001c13..4d9b83a5c503 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -279,10 +279,10 @@ class TestBuilder return *this; } - TestBuilder& Add(const CScript& script) + TestBuilder& Add(const CScript& _script) { DoPush(); - spendTx.vin[0].scriptSig += script; + spendTx.vin[0].scriptSig += _script; return *this; } diff --git a/src/test/test_dash.cpp b/src/test/test_dash.cpp index e2f844939660..9d1b4c85db91 100644 --- a/src/test/test_dash.cpp +++ b/src/test/test_dash.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(new CConnman()); + g_connman = std::unique_ptr(new CConnman(0x1337, 0x1337)); // Deterministic randomness for tests. connman = g_connman.get(); RegisterNodeSignals(GetNodeSignals()); } diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 87f93c576a45..e807c3ff5ff1 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -122,8 +122,8 @@ class TorControlConnection static void eventcb(struct bufferevent *bev, short what, void *ctx); }; -TorControlConnection::TorControlConnection(struct event_base *base): - base(base), b_conn(0) +TorControlConnection::TorControlConnection(struct event_base *_base): + base(_base), b_conn(0) { } @@ -194,7 +194,7 @@ void TorControlConnection::eventcb(struct bufferevent *bev, short what, void *ct } } -bool TorControlConnection::Connect(const std::string &target, const ConnectionCB& connected, const ConnectionCB& disconnected) +bool TorControlConnection::Connect(const std::string &target, const ConnectionCB& _connected, const ConnectionCB& _disconnected) { if (b_conn) Disconnect(); @@ -213,8 +213,8 @@ bool TorControlConnection::Connect(const std::string &target, const ConnectionCB return false; bufferevent_setcb(b_conn, TorControlConnection::readcb, NULL, TorControlConnection::eventcb, this); bufferevent_enable(b_conn, EV_READ|EV_WRITE); - this->connected = connected; - this->disconnected = disconnected; + this->connected = _connected; + this->disconnected = _disconnected; // Finally, connect to target if (bufferevent_socket_connect(b_conn, (struct sockaddr*)&connect_to_addr, connect_to_addrlen) < 0) { @@ -394,18 +394,18 @@ class TorController static void reconnect_cb(evutil_socket_t fd, short what, void *arg); }; -TorController::TorController(struct event_base* baseIn, const std::string& target): - base(baseIn), - target(target), conn(base), reconnect(true), reconnect_ev(0), +TorController::TorController(struct event_base* _base, const std::string& _target): + base(_base), + target(_target), conn(base), reconnect(true), reconnect_ev(0), reconnect_timeout(RECONNECT_TIMEOUT_START) { reconnect_ev = event_new(base, -1, 0, reconnect_cb, this); if (!reconnect_ev) LogPrintf("tor: Failed to create event for reconnection: out of memory?\n"); // Start connection attempts immediately - if (!conn.Connect(target, boost::bind(&TorController::connected_cb, this, _1), + if (!conn.Connect(_target, boost::bind(&TorController::connected_cb, this, _1), boost::bind(&TorController::disconnected_cb, this, _1) )) { - LogPrintf("tor: Initiating connection to Tor control port %s failed\n", target); + LogPrintf("tor: Initiating connection to Tor control port %s failed\n", _target); } // Read service private key if cached std::pair pkf = ReadBinaryFile(GetPrivateKeyFile()); @@ -426,7 +426,7 @@ TorController::~TorController() } } -void TorController::add_onion_cb(TorControlConnection& conn, const TorControlReply& reply) +void TorController::add_onion_cb(TorControlConnection& _conn, const TorControlReply& reply) { if (reply.code == 250) { LogPrint("tor", "tor: ADD_ONION successful\n"); @@ -454,7 +454,7 @@ void TorController::add_onion_cb(TorControlConnection& conn, const TorControlRep } } -void TorController::auth_cb(TorControlConnection& conn, const TorControlReply& reply) +void TorController::auth_cb(TorControlConnection& _conn, const TorControlReply& reply) { if (reply.code == 250) { LogPrint("tor", "tor: Authentication successful\n"); @@ -474,7 +474,7 @@ void TorController::auth_cb(TorControlConnection& conn, const TorControlReply& r // Request hidden service, redirect port. // Note that the 'virtual' port doesn't have to be the same as our internal port, but this is just a convenient // choice. TODO; refactor the shutdown sequence some day. - conn.Command(strprintf("ADD_ONION %s Port=%i,127.0.0.1:%i", private_key, GetListenPort(), GetListenPort()), + _conn.Command(strprintf("ADD_ONION %s Port=%i,127.0.0.1:%i", private_key, GetListenPort(), GetListenPort()), boost::bind(&TorController::add_onion_cb, this, _1, _2)); } else { LogPrintf("tor: Authentication failed\n"); @@ -508,7 +508,7 @@ static std::vector ComputeResponse(const std::string &key, const std::v return computedHash; } -void TorController::authchallenge_cb(TorControlConnection& conn, const TorControlReply& reply) +void TorController::authchallenge_cb(TorControlConnection& _conn, const TorControlReply& reply) { if (reply.code == 250) { LogPrint("tor", "tor: SAFECOOKIE authentication challenge successful\n"); @@ -530,7 +530,7 @@ void TorController::authchallenge_cb(TorControlConnection& conn, const TorContro } std::vector computedClientHash = ComputeResponse(TOR_SAFE_CLIENTKEY, cookie, clientNonce, serverNonce); - conn.Command("AUTHENTICATE " + HexStr(computedClientHash), boost::bind(&TorController::auth_cb, this, _1, _2)); + _conn.Command("AUTHENTICATE " + HexStr(computedClientHash), boost::bind(&TorController::auth_cb, this, _1, _2)); } else { LogPrintf("tor: Invalid reply to AUTHCHALLENGE\n"); } @@ -539,7 +539,7 @@ void TorController::authchallenge_cb(TorControlConnection& conn, const TorContro } } -void TorController::protocolinfo_cb(TorControlConnection& conn, const TorControlReply& reply) +void TorController::protocolinfo_cb(TorControlConnection& _conn, const TorControlReply& reply) { if (reply.code == 250) { std::set methods; @@ -579,23 +579,23 @@ void TorController::protocolinfo_cb(TorControlConnection& conn, const TorControl if (methods.count("HASHEDPASSWORD")) { LogPrint("tor", "tor: Using HASHEDPASSWORD authentication\n"); boost::replace_all(torpassword, "\"", "\\\""); - conn.Command("AUTHENTICATE \"" + torpassword + "\"", boost::bind(&TorController::auth_cb, this, _1, _2)); + _conn.Command("AUTHENTICATE \"" + torpassword + "\"", boost::bind(&TorController::auth_cb, this, _1, _2)); } else { LogPrintf("tor: Password provided with -torpassword, but HASHEDPASSWORD authentication is not available\n"); } } else if (methods.count("NULL")) { LogPrint("tor", "tor: Using NULL authentication\n"); - conn.Command("AUTHENTICATE", boost::bind(&TorController::auth_cb, this, _1, _2)); + _conn.Command("AUTHENTICATE", boost::bind(&TorController::auth_cb, this, _1, _2)); } else if (methods.count("SAFECOOKIE")) { // Cookie: hexdump -e '32/1 "%02x""\n"' ~/.tor/control_auth_cookie LogPrint("tor", "tor: Using SAFECOOKIE authentication, reading cookie authentication from %s\n", cookiefile); std::pair status_cookie = ReadBinaryFile(cookiefile, TOR_COOKIE_SIZE); if (status_cookie.first && status_cookie.second.size() == TOR_COOKIE_SIZE) { - // conn.Command("AUTHENTICATE " + HexStr(status_cookie.second), boost::bind(&TorController::auth_cb, this, _1, _2)); + // _conn.Command("AUTHENTICATE " + HexStr(status_cookie.second), boost::bind(&TorController::auth_cb, this, _1, _2)); cookie = std::vector(status_cookie.second.begin(), status_cookie.second.end()); clientNonce = std::vector(TOR_NONCE_SIZE, 0); GetRandBytes(&clientNonce[0], TOR_NONCE_SIZE); - conn.Command("AUTHCHALLENGE SAFECOOKIE " + HexStr(clientNonce), boost::bind(&TorController::authchallenge_cb, this, _1, _2)); + _conn.Command("AUTHCHALLENGE SAFECOOKIE " + HexStr(clientNonce), boost::bind(&TorController::authchallenge_cb, this, _1, _2)); } else { if (status_cookie.first) { LogPrintf("tor: Authentication cookie %s is not exactly %i bytes, as is required by the spec\n", cookiefile, TOR_COOKIE_SIZE); @@ -613,15 +613,15 @@ void TorController::protocolinfo_cb(TorControlConnection& conn, const TorControl } } -void TorController::connected_cb(TorControlConnection& conn) +void TorController::connected_cb(TorControlConnection& _conn) { reconnect_timeout = RECONNECT_TIMEOUT_START; // First send a PROTOCOLINFO command to figure out what authentication is expected - if (!conn.Command("PROTOCOLINFO 1", boost::bind(&TorController::protocolinfo_cb, this, _1, _2))) + if (!_conn.Command("PROTOCOLINFO 1", boost::bind(&TorController::protocolinfo_cb, this, _1, _2))) LogPrintf("tor: Error sending initial protocolinfo command\n"); } -void TorController::disconnected_cb(TorControlConnection& conn) +void TorController::disconnected_cb(TorControlConnection& _conn) { // Stop advertising service when disconnected if (service.IsValid()) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 756c82645626..40009fb5ff14 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1258,8 +1258,8 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector* pvNoSpends std::vector txn; if (pvNoSpendsRemaining) { txn.reserve(stage.size()); - BOOST_FOREACH(txiter it, stage) - txn.push_back(it->GetTx()); + BOOST_FOREACH(txiter iter, stage) + txn.push_back(iter->GetTx()); } RemoveStaged(stage, false); if (pvNoSpendsRemaining) { diff --git a/src/txmempool.h b/src/txmempool.h index 6a16c6d507b1..4123a04b5c96 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -342,14 +342,17 @@ class SaltedTxidHasher }; /** - * CTxMemPool stores valid-according-to-the-current-best-chain - * transactions that may be included in the next block. + * CTxMemPool stores valid-according-to-the-current-best-chain transactions + * that may be included in the next block. * - * Transactions are added when they are seen on the network - * (or created by the local node), but not all transactions seen - * are added to the pool: if a new transaction double-spends - * an input of a transaction in the pool, it is dropped, - * as are non-standard transactions. + * Transactions are added when they are seen on the network (or created by the + * local node), but not all transactions seen are added to the pool. For + * example, the following new transactions will not be added to the mempool: + * - a transaction which doesn't make the mimimum fee requirements. + * - a new transaction that double-spends an input of a transaction already in + * the pool where the new transaction does not meet the Replace-By-Fee + * requirements as defined in BIP 125. + * - a non-standard transaction. * * CTxMemPool::mapTx, and CTxMemPoolEntry bookkeeping: * diff --git a/src/ui_interface.cpp b/src/ui_interface.cpp index c778e40a9053..74a13e0e052b 100644 --- a/src/ui_interface.cpp +++ b/src/ui_interface.cpp @@ -18,6 +18,11 @@ void InitWarning(const std::string& str) uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING); } +std::string AmountHighWarn(const std::string& optname) +{ + return strprintf(_("%s is set very high!"), optname); +} + std::string AmountErrMsg(const char* const optname, const std::string& strValue) { return strprintf(_("Invalid amount for -%s=: '%s'"), optname, strValue); diff --git a/src/ui_interface.h b/src/ui_interface.h index 58bbeb8d3794..5f36a7ca0cf4 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -125,6 +125,8 @@ void InitWarning(const std::string& str); /** Show error message **/ bool InitError(const std::string& str); +std::string AmountHighWarn(const std::string& optname); + std::string AmountErrMsg(const char* const optname, const std::string& strValue); extern CClientUIInterface uiInterface; diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h index 8428b1c683ac..e48b905bfb85 100644 --- a/src/univalue/include/univalue.h +++ b/src/univalue/include/univalue.h @@ -56,7 +56,7 @@ class UniValue { bool setNumStr(const std::string& val); bool setInt(uint64_t val); bool setInt(int64_t val); - bool setInt(int val) { return setInt((int64_t)val); } + bool setInt(int val_) { return setInt((int64_t)val_); } bool setFloat(double val); bool setStr(const std::string& val); bool setArray(); @@ -95,28 +95,28 @@ class UniValue { bool push_backV(const std::vector& vec); bool pushKV(const std::string& key, const UniValue& val); - bool pushKV(const std::string& key, const std::string& val) { - UniValue tmpVal(VSTR, val); + bool pushKV(const std::string& key, const std::string& val_) { + UniValue tmpVal(VSTR, val_); return pushKV(key, tmpVal); } bool pushKV(const std::string& key, const char *val_) { - std::string val(val_); - return pushKV(key, val); + std::string _val(val_); + return pushKV(key, _val); } - bool pushKV(const std::string& key, int64_t val) { - UniValue tmpVal(val); + bool pushKV(const std::string& key, int64_t val_) { + UniValue tmpVal(val_); return pushKV(key, tmpVal); } - bool pushKV(const std::string& key, uint64_t val) { - UniValue tmpVal(val); + bool pushKV(const std::string& key, uint64_t val_) { + UniValue tmpVal(val_); return pushKV(key, tmpVal); } - bool pushKV(const std::string& key, int val) { - UniValue tmpVal((int64_t)val); + bool pushKV(const std::string& key, int val_) { + UniValue tmpVal((int64_t)val_); return pushKV(key, tmpVal); } - bool pushKV(const std::string& key, double val) { - UniValue tmpVal(val); + bool pushKV(const std::string& key, double val_) { + UniValue tmpVal(val_); return pushKV(key, tmpVal); } bool pushKVs(const UniValue& obj); diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp index 0076d6678ec7..1f8cee6d2983 100644 --- a/src/univalue/lib/univalue.cpp +++ b/src/univalue/lib/univalue.cpp @@ -119,32 +119,29 @@ bool UniValue::setNumStr(const string& val_) return true; } -bool UniValue::setInt(uint64_t val) +bool UniValue::setInt(uint64_t val_) { - string s; ostringstream oss; - oss << val; + oss << val_; return setNumStr(oss.str()); } -bool UniValue::setInt(int64_t val) +bool UniValue::setInt(int64_t val_) { - string s; ostringstream oss; - oss << val; + oss << val_; return setNumStr(oss.str()); } -bool UniValue::setFloat(double val) +bool UniValue::setFloat(double val_) { - string s; ostringstream oss; - oss << std::setprecision(16) << val; + oss << std::setprecision(16) << val_; bool ret = setNumStr(oss.str()); typ = VNUM; @@ -173,12 +170,12 @@ bool UniValue::setObject() return true; } -bool UniValue::push_back(const UniValue& val) +bool UniValue::push_back(const UniValue& val_) { if (typ != VARR) return false; - values.push_back(val); + values.push_back(val_); return true; } @@ -192,13 +189,13 @@ bool UniValue::push_backV(const std::vector& vec) return true; } -bool UniValue::pushKV(const std::string& key, const UniValue& val) +bool UniValue::pushKV(const std::string& key, const UniValue& val_) { if (typ != VOBJ) return false; keys.push_back(key); - values.push_back(val); + values.push_back(val_); return true; } @@ -228,7 +225,7 @@ int UniValue::findKey(const std::string& key) const bool UniValue::checkObject(const std::map& t) { for (std::map::const_iterator it = t.begin(); - it != t.end(); it++) { + it != t.end(); ++it) { int idx = findKey(it->first); if (idx < 0) return false; diff --git a/src/util.cpp b/src/util.cpp index 26b804a94c21..0520395bd332 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -701,19 +701,19 @@ bool TryCreateDirectory(const boost::filesystem::path& p) return false; } -void FileCommit(FILE *fileout) +void FileCommit(FILE *file) { - fflush(fileout); // harmless if redundantly called + fflush(file); // harmless if redundantly called #ifdef WIN32 - HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(fileout)); + HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file)); FlushFileBuffers(hFile); #else #if defined(__linux__) || defined(__NetBSD__) - fdatasync(fileno(fileout)); + fdatasync(fileno(file)); #elif defined(__APPLE__) && defined(F_FULLFSYNC) - fcntl(fileno(fileout), F_FULLFSYNC, 0); + fcntl(fileno(file), F_FULLFSYNC, 0); #else - fsync(fileno(fileout)); + fsync(fileno(file)); #endif #endif } diff --git a/src/util.h b/src/util.h index d02846ff63ef..a61e2797b5fc 100644 --- a/src/util.h +++ b/src/util.h @@ -114,7 +114,7 @@ bool error(const char* fmt, const Args&... args) void PrintExceptionContinue(const std::exception *pex, const char* pszThread); void ParseParameters(int argc, const char*const argv[]); -void FileCommit(FILE *fileout); +void FileCommit(FILE *file); bool TruncateFile(FILE *file, unsigned int length); int RaiseFileDescriptorLimit(int nMinFD); void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length); diff --git a/src/validation.cpp b/src/validation.cpp index f76d51a38ea7..4edafb3914c7 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -657,9 +657,9 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C bool fReplacementOptOut = true; if (fEnableReplacement) { - BOOST_FOREACH(const CTxIn &txin, ptxConflicting->vin) + BOOST_FOREACH(const CTxIn &_txin, ptxConflicting->vin) { - if (txin.nSequence < std::numeric_limits::max()-1) + if (_txin.nSequence < std::numeric_limits::max()-1) { fReplacementOptOut = false; break; @@ -1618,7 +1618,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; @@ -2290,14 +2290,14 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd if (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS)) { if (pindex->GetUndoPos().IsNull()) { - CDiskBlockPos pos; - if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40)) + CDiskBlockPos _pos; + if (!FindUndoPos(state, pindex->nFile, _pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40)) return error("ConnectBlock(): FindUndoPos failed"); - if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart())) + if (!UndoWriteToDisk(blockundo, _pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart())) return AbortNode(state, "Failed to write undo data"); // update nUndoPos in block index - pindex->nUndoPos = pos.nPos; + pindex->nUndoPos = _pos.nPos; pindex->nStatus |= BLOCK_HAVE_UNDO; } @@ -3615,10 +3615,10 @@ void PruneOneBlockFile(const int fileNumber) // mapBlocksUnlinked or setBlockIndexCandidates. std::pair::iterator, std::multimap::iterator> range = mapBlocksUnlinked.equal_range(pindex->pprev); while (range.first != range.second) { - std::multimap::iterator it = range.first; + std::multimap::iterator _it = range.first; range.first++; - if (it->second == pindex) { - mapBlocksUnlinked.erase(it); + if (_it->second == pindex) { + mapBlocksUnlinked.erase(_it); } } } @@ -4414,13 +4414,13 @@ std::string GetWarnings(const std::string& strFor) { nPriority = 2000; strStatusBar = strRPC = "Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."; - strGUI += strGUI.empty() ? "" : uiAlertSeperator + _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."); + strGUI += (strGUI.empty() ? "" : uiAlertSeperator) + _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."); } else if (fLargeWorkInvalidChainFound) { nPriority = 2000; strStatusBar = strRPC = "Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."; - strGUI += strGUI.empty() ? "" : uiAlertSeperator + _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."); + strGUI += (strGUI.empty() ? "" : uiAlertSeperator) + _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."); } // Alerts diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index a14c07e895bb..224123335470 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -345,8 +345,6 @@ UniValue removeprunedfunds(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction does not exist in wallet."); } - ThreadFlushWalletDB(pwalletMain->strWalletFile); - return NullUniValue; } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 039d0398e137..689f16c8b766 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2762,6 +2762,9 @@ static const CRPCCommand commands[] = void RegisterWalletRPCCommands(CRPCTable &t) { + if (GetBoolArg("-disablewallet", false)) + return; + for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) t.appendCommand(commands[vcidx].name, &commands[vcidx]); } diff --git a/src/wallet/test/accounting_tests.cpp b/src/wallet/test/accounting_tests.cpp index a6cada46a226..a833be13d065 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& results) +GetResults(std::map& results) { std::list 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& results) BOOST_AUTO_TEST_CASE(acc_orderupgrade) { - CWalletDB walletdb(pwalletMain->strWalletFile); std::vector 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 7bbf53b54e9a..531dae006d93 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -583,8 +583,8 @@ set CWallet::GetConflicts(const uint256& txid) const if (mapTxSpends.count(txin.prevout) <= 1) continue; // No conflict if zero or one spends range = mapTxSpends.equal_range(txin.prevout); - for (TxSpends::const_iterator it = range.first; it != range.second; ++it) - result.insert(it->second); + for (TxSpends::const_iterator _it = range.first; _it != range.second; ++_it) + result.insert(_it->second); } return result; } @@ -596,6 +596,9 @@ void CWallet::Flush(bool shutdown) bool CWallet::Verify() { + if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) + return true; + LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0)); std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); @@ -863,6 +866,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 @@ -891,7 +900,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; @@ -901,7 +910,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; @@ -1645,9 +1654,9 @@ int CWalletTx::GetRequestCount() const // How about the block it's in? if (nRequests == 0 && !hashUnset()) { - map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); - if (mi != pwallet->mapRequestCount.end()) - nRequests = (*mi).second; + map::const_iterator _mi = pwallet->mapRequestCount.find(hashBlock); + if (_mi != pwallet->mapRequestCount.end()) + nRequests = (*_mi).second; else nRequests = 1; // If it's in someone else's block it must have got out } @@ -3649,9 +3658,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& 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); @@ -4149,17 +4170,17 @@ set< set > CWallet::GetAddressGroupings() set< set* > uniqueGroupings; // a set of pointers to groups of addresses map< CTxDestination, set* > setmap; // map addresses to the unique group containing it - BOOST_FOREACH(set grouping, groupings) + BOOST_FOREACH(set _grouping, groupings) { // make a set of all the groups hit by this new group set< set* > hits; map< CTxDestination, set* >::iterator it; - BOOST_FOREACH(CTxDestination address, grouping) + BOOST_FOREACH(CTxDestination address, _grouping) if ((it = setmap.find(address)) != setmap.end()) hits.insert((*it).second); // merge all hit groups into a new single group and delete old groups - set* merged = new set(grouping); + set* merged = new set(_grouping); BOOST_FOREACH(set* hit, hits) { merged->insert(hit->begin(), hit->end()); @@ -4543,6 +4564,12 @@ std::string CWallet::GetWalletHelpString(bool showDebug) bool CWallet::InitLoadWallet() { + if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { + pwalletMain = NULL; + LogPrintf("Wallet disabled!\n"); + return true; + } + std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); // needed to restore wallet transaction meta data after -zapwallettxes @@ -4740,13 +4767,31 @@ bool CWallet::InitLoadWallet() bool CWallet::ParameterInteraction() { + if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) + return true; + + 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 (::minRelayTxFee.GetFeePerK() > HIGH_TX_FEE_PER_KB) + InitWarning(AmountHighWarn("-minrelaytxfee") + " " + + _("The wallet will avoid paying less than the minimum relay fee.")); + if (mapArgs.count("-mintxfee")) { CAmount n = 0; - if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0) - CWallet::minTxFee = CFeeRate(n); - else + if (!ParseMoney(mapArgs["-mintxfee"], n)) return InitError(AmountErrMsg("mintxfee", mapArgs["-mintxfee"])); + if (n > HIGH_TX_FEE_PER_KB) + InitWarning(AmountHighWarn("-mintxfee") + " " + + _("This is the minimum transaction fee you pay on every transaction.")); + CWallet::minTxFee = CFeeRate(n); } if (mapArgs.count("-fallbackfee")) { @@ -4754,7 +4799,8 @@ bool CWallet::ParameterInteraction() if (!ParseMoney(mapArgs["-fallbackfee"], nFeePerK)) return InitError(strprintf(_("Invalid amount for -fallbackfee=: '%s'"), mapArgs["-fallbackfee"])); if (nFeePerK > HIGH_TX_FEE_PER_KB) - InitWarning(_("-fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available.")); + InitWarning(AmountHighWarn("-fallbackfee") + " " + + _("This is the transaction fee you may pay when fee estimates are not available.")); CWallet::fallbackFee = CFeeRate(nFeePerK); } if (mapArgs.count("-paytxfee")) @@ -4763,7 +4809,9 @@ bool CWallet::ParameterInteraction() if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK)) return InitError(AmountErrMsg("paytxfee", mapArgs["-paytxfee"])); if (nFeePerK > HIGH_TX_FEE_PER_KB) - InitWarning(_("-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); + InitWarning(AmountHighWarn("-paytxfee") + " " + + _("This is the transaction fee you will pay if you send a transaction.")); + payTxFee = CFeeRate(nFeePerK, 1000); if (payTxFee < ::minRelayTxFee) { @@ -4792,6 +4840,29 @@ bool CWallet::ParameterInteraction() return true; } +bool CWallet::InitAutoBackup() +{ + if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) + return true; + + std::string strWarning; + std::string strError; + + nWalletBackups = GetArg("-createwalletbackups", 10); + nWalletBackups = std::max(0, std::min(10, nWalletBackups)); + + std::string strWalletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); + + if(!AutoBackupWallet(NULL, strWalletFile, strWarning, strError)) { + if (!strWarning.empty()) + InitWarning(strWarning); + if (!strError.empty()) + return InitError(strError); + } + + return true; +} + bool CWallet::BackupWallet(const std::string& strDest) { if (!fFileBacked) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 7772ba86a856..ce22d952df03 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -61,6 +61,7 @@ static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2; //! Largest (in bytes) free transaction we're willing to create static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; static const bool DEFAULT_WALLETBROADCAST = true; +static const bool DEFAULT_DISABLE_WALLET = false; extern const char * DEFAULT_WALLET_DAT; @@ -852,6 +853,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface * @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); @@ -899,7 +901,9 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool CreateCollateralTransaction(CMutableTransaction& txCollateral, std::string& strReason); bool ConvertList(std::vector vecTxIn, std::vector& vecAmounts); - bool AddAccountingEntry(const CAccountingEntry&, CWalletDB & pwalletdb); + void ListAccountCreditDebit(const std::string& strAccount, std::list& entries); + bool AddAccountingEntry(const CAccountingEntry&); + bool AddAccountingEntry(const CAccountingEntry&, CWalletDB *pwalletdb); static CFeeRate minTxFee; static CFeeRate fallbackFee; @@ -1038,6 +1042,9 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface /* Wallets parameter interaction */ static bool ParameterInteraction(); + /* Initialize AutoBackup functionality */ + static bool InitAutoBackup(); + bool BackupWallet(const std::string& strDest); /**