Hush Full Node software. We were censored from Github, this is where all development happens now. https://hush.is
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
3.7 KiB

#ifndef ZCINCREMENTALMERKLETREE_H_
#define ZCINCREMENTALMERKLETREE_H_
#include <deque>
#include <boost/optional.hpp>
#include <boost/static_assert.hpp>
#include "uint256.h"
#include "serialize.h"
#include "Zcash.h"
namespace libzcash {
class MerklePath {
public:
std::vector<std::vector<bool>> authentication_path;
std::vector<bool> index;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(authentication_path);
READWRITE(index);
}
MerklePath() { }
MerklePath(std::vector<std::vector<bool>> authentication_path, std::vector<bool> index)
: authentication_path(authentication_path), index(index) { }
};
template<size_t Depth, typename Hash>
class IncrementalWitness;
template<size_t Depth, typename Hash>
class IncrementalMerkleTree {
friend class IncrementalWitness<Depth, Hash>;
public:
BOOST_STATIC_ASSERT(Depth >= 1);
IncrementalMerkleTree() { }
void append(Hash obj);
Hash root() const {
return root(Depth, std::deque<Hash>());
}
IncrementalWitness<Depth, Hash> witness() const {
return IncrementalWitness<Depth, Hash>(*this);
}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(left);
READWRITE(right);
READWRITE(parents);
wfcheck();
}
private:
boost::optional<Hash> left;
boost::optional<Hash> right;
8 years ago
// Collapsed "left" subtrees ordered toward the root of the tree.
std::vector<boost::optional<Hash>> parents;
MerklePath path(std::deque<Hash> filler_hashes = std::deque<Hash>()) const;
Hash root(size_t depth, std::deque<Hash> filler_hashes = std::deque<Hash>()) const;
bool is_complete(size_t depth = Depth) const;
size_t next_depth(size_t skip) const;
void wfcheck() const;
};
template <size_t Depth, typename Hash>
class IncrementalWitness {
friend class IncrementalMerkleTree<Depth, Hash>;
public:
MerklePath path() const {
8 years ago
return tree.path(partial_path());
}
Hash root() const {
8 years ago
return tree.root(Depth, partial_path());
}
void append(Hash obj);
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(tree);
READWRITE(filled);
READWRITE(cursor);
cursor_depth = tree.next_depth(filled.size());
}
private:
IncrementalMerkleTree<Depth, Hash> tree;
std::vector<Hash> filled;
boost::optional<IncrementalMerkleTree<Depth, Hash>> cursor;
size_t cursor_depth;
8 years ago
std::deque<Hash> partial_path() const;
IncrementalWitness(IncrementalMerkleTree<Depth, Hash> tree) : tree(tree) {}
};
class SHA256Compress : public uint256 {
public:
SHA256Compress() : uint256() {}
SHA256Compress(uint256 contents) : uint256(contents) { }
static SHA256Compress combine(const SHA256Compress& a, const SHA256Compress& b);
};
} // end namespace `libzcash`
typedef libzcash::IncrementalMerkleTree<INCREMENTAL_MERKLE_TREE_DEPTH, libzcash::SHA256Compress> ZCIncrementalMerkleTree;
typedef libzcash::IncrementalMerkleTree<INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, libzcash::SHA256Compress> ZCTestingIncrementalMerkleTree;
typedef libzcash::IncrementalWitness<INCREMENTAL_MERKLE_TREE_DEPTH, libzcash::SHA256Compress> ZCIncrementalWitness;
typedef libzcash::IncrementalWitness<INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, libzcash::SHA256Compress> ZCTestingIncrementalWitness;
#endif /* ZCINCREMENTALMERKLETREE_H_ */