diff --git a/src/claimtrie/forks.cpp b/src/claimtrie/forks.cpp index 82fc18c17..dea3e7909 100644 --- a/src/claimtrie/forks.cpp +++ b/src/claimtrie/forks.cpp @@ -236,10 +236,7 @@ uint256 ComputeMerkleRoot(std::vector hashes) if (hashes.size() & 1) hashes.push_back(hashes.back()); - for (std::size_t i = 0, j = 0; i < hashes.size(); i += 2) - hashes[j++] = Hash(hashes[i].begin(), hashes[i].end(), - hashes[i+1].begin(), hashes[i+1].end()); - + sha256n_way(hashes); hashes.resize(hashes.size() / 2); } return hashes.empty() ? uint256{} : hashes[0]; diff --git a/src/claimtrie/hashes.cpp b/src/claimtrie/hashes.cpp index e0a2f293f..3be8f9b58 100644 --- a/src/claimtrie/hashes.cpp +++ b/src/claimtrie/hashes.cpp @@ -11,3 +11,11 @@ uint256 CalcHash(SHA256_CTX* sha) SHA256_Final(result.begin(), sha); return result; } + +// universal N way hash function +std::function&)> sha256n_way = + [](std::vector& hashes) { + for (std::size_t i = 0, j = 0; i < hashes.size(); i += 2) + hashes[j++] = Hash(hashes[i].begin(), hashes[i].end(), + hashes[i+1].begin(), hashes[i+1].end()); + }; diff --git a/src/claimtrie/hashes.h b/src/claimtrie/hashes.h index 10709377d..9dadd5a73 100644 --- a/src/claimtrie/hashes.h +++ b/src/claimtrie/hashes.h @@ -4,6 +4,9 @@ #include +#include +#include + #include uint256 CalcHash(SHA256_CTX* sha); @@ -25,4 +28,6 @@ uint256 Hash(TIterator begin, TIterator end, Args... args) return CalcHash(&sha, begin, end, args...); } +extern std::function&)> sha256n_way; + #endif // CLAIMTRIE_HASHES_H diff --git a/src/init.cpp b/src/init.cpp index 42996a3a1..bb0fc9967 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -1534,6 +1535,13 @@ bool AppInitMain() assert(chainActive.Tip() != nullptr); } + // use faster N way hash function + // NOTE: it assumes memory is continuous + // that means uint256 itself should use std::array or raw pointer + sha256n_way = [](std::vector& hashes) { + SHA256D64(hashes[0].begin(), hashes[0].begin(), hashes.size() / 2); + }; + auto tip = chainActive.Tip(); if (tip && !CClaimTrieCache(pclaimTrie).validateDb(tip->nHeight, tip->hashClaimTrie)) { strLoadError = _("Error validating the claim trie from disk");