Deprecates the generate
RPC method.
For concept discussion, see #14299.
Fixes #14299.
rpc_deprecated.py
test should be fixed now.
re-utACK, just note that the whole rpc_deprecated test will be skipped now if the wallet isn’t enabled, which is ok for now since this is the only test in it I guess
Yes. I did consider just silently skipping the individual test case, but I think “mark the whole test as skipped if part of it is skipped” makes most sense. The other option “mark the test as passed even if part of it is skipped” means that test cases can be silently skipped.
99 memory_before = self.nodes[0].getmemoryinfo()
100 self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
101 mempool_txid = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
102 memory_after = self.nodes[0].getmemoryinfo()
103- assert(memory_before['locked']['used'] + 64 <= memory_after['locked']['used'])
104+ assert_greater_than(memory_after['locked']['used'], memory_before['locked']['used'])
+63
?
The memory usage change between these two calls is actually 32.
I’m not entirely sure why getmemoryinfo
is part of the wallet_basic
test. How bitcoin core allocates locked memory pages seems purely an implementation detail and shouldn’t cause functional wallet tests to fail.
To minimize the delta in this PR, I changed the equality check to a looser inequality check, but I think this test case should be moved out of wallet_basic.py
entirely in a future PR.
sounds like a good one for someone to do =).
Curious how the test passed before if it was only 32 bytes?
28@@ -29,8 +29,8 @@ def run_test(self):
29
30 # Note each time we call generate, all generated coins go into
31 # the same address, so we call twice to get two addresses w/50 each
32- node.generate(1)
33- node.generate(101)
34+ node.generatetoaddress(nblocks=1, address=node.getnewaddress(label='coinbase'))
35+ node.generatetoaddress(nblocks=101, address=node.getnewaddress(label='coinbase'))
coinbase_address
as a variable?
202+ # Try to import the node's deterministic private key. This is a no-op if the private key
203+ # has already been imported.
204+ try:
205+ self.rpc.importprivkey(privkey=self.get_deterministic_priv_key().key, label='coinbase', rescan=False)
206+ except JSONRPCException as e:
207+ assert str(e).startswith('Method not found') or \
I’m not sure I understand this assertion, do we want here to blanket-ignore exceptions matching these strings?
seems to me that continuing with generatetoaddress
if this failed is not a good idea
Only accept importprivkey
failure if:
In either case the outcome is the impossibility of spending the coinbase output. And if that’s relevant to the test then it would fail for not having enough coins to spend.
@promag is right. This call to importprivkey
can fail for the three reasons listed.
I think that this is a bit too much magic behind the scenes though. I’ve tidied up the deterministic priv key import behaviour in another branch here: https://github.com/jnewbery/bitcoin/tree/deprecate_generate2. Rather than complicate this PR and add review burden here, are you happy to leave this as is for now and take the final commit in https://github.com/jnewbery/bitcoin/tree/deprecate_generate2 as a follow-up PR?
124@@ -125,7 +125,8 @@ def wallet_file(name):
125 self.start_node(0, ['-wallet=w4', '-wallet=w5'])
126 assert_equal(set(node.listwallets()), {"w4", "w5"})
127 w5 = wallet("w5")
128- w5.generate(1)
129+ self.nodes[0].generatetoaddress(nblocks=1, address=w5.getnewaddress())
w5.generatetoaddress
despite the fact this RPC doesn’t require a wallet.
Yes, that’s possible, but I think it’s better to call the generatetoaddress
method on the node endpoint rather than the wallet endoint (since it’s a node method).
However, I have updated these calls to use the node
alias rather than self.nodes[0]
to be mode compact.
124@@ -125,7 +125,8 @@ def wallet_file(name):
125 self.start_node(0, ['-wallet=w4', '-wallet=w5'])
126 assert_equal(set(node.listwallets()), {"w4", "w5"})
127 w5 = wallet("w5")
128- w5.generate(1)
129+ self.nodes[0].generatetoaddress(nblocks=1, address=w5.getnewaddress())
130+ # w5.generate(1)
3288@@ -3289,6 +3289,12 @@ UniValue generate(const JSONRPCRequest& request)
3289 );
3290 }
3291
3292+ if (!IsDeprecatedRPCEnabled("generate")) {
3293+ throw JSONRPCError(RPC_METHOD_DEPRECATED, "The wallet generate rpc method is deprecated and will be fully removed in v0.19. "
generate is deprecated
could be interpreted as the node not being able to generate blocks at all.
In advance of deprecating the generate RPC method, make some small
changes to a small number of inidividual test cases:
- make memory checking less prescriptive in wallet_basic.py
- replace calls to generate with generatetoaddress in wallet_keypool.py
- replace calls to generate with generatetoaddress and fixup label
issues in wallet_labels.py
- replace calls to generate with generatetoaddress in wallet_multiwallet.py
Concept ACK
Can you replace the RPC example bitcoin-cli generatetoaddress 11 "myaddress"
with the more useful bitcoin-cli generatetoaddress 1 $(bitcoin-cli getnewaddress)
?
Can you replace the RPC example bitcoin-cli generatetoaddress 11 “myaddress” with the more useful bitcoin-cli generatetoaddress 1 $(bitcoin-cli getnewaddress)?
That example only works if bitcoind is compiled with a wallet and is running with a single wallet. I don’t think it makes sense to make the example so specific.
I also think this is fine. FWIW I would remove all examples.
Adds a generate() method to the TestNode class in the test framework.
This method intercepts calls to generate, imports a dewterministic
private key to the node and then calls generatetoaddress to generate the
block to that address.
Note that repeated calls to importprivkey for the same private keys are
no-ops, so it's fine to call the generate() method many times.
13- self.extra_args = [[], ["-deprecatedrpc=validateaddress"]]
14+ self.extra_args = [[], ["-deprecatedrpc=generate"]]
15+
16+ def skip_test_if_missing_module(self):
17+ # The generate RPC method requires the wallet to be compiled
18+ self.skip_if_no_wallet()
assert_raises_rpc_error
should be skipped. This way other tests in this file that are not wallet-specific would run when the wallet is not compiled.
skip_test_if_missing_module
for test suites that are not module-specific (e.g. wallet_.py or interface_zmq_.py suites).
I don’t think the whole test should be skipped if there is not wallet compiled in, but rather only the wallet-specific assert_raises_rpc_error should be skipped. This way other tests in this file that are not wallet-specific would run when the wallet is not compiled.
See earlier comment:
Yes. I did consider just silently skipping the individual test case, but I think “mark the whole test as skipped if part of it is skipped” makes most sense. The other option “mark the test as passed even if part of it is skipped” means that test cases can be silently skipped.
I’d prefer not to change this PR and invalidate ACKs, but if you feel strongly about this, I could add a wallet_deprecated.py
test.
I locally tested the changes. Everything works correctly.
Also note that popular tutorials (bitcoin.org and maybe others) start with this RPC as the first example. Giving an additional RPC help output which directly gives new users a copy-paste line might be useful.
bitcoin-cli generatetoaddress 1 $(bitcoin-cli getnewaddress)
.
Not a big deal because websites will update eventually. ACK c9f02955b2e9062808a9455c4ee7d52cf401eef5
@Sjors @sanket1729 I’ve added a hint to use getnewaddress
to the generatetoaddress
help text.
I didn’t include the bitcoin-cli generatetoaddress 1 $(bitcoin-cli getnewaddress)
text because that’s specific to posix shells.
is_compiled
helpers, since that seems the only use case of them.
…if you disagree with the concept of (silently) skipping subtests…
I can see the merit in both arguments, and don’t feel strongly one way or the other.
I’d prefer to not churn this PR any more, but as I said earlier, happy to change if you feel strongly.
jnewbery
meshcollider
sipa
gmaxwell
achow101
jimmysong
laanwj
promag
Sjors
MarcoFalke
sanket1729
DrahtBot
nopara73
Labels
Wallet
Milestone
0.18.0