From e4f621fd57c62bfef0eecc7fc92fec5cbf5e86aa Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 23 Oct 2018 18:11:26 -0400 Subject: [PATCH 1/4] merge #14468: [wallet] Deprecate generate RPC method ab9aca2bdf [rpc] add 'getnewaddress' hint to 'generatetoaddress' help text. (John Newbery) c9f02955b2 [wallet] Deprecate the generate RPC method (John Newbery) aab81720de [tests] Add generate method to TestNode (John Newbery) c269209336 [tests] Small fixups before deprecating generate (John Newbery) Pull request description: Deprecates the `generate` RPC method. For concept discussion, see #14299. Fixes #14299. Tree-SHA512: 16a3b8b742932e4f0476c06b23de07a34d9d215b41d9272c1c9d1e39966b0c2406f17c5ab3cc568947620c08171ebe5eb74fd7ed4b62151363e305ee2937cc80 --- doc/release-notes-14468.md | 15 +++++++++++++++ src/rpc/mining.cpp | 2 ++ src/wallet/rpcwallet.cpp | 6 ++++++ test/functional/rpc_deprecated.py | 11 +++++++++-- test/functional/test_framework/test_node.py | 19 +++++++++++++++++++ test/functional/wallet_keypool.py | 9 ++++----- test/functional/wallet_keypool_hd.py | 15 +++++---------- test/functional/wallet_labels.py | 9 +++++---- test/functional/wallet_multiwallet.py | 8 ++++---- 9 files changed, 69 insertions(+), 25 deletions(-) create mode 100644 doc/release-notes-14468.md diff --git a/doc/release-notes-14468.md b/doc/release-notes-14468.md new file mode 100644 index 0000000000..fb0243aba8 --- /dev/null +++ b/doc/release-notes-14468.md @@ -0,0 +1,15 @@ +Wallet `generate` RPC method deprecated +--------------------------------------- + +The wallet's `generate` RPC method has been deprecated and will be fully +removed in v0.19. + +`generate` is only used for testing. The RPC call reaches across multiple +subsystems (wallet and mining), so is deprecated to simplify the wallet-node +interface. Projects that are using `generate` for testing purposes should +transition to using the `generatetoaddress` call, which does not require or use +the wallet component. Calling `generatetoaddress` with an address returned by +`getnewaddress` gives the same functionality as the old `generate` method. + +To continue using `generate` in v0.18, restart bitcoind with the +`-deprecatedrpc=generate` configuration. diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 23e21d1607..d22adeb0d1 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -263,6 +263,8 @@ static UniValue generatetoaddress(const JSONRPCRequest& request) RPCExamples{ "\nGenerate 11 blocks to myaddress\n" + HelpExampleCli("generatetoaddress", "11 \"myaddress\"") + + "If you are running the Dash Core wallet, you can get a new address to send the newly generated coins to with:\n" + + HelpExampleCli("getnewaddress", "") }, }.ToString()); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 521715ae0d..97cbb03297 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3347,6 +3347,12 @@ UniValue generate(const JSONRPCRequest& request) }.ToString()); } + if (!IsDeprecatedRPCEnabled("generate")) { + throw JSONRPCError(RPC_METHOD_DEPRECATED, "The wallet generate rpc method is deprecated and will be fully removed in v0.19. " + "To use generate in v0.18, restart dashd with -deprecatedrpc=generate.\n" + "Clients should transition to using the node rpc method generatetoaddress\n"); + } + std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); diff --git a/test/functional/rpc_deprecated.py b/test/functional/rpc_deprecated.py index 3198862ea6..bc3e56e4fd 100755 --- a/test/functional/rpc_deprecated.py +++ b/test/functional/rpc_deprecated.py @@ -9,7 +9,11 @@ class DeprecatedRpcTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 self.setup_clean_chain = True - self.extra_args = [[], ["-deprecatedrpc=validateaddress"]] + self.extra_args = [[], ["-deprecatedrpc=generate"]] + + def skip_test_if_missing_module(self): + # The generate RPC method requires the wallet to be compiled + self.skip_if_no_wallet() def run_test(self): # This test should be used to verify correct behaviour of deprecated @@ -18,7 +22,10 @@ class DeprecatedRpcTest(BitcoinTestFramework): # self.log.info("Make sure that -deprecatedrpc=createmultisig allows it to take addresses") # assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, [self.nodes[0].getnewaddress()]) # self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()]) - pass + + self.log.info("Test generate RPC") + assert_raises_rpc_error(-32, 'The wallet generate rpc method is deprecated', self.nodes[0].rpc.generate, 1) + self.nodes[1].generate(1) if __name__ == '__main__': DeprecatedRpcTest().main() diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index e3c9b566e5..431c23a3dd 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -264,6 +264,25 @@ class TestNode(): time.sleep(1.0 / poll_per_s) self._raise_assertion_error("Unable to connect to dashd") + def generate(self, nblocks, maxtries=1000000): + self.log.debug("TestNode.generate() dispatches `generate` call to `generatetoaddress`") + # Try to import the node's deterministic private key. This is a no-op if the private key + # has already been imported. + try: + self.rpc.importprivkey(privkey=self.get_deterministic_priv_key().key, label='coinbase', rescan=False) + except JSONRPCException as e: + # This may fail if: + # - wallet is disabled ('Method not found') + # - there are multiple wallets to import to ('Wallet file not specified') + # - wallet is locked ('Error: Please enter the wallet passphrase with walletpassphrase first') + # Just ignore those errors. We can make this tidier by importing the privkey during TestFramework.setup_nodes + # TODO: tidy up deterministic privkey import. + assert str(e).startswith('Method not found') or \ + str(e).startswith('Wallet file not specified') or \ + str(e).startswith('Error: Please enter the wallet passphrase with walletpassphrase first') + + return self.generatetoaddress(nblocks=nblocks, address=self.get_deterministic_priv_key().address, maxtries=maxtries) + def get_wallet_rpc(self, wallet_name): if self.use_cli: return self.cli("-rpcwallet={}".format(wallet_name)) diff --git a/test/functional/wallet_keypool.py b/test/functional/wallet_keypool.py index 0ad9aa2e6c..393b346580 100755 --- a/test/functional/wallet_keypool.py +++ b/test/functional/wallet_keypool.py @@ -49,11 +49,10 @@ class KeyPoolTest(BitcoinTestFramework): time.sleep(1.1) assert_equal(nodes[0].getwalletinfo()["unlocked_until"], 0) - # drain them by mining - nodes[0].generate(1) - nodes[0].generate(1) - nodes[0].generate(1) - assert_raises_rpc_error(-12, "Keypool ran out", nodes[0].generate, 1) + # drain the keypool + for _ in range(3): + nodes[0].getnewaddress() + assert_raises_rpc_error(-12, "Keypool ran out", nodes[0].getnewaddress) if __name__ == '__main__': KeyPoolTest().main() diff --git a/test/functional/wallet_keypool_hd.py b/test/functional/wallet_keypool_hd.py index 6191bcfa93..d22effdeaf 100755 --- a/test/functional/wallet_keypool_hd.py +++ b/test/functional/wallet_keypool_hd.py @@ -11,7 +11,7 @@ import time from test_framework.authproxy import JSONRPCException from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal +from test_framework.util import assert_equal, assert_raises_rpc_error class KeyPoolTest(BitcoinTestFramework): @@ -90,15 +90,10 @@ class KeyPoolTest(BitcoinTestFramework): time.sleep(1.1) assert_equal(nodes[0].getwalletinfo()["unlocked_until"], 0) - # drain them by mining - nodes[0].generate(1) - nodes[0].generate(1) - nodes[0].generate(1) - try: - nodes[0].generate(1) - raise AssertionError('Keypool should be exhausted after three addesses') - except JSONRPCException as e: - assert e.error['code']==-12 + # drain the keypool + for _ in range(3): + nodes[0].getnewaddress() + assert_raises_rpc_error(-12, "Keypool ran out", nodes[0].getnewaddress) nodes[0].walletpassphrase('test', 100) nodes[0].keypoolrefill(100) diff --git a/test/functional/wallet_labels.py b/test/functional/wallet_labels.py index 65c851ec7b..10d618a54d 100755 --- a/test/functional/wallet_labels.py +++ b/test/functional/wallet_labels.py @@ -29,8 +29,8 @@ class WalletLabelsTest(BitcoinTestFramework): # Note each time we call generate, all generated coins go into # the same address, so we call twice to get two addresses w/500 each - node.generate(1) - node.generate(101) + node.generatetoaddress(nblocks=1, address=node.getnewaddress(label='coinbase')) + node.generatetoaddress(nblocks=101, address=node.getnewaddress(label='coinbase')) assert_equal(node.getbalance(), 1000) # there should be 2 address groups @@ -42,8 +42,9 @@ class WalletLabelsTest(BitcoinTestFramework): linked_addresses = set() for address_group in address_groups: assert_equal(len(address_group), 1) - assert_equal(len(address_group[0]), 2) + assert_equal(len(address_group[0]), 3) assert_equal(address_group[0][1], 500) + assert_equal(address_group[0][2], 'coinbase') linked_addresses.add(address_group[0][0]) # send 500 from each address to a third address not in this wallet @@ -79,7 +80,7 @@ class WalletLabelsTest(BitcoinTestFramework): label.verify(node) # Check all labels are returned by listlabels. - assert_equal(node.listlabels(), [label.name for label in labels]) + assert_equal(node.listlabels(), sorted(['coinbase'] + [label.name for label in labels])) # Send a transaction to each label. for label in labels: diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py index 94c6d3d4e6..2383de076a 100755 --- a/test/functional/wallet_multiwallet.py +++ b/test/functional/wallet_multiwallet.py @@ -135,7 +135,7 @@ class MultiWalletTest(BitcoinTestFramework): self.start_node(0, ['-wallet=w4', '-wallet=w5']) assert_equal(set(node.listwallets()), {"w4", "w5"}) w5 = wallet("w5") - w5.generate(1) + node.generatetoaddress(nblocks=1, address=w5.getnewaddress()) # now if wallets/ exists again, but the rootdir is specified as the walletdir, w4 and w5 should still be loaded os.rename(wallet_dir2, wallet_dir()) @@ -159,7 +159,7 @@ class MultiWalletTest(BitcoinTestFramework): wallet_bad = wallet("bad") # check wallet names and balances - wallets[0].generate(1) + node.generatetoaddress(nblocks=1, address=wallets[0].getnewaddress()) for wallet_name, wallet in zip(wallet_names, wallets): info = wallet.getwalletinfo() assert_equal(info['immature_balance'], 500 if wallet is wallets[0] else 0) @@ -172,7 +172,7 @@ class MultiWalletTest(BitcoinTestFramework): assert_raises_rpc_error(-19, "Wallet file not specified", node.getwalletinfo) w1, w2, w3, w4, *_ = wallets - w1.generate(101) + node.generatetoaddress(nblocks=101, address=w1.getnewaddress()) assert_equal(w1.getbalance(), 1000) assert_equal(w2.getbalance(), 0) assert_equal(w3.getbalance(), 0) @@ -181,7 +181,7 @@ class MultiWalletTest(BitcoinTestFramework): w1.sendtoaddress(w2.getnewaddress(), 1) w1.sendtoaddress(w3.getnewaddress(), 2) w1.sendtoaddress(w4.getnewaddress(), 3) - w1.generate(1) + node.generatetoaddress(nblocks=1, address=w1.getnewaddress()) assert_equal(w2.getbalance(), 1) assert_equal(w3.getbalance(), 2) assert_equal(w4.getbalance(), 3) From 8cac4ed930b2940ac7e511a7e7c4b21b2970ba0c Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 2 Mar 2019 09:43:32 -0500 Subject: [PATCH 2/4] Merge #15492: [rpc] remove deprecated generate method 07cae5287c [wallet] remove unused GetScriptForMining (Sjors Provoost) 8bb3e4c487 [rpc] remove deprecated generate method (Sjors Provoost) Pull request description: As announced in v0.18, the wallet generate rpc method is deprecated and will be fully removed in v0.19. Clients should transition to using the node rpc method `generatetoaddress`. Tree-SHA512: 9e5e913b59f3e18440b2b7b356124c7b87ad19f81a1ab6ada06a6c396b84e734895465f569296f1ba8c12abf74863bab5fd77765c9e806c239713aa83a59485f --- doc/release-notes-15492.md | 11 +++++ src/rpc/client.cpp | 2 - src/wallet/rpcwallet.cpp | 67 ------------------------------- src/wallet/wallet.cpp | 11 ----- src/wallet/wallet.h | 2 - test/functional/rpc_deprecated.py | 22 +++++----- 6 files changed, 21 insertions(+), 94 deletions(-) create mode 100644 doc/release-notes-15492.md diff --git a/doc/release-notes-15492.md b/doc/release-notes-15492.md new file mode 100644 index 0000000000..1149eb0dbc --- /dev/null +++ b/doc/release-notes-15492.md @@ -0,0 +1,11 @@ +Deprecated or removed RPCs +-------------------------- +- The wallet's `generate` RPC method was deprecated in v0.18 and has now + been fully removed. This RPC is only used for + testing, but its implementation reached across multiple subsystems + (wallet and mining), so it has been removed to simplify the + wallet-node interface. Projects that are using `generate` for testing + purposes should transition to using the `generatetoaddress` RPC, which + does not require or use the wallet component. Calling + `generatetoaddress` with an address returned by the `getnewaddress` + RPC gives the same functionality as the old `generate` RPC. diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 50f9bfc3e8..b0f3ffc85e 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -29,8 +29,6 @@ static const CRPCConvertParam vRPCConvertParams[] = { "setmocktime", 0, "timestamp" }, { "mockscheduler", 0, "delta_time" }, #if ENABLE_MINER - { "generate", 0, "nblocks" }, - { "generate", 1, "maxtries" }, { "generatetoaddress", 0, "nblocks" }, { "generatetoaddress", 2, "maxtries" }, { "generatetodescriptor", 0, "num_blocks" }, diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 97cbb03297..bc2f1adff0 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -3326,67 +3325,6 @@ UniValue signrawtransactionwithwallet(const JSONRPCRequest& request) return SignTransaction(mtx, request.params[1], pwallet, coins, false, request.params[2]); } -#if ENABLE_MINER -UniValue generate(const JSONRPCRequest& request) -{ - if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { - throw std::runtime_error( - RPCHelpMan{"generate", - "\nMine up to nblocks blocks immediately (before the RPC call returns) to an address in the wallet.\n", - { - {"nblocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated immediately."}, - {"maxtries", RPCArg::Type::NUM, /* default */ "1000000", "How many iterations to try."}, - }, - RPCResult{ - "[ blockhashes ] (json array) hashes of blocks generated\n" - }, - RPCExamples{ - "\nGenerate 11 blocks\n" - + HelpExampleCli("generate", "11") - }, - }.ToString()); - } - - if (!IsDeprecatedRPCEnabled("generate")) { - throw JSONRPCError(RPC_METHOD_DEPRECATED, "The wallet generate rpc method is deprecated and will be fully removed in v0.19. " - "To use generate in v0.18, restart dashd with -deprecatedrpc=generate.\n" - "Clients should transition to using the node rpc method generatetoaddress\n"); - } - - std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); - if (!wallet) return NullUniValue; - CWallet* const pwallet = wallet.get(); - - int num_generate = request.params[0].get_int(); - uint64_t max_tries = 1000000; - if (!request.params[1].isNull()) { - max_tries = request.params[1].get_int(); - } - - std::shared_ptr coinbase_script; - pwallet->GetScriptForMining(coinbase_script); - - // If the keypool is exhausted, no script is returned at all. Catch this. - if (!coinbase_script) { - throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); - } - - //throw an error if no script was provided - if (coinbase_script->reserveScript.empty()) { - throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available"); - } - - const CTxMemPool& mempool = EnsureMemPool(); - - return generateBlocks(mempool, coinbase_script, num_generate, max_tries, true); -} -#else -UniValue generate(const JSONRPCRequest& request) -{ - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This call is not available because RPC miner isn't compiled"); -} -#endif //ENABLE_MINING - static UniValue rescanblockchain(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() > 2) { @@ -3990,11 +3928,6 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request) static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- -#if ENABLE_MINER - { "generating", "generate", &generate, {"nblocks","maxtries"} }, -#else - { "hidden", "generate", &generate, {"nblocks","maxtries"} }, // Hidden as it isn't functional, just an error to let people know if miner isn't compiled -#endif //ENABLE_MINER { "hidden", "instantsendtoaddress", &instantsendtoaddress, {} }, { "rawtransactions", "fundrawtransaction", &fundrawtransaction, {"hexstring","options"} }, { "wallet", "abandontransaction", &abandontransaction, {"txid"} }, diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 89c6571706..3eb2486aab 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4772,17 +4772,6 @@ void CWallet::MarkReserveKeysAsUsed(int64_t keypool_id) } } -void CWallet::GetScriptForMining(std::shared_ptr &script) -{ - std::shared_ptr rKey = std::make_shared(this); - CPubKey pubkey; - if (!rKey->GetReservedKey(pubkey, false)) - return; - - script = rKey; - script->reserveScript = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; -} - void CWallet::LockCoin(const COutPoint& output) { AssertLockHeld(cs_wallet); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 0c5affa543..afc7b67d88 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1177,8 +1177,6 @@ public: bool DelAddressBook(const CTxDestination& address); - void GetScriptForMining(std::shared_ptr &script); - unsigned int GetKeyPoolSize() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); diff --git a/test/functional/rpc_deprecated.py b/test/functional/rpc_deprecated.py index bc3e56e4fd..e31143524d 100755 --- a/test/functional/rpc_deprecated.py +++ b/test/functional/rpc_deprecated.py @@ -4,28 +4,26 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test deprecation of RPC calls.""" from test_framework.test_framework import BitcoinTestFramework +# from test_framework.util import assert_raises_rpc_error class DeprecatedRpcTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 self.setup_clean_chain = True - self.extra_args = [[], ["-deprecatedrpc=generate"]] - - def skip_test_if_missing_module(self): - # The generate RPC method requires the wallet to be compiled - self.skip_if_no_wallet() + self.extra_args = [[], []] def run_test(self): # This test should be used to verify correct behaviour of deprecated # RPC methods with and without the -deprecatedrpc flags. For example: # - # self.log.info("Make sure that -deprecatedrpc=createmultisig allows it to take addresses") - # assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, [self.nodes[0].getnewaddress()]) - # self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()]) - - self.log.info("Test generate RPC") - assert_raises_rpc_error(-32, 'The wallet generate rpc method is deprecated', self.nodes[0].rpc.generate, 1) - self.nodes[1].generate(1) + # In set_test_params: + # self.extra_args = [[], ["-deprecatedrpc=generate"]] + # + # In run_test: + # self.log.info("Test generate RPC") + # assert_raises_rpc_error(-32, 'The wallet generate rpc method is deprecated', self.nodes[0].rpc.generate, 1) + # self.nodes[1].generate(1) + self.log.info("No tested deprecated RPC methods") if __name__ == '__main__': DeprecatedRpcTest().main() From 0bbd8bfab6166fbe2369b285cc3553a54f2ce808 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 2 Nov 2018 11:41:29 -0400 Subject: [PATCH 3/4] Merge #14631: [tests] Move deterministic address import to setup_nodes 3fd7e76f6d [tests] Move deterministic address import to setup_nodes (John Newbery) Pull request description: This requires a small changes to a few tests, but means that deterministic addresses will always be imported (unless setup_nodes behaviour is explicitly overridden). Tidies up the way we import deterministic addresses, requested in review comment here: https://github.com/bitcoin/bitcoin/pull/14468#discussion_r225594586. Tree-SHA512: 2b32edf500e286c463398487ab1153116a1dc90f64a53614716373311abdc83d8a251fdd8f42d1146b56e308664deaf62952113f66e98bc37f23968096d1a961 --- test/functional/feature_addressindex.py | 2 +- test/functional/feature_dbcrash.py | 1 + test/functional/feature_dip3_deterministicmns.py | 1 + test/functional/feature_fee_estimation.py | 8 +++----- test/functional/feature_pruning.py | 2 ++ test/functional/feature_spentindex.py | 2 +- test/functional/feature_txindex.py | 2 +- test/functional/interface_zmq.py | 1 + test/functional/p2p_node_network_limited.py | 4 ++-- test/functional/test_framework/test_framework.py | 9 ++++----- test/functional/test_framework/test_node.py | 15 --------------- test/functional/wallet_basic.py | 7 +++---- test/functional/wallet_hd.py | 1 + test/functional/wallet_import_rescan.py | 6 ++---- test/functional/wallet_listreceivedby.py | 12 +++++------- test/functional/wallet_upgradetohd.py | 1 + 16 files changed, 29 insertions(+), 45 deletions(-) diff --git a/test/functional/feature_addressindex.py b/test/functional/feature_addressindex.py index 5643e8005b..7f71e6c9d3 100755 --- a/test/functional/feature_addressindex.py +++ b/test/functional/feature_addressindex.py @@ -35,8 +35,8 @@ class AddressIndexTest(BitcoinTestFramework): connect_nodes(self.nodes[0], 1) connect_nodes(self.nodes[0], 2) connect_nodes(self.nodes[0], 3) - self.sync_all() + self.import_deterministic_coinbase_privkeys() def run_test(self): self.log.info("Test that settings can't be changed without -reindex...") diff --git a/test/functional/feature_dbcrash.py b/test/functional/feature_dbcrash.py index b7cc776fa2..3a18d74c74 100755 --- a/test/functional/feature_dbcrash.py +++ b/test/functional/feature_dbcrash.py @@ -74,6 +74,7 @@ class ChainstateWriteCrashTest(BitcoinTestFramework): def setup_network(self): self.add_nodes(self.num_nodes, extra_args=self.extra_args) self.start_nodes() + self.import_deterministic_coinbase_privkeys() # Leave them unconnected, we'll use submitblock directly in this test def restart_node(self, node_index, expected_tip): diff --git a/test/functional/feature_dip3_deterministicmns.py b/test/functional/feature_dip3_deterministicmns.py index 7019b10028..3d53d3ff1f 100755 --- a/test/functional/feature_dip3_deterministicmns.py +++ b/test/functional/feature_dip3_deterministicmns.py @@ -35,6 +35,7 @@ class DIP3Test(BitcoinTestFramework): self.disable_mocktime() self.add_nodes(1) self.start_controller_node() + self.import_deterministic_coinbase_privkeys() def start_controller_node(self): self.log.info("starting controller node") diff --git a/test/functional/feature_fee_estimation.py b/test/functional/feature_fee_estimation.py index 692c71a2f6..0007447947 100755 --- a/test/functional/feature_fee_estimation.py +++ b/test/functional/feature_fee_estimation.py @@ -147,6 +147,9 @@ class EstimateFeeTest(BitcoinTestFramework): # (17k is room enough for 110 or so transactions) # Node2 is a stingy miner, that # produces too small blocks (room for only 55 or so transactions) + self.start_nodes() + self.import_deterministic_coinbase_privkeys() + self.stop_nodes() def transact_and_mine(self, numblocks, mining_node): min_fee = Decimal("0.0001") @@ -174,11 +177,6 @@ class EstimateFeeTest(BitcoinTestFramework): newmem.append(utx) self.memutxo = newmem - def import_deterministic_coinbase_privkeys(self): - self.start_nodes() - super().import_deterministic_coinbase_privkeys() - self.stop_nodes() - def run_test(self): self.log.info("This test is time consuming, please be patient") self.log.info("Splitting inputs so we can generate tx's") diff --git a/test/functional/feature_pruning.py b/test/functional/feature_pruning.py index 507249f605..7c9c3af38f 100755 --- a/test/functional/feature_pruning.py +++ b/test/functional/feature_pruning.py @@ -105,6 +105,8 @@ class PruneTest(BitcoinTestFramework): def setup_nodes(self): self.add_nodes(self.num_nodes, self.extra_args) self.start_nodes() + for n in self.nodes: + n.importprivkey(privkey=n.get_deterministic_priv_key().key, label='coinbase', rescan=False) def create_big_chain(self): # Start by creating some coinbases we can spend later diff --git a/test/functional/feature_spentindex.py b/test/functional/feature_spentindex.py index 9fcc853dcf..0015e8708b 100755 --- a/test/functional/feature_spentindex.py +++ b/test/functional/feature_spentindex.py @@ -37,8 +37,8 @@ class SpentIndexTest(BitcoinTestFramework): connect_nodes(self.nodes[0], 1) connect_nodes(self.nodes[0], 2) connect_nodes(self.nodes[0], 3) - self.sync_all() + self.import_deterministic_coinbase_privkeys() def run_test(self): self.log.info("Test that settings can't be changed without -reindex...") diff --git a/test/functional/feature_txindex.py b/test/functional/feature_txindex.py index 449cc9f725..05f0907636 100755 --- a/test/functional/feature_txindex.py +++ b/test/functional/feature_txindex.py @@ -35,8 +35,8 @@ class TxIndexTest(BitcoinTestFramework): connect_nodes(self.nodes[0], 1) connect_nodes(self.nodes[0], 2) connect_nodes(self.nodes[0], 3) - self.sync_all() + self.import_deterministic_coinbase_privkeys() def run_test(self): self.log.info("Mining blocks...") diff --git a/test/functional/interface_zmq.py b/test/functional/interface_zmq.py index b6b45ffe78..b6301b4729 100755 --- a/test/functional/interface_zmq.py +++ b/test/functional/interface_zmq.py @@ -73,6 +73,7 @@ class ZMQTest (BitcoinTestFramework): ] self.add_nodes(self.num_nodes, self.extra_args) self.start_nodes() + self.import_deterministic_coinbase_privkeys() def run_test(self): try: diff --git a/test/functional/p2p_node_network_limited.py b/test/functional/p2p_node_network_limited.py index 0cb4c371f0..a4b5f85de3 100755 --- a/test/functional/p2p_node_network_limited.py +++ b/test/functional/p2p_node_network_limited.py @@ -43,8 +43,8 @@ class NodeNetworkLimitedTest(BitcoinTestFramework): disconnect_nodes(self.nodes[1], 2) def setup_network(self): - super(NodeNetworkLimitedTest, self).setup_network() - self.disconnect_all() + self.add_nodes(self.num_nodes, self.extra_args) + self.start_nodes() def run_test(self): node = self.nodes[0].add_p2p_connection(P2PIgnoreInv()) diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index bf0091d8c9..9fbd70030c 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -230,7 +230,6 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): self.skip_test_if_missing_module() self.setup_chain() self.setup_network() - self.import_deterministic_coinbase_privkeys() self.run_test() success = TestStatus.PASSED except JSONRPCException: @@ -353,11 +352,9 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): extra_args = self.extra_args self.add_nodes(self.num_nodes, extra_args) self.start_nodes() + self.import_deterministic_coinbase_privkeys() def import_deterministic_coinbase_privkeys(self): - if self.setup_clean_chain: - return - for n in self.nodes: try: n.getwalletinfo() @@ -365,7 +362,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): assert str(e).startswith('Method not found') continue - n.importprivkey(n.get_deterministic_priv_key().key) + n.importprivkey(privkey=n.get_deterministic_priv_key().key, label='coinbase') def run_test(self): """Tests must override this method to define test logic""" @@ -925,6 +922,7 @@ class DashTestFramework(BitcoinTestFramework): self.log.info("Creating and starting controller node") self.add_nodes(1, extra_args=[self.extra_args[0]]) self.start_node(0) + self.import_deterministic_coinbase_privkeys() required_balance = MASTERNODE_COLLATERAL * self.mn_count + 1 self.log.info("Generating %d coins" % required_balance) while self.nodes[0].getbalance() < required_balance: @@ -945,6 +943,7 @@ class DashTestFramework(BitcoinTestFramework): self.prepare_masternodes() self.prepare_datadirs() self.start_masternodes() + self.import_deterministic_coinbase_privkeys() # non-masternodes where disconnected from the control node during prepare_datadirs, # let's reconnect them back to make sure they receive updates diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index 431c23a3dd..04546edc3a 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -266,21 +266,6 @@ class TestNode(): def generate(self, nblocks, maxtries=1000000): self.log.debug("TestNode.generate() dispatches `generate` call to `generatetoaddress`") - # Try to import the node's deterministic private key. This is a no-op if the private key - # has already been imported. - try: - self.rpc.importprivkey(privkey=self.get_deterministic_priv_key().key, label='coinbase', rescan=False) - except JSONRPCException as e: - # This may fail if: - # - wallet is disabled ('Method not found') - # - there are multiple wallets to import to ('Wallet file not specified') - # - wallet is locked ('Error: Please enter the wallet passphrase with walletpassphrase first') - # Just ignore those errors. We can make this tidier by importing the privkey during TestFramework.setup_nodes - # TODO: tidy up deterministic privkey import. - assert str(e).startswith('Method not found') or \ - str(e).startswith('Wallet file not specified') or \ - str(e).startswith('Error: Please enter the wallet passphrase with walletpassphrase first') - return self.generatetoaddress(nblocks=nblocks, address=self.get_deterministic_priv_key().address, maxtries=maxtries) def get_wallet_rpc(self, wallet_name): diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py index 2a0243f32f..fb58e67631 100755 --- a/test/functional/wallet_basic.py +++ b/test/functional/wallet_basic.py @@ -31,10 +31,9 @@ class WalletTest(BitcoinTestFramework): self.skip_if_no_wallet() def setup_network(self): - self.add_nodes(4, self.extra_args) - self.start_node(0) - self.start_node(1) - self.start_node(2) + self.setup_nodes() + # Only need nodes 0-2 running at start of test + self.stop_node(3) connect_nodes(self.nodes[0], 1) connect_nodes(self.nodes[1], 2) connect_nodes(self.nodes[0], 2) diff --git a/test/functional/wallet_hd.py b/test/functional/wallet_hd.py index 2c1915a747..18453c2b40 100755 --- a/test/functional/wallet_hd.py +++ b/test/functional/wallet_hd.py @@ -22,6 +22,7 @@ class WalletHDTest(BitcoinTestFramework): def setup_network(self): self.add_nodes(self.num_nodes, self.extra_args) self.start_nodes() + self.import_deterministic_coinbase_privkeys() def skip_test_if_missing_module(self): self.skip_if_no_wallet() diff --git a/test/functional/wallet_import_rescan.py b/test/functional/wallet_import_rescan.py index 823551bfa7..fcc3ae86b8 100755 --- a/test/functional/wallet_import_rescan.py +++ b/test/functional/wallet_import_rescan.py @@ -135,16 +135,14 @@ class ImportRescanTest(BitcoinTestFramework): # Import keys with pruning disabled self.start_nodes(extra_args=[[]] * self.num_nodes) - super().import_deterministic_coinbase_privkeys() + for n in self.nodes: + n.importprivkey(privkey=n.get_deterministic_priv_key().key, label='coinbase') self.stop_nodes() self.start_nodes() for i in range(1, self.num_nodes): connect_nodes(self.nodes[i], 0) - def import_deterministic_coinbase_privkeys(self): - pass - def run_test(self): # Create one transaction on node 0 with a unique amount for # each possible type of wallet import RPC. diff --git a/test/functional/wallet_listreceivedby.py b/test/functional/wallet_listreceivedby.py index 21f13035e5..5e8a48832a 100755 --- a/test/functional/wallet_listreceivedby.py +++ b/test/functional/wallet_listreceivedby.py @@ -18,11 +18,6 @@ class ReceivedByTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 - def import_deterministic_coinbase_privkeys(self): - assert_equal(0, len(self.nodes[1].listreceivedbyaddress(minconf=0, include_empty=True, include_watchonly=True))) - super().import_deterministic_coinbase_privkeys() - self.num_cb_reward_addresses = len(self.nodes[1].listreceivedbyaddress(minconf=0, include_empty=True, include_watchonly=True)) - def skip_test_if_missing_module(self): self.skip_if_no_wallet() self.skip_if_no_cli() @@ -32,6 +27,9 @@ class ReceivedByTest(BitcoinTestFramework): self.nodes[0].generate(1) sync_blocks(self.nodes) + # save the number of coinbase reward addresses so far + num_cb_reward_addresses = len(self.nodes[1].listreceivedbyaddress(minconf=0, include_empty=True, include_watchonly=True)) + self.log.info("listreceivedbyaddress Test") # Send from node 0 to 1 @@ -77,7 +75,7 @@ class ReceivedByTest(BitcoinTestFramework): assert_raises_rpc_error(-4, "address_filter parameter was invalid", self.nodes[1].listreceivedbyaddress, minconf=0, addlocked=True, include_empty=True, include_watchonly=True, address_filter="bamboozling") # Another address receive money res = self.nodes[1].listreceivedbyaddress(0, True, True, True) - assert_equal(len(res), 2 + self.num_cb_reward_addresses) # Right now 2 entries + assert_equal(len(res), 2 + num_cb_reward_addresses) # Right now 2 entries other_addr = self.nodes[1].getnewaddress() txid2 = self.nodes[0].sendtoaddress(other_addr, 0.1) self.nodes[0].generate(1) @@ -94,7 +92,7 @@ class ReceivedByTest(BitcoinTestFramework): assert_equal(len(res), 1) # Should be two entries though without filter res = self.nodes[1].listreceivedbyaddress(0, True, True, True) - assert_equal(len(res), 3 + self.num_cb_reward_addresses) # Became 3 entries + assert_equal(len(res), 3 + num_cb_reward_addresses) # Became 3 entries # Not on random addr other_addr = self.nodes[0].getnewaddress() # note on node[0]! just a random addr diff --git a/test/functional/wallet_upgradetohd.py b/test/functional/wallet_upgradetohd.py index 4b21434a3a..7f798365cd 100755 --- a/test/functional/wallet_upgradetohd.py +++ b/test/functional/wallet_upgradetohd.py @@ -28,6 +28,7 @@ class WalletUpgradeToHDTest(BitcoinTestFramework): def setup_network(self): self.add_nodes(self.num_nodes) self.start_nodes() + self.import_deterministic_coinbase_privkeys() def recover_non_hd(self): self.log.info("Recover non-HD wallet to check different upgrade paths") From e743af559fe1b881d64f728a75aaa2c801b8a44d Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Sun, 1 May 2022 22:42:51 +0300 Subject: [PATCH 4/4] fix tool_wallet.py --- test/functional/tool_wallet.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/functional/tool_wallet.py b/test/functional/tool_wallet.py index 92b87fc53a..3c58d911a3 100755 --- a/test/functional/tool_wallet.py +++ b/test/functional/tool_wallet.py @@ -99,7 +99,7 @@ class ToolWalletTest(BitcoinTestFramework): HD (hd seed available): no Keypool Size: 1 Transactions: 0 - Address Book: 0 + Address Book: 1 ''') self.assert_tool_output(out, '-wallet=wallet.dat', 'info') @@ -114,7 +114,7 @@ class ToolWalletTest(BitcoinTestFramework): HD (hd seed available): yes Keypool Size: 2 Transactions: 0 - Address Book: 0 + Address Book: 1 ''') self.assert_tool_output(out, '-wallet=wallet.dat', 'info') timestamp_after = self.wallet_timestamp() @@ -151,9 +151,9 @@ class ToolWalletTest(BitcoinTestFramework): =========== Encrypted: no HD (hd seed available): yes - Keypool Size: 1 + Keypool Size: 2 Transactions: 1 - Address Book: 0 + Address Book: 1 ''') self.assert_tool_output(out, '-wallet=wallet.dat', 'info') shasum_after = self.wallet_shasum()