From 91f83dbeb197fc0fff574d9e29b4560b1d236bec Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Sun, 15 Jan 2023 20:18:11 -0500 Subject: 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 --- src/hash.h | 25 +++++++++++++++++++++++++ src/test/streams_tests.cpp | 14 ++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/hash.h b/src/hash.h index b1ff3acc7d..50255705e4 100644 --- a/src/hash.h +++ b/src/hash.h @@ -6,6 +6,7 @@ #ifndef BITCOIN_HASH_H #define BITCOIN_HASH_H +#include #include #include #include @@ -199,6 +200,30 @@ public: } }; +/** Writes data to an underlying source stream, while hashing the written data. */ +template +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 src) + { + m_source.write(src); + CHashWriter::write(src); + } + + template + HashedSourceWriter& operator<<(const T& obj) + { + ::Serialize(*this, obj); + return *this; + } +}; + /** Compute the 256-bit hash of an object's serialization. */ template 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() -- cgit v1.2.3