New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Do not store Merkle branches in the wallet. #6550
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,7 @@ uint256 CBlockHeader::GetHash() const | |
return SerializeHash(*this); | ||
} | ||
|
||
uint256 CBlock::BuildMerkleTree(bool* fMutated) const | ||
uint256 CBlock::ComputeMerkleRoot(bool* fMutated) const | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unrelated to this PR, but is there any reason we prefer the optional arguments compared to a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure this is so much "preferred", it's how it happens to be written between two more-or-less equivalent ways to formulate it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're relying on an optional optimization allowed by the C++ standard (copy elision) to avoid constructing a tuple as a temporary and copying it to the return location. In C++11 it's better because you can explicitly indicate move semantics. |
||
{ | ||
/* WARNING! If you're reading this because you're learning about crypto | ||
and/or designing a new system that will use merkle trees, keep in mind | ||
|
@@ -52,7 +52,7 @@ uint256 CBlock::BuildMerkleTree(bool* fMutated) const | |
known ways of changing the transactions without affecting the merkle | ||
root. | ||
*/ | ||
vMerkleTree.clear(); | ||
std::vector<uint256> vMerkleTree; | ||
vMerkleTree.reserve(vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes. | ||
for (std::vector<CTransaction>::const_iterator it(vtx.begin()); it != vtx.end(); ++it) | ||
vMerkleTree.push_back(it->GetHash()); | ||
|
@@ -78,37 +78,6 @@ uint256 CBlock::BuildMerkleTree(bool* fMutated) const | |
return (vMerkleTree.empty() ? uint256() : vMerkleTree.back()); | ||
} | ||
|
||
std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const | ||
{ | ||
if (vMerkleTree.empty()) | ||
BuildMerkleTree(); | ||
std::vector<uint256> vMerkleBranch; | ||
int j = 0; | ||
for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) | ||
{ | ||
int i = std::min(nIndex^1, nSize-1); | ||
vMerkleBranch.push_back(vMerkleTree[j+i]); | ||
nIndex >>= 1; | ||
j += nSize; | ||
} | ||
return vMerkleBranch; | ||
} | ||
|
||
uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex) | ||
{ | ||
if (nIndex == -1) | ||
return uint256(); | ||
for (std::vector<uint256>::const_iterator it(vMerkleBranch.begin()); it != vMerkleBranch.end(); ++it) | ||
{ | ||
if (nIndex & 1) | ||
hash = Hash(BEGIN(*it), END(*it), BEGIN(hash), END(hash)); | ||
else | ||
hash = Hash(BEGIN(hash), END(hash), BEGIN(*it), END(*it)); | ||
nIndex >>= 1; | ||
} | ||
return hash; | ||
} | ||
|
||
std::string CBlock::ToString() const | ||
{ | ||
std::stringstream s; | ||
|
@@ -123,9 +92,5 @@ std::string CBlock::ToString() const | |
{ | ||
s << " " << vtx[i].ToString() << "\n"; | ||
} | ||
s << " vMerkleTree: "; | ||
for (unsigned int i = 0; i < vMerkleTree.size(); i++) | ||
s << " " << vMerkleTree[i].ToString(); | ||
s << "\n"; | ||
return s.str(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -78,7 +78,7 @@ class CBlock : public CBlockHeader | |
std::vector<CTransaction> vtx; | ||
|
||
// memory only | ||
mutable std::vector<uint256> vMerkleTree; | ||
mutable bool fChecked; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideally we'd have this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fully agree, I actually started implementing that as a follow-up, but didn't want to interfere with other refactorings. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, yes, I'm fine with keeping it like this for this pull |
||
|
||
CBlock() | ||
{ | ||
|
@@ -103,7 +103,7 @@ class CBlock : public CBlockHeader | |
{ | ||
CBlockHeader::SetNull(); | ||
vtx.clear(); | ||
vMerkleTree.clear(); | ||
fChecked = false; | ||
} | ||
|
||
CBlockHeader GetBlockHeader() const | ||
|
@@ -118,14 +118,12 @@ class CBlock : public CBlockHeader | |
return block; | ||
} | ||
|
||
// Build the in-memory merkle tree for this block and return the merkle root. | ||
// Build the merkle tree for this block and return the merkle root. | ||
// If non-NULL, *mutated is set to whether mutation was detected in the merkle | ||
// tree (a duplication of transactions in the block leading to an identical | ||
// merkle root). | ||
uint256 BuildMerkleTree(bool* mutated = NULL) const; | ||
uint256 ComputeMerkleRoot(bool* mutated = NULL) const; | ||
|
||
std::vector<uint256> GetMerkleBranch(int nIndex) const; | ||
static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex); | ||
std::string ToString() const; | ||
}; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const what?