-
Notifications
You must be signed in to change notification settings - Fork 37.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
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
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 <joao.paulo.barbosa@gmail.com> Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
25969f3
to
63493d7
Compare
Rebased to address silent conflicts. |
ACK 63493d7 |
Co-authored-by: Ryan Ofsky <ryan@ofsky.org> Co-authored-by: Andreas Kouloumos <kouloumosa@gmail.com>
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.
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 += 600
Also, 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 --nocleanup
will 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.