void PartialMerkleTree::merge(std::queue<uchar_vector>& hashQueue1, std::queue<uchar_vector>& hashQueue2, std::queue<bool>& bitQueue1, std::queue<bool>& bitQueue2, unsigned int depth) { if (hashQueue1.empty()) { hashQueue1.swap(hashQueue2); bitQueue1.swap(bitQueue2); } if (hashQueue2.empty()) { if (hashQueue1.empty()) return; PartialMerkleTree tree; tree.setCompressed(hashQueue1, bitQueue1, depth); merkleHashes_.splice(merkleHashes_.end(), tree.merkleHashes_); txHashes_.splice(txHashes_.end(), tree.txHashes_); bits_.splice(bits_.end(), tree.bits_); return; } bool bit1 = bitQueue1.front(); bool bit2 = bitQueue2.front(); bool hasMatch = (bit1 || bit2); bitQueue1.pop(); bitQueue2.pop(); // We've reached a leaf of the partial merkle tree if (depth == 0 || !hasMatch) { if (hashQueue1.front() != hashQueue2.front()) { std::stringstream error; error << "PartialMerkleTree::merge - leaves do not match: " << hashQueue1.front().getReverse().getHex() << ", " << hashQueue2.front().getReverse().getHex() << std::endl; throw std::runtime_error(error.str()); } merkleHashes_.push_back(hashQueue1.front()); std::cout << hashQueue1.front().getReverse().getHex() << std::endl; if (hasMatch) { txHashes_.push_back(hashQueue1.front()); } bits_.push_back(hasMatch); hashQueue1.pop(); hashQueue2.pop(); return; } bits_.push_back(true); depth--; // Both trees continue down this branch. if (bit1 && bit2) { merge(hashQueue1, hashQueue2, bitQueue1, bitQueue2, depth); merge(hashQueue1, hashQueue2, bitQueue1, bitQueue2, depth); return; } // Only one tree continues down this branch. Swap them if it's the second. if (bit2) { hashQueue1.swap(hashQueue2); bitQueue1.swap(bitQueue2); } PartialMerkleTree leftSubtree; leftSubtree.setCompressed(hashQueue1, bitQueue1, depth); merkleHashes_.splice(merkleHashes_.end(), leftSubtree.merkleHashes_); txHashes_.splice(txHashes_.end(), leftSubtree.txHashes_); bits_.splice(bits_.end(), leftSubtree.bits_); uchar_vector root; if (!hashQueue1.empty()) { PartialMerkleTree rightSubtree; rightSubtree.setCompressed(hashQueue1, bitQueue1, depth); root = sha256_2(leftSubtree.root_ + rightSubtree.root_); merkleHashes_.splice(merkleHashes_.end(), rightSubtree.merkleHashes_); txHashes_.splice(txHashes_.end(), rightSubtree.txHashes_); bits_.splice(bits_.end(), rightSubtree.bits_); } else { root = sha256_2(leftSubtree.root_ + leftSubtree.root_); } if (root != hashQueue2.front()) { std::stringstream error; error << "PartialMerkleTree::merge - inner nodes do not match: " << root.getHex() << ", " << hashQueue2.front().getReverse().getHex(); throw std::runtime_error(error.str()); } hashQueue2.pop(); }