aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hash.h35
-rw-r--r--src/validation.cpp9
2 files changed, 39 insertions, 5 deletions
diff --git a/src/hash.h b/src/hash.h
index eacb8f04fe..b8de19c0fd 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -160,6 +160,41 @@ public:
}
};
+/** Reads data from an underlying stream, while hashing the read data. */
+template<typename Source>
+class CHashVerifier : public CHashWriter
+{
+private:
+ Source* source;
+
+public:
+ CHashVerifier(Source* source_) : CHashWriter(source_->GetType(), source_->GetVersion()), source(source_) {}
+
+ void read(char* pch, size_t nSize)
+ {
+ source->read(pch, nSize);
+ this->write(pch, nSize);
+ }
+
+ void ignore(size_t nSize)
+ {
+ char data[1024];
+ while (nSize > 0) {
+ size_t now = std::min<size_t>(nSize, 1024);
+ read(data, now);
+ nSize -= now;
+ }
+ }
+
+ template<typename T>
+ CHashVerifier<Source>& operator>>(T& obj)
+ {
+ // Unserialize from this stream
+ ::Unserialize(*this, obj);
+ return (*this);
+ }
+};
+
/** Compute the 256-bit hash of an object's serialization. */
template<typename T>
uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
diff --git a/src/validation.cpp b/src/validation.cpp
index ed94be5c26..fc7e129c05 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -1210,8 +1210,10 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin
// Read block
uint256 hashChecksum;
+ CHashVerifier<CAutoFile> verifier(&filein); // We need a CHashVerifier as reserializing may lose data
try {
- filein >> blockundo;
+ verifier << hashBlock;
+ verifier >> blockundo;
filein >> hashChecksum;
}
catch (const std::exception& e) {
@@ -1219,10 +1221,7 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin
}
// Verify checksum
- CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
- hasher << hashBlock;
- hasher << blockundo;
- if (hashChecksum != hasher.GetHash())
+ if (hashChecksum != verifier.GetHash())
return error("%s: Checksum mismatch", __func__);
return true;