CAddrDB::Read is used to manage the loading of AddrMan from peers.dat. As shown in the code below, when CAddrDB::Read catches an exception from the de-serialization code it returns addrman “as-is”, despite the fact that it failed to load correctly.
0 try {
1 // de-serialize file header (network specific magic number) and ..
2 ssPeers >> FLATDATA(pchMsgTmp);
3
4 // ... verify the network matches ours
5 if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
6 return error("%s: Invalid network magic number", __func__);
7
8 // de-serialize address data into one CAddrMan object
9 ssPeers >> addr;
10 }
11 catch (const std::exception& e) {
12 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
13 }
https://github.com/bitcoin/bitcoin/blob/master/src/net.cpp#L2330
This use of a corrupted addrman can cause a bitcoind client to get in a state such that when bitcoind starts it will not run correctly. Once bitcoind gets into such a state the only fix is for the user to manually delete the offending peers.dat file.
This pull request fixes this behavior so that an exception during the de-serialization process will leave addrman in a clean state. Unittests verify this new behavior.