Fix de-serialization bug where AddrMan is corrupted after exception

This commit is contained in:
EthanHeilman
2016-03-16 12:54:30 -04:00
committed by lateminer
parent 350a2d9b50
commit 51c23024eb
4 changed files with 151 additions and 1 deletions

View File

@@ -1946,8 +1946,13 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler)
int64_t nStart = GetTimeMillis();
{
CAddrDB adb;
if (!adb.Read(addrman))
if (adb.Read(addrman))
LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman.size(), GetTimeMillis() - nStart);
else {
addrman.Clear(); // Addrman can be in an inconsistent state after failure, reset it
LogPrintf("Invalid or missing peers.dat; recreating\n");
DumpAddresses();
}
}
//try to read stored banlist
@@ -2297,6 +2302,11 @@ bool CAddrDB::Read(CAddrMan& addr)
if (hashIn != hashTmp)
return error("%s: Checksum mismatch, data corrupted", __func__);
return Read(addr, ssPeers);
}
bool CAddrDB::Read(CAddrMan& addr, CDataStream& ssPeers)
{
unsigned char pchMsgTmp[4];
try {
// de-serialize file header (network specific magic number) and ..
@@ -2310,6 +2320,8 @@ bool CAddrDB::Read(CAddrMan& addr)
ssPeers >> addr;
}
catch (const std::exception& e) {
// de-serialization has failed, ensure addrman is left in a clean state
addr.Clear();
return error("%s: Deserialize or I/O error - %s", __func__, e.what());
}