@ -5,6 +5,7 @@
""" Stress tests related to node initialization. """
""" Stress tests related to node initialization. """
import os
import os
from pathlib import Path
from pathlib import Path
import shutil
from test_framework . test_framework import BitcoinTestFramework , SkipTest
from test_framework . test_framework import BitcoinTestFramework , SkipTest
from test_framework . test_node import ErrorMatch
from test_framework . test_node import ErrorMatch
@ -47,7 +48,7 @@ class InitStressTest(BitcoinTestFramework):
def start_expecting_error ( err_fragment ) :
def start_expecting_error ( err_fragment ) :
node . assert_start_raises_init_error (
node . assert_start_raises_init_error (
extra_args = [ ' -txindex=1 ' , ' -blockfilterindex=1 ' , ' -coinstatsindex=1 ' ],
extra_args = [ ' -txindex=1 ' , ' -blockfilterindex=1 ' , ' -coinstatsindex=1 ' , ' -checkblocks=200 ' , ' -checklevel=4 ' ],
expected_msg = err_fragment ,
expected_msg = err_fragment ,
match = ErrorMatch . PARTIAL_REGEX ,
match = ErrorMatch . PARTIAL_REGEX ,
)
)
@ -101,9 +102,9 @@ class InitStressTest(BitcoinTestFramework):
}
}
files_to_perturb = {
files_to_perturb = {
' blocks/index/*.ldb ' : ' Error open ing block database.' ,
' blocks/index/*.ldb ' : ' Error load ing block database.' ,
' chainstate/*.ldb ' : ' Error opening block database. ' ,
' chainstate/*.ldb ' : ' Error opening block database. ' ,
' blocks/blk*.dat ' : ' Error opening block database .' ,
' blocks/blk*.dat ' : ' Corrupted block database detected .' ,
}
}
for file_patt , err_fragment in files_to_delete . items ( ) :
for file_patt , err_fragment in files_to_delete . items ( ) :
@ -124,18 +125,31 @@ class InitStressTest(BitcoinTestFramework):
check_clean_start ( )
check_clean_start ( )
self . stop_node ( 0 )
self . stop_node ( 0 )
self . log . info ( " Test startup errors after perturbing certain essential files " )
for file_patt , err_fragment in files_to_perturb . items ( ) :
for file_patt , err_fragment in files_to_perturb . items ( ) :
shutil . copytree ( node . chain_path / " blocks " , node . chain_path / " blocks_bak " )
shutil . copytree ( node . chain_path / " chainstate " , node . chain_path / " chainstate_bak " )
target_files = list ( node . chain_path . glob ( file_patt ) )
target_files = list ( node . chain_path . glob ( file_patt ) )
for target_file in target_files :
for target_file in target_files :
self . log . info ( f " Perturbing file to ensure failure { target_file } " )
self . log . info ( f " Perturbing file to ensure failure { target_file } " )
with open ( target_file , " rb " ) as tf_read , open ( target_file , " wb " ) as tf_write :
with open ( target_file , " rb " ) as tf_read :
contents = tf_read . read ( )
contents = tf_read . read ( )
tweaked_contents = bytearray ( contents )
tweaked_contents = bytearray ( contents )
tweaked_contents [ 50 : 250 ] = b ' 1 ' * 200
# Since the genesis block is not checked by -checkblocks, the
# perturbation window must be chosen such that a higher block
# in blk*.dat is affected.
tweaked_contents [ 150 : 350 ] = b ' 1 ' * 200
with open ( target_file , " wb " ) as tf_write :
tf_write . write ( bytes ( tweaked_contents ) )
tf_write . write ( bytes ( tweaked_contents ) )
start_expecting_error ( err_fragment )
start_expecting_error ( err_fragment )
shutil . rmtree ( node . chain_path / " blocks " )
shutil . rmtree ( node . chain_path / " chainstate " )
shutil . move ( node . chain_path / " blocks_bak " , node . chain_path / " blocks " )
shutil . move ( node . chain_path / " chainstate_bak " , node . chain_path / " chainstate " )
if __name__ == ' __main__ ' :
if __name__ == ' __main__ ' :
InitStressTest ( ) . main ( )
InitStressTest ( ) . main ( )