aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Zumsande <mzumsande@gmail.com>2023-01-15 20:18:11 -0500
committerfanquake <fanquake@gmail.com>2023-01-19 15:13:21 +0000
commitfd94befbc62e5f6b93f87979cc2011508378043d (patch)
tree03dbe512a837750217d218e9b3a0c02f02c8f682
parentdd04f2dda5fa9bd60a665ec11761669ca78421e8 (diff)
hash: add HashedSourceWriter
This class is the counterpart to CHashVerifier, in that it writes data to an underlying source stream, while keeping a hash of the written data. Github-Pull: #26909 Rebased-From: da6c7aeca38e1d0ab5839a374c26af0504d603fc
-rw-r--r--src/hash.h24
-rw-r--r--src/test/streams_tests.cpp14
2 files changed, 38 insertions, 0 deletions
diff --git a/src/hash.h b/src/hash.h
index 9f582842c1..7515fc45a6 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -188,6 +188,30 @@ public:
}
};
+/** Writes data to an underlying source stream, while hashing the written data. */
+template <typename Source>
+class HashedSourceWriter : public CHashWriter
+{
+private:
+ Source& m_source;
+
+public:
+ explicit HashedSourceWriter(Source& source LIFETIMEBOUND) : CHashWriter{source.GetType(), source.GetVersion()}, m_source{source} {}
+
+ void write(Span<const std::byte> src)
+ {
+ m_source.write(src);
+ CHashWriter::write(src);
+ }
+
+ template <typename T>
+ HashedSourceWriter& operator<<(const T& obj)
+ {
+ ::Serialize(*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/test/streams_tests.cpp b/src/test/streams_tests.cpp
index 0925e2e9ee..e30ae845ef 100644
--- a/src/test/streams_tests.cpp
+++ b/src/test/streams_tests.cpp
@@ -441,4 +441,18 @@ BOOST_AUTO_TEST_CASE(streams_buffered_file_rand)
fs::remove(streams_test_filename);
}
+BOOST_AUTO_TEST_CASE(streams_hashed)
+{
+ CDataStream stream(SER_NETWORK, INIT_PROTO_VERSION);
+ HashedSourceWriter hash_writer{stream};
+ const std::string data{"bitcoin"};
+ hash_writer << data;
+
+ CHashVerifier hash_verifier{&stream};
+ std::string result;
+ hash_verifier >> result;
+ BOOST_CHECK_EQUAL(data, result);
+ BOOST_CHECK_EQUAL(hash_writer.GetHash(), hash_verifier.GetHash());
+}
+
BOOST_AUTO_TEST_SUITE_END()