コード例 #1
0
ファイル: MerkleTree.cpp プロジェクト: ciphrex/mSIGNA
void PartialMerkleTree::setCompressed(std::queue<uchar_vector>& hashQueue, std::queue<bool>& bitQueue, unsigned int depth)
{
    depth_ = depth;

    if (hashQueue.empty() || bitQueue.empty()) {
        throw std::runtime_error("PartialMerkleTree::setCompressed - Invalid compressed partial merkle tree data.");
    }

    bool bit = bitQueue.front();
    bits_.push_back(bit);
    bitQueue.pop();

    // We've reached a leaf of the partial merkle tree
    if (depth == 0 || !bit) {
        root_ = hashQueue.front();
        merkleHashes_.push_back(hashQueue.front());
        if (bit) txHashes_.push_back(hashQueue.front());
        hashQueue.pop();
        return;
    }

    depth--;

    // we're not at a leaf and bit is set so recurse
    PartialMerkleTree leftSubtree;
    leftSubtree.setCompressed(hashQueue, bitQueue, depth);

    merkleHashes_.swap(leftSubtree.merkleHashes_);
    txHashes_.swap(leftSubtree.txHashes_);
    bits_.splice(bits_.end(), leftSubtree.bits_);

    if (!hashQueue.empty()) {
        // A right subtree also exists, so find it
        PartialMerkleTree rightSubtree;
        rightSubtree.setCompressed(hashQueue, bitQueue, 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 {
        // There's no right subtree - copy over this node's hash
        root_ = sha256_2(leftSubtree.root_ + leftSubtree.root_);
    }
}
コード例 #2
0
ファイル: MerkleTree.cpp プロジェクト: ciphrex/mSIGNA
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();
}