mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-05-03 18:29:21 +02:00
Merge bitcoin/bitcoin#22762: Raise InitError when peers.dat is invalid or corrupted
fa55c3dc1bRaise InitError when peers.dat is invalid or corrupted (MarcoFalke)fa4e2ccfd8Inline ReadPeerAddresses (MarcoFalke)fa5aeec80cMove LoadAddrman from init to addrdb (MarcoFalke) Pull request description: peers.dat is silently erased when it can not be parsed or when it appears corrupted. Fix that by notifying the user. This might help in the following examples: * The user provided the database, but picked the wrong one. * A future version of Bitcoin Core wrote the file and it can't be read. * The file was corrupted by a logic bug in Bitcoin Core. * The file was corrupted by a disk failure. ACKs for top commit: jonatack: Code review re-ACKfa55c3dc1bper `git range-diffeb1f570fa59c6d fa55c3` and verified the new tests fail on master, except "Check mocked addrman is valid", as expected prayank23: tACKfa55c3dc1bvasild: ACKfa55c3dc1bTree-SHA512: 78264a78ee570a3c3262cf9c8542b5ffaffa5f52da1eef66c8c381f346989272967cfe1769c573502d9d7d3f7ad68c3ac3b2ec734185d2e4e7595b7122b14196
This commit is contained in:
@@ -10,6 +10,7 @@ import struct
|
||||
from test_framework.messages import ser_uint256, hash256
|
||||
from test_framework.p2p import MAGIC_BYTES
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.test_node import ErrorMatch
|
||||
from test_framework.util import assert_equal
|
||||
|
||||
|
||||
@@ -43,6 +44,12 @@ class AddrmanTest(BitcoinTestFramework):
|
||||
|
||||
def run_test(self):
|
||||
peers_dat = os.path.join(self.nodes[0].datadir, self.chain, "peers.dat")
|
||||
init_error = lambda reason: (
|
||||
f"Error: Invalid or corrupt peers.dat \\({reason}\\). If you believe this "
|
||||
f"is a bug, please report it to {self.config['environment']['PACKAGE_BUGREPORT']}. "
|
||||
f'As a workaround, you can move the file \\("{peers_dat}"\\) out of the way \\(rename, '
|
||||
"move, or delete\\) to have a new one created on the next start."
|
||||
)
|
||||
|
||||
self.log.info("Check that mocked addrman is valid")
|
||||
self.stop_node(0)
|
||||
@@ -54,30 +61,29 @@ class AddrmanTest(BitcoinTestFramework):
|
||||
self.log.info("Check that addrman from future cannot be read")
|
||||
self.stop_node(0)
|
||||
write_addrman(peers_dat, lowest_compatible=111)
|
||||
with self.nodes[0].assert_debug_log([
|
||||
f'ERROR: DeserializeDB: Deserialize or I/O error - Unsupported format of addrman database: 1. It is compatible with formats >=111, but the maximum supported by this version of {self.config["environment"]["PACKAGE_NAME"]} is 3.',
|
||||
"Recreating peers.dat",
|
||||
]):
|
||||
self.start_node(0)
|
||||
assert_equal(self.nodes[0].getnodeaddresses(), [])
|
||||
self.nodes[0].assert_start_raises_init_error(
|
||||
expected_msg=init_error(
|
||||
"Unsupported format of addrman database: 1. It is compatible with "
|
||||
"formats >=111, but the maximum supported by this version of "
|
||||
f"{self.config['environment']['PACKAGE_NAME']} is 3.: (.+)"
|
||||
),
|
||||
match=ErrorMatch.FULL_REGEX,
|
||||
)
|
||||
|
||||
self.log.info("Check that corrupt addrman cannot be read")
|
||||
self.stop_node(0)
|
||||
with open(peers_dat, "wb") as f:
|
||||
f.write(serialize_addrman()[:-1])
|
||||
with self.nodes[0].assert_debug_log([
|
||||
"ERROR: DeserializeDB: Deserialize or I/O error - CAutoFile::read: end of file",
|
||||
"Recreating peers.dat",
|
||||
]):
|
||||
self.start_node(0)
|
||||
assert_equal(self.nodes[0].getnodeaddresses(), [])
|
||||
self.nodes[0].assert_start_raises_init_error(
|
||||
expected_msg=init_error("CAutoFile::read: end of file.*"),
|
||||
match=ErrorMatch.FULL_REGEX,
|
||||
)
|
||||
|
||||
self.log.info("Check that missing addrman is recreated")
|
||||
self.stop_node(0)
|
||||
os.remove(peers_dat)
|
||||
with self.nodes[0].assert_debug_log([
|
||||
f"Missing or invalid file {peers_dat}",
|
||||
"Recreating peers.dat",
|
||||
f'Creating peers.dat because the file was not found ("{peers_dat}")',
|
||||
]):
|
||||
self.start_node(0)
|
||||
assert_equal(self.nodes[0].getnodeaddresses(), [])
|
||||
|
||||
Reference in New Issue
Block a user