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
This commit is contained in:
MarcoFalke 2018-10-23 18:11:26 -04:00 committed by UdjinM6
parent 29cdb4adb0
commit e4f621fd57
No known key found for this signature in database
GPG Key ID: 83592BD1400D58D9
9 changed files with 69 additions and 25 deletions

View File

@ -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.

View File

@ -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());

View File

@ -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<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
if (!wallet) return NullUniValue;
CWallet* const pwallet = wallet.get();

View File

@ -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()

View File

@ -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))

View File

@ -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()

View File

@ -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)

View File

@ -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:

View File

@ -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)