-
Notifications
You must be signed in to change notification settings - Fork 38.7k
rpc: Enable wallet import on pruned nodes and add test #24865
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rpc: Enable wallet import on pruned nodes and add test #24865
Conversation
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsNo conflicts as of last run. |
3543290 to
5dabfed
Compare
5dabfed to
f8aa5b0
Compare
bd36a43 to
46b7f73
Compare
murchandamus
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did a light code-review, concept ACK
2b36593 to
f76b309
Compare
926f40c to
b45e54b
Compare
kouloumos
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that wallet_pruning.py is not testing properly this added feature. This is due to the testing logic but mainly because of the default setup of the testing framework that is being used in this test.
This is possible because the dump format includes key timestamps.
The importwallet rpc calculates the min nTimeBegin timestamp for which findFirstBlockWithTimeAndHeight in the newly created function EnsureBlockDataFromTime will find the earliest block with timestamp equal or greater to.
As you can verify from the wallet_*.dat dumps of this test
# node1 wallet dump
...
cUxsWyKyZ9MAQTaAhUQWJmBbSvHMwSmuv59KgxQV7oZQU3PXN3KE 1970-01-01T00:00:01Z label=coinbase # addr=msX6jQXvxiNhx3Q62PKeLPrhrqZQdSimTg,2MtBq31Chq2pntJ81PQLR4q4sMEG7K46wsQ,bcrt1qsw5g6ehh439vurfyhdh93d66hw0kf9085wy7ma
...
the deterministic private keys that are imported to each test node as part of the testing framework setup
| n.importprivkey(privkey=n.get_deterministic_priv_key().key, label='coinbase', rescan=True) |
have a 1970-01-01T00:00:01Z timestamp which means that EnsureBlockDataFromTime will always check for the existence of all blocks between genesis and the current height.
Even if that was not the case, because the nodes' wallets are initialized before we start generating blocks, the timestamp in the wallet dump is still before the first created block thus EnsureBlockDataFromTime checks for the existence of all blocks between the first block and the current height.
This behaviour will always result to missing blocks as soon as we start pruning. The reason that the first part of the test (wallet_import_pruned_test) is not failing is because it never reaches the prune state (height < PruntAfterHeight).
I believe that you can better test for the new feature by overriding setup_nodes and initializing node1 wallet mid-test
a8d8f89 to
45435bc
Compare
|
Thank you for your thorough review @kouloumos ! |
ea532ba to
0aedf6f
Compare
|
It also runs as part of Win64 native [vs2022]. I can see that the extended tests run there and |
|
Ah thx. Maybe there should be a Also, I think this needs a rebase, see upcoming CI failure in https://cirrus-ci.com/task/6513158118965248 |
8e87433 to
25969f3
Compare
Co-authored-by: João Barbosa <[email protected]> Co-authored-by: Ryan Ofsky <[email protected]>
25969f3 to
63493d7
Compare
|
Rebased to address silent conflicts. |
|
ACK 63493d778f443554059d77bd8c9b1a926685a892 |
Co-authored-by: Ryan Ofsky <[email protected]> Co-authored-by: Andreas Kouloumos <[email protected]>
63493d7 to
564b580
Compare
|
Thanks @kouloumos I addressed your comments. |
|
ACK 564b580 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 564b580
left few non-blocking nits.
| } | ||
|
|
||
| int height{0}; | ||
| const bool found{chain.findFirstBlockWithTimeAndHeight(timestamp - TIMESTAMP_WINDOW, 0, FoundBlock().height(height))}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In e6906fc:
tiny nit:
(only if you have to re-touch)
| const bool found{chain.findFirstBlockWithTimeAndHeight(timestamp - TIMESTAMP_WINDOW, 0, FoundBlock().height(height))}; | |
| const bool found{chain.findFirstBlockWithTimeAndHeight(timestamp - TIMESTAMP_WINDOW, /*min_height=*/ 0, FoundBlock().height(height))}; |
| if pubkey is not None: | ||
| coinbaseoutput.scriptPubKey = key_to_p2pk_script(pubkey) | ||
| elif script_pubkey is not None: | ||
| coinbaseoutput.scriptPubKey = script_pubkey |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 71d9a7c:
atm is just a non-blocking nit:
it's weird to add this new ´script_pubkey´ arg that is only set if the ´pubkey´ arg is not provided. It is not stated anywhere.
Ideally, should unify both into a single arg. So there is no confusion over which of them take precedence over the other.
| # Important for matching a timestamp with a block +- some window | ||
| self.nTime += 600 | ||
| for n in self.nodes: | ||
| if n.running: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 71d9a7c:
why the node would not be running?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, in a previous version of the test it could crash without this check.
w0xlt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 564b580
|
reACK 564b580 |
| previousblockhash = int(best_block["hash"], 16) | ||
| big_script = CScript([OP_RETURN] + [OP_TRUE] * 950000) | ||
| for _ in range(n): | ||
| block = create_block(hashprev=previousblockhash, ntime=self.nTime, coinbase=create_coinbase(height, script_pubkey=big_script)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: It is possible to do this without blocktools. See
diff --git a/test/functional/wallet_pruning.py b/test/functional/wallet_pruning.py
index 6d8475ce8d..d768130776 100755
--- a/test/functional/wallet_pruning.py
+++ b/test/functional/wallet_pruning.py
@@ -40,20 +40,10 @@ class WalletPruningTest(BitcoinTestFramework):
def mine_large_blocks(self, node, n):
# Get the block parameters for the first block
best_block = node.getblock(node.getbestblockhash())
- height = int(best_block["height"]) + 1
self.nTime = max(self.nTime, int(best_block["time"])) + 1
- previousblockhash = int(best_block["hash"], 16)
- big_script = CScript([OP_RETURN] + [OP_TRUE] * 950000)
+ big_script = "raw({})".format(bytes([OP_RETURN] + [OP_TRUE] * 950000).hex())
for _ in range(n):
- block = create_block(hashprev=previousblockhash, ntime=self.nTime, coinbase=create_coinbase(height, script_pubkey=big_script))
- block.solve()
-
- # Submit to the node
- node.submitblock(block.serialize().hex())
-
- previousblockhash = block.sha256
- height += 1
-
+ self.generateblock(node, big_script, [])
# Simulate 10 minutes of work time per block
# Important for matching a timestamp with a block +- some window
self.nTime += 600Also, might be good to double check the runtime in light of 6c872d5
Reopens #16037
I have rebased the PR, addressed the comments of the original PR and added a functional test.
For reviewers:
python test/functional/wallet_pruning.py --nocleanupwill generate a large blockchain (~700MB) that can be used to manually test wallet imports on a pruned node. Node0 is not pruned, while node1 is.