aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Zumsande <mzumsande@gmail.com>2023-01-13 14:12:25 -0500
committerMartin Zumsande <mzumsande@gmail.com>2023-01-17 17:20:03 -0500
commit5eabb61b2386d00e93e6bbb2f493a56d1b326ad9 (patch)
treedd8c800ecab40f2744697df5bbc42f463b4da814 /src
parentda6c7aeca38e1d0ab5839a374c26af0504d603fc (diff)
downloadbitcoin-5eabb61b2386d00e93e6bbb2f493a56d1b326ad9.tar.xz
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.
Diffstat (limited to 'src')
-rw-r--r--src/addrdb.cpp7
-rw-r--r--src/addrman.cpp3
2 files changed, 4 insertions, 6 deletions
diff --git a/src/addrdb.cpp b/src/addrdb.cpp
index d95c07d6a8..7c954dbf3a 100644
--- a/src/addrdb.cpp
+++ b/src/addrdb.cpp
@@ -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());
}
diff --git a/src/addrman.cpp b/src/addrman.cpp
index 91eedeebe1..f86bdfa3df 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -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);