aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2012-07-07 22:57:42 +0200
committerPieter Wuille <pieter.wuille@gmail.com>2012-07-07 23:09:14 +0200
commit6ece1d747eed764f727ef60961ebdac66ab249c7 (patch)
tree4a673f1b81d5e98919fcb8069d3ab949d2d0d757
parentabbb9a829c6a381c7df1041ccfd2adebce86eafe (diff)
CHashWriter that does SHA256 in-place during serialization
-rw-r--r--src/util.h48
1 files changed, 42 insertions, 6 deletions
diff --git a/src/util.h b/src/util.h
index 7b2c678916..7fe204c0df 100644
--- a/src/util.h
+++ b/src/util.h
@@ -391,6 +391,46 @@ inline uint256 Hash(const T1 pbegin, const T1 pend)
return hash2;
}
+class CHashWriter
+{
+private:
+ SHA256_CTX ctx;
+
+public:
+ int nType;
+ int nVersion;
+
+ void Init() {
+ SHA256_Init(&ctx);
+ }
+
+ CHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) {
+ Init();
+ }
+
+ CHashWriter& write(const char *pch, size_t size) {
+ SHA256_Update(&ctx, pch, size);
+ return (*this);
+ }
+
+ // invalidates the object
+ uint256 GetHash() {
+ uint256 hash1;
+ SHA256_Final((unsigned char*)&hash1, &ctx);
+ uint256 hash2;
+ SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
+ return hash2;
+ }
+
+ template<typename T>
+ CHashWriter& operator<<(const T& obj) {
+ // Serialize to this stream
+ ::Serialize(*this, obj, nType, nVersion);
+ return (*this);
+ }
+};
+
+
template<typename T1, typename T2>
inline uint256 Hash(const T1 p1begin, const T1 p1end,
const T2 p2begin, const T2 p2end)
@@ -428,13 +468,9 @@ inline uint256 Hash(const T1 p1begin, const T1 p1end,
template<typename T>
uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
{
- // Most of the time is spent allocating and deallocating CDataStream's
- // buffer. If this ever needs to be optimized further, make a CStaticStream
- // class with its buffer on the stack.
- CDataStream ss(nType, nVersion);
- ss.reserve(10000);
+ CHashWriter ss(nType, nVersion);
ss << obj;
- return Hash(ss.begin(), ss.end());
+ return ss.GetHash();
}
inline uint160 Hash160(const std::vector<unsigned char>& vch)