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);
93 case CMerkleBranchBase::BRANCH_MMRBLAKE_POWERNODE:
95 hash = ((CMMRPowerNodeBranch *)pProof)->SafeCheck(hash);
103 // return the index that would be generated for an mmv of the indicated size at the specified position
104 uint64_t CMerkleBranchBase::GetMMRProofIndex(uint64_t pos, uint64_t mmvSize, int extrahashes)
106 uint64_t retIndex = 0;
108 std::vector<uint64_t> Sizes;
109 std::vector<unsigned char> PeakIndexes;
110 std::vector<uint64_t> MerkleSizes;
112 // printf("%s: pos: %lu, mmvSize: %lu\n", __func__, pos, mmvSize);
114 // find a path from the indicated position to the root in the current view
115 if (pos > 0 && pos < mmvSize)
117 Sizes.push_back(mmvSize);
122 Sizes.push_back(mmvSize);
126 for (uint32_t ht = 0; ht < Sizes.size(); ht++)
128 // 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
129 if (ht == ((uint32_t)Sizes.size() - 1) || (Sizes[ht] & 1))
131 PeakIndexes.insert(PeakIndexes.begin(), ht);
135 uint64_t layerNum = 0, layerSize = Sizes[0];
136 // with an odd number of elements below, the edge passes through
137 for (bool passThrough = (layerSize & 1); layerNum == 0 || layerSize > 1; passThrough = (layerSize & 1), layerNum++)
139 layerSize = (layerSize >> 1) + passThrough;
142 MerkleSizes.push_back(layerSize);
146 // add extra hashes for a node on the right
147 for (int i = 0; i < extrahashes; i++)
149 // move to the next position
154 for (int l = 0; l < Sizes.size(); l++)
156 // printf("GetProofBits - Bits.size: %lu\n", Bits.size());
160 retIndex |= ((uint64_t)1) << bitPos++;
163 for (int i = 0; i < extrahashes; i++)
170 // 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
171 if (Sizes[l] > (p + 1))
176 for (int i = 0; i < extrahashes; i++)
183 for (p = 0; p < PeakIndexes.size(); p++)
185 if (PeakIndexes[p] == l)
191 // p is the position in the merkle tree of peaks
192 assert(p < PeakIndexes.size());
194 // move up to the top, which is always a peak of size 1
197 for (layerNum = -1, layerSize = PeakIndexes.size(); layerNum == -1 || layerSize > 1; layerSize = MerkleSizes[++layerNum])
199 // printf("GetProofBits - Bits.size: %lu\n", Bits.size());
200 if (p < (layerSize - 1) || (p & 1))
204 // hash with the one before us
205 retIndex |= ((uint64_t)1) << bitPos;
207 for (int i = 0; i < extrahashes; i++)
214 // hash with the one in front of us
217 for (int i = 0; i < extrahashes; i++)
231 //printf("retindex: %lu\n", retIndex);