0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-03-05 14:06:27 -05:00

addrdb: Only call Serialize() once

The previous logic would call it once for serializing into the filestream,
and then again for serializing into the hasher. If AddrMan was changed
in between these calls by another thread, the resulting peers.dat would
be corrupt with non-matching checksum and data.
Fix this by using HashedSourceWriter, which writes the data
to the underlying stream and keeps track of the hash in one go.
This commit is contained in:
Martin Zumsande 2023-01-13 14:12:25 -05:00
parent da6c7aeca3
commit 5eabb61b23
2 changed files with 4 additions and 6 deletions

View file

@ -34,10 +34,9 @@ bool SerializeDB(Stream& stream, const Data& data)
{
// Write and commit header, data
try {
CHashWriter hasher(stream.GetType(), stream.GetVersion());
stream << Params().MessageStart() << data;
hasher << Params().MessageStart() << data;
stream << hasher.GetHash();
HashedSourceWriter hashwriter{stream};
hashwriter << Params().MessageStart() << data;
stream << hashwriter.GetHash();
} catch (const std::exception& e) {
return error("%s: Serialize or I/O error - %s", __func__, e.what());
}

View file

@ -1178,8 +1178,7 @@ void AddrMan::Unserialize(Stream& s_)
}
// explicit instantiation
template void AddrMan::Serialize(CHashWriter& s) const;
template void AddrMan::Serialize(CAutoFile& s) const;
template void AddrMan::Serialize(HashedSourceWriter<CAutoFile>& s) const;
template void AddrMan::Serialize(CDataStream& s) const;
template void AddrMan::Unserialize(CAutoFile& s);
template void AddrMan::Unserialize(CHashVerifier<CAutoFile>& s);