1 /********************************************************************
2 * (C) 2020 Michael Toutonghi
4 * Distributed under the MIT software license, see the accompanying
5 * file COPYING or http://www.opensource.org/licenses/mit-license.php.
11 // just used for setting breakpoints that may be hard to set and printing messages
12 void ErrorAndBP(std::string msg)
14 printf("%s\n", msg.c_str());
15 LogPrintf("%s\n", msg.c_str());
19 void CMMRProof::DeleteProofSequence()
21 // delete any objects that may be present
22 for (int i = proofSequence.size() - 1; i >= 0 && proofSequence[i]; i--)
24 CMerkleBranchBase *pProof = proofSequence[i];
25 switch(pProof->branchType)
27 case CMerkleBranchBase::BRANCH_BTC:
29 delete (CBTCMerkleBranch *)pProof;
32 case CMerkleBranchBase::BRANCH_MMRBLAKE_NODE:
34 delete (CMMRNodeBranch *)pProof;
37 case CMerkleBranchBase::BRANCH_MMRBLAKE_POWERNODE:
39 delete (CMMRPowerNodeBranch *)pProof;
44 ErrorAndBP("ERROR: likely double-free or memory corruption, unrecognized object in proof sequence");
45 // this is likely a memory error
49 proofSequence.pop_back();
53 const CMMRProof &CMMRProof::operator<<(const CBTCMerkleBranch &append)
55 CMerkleBranchBase *pNewProof = new CBTCMerkleBranch(append);
56 pNewProof->branchType = CMerkleBranchBase::BRANCH_BTC;
57 proofSequence.push_back(pNewProof);
61 const CMMRProof &CMMRProof::operator<<(const CMMRNodeBranch &append)
63 CMerkleBranchBase *pNewProof = new CMMRNodeBranch(append);
64 pNewProof->branchType = CMerkleBranchBase::BRANCH_MMRBLAKE_NODE;
65 proofSequence.push_back(pNewProof);
69 const CMMRProof &CMMRProof::operator<<(const CMMRPowerNodeBranch &append)
71 CMerkleBranchBase *pNewProof = new CMMRPowerNodeBranch(append);
72 pNewProof->branchType = CMerkleBranchBase::BRANCH_MMRBLAKE_POWERNODE;
73 proofSequence.push_back(pNewProof);
77 uint256 CMMRProof::CheckProof(uint256 hash) const
79 for (auto &pProof : proofSequence)
81 switch(pProof->branchType)
83 case CMerkleBranchBase::BRANCH_BTC:
85 hash = ((CBTCMerkleBranch *)pProof)->SafeCheck(hash);
88 case CMerkleBranchBase::BRANCH_MMRBLAKE_NODE:
90 hash = ((CMMRNodeBranch *)pProof)->SafeCheck(hash);
91 //printf("Result from CMMRNodeBranch check: %s\n", hash.GetHex().c_str());
94 case CMerkleBranchBase::BRANCH_MMRBLAKE_POWERNODE:
96 hash = ((CMMRPowerNodeBranch *)pProof)->SafeCheck(hash);
97 //printf("Result from CMMRPowerNodeBranch check: %s\n", hash.GetHex().c_str());
105 // return the index that would be generated for an mmv of the indicated size at the specified position
106 uint64_t CMerkleBranchBase::GetMMRProofIndex(uint64_t pos, uint64_t mmvSize, int extrahashes)
108 uint64_t retIndex = 0;
110 std::vector<uint64_t> Sizes;
111 std::vector<unsigned char> PeakIndexes;
112 std::vector<uint64_t> MerkleSizes;
114 // printf("%s: pos: %lu, mmvSize: %lu\n", __func__, pos, mmvSize);
116 // find a path from the indicated position to the root in the current view
117 if (pos > 0 && pos < mmvSize)
119 Sizes.push_back(mmvSize);
124 Sizes.push_back(mmvSize);
128 for (uint32_t ht = 0; ht < Sizes.size(); ht++)
130 // if we're at the top or the layer above us is smaller than 1/2 the size of this layer, rounded up, we are a peak
131 if (ht == ((uint32_t)Sizes.size() - 1) || (Sizes[ht] & 1))
133 PeakIndexes.insert(PeakIndexes.begin(), ht);
137 // figure out the peak merkle
138 uint64_t layerNum = 0, layerSize = PeakIndexes.size();
139 // with an odd number of elements below, the edge passes through
140 for (int passThrough = (layerSize & 1); layerNum == 0 || layerSize > 1; passThrough = (layerSize & 1), layerNum++)
142 layerSize = (layerSize >> 1) + passThrough;
145 MerkleSizes.push_back(layerSize);
149 // add extra hashes for a node on the right
150 for (int i = 0; i < extrahashes; i++)
152 // move to the next position
157 for (int l = 0; l < Sizes.size(); l++)
159 // printf("GetProofBits - Bits.size: %lu\n", Bits.size());
163 retIndex |= ((uint64_t)1) << bitPos++;
166 for (int i = 0; i < extrahashes; i++)
173 // make sure there is one after us to hash with or we are a peak and should be hashed with the rest of the peaks
174 if (Sizes[l] > (p + 1))
179 for (int i = 0; i < extrahashes; i++)
186 for (p = 0; p < PeakIndexes.size(); p++)
188 if (PeakIndexes[p] == l)
194 // p is the position in the merkle tree of peaks
195 assert(p < PeakIndexes.size());
197 // move up to the top, which is always a peak of size 1
200 for (layerNum = -1, layerSize = PeakIndexes.size(); layerNum == -1 || layerSize > 1; layerSize = MerkleSizes[++layerNum])
202 // printf("GetProofBits - Bits.size: %lu\n", Bits.size());
203 if (p < (layerSize - 1) || (p & 1))
207 // hash with the one before us
208 retIndex |= ((uint64_t)1) << bitPos;
211 for (int i = 0; i < extrahashes; i++)
218 // hash with the one in front of us
221 for (int i = 0; i < extrahashes; i++)
235 //printf("retindex: %lu\n", retIndex);