#ifndef ZCINCREMENTALMERKLETREE_H_ #define ZCINCREMENTALMERKLETREE_H_ #include #include #include #include "uint256.h" #include "serialize.h" static const unsigned int INCREMENTAL_MERKLE_TREE_DEPTH = 20; static const unsigned int INCREMENTAL_MERKLE_TREE_DEPTH_TESTING = 4; namespace libzcash { class MerklePath { public: std::vector> authentication_path; std::vector index; ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(authentication_path); READWRITE(index); } MerklePath(std::vector> authentication_path, std::vector index) : authentication_path(authentication_path), index(index) { } }; template class IncrementalWitness; template class IncrementalMerkleTree { friend class IncrementalWitness; public: BOOST_STATIC_ASSERT(Depth >= 1); IncrementalMerkleTree() { } void append(Hash obj); Hash root() const { return root(Depth, std::deque()); } IncrementalWitness witness() const { return IncrementalWitness(*this); } ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(left); READWRITE(right); READWRITE(parents); wfcheck(); } private: boost::optional left; boost::optional right; std::vector> parents; MerklePath path(std::deque filler_hashes = std::deque()) const; Hash root(size_t depth, std::deque filler_hashes = std::deque()) const; bool is_complete(size_t depth = Depth) const; size_t next_depth(size_t skip) const; void wfcheck() const; }; template class IncrementalWitness { friend class IncrementalMerkleTree; public: MerklePath path() const { return tree.path(uncle_train()); } Hash root() const { return tree.root(Depth, uncle_train()); } void append(Hash obj); ADD_SERIALIZE_METHODS; template 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 tree; std::vector filled; boost::optional> cursor; size_t cursor_depth; std::deque uncle_train() const; IncrementalWitness(IncrementalMerkleTree 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 ZCIncrementalMerkleTree; typedef libzcash::IncrementalMerkleTree ZCTestingIncrementalMerkleTree; typedef libzcash::IncrementalWitness ZCIncrementalWitness; typedef libzcash::IncrementalWitness ZCTestingIncrementalWitness; #endif /* ZCINCREMENTALMERKLETREE_H_ */