aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Zumsande <mzumsande@gmail.com>2023-01-13 14:12:25 -0500
committerfanquake <fanquake@gmail.com>2023-01-19 15:13:39 +0000
commit412cd1a34e035c1a2f35f4b4ac14eb192835950c (patch)
treedff51790d822782ab00825f7370b9b2fa3c981e7
parentfd94befbc62e5f6b93f87979cc2011508378043d (diff)
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. Github-Pull: #26909 Rebased-From: 5eabb61b2386d00e93e6bbb2f493a56d1b326ad9
-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 0fa8f3c3da..0d68719478 100644
--- a/src/addrdb.cpp
+++ b/src/addrdb.cpp
@@ -33,10 +33,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 f91a979934..64137e1523 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -1171,8 +1171,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);