aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Falbesoner <sebastian.falbesoner@gmail.com>2024-08-14 17:21:07 +0200
committerSebastian Falbesoner <sebastian.falbesoner@gmail.com>2024-08-14 17:38:28 +0200
commitfaa1b9b0e6de7d213699fbdbc2e25a2a81c35cdc (patch)
tree72c3bdcb4219b576aa3e86990df41efaf2a59ae5
parent6b3676be3e5b6e407876031791172f441b359295 (diff)
test: add functional test for XORed block/undo files (`-blocksxor`)
-rwxr-xr-xtest/functional/feature_blocksxor.py65
-rwxr-xr-xtest/functional/test_runner.py1
2 files changed, 66 insertions, 0 deletions
diff --git a/test/functional/feature_blocksxor.py b/test/functional/feature_blocksxor.py
new file mode 100755
index 0000000000..88e0244cd4
--- /dev/null
+++ b/test/functional/feature_blocksxor.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+# Copyright (c) 2024 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""Test support for XORed block data and undo files (`-blocksxor` option)."""
+import os
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.test_node import ErrorMatch
+from test_framework.util import (
+ assert_equal,
+ assert_greater_than,
+ read_xor_key,
+ util_xor,
+)
+from test_framework.wallet import MiniWallet
+
+
+class BlocksXORTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.num_nodes = 1
+ self.extra_args = [[
+ '-blocksxor=1',
+ '-fastprune=1', # use smaller block files
+ '-datacarriersize=100000', # needed to pad transaction with MiniWallet
+ ]]
+
+ def run_test(self):
+ self.log.info("Mine some blocks, to create multiple blk*.dat/rev*.dat files")
+ node = self.nodes[0]
+ wallet = MiniWallet(node)
+ for _ in range(5):
+ wallet.send_self_transfer(from_node=node, target_weight=80000)
+ self.generate(wallet, 1)
+
+ block_files = list(node.blocks_path.glob('blk[0-9][0-9][0-9][0-9][0-9].dat'))
+ undo_files = list(node.blocks_path.glob('rev[0-9][0-9][0-9][0-9][0-9].dat'))
+ assert_equal(len(block_files), len(undo_files))
+ assert_greater_than(len(block_files), 1) # we want at least one full block file
+
+ self.log.info("Shut down node and un-XOR block/undo files manually")
+ self.stop_node(0)
+ xor_key = read_xor_key(node=node)
+ for data_file in sorted(block_files + undo_files):
+ self.log.debug(f"Rewriting file {data_file}...")
+ with open(data_file, 'rb+') as f:
+ xored_data = f.read()
+ f.seek(0)
+ f.write(util_xor(xored_data, xor_key, offset=0))
+
+ self.log.info("Check that restarting with 'blocksxor=0' fails if XOR key is present")
+ node.assert_start_raises_init_error(['-blocksxor=0'],
+ 'The blocksdir XOR-key can not be disabled when a random key was already stored!',
+ match=ErrorMatch.PARTIAL_REGEX)
+
+ self.log.info("Delete XOR key, restart node with '-blocksxor=0', check blk*.dat/rev*.dat file integrity")
+ os.remove(node.blocks_path / 'xor.dat')
+ self.start_node(0, extra_args=['-blocksxor=0'])
+ # checklevel=2 -> verify block validity + undo data
+ # nblocks=0 -> verify all blocks
+ node.verifychain(checklevel=2, nblocks=0)
+
+
+if __name__ == '__main__':
+ BlocksXORTest(__file__).main()
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 67693259d3..b85bf1c668 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -284,6 +284,7 @@ BASE_SCRIPTS = [
'mempool_package_limits.py',
'mempool_package_rbf.py',
'feature_versionbits_warning.py',
+ 'feature_blocksxor.py',
'rpc_preciousblock.py',
'wallet_importprunedfunds.py --legacy-wallet',
'wallet_importprunedfunds.py --descriptors',