|
11 | 11 | #include "checkpoints.h"
|
12 | 12 | #include "checkqueue.h"
|
13 | 13 | #include "init.h"
|
| 14 | +#include "merkleblock.h" |
14 | 15 | #include "net.h"
|
15 | 16 | #include "pow.h"
|
16 | 17 | #include "txdb.h"
|
@@ -2721,159 +2722,6 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex
|
2721 | 2722 |
|
2722 | 2723 |
|
2723 | 2724 |
|
2724 |
| -CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter) |
2725 |
| -{ |
2726 |
| - header = block.GetBlockHeader(); |
2727 |
| - |
2728 |
| - vector<bool> vMatch; |
2729 |
| - vector<uint256> vHashes; |
2730 |
| - |
2731 |
| - vMatch.reserve(block.vtx.size()); |
2732 |
| - vHashes.reserve(block.vtx.size()); |
2733 |
| - |
2734 |
| - for (unsigned int i = 0; i < block.vtx.size(); i++) |
2735 |
| - { |
2736 |
| - const uint256& hash = block.vtx[i].GetHash(); |
2737 |
| - if (filter.IsRelevantAndUpdate(block.vtx[i])) |
2738 |
| - { |
2739 |
| - vMatch.push_back(true); |
2740 |
| - vMatchedTxn.push_back(make_pair(i, hash)); |
2741 |
| - } |
2742 |
| - else |
2743 |
| - vMatch.push_back(false); |
2744 |
| - vHashes.push_back(hash); |
2745 |
| - } |
2746 |
| - |
2747 |
| - txn = CPartialMerkleTree(vHashes, vMatch); |
2748 |
| -} |
2749 |
| - |
2750 |
| - |
2751 |
| - |
2752 |
| - |
2753 |
| - |
2754 |
| - |
2755 |
| - |
2756 |
| - |
2757 |
| -uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid) { |
2758 |
| - if (height == 0) { |
2759 |
| - // hash at height 0 is the txids themself |
2760 |
| - return vTxid[pos]; |
2761 |
| - } else { |
2762 |
| - // calculate left hash |
2763 |
| - uint256 left = CalcHash(height-1, pos*2, vTxid), right; |
2764 |
| - // calculate right hash if not beyond the end of the array - copy left hash otherwise1 |
2765 |
| - if (pos*2+1 < CalcTreeWidth(height-1)) |
2766 |
| - right = CalcHash(height-1, pos*2+1, vTxid); |
2767 |
| - else |
2768 |
| - right = left; |
2769 |
| - // combine subhashes |
2770 |
| - return Hash(BEGIN(left), END(left), BEGIN(right), END(right)); |
2771 |
| - } |
2772 |
| -} |
2773 |
| - |
2774 |
| -void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) { |
2775 |
| - // determine whether this node is the parent of at least one matched txid |
2776 |
| - bool fParentOfMatch = false; |
2777 |
| - for (unsigned int p = pos << height; p < (pos+1) << height && p < nTransactions; p++) |
2778 |
| - fParentOfMatch |= vMatch[p]; |
2779 |
| - // store as flag bit |
2780 |
| - vBits.push_back(fParentOfMatch); |
2781 |
| - if (height==0 || !fParentOfMatch) { |
2782 |
| - // if at height 0, or nothing interesting below, store hash and stop |
2783 |
| - vHash.push_back(CalcHash(height, pos, vTxid)); |
2784 |
| - } else { |
2785 |
| - // otherwise, don't store any hash, but descend into the subtrees |
2786 |
| - TraverseAndBuild(height-1, pos*2, vTxid, vMatch); |
2787 |
| - if (pos*2+1 < CalcTreeWidth(height-1)) |
2788 |
| - TraverseAndBuild(height-1, pos*2+1, vTxid, vMatch); |
2789 |
| - } |
2790 |
| -} |
2791 |
| - |
2792 |
| -uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch) { |
2793 |
| - if (nBitsUsed >= vBits.size()) { |
2794 |
| - // overflowed the bits array - failure |
2795 |
| - fBad = true; |
2796 |
| - return 0; |
2797 |
| - } |
2798 |
| - bool fParentOfMatch = vBits[nBitsUsed++]; |
2799 |
| - if (height==0 || !fParentOfMatch) { |
2800 |
| - // if at height 0, or nothing interesting below, use stored hash and do not descend |
2801 |
| - if (nHashUsed >= vHash.size()) { |
2802 |
| - // overflowed the hash array - failure |
2803 |
| - fBad = true; |
2804 |
| - return 0; |
2805 |
| - } |
2806 |
| - const uint256 &hash = vHash[nHashUsed++]; |
2807 |
| - if (height==0 && fParentOfMatch) // in case of height 0, we have a matched txid |
2808 |
| - vMatch.push_back(hash); |
2809 |
| - return hash; |
2810 |
| - } else { |
2811 |
| - // otherwise, descend into the subtrees to extract matched txids and hashes |
2812 |
| - uint256 left = TraverseAndExtract(height-1, pos*2, nBitsUsed, nHashUsed, vMatch), right; |
2813 |
| - if (pos*2+1 < CalcTreeWidth(height-1)) |
2814 |
| - right = TraverseAndExtract(height-1, pos*2+1, nBitsUsed, nHashUsed, vMatch); |
2815 |
| - else |
2816 |
| - right = left; |
2817 |
| - // and combine them before returning |
2818 |
| - return Hash(BEGIN(left), END(left), BEGIN(right), END(right)); |
2819 |
| - } |
2820 |
| -} |
2821 |
| - |
2822 |
| -CPartialMerkleTree::CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) : nTransactions(vTxid.size()), fBad(false) { |
2823 |
| - // reset state |
2824 |
| - vBits.clear(); |
2825 |
| - vHash.clear(); |
2826 |
| - |
2827 |
| - // calculate height of tree |
2828 |
| - int nHeight = 0; |
2829 |
| - while (CalcTreeWidth(nHeight) > 1) |
2830 |
| - nHeight++; |
2831 |
| - |
2832 |
| - // traverse the partial tree |
2833 |
| - TraverseAndBuild(nHeight, 0, vTxid, vMatch); |
2834 |
| -} |
2835 |
| - |
2836 |
| -CPartialMerkleTree::CPartialMerkleTree() : nTransactions(0), fBad(true) {} |
2837 |
| - |
2838 |
| -uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) { |
2839 |
| - vMatch.clear(); |
2840 |
| - // An empty set will not work |
2841 |
| - if (nTransactions == 0) |
2842 |
| - return 0; |
2843 |
| - // check for excessively high numbers of transactions |
2844 |
| - if (nTransactions > MAX_BLOCK_SIZE / 60) // 60 is the lower bound for the size of a serialized CTransaction |
2845 |
| - return 0; |
2846 |
| - // there can never be more hashes provided than one for every txid |
2847 |
| - if (vHash.size() > nTransactions) |
2848 |
| - return 0; |
2849 |
| - // there must be at least one bit per node in the partial tree, and at least one node per hash |
2850 |
| - if (vBits.size() < vHash.size()) |
2851 |
| - return 0; |
2852 |
| - // calculate height of tree |
2853 |
| - int nHeight = 0; |
2854 |
| - while (CalcTreeWidth(nHeight) > 1) |
2855 |
| - nHeight++; |
2856 |
| - // traverse the partial tree |
2857 |
| - unsigned int nBitsUsed = 0, nHashUsed = 0; |
2858 |
| - uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch); |
2859 |
| - // verify that no problems occured during the tree traversal |
2860 |
| - if (fBad) |
2861 |
| - return 0; |
2862 |
| - // verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence) |
2863 |
| - if ((nBitsUsed+7)/8 != (vBits.size()+7)/8) |
2864 |
| - return 0; |
2865 |
| - // verify that all hashes were consumed |
2866 |
| - if (nHashUsed != vHash.size()) |
2867 |
| - return 0; |
2868 |
| - return hashMerkleRoot; |
2869 |
| -} |
2870 |
| - |
2871 |
| - |
2872 |
| - |
2873 |
| - |
2874 |
| - |
2875 |
| - |
2876 |
| - |
2877 | 2725 | bool AbortNode(const std::string &strMessage, const std::string &userMessage) {
|
2878 | 2726 | strMiscWarning = strMessage;
|
2879 | 2727 | LogPrintf("*** %s\n", strMessage);
|
|
0 commit comments