aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Zumsande <mzumsande@gmail.com>2023-01-13 14:12:25 -0500
committerfanquake <fanquake@gmail.com>2023-02-20 17:15:37 +0000
commit07397cdedeffb4da0aedd454d4539d65a0204291 (patch)
treea1bf1b95dffc5fcf39c71f5b3c49e8d4f75deeef
parent91f83dbeb197fc0fff574d9e29b4560b1d236bec (diff)
downloadbitcoin-07397cdedeffb4da0aedd454d4539d65a0204291.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. 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 7106d819b0..554f20adc5 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 f16ff2230b..b281344b04 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);