diff options
-rw-r--r-- | .travis.yml | 6 | ||||
-rwxr-xr-x | contrib/devtools/github-merge.py | 46 | ||||
-rw-r--r-- | contrib/verify-commits/allow-revsig-commits | 104 | ||||
-rw-r--r-- | depends/packages/native_cctools.mk | 3 | ||||
-rw-r--r-- | doc/bips.md | 1 | ||||
-rw-r--r-- | doc/man/Makefile.am | 14 | ||||
-rwxr-xr-x | qa/rpc-tests/import-rescan.py | 30 | ||||
-rw-r--r-- | src/init.cpp | 43 | ||||
-rw-r--r-- | src/net.cpp | 5 | ||||
-rw-r--r-- | src/prevector.h | 6 | ||||
-rw-r--r-- | src/rpc/misc.cpp | 8 | ||||
-rw-r--r-- | src/test/bip32_tests.cpp | 13 | ||||
-rw-r--r-- | src/test/data/tx_invalid.json | 2 | ||||
-rw-r--r-- | src/test/data/tx_valid.json | 2 | ||||
-rw-r--r-- | src/test/dbwrapper_tests.cpp | 6 | ||||
-rw-r--r-- | src/txmempool.h | 1 | ||||
-rw-r--r-- | src/uint256.cpp | 5 | ||||
-rw-r--r-- | src/wallet/rpcdump.cpp | 1 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 30 | ||||
-rw-r--r-- | src/wallet/test/wallet_tests.cpp | 19 |
20 files changed, 265 insertions, 80 deletions
diff --git a/.travis.yml b/.travis.yml index ccd2490925..ce6cdc2db0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,9 +51,9 @@ before_script: - if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS script: - - if [ "$RUN_TESTS" = "true" -a "$TRAVIS_REPO_SLUG" = "bitcoin/bitcoin" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then while read LINE; do travis_retry gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys $LINE; done < contrib/verify-commits/trusted-keys; fi - - if [ "$RUN_TESTS" = "true" -a "$TRAVIS_REPO_SLUG" = "bitcoin/bitcoin" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then git fetch --unshallow; fi - - if [ "$RUN_TESTS" = "true" -a "$TRAVIS_REPO_SLUG" = "bitcoin/bitcoin" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then contrib/verify-commits/verify-commits.sh; fi + - if [ "$CHECK_DOC" = 1 -a "$TRAVIS_REPO_SLUG" = "bitcoin/bitcoin" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then while read LINE; do travis_retry gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys $LINE; done < contrib/verify-commits/trusted-keys; fi + - if [ "$CHECK_DOC" = 1 -a "$TRAVIS_REPO_SLUG" = "bitcoin/bitcoin" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then git fetch --unshallow; fi + - if [ "$CHECK_DOC" = 1 -a "$TRAVIS_REPO_SLUG" = "bitcoin/bitcoin" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then contrib/verify-commits/verify-commits.sh; fi - export TRAVIS_COMMIT_LOG=`git log --format=fuller -1` - if [ -n "$USE_SHELL" ]; then export CONFIG_SHELL="$USE_SHELL"; fi - OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST diff --git a/contrib/devtools/github-merge.py b/contrib/devtools/github-merge.py index 0cee0921b1..bb6ffb0253 100755 --- a/contrib/devtools/github-merge.py +++ b/contrib/devtools/github-merge.py @@ -18,6 +18,7 @@ from __future__ import division,print_function,unicode_literals import os from sys import stdin,stdout,stderr import argparse +import hashlib import subprocess import json,codecs try: @@ -69,6 +70,27 @@ def ask_prompt(text): print("",file=stderr) return reply +def tree_sha512sum(): + files = sorted(subprocess.check_output([GIT, 'ls-tree', '--full-tree', '-r', '--name-only', 'HEAD']).splitlines()) + overall = hashlib.sha512() + for f in files: + intern = hashlib.sha512() + fi = open(f, 'rb') + while True: + piece = fi.read(65536) + if piece: + intern.update(piece) + else: + break + fi.close() + dig = intern.hexdigest() + overall.update(dig.encode("utf-8")) + overall.update(" ".encode("utf-8")) + overall.update(f) + overall.update("\n".encode("utf-8")) + return overall.hexdigest() + + def parse_arguments(): epilog = ''' In addition, you can set the following git configuration variables: @@ -157,6 +179,9 @@ def main(): subprocess.check_call([GIT,'checkout','-q','-b',local_merge_branch]) try: + # Go up to the repository's root. + toplevel = subprocess.check_output([GIT,'rev-parse','--show-toplevel']).strip() + os.chdir(toplevel) # Create unsigned merge commit. if title: firstline = 'Merge #%s: %s' % (pull,title) @@ -175,14 +200,29 @@ def main(): print("ERROR: Creating merge failed (already merged?).",file=stderr) exit(4) + # Put tree SHA512 into the message + try: + first_sha512 = tree_sha512sum() + message += '\n\nTree-SHA512: ' + first_sha512 + except subprocess.CalledProcessError as e: + printf("ERROR: Unable to compute tree hash") + exit(4) + try: + subprocess.check_call([GIT,'commit','--amend','-m',message.encode('utf-8')]) + except subprocess.CalledProcessError as e: + printf("ERROR: Cannot update message.",file=stderr) + exit(4) + second_sha512 = tree_sha512sum() + if first_sha512 != second_sha512: + print("ERROR: Tree hash changed unexpectedly",file=stderr) + exit(4) + print('%s#%s%s %s %sinto %s%s' % (ATTR_RESET+ATTR_PR,pull,ATTR_RESET,title,ATTR_RESET+ATTR_PR,branch,ATTR_RESET)) subprocess.check_call([GIT,'log','--graph','--topo-order','--pretty=format:'+COMMIT_FORMAT,base_branch+'..'+head_branch]) print() + # Run test command if configured. if testcmd: - # Go up to the repository's root. - toplevel = subprocess.check_output([GIT,'rev-parse','--show-toplevel']).strip() - os.chdir(toplevel) if subprocess.call(testcmd,shell=True): print("ERROR: Running %s failed." % testcmd,file=stderr) exit(5) diff --git a/contrib/verify-commits/allow-revsig-commits b/contrib/verify-commits/allow-revsig-commits index e69de29bb2..f0088cdca4 100644 --- a/contrib/verify-commits/allow-revsig-commits +++ b/contrib/verify-commits/allow-revsig-commits @@ -0,0 +1,104 @@ +a06ede9a138d0fb86b0de17c42b936d9fe6e2158 +923dc447eaa8e017985b2afbbb12dd1283fbea0e +71148b8947fe8b4d756822420a7f31c380159425 +6696b4635ceb9b47aaa63244bff9032fa7b08354 +812714fd80e96e28cd288c553c83838cecbfc2d9 +8a445c5651edb9a1f51497055b7ddf4402be9188 +e126d0c12ca66278d9e7b12187c5ff4fc02a7e6c +3908fc4728059719bed0e1c7b1c8b388c2d4a8da +8b66bf74e2a349e71eaa183af81fa63eaee76ad2 +05950427d310654774031764a7141a1a4fd9c6e4 +07fd147b9f12e9205afd66a624edce357977d615 +12e31127948fa4bb01c3bddc1b8c85b432f7465b +8c87f175d335e9d9e93f987d871ae9f05f6a10a7 +46b249e578e8a3dfbe85bc7253a12e82ef4b658b +a55716abe5662ec74c2f8af93023f1e7cca901fc +f646275b90b1de93bc62b4c4d045d75ac0b96eee +c252685aa5867631e9a5ef07ccae7c7c25cae8ff +a7d55c93385359952d85decd5037843ac70ba3d4 +7dac1e5e9e887f5f6ff146e812a05bd3bf281eae +2a524b8e8fe69ef487fd8ea1b4f7a03f473ed201 +ce5c1f4acae43477989cdf9a82ed33703919cda2 +2db4cbcc437f51f5dac82cc4de46f383b92e6f11 +7aa700424cbda387536373d8dfec88aee43f950e +b99a093afed880f23fb279c443cc6ae5e379cc43 +b83264d9c7a8ddb79f64bd9540caddc8632ef31f +57e337d40e94ba33d8cd265c134d6ef857b32b59 +a1dcf2e1087beaf3981739fd2bb74f35ecad630a +d38b0d7a6b6056cba26999b702815775e2437d87 +815640ec6af9a38d6a2da4a4400056e2f4105080 +09c4fd157c5b88df2d97fad4826c79b094db90c9 +2efcfa5acfacb958973d9e8125e1d81f102e2dfd +dc6dee41f7cf2ba93fcd0fea7c157e4b2775d439 +ad826b3df9f763b49f1e3e3d50c4efdd438c7547 +c1a52276848d8caa9a9789dff176408c1aa6b1ed +3bf06e9bac57b5b5a746677b75e297a7b154bdbd +72ae6f8cf0224370e8121d6769b21e612ca15d6f +a143b88dbd4971ecfdd1d39a494489c8f2db0344 +76fec09d878d6dbf214bdb6228d480bd9195db4c +93566e0c37c5ae104095474fea89f00dcb40f551 +407d9232ef5cb1ebf6cff21f3d13e07ea4158eeb +9346f8429957e356d21c665bab59fe45bcf1f74e +6eeac6e30d65f9a972067c1ea8c49978c8e631ac +dc6b9406bdfab2af8c86cb080cb3e6cf8f2385d8 +9f554e03ebe5701c1b75ff03b3d6152095c0cad3 +05009935f9ac070197113954d680bc2c9150b9b3 +508404de98a8a5435f52916cef8f328e82651961 +ed0cc50afed146c27f6d8129c683c225fb940093 +6429cfa8a70308241c576aeb92ffe3db5203b2ef +6898213409811b140843c3d89af43328c3b22fad +5b2ea29cf4fd298346437bb16a54407f8c1f9dca +e2a1a1ee895149c544d4ae295466611f0cec3094 +e82fb872ff5cc8fd22d43327c1ee3e755f61c562 +19b0f33de0efd9da788e8e4f3fdc2a9e159abdb1 +89de1538ce1f8c00f80e8d11f43e1b77e24d7dea +de07fdcf77e97b8613091285e4d0a734f5de7492 +01680195f8aa586c55c44767397380def3a23b54 +05e1c85fb687c82ae477c72d4a7e2d6b0c692167 +c072b8fd95cd4fa84f08189a0cd8b173ea2dbb8e +9a0ed08b40b15ae2b791aa8549b53e69934b4ea7 +53f8f226bd1d627c4a6dec5862a1d4ea5a933e45 +9d0f43b7ca7241d8a018fd35dd3bc01555235ec6 +f12d2b5a8ac397e4bcaefcc19898f8ff5705dea5 +8250de13587ed05ca45df3e12c5dc9bcb1500e2c +d727f77e390426e9e463336bda08d50c451c7086 +484312bda2d43e3ea60047be076332299463adf8 +c7e05b35ab0a791c7a8e2d863e716fdec6f3f671 +b9c1cd81848da9de1baf9c2f29c19c50e549de13 +8ea7d31e384975019733b5778feabbd9955c79d8 +f798b891bcecea9548eedacae70eeb9906c1ddbf +ebefe7a00b46579cdd1e033a8c7fd8ce9aa578e4 +ad087638ee4864d6244ec9381ff764bfa6ee5086 +66db2d62d59817320c9182fc18e75a93b76828ea +7ce9ac5c83b1844a518ef2e12e87aae3cacdfe58 +4286f43025149cf44207c3ad98e4a1f068520ada +cd0c5135ab2291aaa5410ac919bad3fc87249a4a +66ed450d771a8fc01c159a8402648ebd1c35eb4c +a82f03393a32842d49236e8666ee57805ca701f8 +f972b04d63eb8af79ff3cec1dc561ed13dfa6053 +ec45cc5e27668171b55271b0c735194c70e7da41 +715e9fd7454f7a48d7adba7d42f662c20a3e3367 +2e0a99037dcc35bc63ba0d54371bc678af737c8e +7fa8d758598407f3bf0beb0118dc122ea5340736 +6a22373771edbc3c7513cacb9355f880c73c2cbf +b89ef131147f71a96152a7b5c4374266cdf539b2 +01d8359983e2f77b5118fede3ffa947072c666c8 +58f0c929a3d70a4bff79cc200f1c186f71ef1675 +950be19727a581970591d8f8138dfe4725750382 +425278d17bd0edf8a3a7cc81e55016f7fd8e7726 +c028c7b7557da2baff7af8840108e8be4db8e0c6 +47a7cfb0aa2498f6801026d258a59f9de48f60b0 +f6b7df3155ddb4cedfbcf5d3eb3383d4614b3a85 +d72098038f3b55a714ed8adb34fab547b15eb0d5 +c49c825bd9f4764536b45df5a684d97173673fc7 +33799afe83eec4200ff140e9bf5eae83701a4d7f +5c3f8ddcaa1164079105c452429fccf8127b01b6 +1f01443567b03ac75a91c810f1733f5c21b5699d +b3e42b6d02e8d19658a9135e427ebceab5367779 +69b3a6dd9d9a0adf5506c8b9fde42187356bd4a8 +bafd075c5e6a1088ef0f1aa0b0b224e026a3d3e0 +7daa3adb242d9c8728fdb15c6af6596aaad5502f +514993554c370f4cf30a109ac28d5d64893dbf0a +c8d2473e6cb042e7275a10c49d3f6a4a91bf0166 +386f4385ab04b0b2c3d47bddc0dc0f2de7354964 +9f33dba05c01ecc5c56eb1284ab7d64d42f55171 diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index 797480c25e..44d238cc4c 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -38,7 +38,8 @@ $(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++ endef define $(package)_preprocess_cmds - cd $($(package)_build_subdir); ./autogen.sh + cd $($(package)_build_subdir); ./autogen.sh && \ + sed -i.old "/define HAVE_PTHREADS/d" ld64/src/ld/InputFiles.h endef define $(package)_config_cmds diff --git a/doc/bips.md b/doc/bips.md index 4f41610089..bc8dcb6fb3 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -20,6 +20,7 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.13.0**): * [`BIP 66`](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki): The strict DER rules and associated version 3 blocks have been implemented since **v0.10.0** ([PR #5713](https://github.com/bitcoin/bitcoin/pull/5713)). * [`BIP 68`](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki): Sequence locks have been implemented as of **v0.12.1** ([PR #7184](https://github.com/bitcoin/bitcoin/pull/7184)), and have been activated since *block 419328*. * [`BIP 70`](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) [`71`](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki) [`72`](https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki): Payment Protocol support has been available in Bitcoin Core GUI since **v0.9.0** ([PR #5216](https://github.com/bitcoin/bitcoin/pull/5216)). +* [`BIP 90`](https://github.com/bitcoin/bips/blob/master/bip-0090.mediawiki): Trigger mechanism for activation of BIPs 34, 65, and 66 has been simplified to block height checks since **v0.14.0** ([PR #8391](https://github.com/bitcoin/bitcoin/pull/8391)). * [`BIP 111`](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki): `NODE_BLOOM` service bit added, and enforced for all peer versions as of **v0.13.0** ([PR #6579](https://github.com/bitcoin/bitcoin/pull/6579) and [PR #6641](https://github.com/bitcoin/bitcoin/pull/6641)). * [`BIP 112`](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki): The CHECKSEQUENCEVERIFY opcode has been implemented since **v0.12.1** ([PR #7524](https://github.com/bitcoin/bitcoin/pull/7524)) and has been activated since *block 419328*. * [`BIP 113`](https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki): Median time past lock-time calculations have been implemented since **v0.12.1** ([PR #6566](https://github.com/bitcoin/bitcoin/pull/6566)) and have been activated since *block 419328*. diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index 5252ef4a19..08ff4d6ac1 100644 --- a/doc/man/Makefile.am +++ b/doc/man/Makefile.am @@ -1 +1,13 @@ -dist_man1_MANS=bitcoind.1 bitcoin-qt.1 bitcoin-cli.1 bitcoin-tx.1 +dist_man1_MANS= + +if BUILD_BITCOIND + dist_man1_MANS+=bitcoind.1 +endif + +if ENABLE_QT + dist_man1_MANS+=bitcoin-qt.1 +endif + +if BUILD_BITCOIN_UTILS + dist_man1_MANS+=bitcoin-cli.1 bitcoin-tx.1 +endif diff --git a/qa/rpc-tests/import-rescan.py b/qa/rpc-tests/import-rescan.py index 18551caaf7..7ca61824c9 100755 --- a/qa/rpc-tests/import-rescan.py +++ b/qa/rpc-tests/import-rescan.py @@ -7,11 +7,11 @@ Test rescan behavior of importaddress, importpubkey, importprivkey, and importmulti RPCs with different types of keys and rescan options. -In the first part of the test, node 0 creates an address for each type of -import RPC call and sends BTC to it. Then other nodes import the addresses, -and the test makes listtransactions and getbalance calls to confirm that the -importing node either did or did not execute rescans picking up the send -transactions. +In the first part of the test, node 1 creates an address for each type of +import RPC call and node 0 sends BTC to it. Then other nodes import the +addresses, and the test makes listtransactions and getbalance calls to confirm +that the importing node either did or did not execute rescans picking up the +send transactions. In the second part of the test, node 0 sends more BTC to each address, and the test makes more listtransactions and getbalance calls to confirm that the @@ -83,6 +83,12 @@ class Variant(collections.namedtuple("Variant", "call data rescan prune")): assert_equal(tx["txid"], txid) assert_equal(tx["confirmations"], confirmations) assert_equal("trusted" not in tx, True) + # Verify the transaction is correctly marked watchonly depending on + # whether the transaction pays to an imported public key or + # imported private key. The test setup ensures that transaction + # inputs will not be from watchonly keys (important because + # involvesWatchonly will be true if either the transaction output + # or inputs are watchonly). if self.data != Data.priv: assert_equal(tx["involvesWatchonly"], True) else: @@ -108,11 +114,11 @@ RESCAN_WINDOW = 2 * 60 * 60 class ImportRescanTest(BitcoinTestFramework): def __init__(self): super().__init__() - self.num_nodes = 1 + len(IMPORT_NODES) + self.num_nodes = 2 + len(IMPORT_NODES) def setup_network(self): extra_args = [["-debug=1"] for _ in range(self.num_nodes)] - for i, import_node in enumerate(IMPORT_NODES, 1): + for i, import_node in enumerate(IMPORT_NODES, 2): if import_node.prune: extra_args[i] += ["-prune=1"] @@ -125,9 +131,9 @@ class ImportRescanTest(BitcoinTestFramework): # each possible type of wallet import RPC. for i, variant in enumerate(IMPORT_VARIANTS): variant.label = "label {} {}".format(i, variant) - variant.address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress(variant.label)) - variant.key = self.nodes[0].dumpprivkey(variant.address["address"]) - variant.initial_amount = 25 - (i + 1) / 4.0 + variant.address = self.nodes[1].validateaddress(self.nodes[1].getnewaddress(variant.label)) + variant.key = self.nodes[1].dumpprivkey(variant.address["address"]) + variant.initial_amount = 10 - (i + 1) / 4.0 variant.initial_txid = self.nodes[0].sendtoaddress(variant.address["address"], variant.initial_amount) # Generate a block containing the initial transactions, then another @@ -144,7 +150,7 @@ class ImportRescanTest(BitcoinTestFramework): for variant in IMPORT_VARIANTS: variant.expect_disabled = variant.rescan == Rescan.yes and variant.prune and variant.call == Call.single expect_rescan = variant.rescan == Rescan.yes and not variant.expect_disabled - variant.node = self.nodes[1 + IMPORT_NODES.index(ImportNode(variant.prune, expect_rescan))] + variant.node = self.nodes[2 + IMPORT_NODES.index(ImportNode(variant.prune, expect_rescan))] variant.do_import(timestamp) if expect_rescan: variant.expected_balance = variant.initial_amount @@ -158,7 +164,7 @@ class ImportRescanTest(BitcoinTestFramework): # Create new transactions sending to each address. fee = self.nodes[0].getnetworkinfo()["relayfee"] for i, variant in enumerate(IMPORT_VARIANTS): - variant.sent_amount = 25 - (2 * i + 1) / 8.0 + variant.sent_amount = 10 - (2 * i + 1) / 8.0 variant.sent_txid = self.nodes[0].sendtoaddress(variant.address["address"], variant.sent_amount) # Generate a block containing the new transactions. diff --git a/src/init.cpp b/src/init.cpp index 196b840cb7..1c8c3bc620 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -797,6 +797,19 @@ ServiceFlags nLocalServices = NODE_NETWORK; } +[[noreturn]] static void new_handler_terminate() +{ + // Rather than throwing std::bad-alloc if allocation fails, terminate + // immediately to (try to) avoid chain corruption. + // Since LogPrintf may itself allocate memory, set the handler directly + // to terminate first. + std::set_new_handler(std::terminate); + LogPrintf("Error: Out of memory. Terminating.\n"); + + // The log was successful, terminate now. + std::terminate(); +}; + bool AppInitBasicSetup() { // ********************************************************* Step 1: setup @@ -849,6 +862,9 @@ bool AppInitBasicSetup() // Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly signal(SIGPIPE, SIG_IGN); #endif + + std::set_new_handler(new_handler_terminate); + return true; } @@ -1349,32 +1365,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) fReindex = GetBoolArg("-reindex", false); bool fReindexChainState = GetBoolArg("-reindex-chainstate", false); - // Upgrading to 0.8; hard-link the old blknnnn.dat files into /blocks/ - boost::filesystem::path blocksDir = GetDataDir() / "blocks"; - if (!boost::filesystem::exists(blocksDir)) - { - boost::filesystem::create_directories(blocksDir); - bool linked = false; - for (unsigned int i = 1; i < 10000; i++) { - boost::filesystem::path source = GetDataDir() / strprintf("blk%04u.dat", i); - if (!boost::filesystem::exists(source)) break; - boost::filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1); - try { - boost::filesystem::create_hard_link(source, dest); - LogPrintf("Hardlinked %s -> %s\n", source.string(), dest.string()); - linked = true; - } catch (const boost::filesystem::filesystem_error& e) { - // Note: hardlink creation failing is not a disaster, it just means - // blocks will get re-downloaded from peers. - LogPrintf("Error hardlinking blk%04u.dat: %s\n", i, e.what()); - break; - } - } - if (linked) - { - fReindex = true; - } - } + boost::filesystem::create_directories(GetDataDir() / "blocks"); // cache size calculations int64_t nTotalCache = (GetArg("-dbcache", nDefaultDbCache) << 20); diff --git a/src/net.cpp b/src/net.cpp index de5fc29693..e38d3b344e 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2210,8 +2210,9 @@ bool CConnman::Start(CScheduler& scheduler, std::string& strNodeError, Options c SetBestHeight(connOptions.nBestHeight); clientInterface = connOptions.uiInterface; - if (clientInterface) - clientInterface->InitMessage(_("Loading addresses...")); + if (clientInterface) { + clientInterface->InitMessage(_("Loading P2P addresses...")); + } // Load addresses from peers.dat int64_t nStart = GetTimeMillis(); { diff --git a/src/prevector.h b/src/prevector.h index 6b2f578f5c..cba2e30057 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -5,6 +5,7 @@ #ifndef _BITCOIN_PREVECTOR_H_ #define _BITCOIN_PREVECTOR_H_ +#include <assert.h> #include <stdlib.h> #include <stdint.h> #include <string.h> @@ -170,10 +171,15 @@ private: } } else { if (!is_direct()) { + /* FIXME: Because malloc/realloc here won't call new_handler if allocation fails, assert + success. These should instead use an allocator or new/delete so that handlers + are called as necessary, but performance would be slightly degraded by doing so. */ _union.indirect = static_cast<char*>(realloc(_union.indirect, ((size_t)sizeof(T)) * new_capacity)); + assert(_union.indirect); _union.capacity = new_capacity; } else { char* new_indirect = static_cast<char*>(malloc(((size_t)sizeof(T)) * new_capacity)); + assert(new_indirect); T* src = direct_ptr(0); T* dst = reinterpret_cast<T*>(new_indirect); memcpy(dst, src, size() * sizeof(T)); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 140cb4840b..c84eab7d23 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -347,11 +347,11 @@ UniValue verifymessage(const JSONRPCRequest& request) "\nUnlock the wallet for 30 seconds\n" + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") + "\nCreate the signature\n" - + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") + + + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") + "\nVerify the signature\n" - + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") + + + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") + "\nAs json rpc\n" - + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"") + + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"signature\", \"my message\"") ); LOCK(cs_main); @@ -400,7 +400,7 @@ UniValue signmessagewithprivkey(const JSONRPCRequest& request) "\nCreate the signature\n" + HelpExampleCli("signmessagewithprivkey", "\"privkey\" \"my message\"") + "\nVerify the signature\n" - + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") + + + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") + "\nAs json rpc\n" + HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"") ); diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 7f1c2a32dd..c148ad6d82 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -78,6 +78,15 @@ TestVector test2 = "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j", 0); +TestVector test3 = + TestVector("4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be") + ("xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13", + "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6", + 0x80000000) + ("xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y", + "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L", + 0); + void RunTest(const TestVector &test) { std::vector<unsigned char> seed = ParseHex(test.strHexMaster); CExtKey key; @@ -146,4 +155,8 @@ BOOST_AUTO_TEST_CASE(bip32_test2) { RunTest(test2); } +BOOST_AUTO_TEST_CASE(bip32_test3) { + RunTest(test3); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index f7d9e1847f..2235bd0ae7 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -1,7 +1,7 @@ [ ["The following are deserialized transactions which are invalid."], ["They are in the form"], -["[[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], +["[[[prevout hash, prevout index, prevout scriptPubKey, amount?], [input 2], ...],"], ["serializedTransaction, verifyFlags]"], ["Objects that are only a single string (like this one) are ignored"], diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index a3f47fcee2..d70fa54333 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -1,7 +1,7 @@ [ ["The following are deserialized transactions which are valid."], ["They are in the form"], -["[[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], +["[[[prevout hash, prevout index, prevout scriptPubKey, amount?], [input 2], ...],"], ["serializedTransaction, verifyFlags]"], ["Objects that are only a single string (like this one) are ignored"], diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index d5d158027b..22c90bd95b 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -277,7 +277,7 @@ BOOST_AUTO_TEST_CASE(iterator_string_ordering) CDBWrapper dbw(ph, (1 << 20), true, false, false); for (int x=0x00; x<10; ++x) { for (int y = 0; y < 10; y++) { - sprintf(buf, "%d", x); + snprintf(buf, sizeof(buf), "%d", x); StringContentsSerializer key(buf); for (int z = 0; z < y; z++) key += key; @@ -293,12 +293,12 @@ BOOST_AUTO_TEST_CASE(iterator_string_ordering) seek_start = 0; else seek_start = 5; - sprintf(buf, "%d", seek_start); + snprintf(buf, sizeof(buf), "%d", seek_start); StringContentsSerializer seek_key(buf); it->Seek(seek_key); for (int x=seek_start; x<10; ++x) { for (int y = 0; y < 10; y++) { - sprintf(buf, "%d", x); + snprintf(buf, sizeof(buf), "%d", x); std::string exp_key(buf); for (int z = 0; z < y; z++) exp_key += exp_key; diff --git a/src/txmempool.h b/src/txmempool.h index a7ecb64390..8a8039ded1 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -20,7 +20,6 @@ #include "sync.h" #include "random.h" -#undef foreach #include "boost/multi_index_container.hpp" #include "boost/multi_index/ordered_index.hpp" #include "boost/multi_index/hashed_index.hpp" diff --git a/src/uint256.cpp b/src/uint256.cpp index bd3d017085..c4c7b716fe 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -20,10 +20,7 @@ base_blob<BITS>::base_blob(const std::vector<unsigned char>& vch) template <unsigned int BITS> std::string base_blob<BITS>::GetHex() const { - char psz[sizeof(data) * 2 + 1]; - for (unsigned int i = 0; i < sizeof(data); i++) - sprintf(psz + i * 2, "%02x", data[sizeof(data) - i - 1]); - return std::string(psz, psz + sizeof(data) * 2); + return HexStr(std::reverse_iterator<const uint8_t*>(data + sizeof(data)), std::reverse_iterator<const uint8_t*>(data)); } template <unsigned int BITS> diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 8a9e7d1444..20a3cbda1e 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -1098,6 +1098,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) result.pushKV("error", JSONRPCError(RPC_MISC_ERROR, strprintf("Failed to rescan before time %d, transactions may be missing.", scannedRange->GetBlockTimeMax()))); response.push_back(std::move(result)); } + ++i; } } } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 6b9e49038b..d785c95ae0 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -236,8 +236,8 @@ UniValue setaccount(const JSONRPCRequest& request) "1. \"address\" (string, required) The bitcoin address to be associated with an account.\n" "2. \"account\" (string, required) The account to assign the address to.\n" "\nExamples:\n" - + HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"tabby\"") - + HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"tabby\"") + + HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"tabby\"") + + HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"tabby\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -283,8 +283,8 @@ UniValue getaccount(const JSONRPCRequest& request) "\nResult:\n" "\"accountname\" (string) the account address\n" "\nExamples:\n" - + HelpExampleCli("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"") - + HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"") + + HelpExampleCli("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") + + HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -503,11 +503,11 @@ UniValue signmessage(const JSONRPCRequest& request) "\nUnlock the wallet for 30 seconds\n" + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") + "\nCreate the signature\n" - + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") + + + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") + "\nVerify the signature\n" - + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") + + + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") + "\nAs json rpc\n" - + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"my message\"") + + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -556,13 +556,13 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request) "amount (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n" "\nExamples:\n" "\nThe amount from transactions with at least 1 confirmation\n" - + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"") + + + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") + "\nThe amount including unconfirmed transactions, zero confirmations\n" - + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" 0") + + + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 0") + "\nThe amount with at least 6 confirmation, very safe\n" - + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" 6") + + + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 6") + "\nAs a json rpc call\n" - + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", 6") + + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", 6") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -906,13 +906,13 @@ UniValue sendmany(const JSONRPCRequest& request) " the number of addresses.\n" "\nExamples:\n" "\nSend two amounts to two different addresses:\n" - + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") + + + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") + "\nSend two amounts to two different addresses setting the confirmation and comment:\n" - + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") + + + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") + "\nSend two amounts to two different addresses, subtract fee from amount:\n" - + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") + + + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") + "\nAs a json rpc call\n" - + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"") + + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index d32e8ba06a..7ac2112dd2 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -395,23 +395,36 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 50 * COIN); } + // Verify importmulti RPC returns failure for a key whose creation time is + // before the missing block, and success for a key whose creation time is + // after. { CWallet wallet; + CWallet *backup = ::pwalletMain; ::pwalletMain = &wallet; + UniValue keys; + keys.setArray(); UniValue key; key.setObject(); key.pushKV("scriptPubKey", HexStr(GetScriptForRawPubKey(coinbaseKey.GetPubKey()))); key.pushKV("timestamp", 0); key.pushKV("internal", UniValue(true)); - UniValue keys; - keys.setArray(); + keys.push_back(key); + key.clear(); + key.setObject(); + CKey futureKey; + futureKey.MakeNewKey(true); + key.pushKV("scriptPubKey", HexStr(GetScriptForRawPubKey(futureKey.GetPubKey()))); + key.pushKV("timestamp", newTip->GetBlockTimeMax() + 7200); + key.pushKV("internal", UniValue(true)); keys.push_back(key); JSONRPCRequest request; request.params.setArray(); request.params.push_back(keys); UniValue response = importmulti(request); - BOOST_CHECK_EQUAL(response.write(), strprintf("[{\"success\":false,\"error\":{\"code\":-1,\"message\":\"Failed to rescan before time %d, transactions may be missing.\"}}]", newTip->GetBlockTimeMax())); + BOOST_CHECK_EQUAL(response.write(), strprintf("[{\"success\":false,\"error\":{\"code\":-1,\"message\":\"Failed to rescan before time %d, transactions may be missing.\"}},{\"success\":true}]", newTip->GetBlockTimeMax())); + ::pwalletMain = backup; } } |