mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-12-08 03:33:32 +01:00
Merge bitcoin/bitcoin#29553: assumeutxo: Add dumptxoutset height param, remove shell scripts
94b0adcc37rpc, refactor: Prevent potential race conditions in dumptxoutset (Fabian Jahr)e868a6e070doc: Improve assumeutxo guide and add more docs/comments (Fabian Jahr)b29c21fc92assumeutxo: Remove devtools/utxo_snapshot.sh (Fabian Jahr)20a1c77aa7contrib: Remove test_utxo_snapshots.sh (Fabian Jahr)8426850352test: Test for dumptxoutset at specific height (Fabian Jahr)993cafe7e4RPC: Add type parameter to dumptxoutset (Fabian Jahr)fccf4f91d2RPC: Extract ReconsiderBlock helper (Fabian Jahr)446ce51c21RPC: Extract InvalidateBlock helper (Fabian Jahr) Pull request description: This adds a height parameter to the `dumptxoutset` RPC. This internalizes the workflow that was previously done by scripts: roll back the chain to the height we actually want the snapshot from, create the snapshot, roll forward to the real tip again. The nice thing about internalizing this functionality is that we can write tests for the code and it gives us more options to make the functionality robust. The shell scripts we have so far will be more cumbersome to maintain in the long run, especially since we will only notice later when we have broken them. I think it's safe to remove these `test_utxo_snapshots.sh` as well when we have this option in `dumptxoutset` because we have also added some good additional functional test coverage for this functionality. ACKs for top commit: Sjors: re-utACK94b0adcc37achow101: ACK94b0adcc37mzumsande: ACK94b0adcc37pablomartin4btc: re-ACK94b0adcc37Tree-SHA512: a4c9af5f687d1ca7bfb579a36f363882823386b5fa80c05de531b05a2782b5da6ff5baf3ada4bca8f32f63975d86f1948175abed9affe51fc958472b5f838dab
This commit is contained in:
@@ -22,6 +22,7 @@ from test_framework.util import (
|
||||
assert_approx,
|
||||
assert_equal,
|
||||
assert_raises_rpc_error,
|
||||
sha256sum_file,
|
||||
)
|
||||
from test_framework.wallet import (
|
||||
getnewdestination,
|
||||
@@ -295,7 +296,7 @@ class AssumeutxoTest(BitcoinTestFramework):
|
||||
assert_equal(n1.getblockcount(), START_HEIGHT)
|
||||
|
||||
self.log.info(f"Creating a UTXO snapshot at height {SNAPSHOT_BASE_HEIGHT}")
|
||||
dump_output = n0.dumptxoutset('utxos.dat')
|
||||
dump_output = n0.dumptxoutset('utxos.dat', "latest")
|
||||
|
||||
self.log.info("Test loading snapshot when the node tip is on the same block as the snapshot")
|
||||
assert_equal(n0.getblockcount(), SNAPSHOT_BASE_HEIGHT)
|
||||
@@ -320,12 +321,16 @@ class AssumeutxoTest(BitcoinTestFramework):
|
||||
for n in self.nodes:
|
||||
assert_equal(n.getblockchaininfo()["headers"], SNAPSHOT_BASE_HEIGHT)
|
||||
|
||||
assert_equal(
|
||||
dump_output['txoutset_hash'],
|
||||
"a4bf3407ccb2cc0145c49ebba8fa91199f8a3903daf0883875941497d2493c27")
|
||||
assert_equal(dump_output["nchaintx"], blocks[SNAPSHOT_BASE_HEIGHT].chain_tx)
|
||||
assert_equal(n0.getblockchaininfo()["blocks"], SNAPSHOT_BASE_HEIGHT)
|
||||
|
||||
def check_dump_output(output):
|
||||
assert_equal(
|
||||
output['txoutset_hash'],
|
||||
"a4bf3407ccb2cc0145c49ebba8fa91199f8a3903daf0883875941497d2493c27")
|
||||
assert_equal(output["nchaintx"], blocks[SNAPSHOT_BASE_HEIGHT].chain_tx)
|
||||
|
||||
check_dump_output(dump_output)
|
||||
|
||||
# Mine more blocks on top of the snapshot that n1 hasn't yet seen. This
|
||||
# will allow us to test n1's sync-to-tip on top of a snapshot.
|
||||
self.generate(n0, nblocks=100, sync_fun=self.no_op)
|
||||
@@ -335,6 +340,39 @@ class AssumeutxoTest(BitcoinTestFramework):
|
||||
|
||||
assert_equal(n0.getblockchaininfo()["blocks"], FINAL_HEIGHT)
|
||||
|
||||
self.log.info(f"Check that dumptxoutset works for past block heights")
|
||||
# rollback defaults to the snapshot base height
|
||||
dump_output2 = n0.dumptxoutset('utxos2.dat', "rollback")
|
||||
check_dump_output(dump_output2)
|
||||
assert_equal(sha256sum_file(dump_output['path']), sha256sum_file(dump_output2['path']))
|
||||
|
||||
# Rollback with specific height
|
||||
dump_output3 = n0.dumptxoutset('utxos3.dat', rollback=SNAPSHOT_BASE_HEIGHT)
|
||||
check_dump_output(dump_output3)
|
||||
assert_equal(sha256sum_file(dump_output['path']), sha256sum_file(dump_output3['path']))
|
||||
|
||||
# Specified height that is not a snapshot height
|
||||
prev_snap_height = SNAPSHOT_BASE_HEIGHT - 1
|
||||
dump_output4 = n0.dumptxoutset(path='utxos4.dat', rollback=prev_snap_height)
|
||||
assert_equal(
|
||||
dump_output4['txoutset_hash'],
|
||||
"8a1db0d6e958ce0d7c963bc6fc91ead596c027129bacec68acc40351037b09d7")
|
||||
assert sha256sum_file(dump_output['path']) != sha256sum_file(dump_output4['path'])
|
||||
|
||||
# Use a hash instead of a height
|
||||
prev_snap_hash = n0.getblockhash(prev_snap_height)
|
||||
dump_output5 = n0.dumptxoutset('utxos5.dat', rollback=prev_snap_hash)
|
||||
assert_equal(sha256sum_file(dump_output4['path']), sha256sum_file(dump_output5['path']))
|
||||
|
||||
# TODO: This is a hack to set m_best_header to the correct value after
|
||||
# dumptxoutset/reconsiderblock. Otherwise the wrong error messages are
|
||||
# returned in following tests. It can be removed once this bug is
|
||||
# fixed. See also https://github.com/bitcoin/bitcoin/issues/26245
|
||||
self.restart_node(0, ["-reindex"])
|
||||
|
||||
# Ensure n0 is back at the tip
|
||||
assert_equal(n0.getblockchaininfo()["blocks"], FINAL_HEIGHT)
|
||||
|
||||
self.test_snapshot_with_less_work(dump_output['path'])
|
||||
self.test_invalid_mempool_state(dump_output['path'])
|
||||
self.test_invalid_snapshot_scenarios(dump_output['path'])
|
||||
|
||||
@@ -27,7 +27,7 @@ class DumptxoutsetTest(BitcoinTestFramework):
|
||||
self.generate(node, COINBASE_MATURITY)
|
||||
|
||||
FILENAME = 'txoutset.dat'
|
||||
out = node.dumptxoutset(FILENAME)
|
||||
out = node.dumptxoutset(FILENAME, "latest")
|
||||
expected_path = node.datadir_path / self.chain / FILENAME
|
||||
|
||||
assert expected_path.is_file()
|
||||
@@ -51,10 +51,14 @@ class DumptxoutsetTest(BitcoinTestFramework):
|
||||
|
||||
# Specifying a path to an existing or invalid file will fail.
|
||||
assert_raises_rpc_error(
|
||||
-8, '{} already exists'.format(FILENAME), node.dumptxoutset, FILENAME)
|
||||
-8, '{} already exists'.format(FILENAME), node.dumptxoutset, FILENAME, "latest")
|
||||
invalid_path = node.datadir_path / "invalid" / "path"
|
||||
assert_raises_rpc_error(
|
||||
-8, "Couldn't open file {}.incomplete for writing".format(invalid_path), node.dumptxoutset, invalid_path)
|
||||
-8, "Couldn't open file {}.incomplete for writing".format(invalid_path), node.dumptxoutset, invalid_path, "latest")
|
||||
|
||||
self.log.info(f"Test that dumptxoutset with unknown dump type fails")
|
||||
assert_raises_rpc_error(
|
||||
-8, 'Invalid snapshot type "bogus" specified. Please specify "rollback" or "latest"', node.dumptxoutset, 'utxos.dat', "bogus")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -93,7 +93,7 @@ class AssumeutxoTest(BitcoinTestFramework):
|
||||
|
||||
self.log.info(
|
||||
f"Creating a UTXO snapshot at height {SNAPSHOT_BASE_HEIGHT}")
|
||||
dump_output = n0.dumptxoutset('utxos.dat')
|
||||
dump_output = n0.dumptxoutset('utxos.dat', "latest")
|
||||
|
||||
assert_equal(
|
||||
dump_output['txoutset_hash'],
|
||||
|
||||
Reference in New Issue
Block a user