From 0e0fb4a0568530a4de6c8de38bc9fcd87cbc63a9 Mon Sep 17 00:00:00 2001 From: Jimmy Kiselak Date: Wed, 25 Mar 2015 22:10:05 -0400 Subject: [PATCH] hash txid and nOut in CNodeValue hash to make spoofing the value more difficult --- src/ncctrie.cpp | 72 ++++++++++++++++++++++---------------- src/ncctrie.h | 3 +- src/test/ncctrie_tests.cpp | 8 ++--- 3 files changed, 46 insertions(+), 37 deletions(-) diff --git a/src/ncctrie.cpp b/src/ncctrie.cpp index 91005ecd5..d407522db 100644 --- a/src/ncctrie.cpp +++ b/src/ncctrie.cpp @@ -3,11 +3,29 @@ #include -std::string CNodeValue::ToString() +uint256 CNodeValue::GetHash() const { + CHash256 valTxHasher; + valTxHasher.Write(txhash.begin(), txhash.size()); + std::vector vchValTxHash(valTxHasher.OUTPUT_SIZE); + valTxHasher.Finalize(&(vchValTxHash[0])); + + CHash256 valnOutHasher; std::stringstream ss; ss << nOut; - return txhash.ToString() + ss.str(); + std::string snOut = ss.str(); + valnOutHasher.Write((unsigned char*) snOut.data(), snOut.size()); + std::vector vchValnOutHash(valnOutHasher.OUTPUT_SIZE); + valnOutHasher.Finalize(&(vchValnOutHash[0])); + + CHash256 valHasher; + valHasher.Write(vchValTxHash.data(), vchValTxHash.size()); + valHasher.Write(vchValnOutHash.data(), vchValnOutHash.size()); + std::vector vchValHash(valHasher.OUTPUT_SIZE); + valHasher.Finalize(&(vchValHash[0])); + + uint256 valHash(vchValHash); + return valHash; } bool CNCCTrieNode::insertValue(CNodeValue val, bool * pfChanged) @@ -35,7 +53,7 @@ bool CNCCTrieNode::insertValue(CNodeValue val, bool * pfChanged) bool CNCCTrieNode::removeValue(uint256& txhash, uint32_t nOut, CNodeValue& val, bool * pfChanged) { - LogPrintf("%s: Removing %s from the ncc trie\n", __func__, val.ToString()); + LogPrintf("%s: Removing txid: %s, nOut: %d from the ncc trie\n", __func__, txhash.ToString(), nOut); bool fChanged = false; CNodeValue currentTop = values.front(); @@ -53,12 +71,11 @@ bool CNCCTrieNode::removeValue(uint256& txhash, uint32_t nOut, CNodeValue& val, values.erase(position); else { - LogPrintf("CNCCTrieNode::removeValue() : asked to remove a value that doesn't exist\n"); - LogPrintf("CNCCTrieNode::removeValue() : value that doesn't exist: %s.\n", val.ToString()); - LogPrintf("CNCCTrieNode::removeValue() : values that do exist:\n"); + LogPrintf("CNCCTrieNode::%s() : asked to remove a value that doesn't exist\n", __func__); + LogPrintf("CNCCTrieNode::%s() : values that do exist:\n", __func__); for (unsigned int i = 0; i < values.size(); i++) { - LogPrintf("%s\n", values[i].ToString()); + LogPrintf("\ttxid: %s, nOut: %d\n", values[i].txhash.ToString(), values[i].nOut); } return false; } @@ -191,16 +208,14 @@ bool CNCCTrie::checkConsistency() bool CNCCTrie::recursiveCheckConsistency(CNCCTrieNode* node) { - std::string stringToHash; + std::vector vchToHash; for (nodeMapType::iterator it = node->children.begin(); it != node->children.end(); ++it) { - std::stringstream ss; - ss << it->first; if (recursiveCheckConsistency(it->second)) { - stringToHash += ss.str(); - stringToHash += it->second->hash.ToString(); + vchToHash.push_back(it->first); + vchToHash.insert(vchToHash.end(), it->second->hash.begin(), it->second->hash.end()); } else return false; @@ -211,17 +226,13 @@ bool CNCCTrie::recursiveCheckConsistency(CNCCTrieNode* node) if (hasValue) { - CHash256 valHasher; - std::vector vchValHash(valHasher.OUTPUT_SIZE); - valHasher.Write((const unsigned char*) val.ToString().data(), val.ToString().size()); - valHasher.Finalize(&(vchValHash[0])); - uint256 valHash(vchValHash); - stringToHash += valHash.ToString(); + uint256 valHash = val.GetHash(); + vchToHash.insert(vchToHash.end(), valHash.begin(), valHash.end()); } CHash256 hasher; std::vector vchHash(hasher.OUTPUT_SIZE); - hasher.Write((const unsigned char*) stringToHash.data(), stringToHash.size()); + hasher.Write(vchToHash.data(), vchToHash.size()); hasher.Finalize(&(vchHash[0])); uint256 calculatedHash(vchHash); return calculatedHash == node->hash; @@ -507,8 +518,7 @@ bool CNCCTrieCache::recursiveComputeMerkleHash(CNCCTrieNode* tnCurrent, std::str cacheHashes[""] = uint256S("0000000000000000000000000000000000000000000000000000000000000001"); return true; } - std::string stringToHash; - + std::vector vchToHash; nodeCacheType::iterator cachedNode; @@ -526,12 +536,16 @@ bool CNCCTrieCache::recursiveComputeMerkleHash(CNCCTrieNode* tnCurrent, std::str else recursiveComputeMerkleHash(it->second, sNextPos); } - stringToHash += ss.str(); + vchToHash.push_back(it->first); hashMapType::iterator ithash = cacheHashes.find(sNextPos); if (ithash != cacheHashes.end()) - stringToHash += ithash->second.ToString(); + { + vchToHash.insert(vchToHash.end(), ithash->second.begin(), ithash->second.end()); + } else - stringToHash += it->second->hash.ToString(); + { + vchToHash.insert(vchToHash.end(), it->second->hash.begin(), it->second->hash.end()); + } } CNodeValue val; @@ -539,17 +553,13 @@ bool CNCCTrieCache::recursiveComputeMerkleHash(CNCCTrieNode* tnCurrent, std::str if (hasValue) { - CHash256 valHasher; - std::vector vchValHash(valHasher.OUTPUT_SIZE); - valHasher.Write((const unsigned char*) val.ToString().data(), val.ToString().size()); - valHasher.Finalize(&(vchValHash[0])); - uint256 valHash(vchValHash); - stringToHash += valHash.ToString(); + uint256 valHash = val.GetHash(); + vchToHash.insert(vchToHash.end(), valHash.begin(), valHash.end()); } CHash256 hasher; std::vector vchHash(hasher.OUTPUT_SIZE); - hasher.Write((const unsigned char*) stringToHash.data(), stringToHash.size()); + hasher.Write(vchToHash.data(), vchToHash.size()); hasher.Finalize(&(vchHash[0])); cacheHashes[sPos] = uint256(vchHash); std::set::iterator itDirty = dirtyHashes.find(sPos); diff --git a/src/ncctrie.h b/src/ncctrie.h index 179bfdb0c..80d84cbd8 100644 --- a/src/ncctrie.h +++ b/src/ncctrie.h @@ -27,8 +27,7 @@ public: int nValidAtHeight; CNodeValue() {}; CNodeValue(uint256 txhash, uint32_t nOut, CAmount nAmount, int nHeight, int nValidAtHeight) : txhash(txhash), nOut(nOut), nAmount(nAmount), nHeight(nHeight), nValidAtHeight(nValidAtHeight) {} - std::string ToString(); - + uint256 GetHash() const; ADD_SERIALIZE_METHODS; template diff --git a/src/test/ncctrie_tests.cpp b/src/test/ncctrie_tests.cpp index b818961d2..f3058c4d5 100644 --- a/src/test/ncctrie_tests.cpp +++ b/src/test/ncctrie_tests.cpp @@ -110,16 +110,16 @@ BOOST_AUTO_TEST_CASE(ncctrie_merkle_hash) CMutableTransaction tx6 = BuildTransaction(tx5.GetHash()); uint256 hash1; - hash1.SetHex("2f3ae25e923dfa6fc24f0ff5d4367239425effaf47b703857436947a2dbfdda1"); + hash1.SetHex("09732c6efebb4065a27f184285a6b66280a978cf972b1f41a563f0d3644f3e5c"); uint256 hash2; - hash2.SetHex("833c0a897d1e32b16a7988c574dbcd750ed6695b947dea7b16e7782eac070a5d"); + hash2.SetHex("8db92b76b6b0416d7abda4fd7404ba69e340853dfe9ffc04843c50142b857471"); uint256 hash3; - hash3.SetHex("5ea4c62fb56bbca0cdf6fe4b2668c737641b4f48af8ef5041faa42df12aa3078"); + hash3.SetHex("2e38561067f3e83d6ca0b627861689de72bba77cb5aca69d13b3685b5229525b"); uint256 hash4; - hash4.SetHex("47ae7f3ab9c0e9b13d08d5535a76fd36cecad0529baca390cea77b5bd3d99290"); + hash4.SetHex("6ec84089eb4ca1aeead6cf3538d4def78baebb44715c31be8790e627e0dcbc28"); BOOST_CHECK(pnccTrie->empty());