diff options
-rw-r--r-- | doc/bips.md | 1 | ||||
-rw-r--r-- | doc/release-notes.md | 8 | ||||
-rwxr-xr-x | qa/rpc-tests/import-rescan.py | 30 | ||||
-rw-r--r-- | src/init.cpp | 16 | ||||
-rw-r--r-- | src/prevector.h | 6 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 3 | ||||
-rw-r--r-- | src/wallet/test/wallet_tests.cpp | 2 |
7 files changed, 53 insertions, 13 deletions
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/release-notes.md b/doc/release-notes.md index 1bf9261c8d..9d3c3e34fe 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -168,7 +168,8 @@ Opt into RBF When Sending A new startup option, `-walletrbf`, has been added to allow users to have all transactions sent opt into RBF support. The default value for this option is -currently `false`, so transactions will not opt into RBF by default. +currently `false`, so transactions will not opt into RBF by default. The new +`bumpfee` RPC can be used to replace transactions that opt into RBF. Sensitive Data Is No Longer Stored In Debug Console History ----------------------------------------------------------- @@ -247,6 +248,11 @@ Low-level RPC changes optimizations to memory management. See [Pull #8753](https://github.com/bitcoin/bitcoin/pull/8753) for more information. + - A new RPC command `bumpfee` has been added which allows replacing an + unconfirmed wallet transaction that signaled RBF (see the `-walletrbf` + startup option above) with a new transaction that pays a higher fee, and + should be more likely to get confirmed quickly. + HTTP REST Changes ----------------- diff --git a/qa/rpc-tests/import-rescan.py b/qa/rpc-tests/import-rescan.py index 54cc6d2642..7f2c321746 100755 --- a/qa/rpc-tests/import-rescan.py +++ b/qa/rpc-tests/import-rescan.py @@ -5,11 +5,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 @@ -81,6 +81,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: @@ -106,11 +112,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"] @@ -123,9 +129,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 @@ -142,7 +148,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 @@ -156,7 +162,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 7c108ac4a6..5820d8f57c 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -801,6 +801,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 @@ -853,6 +866,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; } 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/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 45b572aa2e..510b2d6ebc 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -819,6 +819,9 @@ UniValue sendfrom(const JSONRPCRequest& request) + HelpRequiringPassphrase() + "\n" "\nArguments:\n" "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n" + " Specifying an account does not influence coin selection, but it does associate the newly created\n" + " transaction with the account, so the account's balance computation and transaction history can reflect\n" + " the spend.\n" "2. \"toaddress\" (string, required) The bitcoin address to send funds to.\n" "3. amount (numeric or string, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n" "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index d32e8ba06a..43d7e3c617 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -397,6 +397,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) { CWallet wallet; + CWallet *backup = ::pwalletMain; ::pwalletMain = &wallet; UniValue key; key.setObject(); @@ -412,6 +413,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) 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())); + ::pwalletMain = backup; } } |