mirror of https://github.com/bitcoin/bitcoin
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
2.7 KiB
69 lines
2.7 KiB
#!/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)."""
|
|
|
|
from test_framework.test_framework import BitcoinTestFramework
|
|
from test_framework.test_node import (
|
|
ErrorMatch,
|
|
NULL_BLK_XOR_KEY,
|
|
)
|
|
from test_framework.util import (
|
|
assert_equal,
|
|
assert_greater_than,
|
|
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_vsize=20000)
|
|
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 = node.read_xor_key()
|
|
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")
|
|
node.blocks_key_path.unlink()
|
|
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)
|
|
self.log.info("Check that blocks XOR key is recreated")
|
|
assert_equal(node.read_xor_key(), NULL_BLK_XOR_KEY)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
BlocksXORTest(__file__).main()
|