Merge pull request #5356 from nuttycom/feature/wallet_orchard-rename_tree_types
Rename OrchardMerkleTree -> OrchardMerkleFrontier, remove IncrementalSinsemillaTree
This commit is contained in:
commit
c76b756a68
|
@ -46,7 +46,7 @@ bool CCoins::Spend(uint32_t nPos)
|
||||||
}
|
}
|
||||||
bool CCoinsView::GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const { return false; }
|
bool CCoinsView::GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const { return false; }
|
||||||
bool CCoinsView::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { return false; }
|
bool CCoinsView::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { return false; }
|
||||||
bool CCoinsView::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const { return false; }
|
bool CCoinsView::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const { return false; }
|
||||||
bool CCoinsView::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return false; }
|
bool CCoinsView::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return false; }
|
||||||
bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; }
|
bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; }
|
||||||
bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; }
|
bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; }
|
||||||
|
@ -75,7 +75,7 @@ CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { }
|
||||||
|
|
||||||
bool CCoinsViewBacked::GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const { return base->GetSproutAnchorAt(rt, tree); }
|
bool CCoinsViewBacked::GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const { return base->GetSproutAnchorAt(rt, tree); }
|
||||||
bool CCoinsViewBacked::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { return base->GetSaplingAnchorAt(rt, tree); }
|
bool CCoinsViewBacked::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { return base->GetSaplingAnchorAt(rt, tree); }
|
||||||
bool CCoinsViewBacked::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const { return base->GetOrchardAnchorAt(rt, tree); }
|
bool CCoinsViewBacked::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const { return base->GetOrchardAnchorAt(rt, tree); }
|
||||||
bool CCoinsViewBacked::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return base->GetNullifier(nullifier, type); }
|
bool CCoinsViewBacked::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return base->GetNullifier(nullifier, type); }
|
||||||
bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); }
|
bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); }
|
||||||
bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); }
|
bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); }
|
||||||
|
@ -191,7 +191,7 @@ bool CCoinsViewCache::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &t
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCoinsViewCache::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const {
|
bool CCoinsViewCache::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const {
|
||||||
CAnchorsOrchardMap::const_iterator it = cacheOrchardAnchors.find(rt);
|
CAnchorsOrchardMap::const_iterator it = cacheOrchardAnchors.find(rt);
|
||||||
if (it != cacheOrchardAnchors.end()) {
|
if (it != cacheOrchardAnchors.end()) {
|
||||||
if (it->second.entered) {
|
if (it->second.entered) {
|
||||||
|
@ -321,9 +321,9 @@ template<> void CCoinsViewCache::PushAnchor(const SaplingMerkleTree &tree)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> void CCoinsViewCache::PushAnchor(const OrchardMerkleTree &tree)
|
template<> void CCoinsViewCache::PushAnchor(const OrchardMerkleFrontier &tree)
|
||||||
{
|
{
|
||||||
AbstractPushAnchor<OrchardMerkleTree, CAnchorsOrchardMap, CAnchorsOrchardMap::iterator, CAnchorsOrchardCacheEntry>(
|
AbstractPushAnchor<OrchardMerkleFrontier, CAnchorsOrchardMap, CAnchorsOrchardMap::iterator, CAnchorsOrchardCacheEntry>(
|
||||||
tree,
|
tree,
|
||||||
ORCHARD,
|
ORCHARD,
|
||||||
cacheOrchardAnchors,
|
cacheOrchardAnchors,
|
||||||
|
@ -352,7 +352,7 @@ void CCoinsViewCache::BringBestAnchorIntoCache(
|
||||||
template<>
|
template<>
|
||||||
void CCoinsViewCache::BringBestAnchorIntoCache(
|
void CCoinsViewCache::BringBestAnchorIntoCache(
|
||||||
const uint256 ¤tRoot,
|
const uint256 ¤tRoot,
|
||||||
OrchardMerkleTree &tree
|
OrchardMerkleFrontier &tree
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
assert(GetOrchardAnchorAt(currentRoot, tree));
|
assert(GetOrchardAnchorAt(currentRoot, tree));
|
||||||
|
@ -1069,7 +1069,7 @@ std::optional<UnsatisfiedShieldedReq> CCoinsViewCache::HaveShieldedRequirements(
|
||||||
|
|
||||||
std::optional<uint256> root = tx.GetOrchardBundle().GetAnchor();
|
std::optional<uint256> root = tx.GetOrchardBundle().GetAnchor();
|
||||||
if (root) {
|
if (root) {
|
||||||
OrchardMerkleTree tree;
|
OrchardMerkleFrontier tree;
|
||||||
if (!GetOrchardAnchorAt(root.value(), tree)) {
|
if (!GetOrchardAnchorAt(root.value(), tree)) {
|
||||||
auto txid = tx.GetHash().ToString();
|
auto txid = tx.GetHash().ToString();
|
||||||
auto anchor = root.value().ToString();
|
auto anchor = root.value().ToString();
|
||||||
|
|
|
@ -304,7 +304,7 @@ struct CAnchorsSaplingCacheEntry
|
||||||
struct CAnchorsOrchardCacheEntry
|
struct CAnchorsOrchardCacheEntry
|
||||||
{
|
{
|
||||||
bool entered; // This will be false if the anchor is removed from the cache
|
bool entered; // This will be false if the anchor is removed from the cache
|
||||||
OrchardMerkleTree tree; // The tree itself
|
OrchardMerkleFrontier tree; // The tree itself
|
||||||
unsigned char flags;
|
unsigned char flags;
|
||||||
|
|
||||||
enum Flags {
|
enum Flags {
|
||||||
|
@ -368,7 +368,7 @@ public:
|
||||||
virtual bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
virtual bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
||||||
|
|
||||||
//! Retrieve the tree (Orchard) at a particular anchored root in the chain
|
//! Retrieve the tree (Orchard) at a particular anchored root in the chain
|
||||||
virtual bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const;
|
virtual bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const;
|
||||||
|
|
||||||
//! Determine whether a nullifier is spent or not
|
//! Determine whether a nullifier is spent or not
|
||||||
virtual bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
virtual bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
||||||
|
@ -428,7 +428,7 @@ public:
|
||||||
CCoinsViewBacked(CCoinsView *viewIn);
|
CCoinsViewBacked(CCoinsView *viewIn);
|
||||||
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const;
|
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const;
|
||||||
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
||||||
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const;
|
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const;
|
||||||
bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
||||||
bool GetCoins(const uint256 &txid, CCoins &coins) const;
|
bool GetCoins(const uint256 &txid, CCoins &coins) const;
|
||||||
bool HaveCoins(const uint256 &txid) const;
|
bool HaveCoins(const uint256 &txid) const;
|
||||||
|
@ -521,7 +521,7 @@ public:
|
||||||
// Standard CCoinsView methods
|
// Standard CCoinsView methods
|
||||||
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const;
|
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const;
|
||||||
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
||||||
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const;
|
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const;
|
||||||
bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
||||||
bool GetCoins(const uint256 &txid, CCoins &coins) const;
|
bool GetCoins(const uint256 &txid, CCoins &coins) const;
|
||||||
bool HaveCoins(const uint256 &txid) const;
|
bool HaveCoins(const uint256 &txid) const;
|
||||||
|
|
|
@ -293,13 +293,13 @@ TEST(orchardMerkleTree, emptyroot) {
|
||||||
// an integer, which is converted to little-endian internally.
|
// an integer, which is converted to little-endian internally.
|
||||||
uint256 expected = uint256S("2fd8e51a03d9bbe2dd809831b1497aeb68a6e37ddf707ced4aa2d8dff13529ae");
|
uint256 expected = uint256S("2fd8e51a03d9bbe2dd809831b1497aeb68a6e37ddf707ced4aa2d8dff13529ae");
|
||||||
|
|
||||||
ASSERT_EQ(OrchardMerkleTree::empty_root(), expected);
|
ASSERT_EQ(OrchardMerkleFrontier::empty_root(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(orchardMerkleTree, appendBundle) {
|
TEST(orchardMerkleTree, appendBundle) {
|
||||||
OrchardMerkleTree newTree;
|
OrchardMerkleFrontier newTree;
|
||||||
|
|
||||||
ASSERT_EQ(newTree.root(), OrchardMerkleTree::empty_root());
|
ASSERT_EQ(newTree.root(), OrchardMerkleFrontier::empty_root());
|
||||||
|
|
||||||
for (int i = 0; i < 1; i++) {
|
for (int i = 0; i < 1; i++) {
|
||||||
CDataStream ssBundleData(merkle_roots_orchard[i].bundle, SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ssBundleData(merkle_roots_orchard[i].bundle, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
|
|
@ -3125,7 +3125,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||||
SaplingMerkleTree sapling_tree;
|
SaplingMerkleTree sapling_tree;
|
||||||
assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree));
|
assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree));
|
||||||
|
|
||||||
OrchardMerkleTree orchard_tree;
|
OrchardMerkleFrontier orchard_tree;
|
||||||
assert(view.GetOrchardAnchorAt(view.GetBestAnchor(ORCHARD), orchard_tree));
|
assert(view.GetOrchardAnchorAt(view.GetBestAnchor(ORCHARD), orchard_tree));
|
||||||
|
|
||||||
// Grab the consensus branch ID for this block and its parent
|
// Grab the consensus branch ID for this block and its parent
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include <amount.h>
|
#include <amount.h>
|
||||||
#include <rust/orchard.h>
|
#include <rust/orchard.h>
|
||||||
|
|
||||||
class OrchardMerkleTree;
|
class OrchardMerkleFrontier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Orchard component of a transaction.
|
* The Orchard component of a transaction.
|
||||||
|
@ -22,7 +22,7 @@ private:
|
||||||
/// Memory is allocated by Rust.
|
/// Memory is allocated by Rust.
|
||||||
std::unique_ptr<OrchardBundlePtr, decltype(&orchard_bundle_free)> inner;
|
std::unique_ptr<OrchardBundlePtr, decltype(&orchard_bundle_free)> inner;
|
||||||
|
|
||||||
friend class OrchardMerkleTree;
|
friend class OrchardMerkleFrontier;
|
||||||
public:
|
public:
|
||||||
OrchardBundle() : inner(nullptr, orchard_bundle_free) {}
|
OrchardBundle() : inner(nullptr, orchard_bundle_free) {}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
// Copyright (c) 2021 The Zcash developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
||||||
|
|
||||||
|
#ifndef ZCASH_RUST_INCLUDE_RUST_ORCHARD_INCREMENTAL_MERKLE_TREE_H
|
||||||
|
#define ZCASH_RUST_INCLUDE_RUST_ORCHARD_INCREMENTAL_MERKLE_TREE_H
|
||||||
|
|
||||||
|
#include "rust/streams.h"
|
||||||
|
#include "rust/orchard.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SINSEMILLA_DIGEST_LEN 32U
|
||||||
|
|
||||||
|
/// Pointer to an Orchard incremental merkle tree frontier
|
||||||
|
struct OrchardMerkleFrontierPtr;
|
||||||
|
typedef struct OrchardMerkleFrontierPtr OrchardMerkleFrontierPtr;
|
||||||
|
|
||||||
|
// Create an empty Orchard Merkle frontier.
|
||||||
|
//
|
||||||
|
// Memory allocated to the resulting value must be manually freed.
|
||||||
|
OrchardMerkleFrontierPtr* orchard_merkle_frontier_empty();
|
||||||
|
|
||||||
|
// Clones the given Orchard Merkle frontier and returns
|
||||||
|
// a pointer to the newly created tree. Both the original
|
||||||
|
// tree's memory and the newly allocated one need to be freed
|
||||||
|
// independently.
|
||||||
|
OrchardMerkleFrontierPtr* orchard_merkle_frontier_clone(
|
||||||
|
const OrchardMerkleFrontierPtr* tree_ptr);
|
||||||
|
|
||||||
|
// Free the memory allocated for the given Orchard Merkle frontier.
|
||||||
|
void orchard_merkle_frontier_free(
|
||||||
|
OrchardMerkleFrontierPtr* tree_ptr);
|
||||||
|
|
||||||
|
// Parses an Orchard Merkle frontier from a stream. If parsing
|
||||||
|
// fails, this will return the null pointer.
|
||||||
|
//
|
||||||
|
// Memory allocated to the resulting value must be manually freed.
|
||||||
|
OrchardMerkleFrontierPtr* orchard_merkle_frontier_parse(
|
||||||
|
void* stream,
|
||||||
|
read_callback_t read_cb);
|
||||||
|
|
||||||
|
// Serializes an Orchard Merkle frontier to a stream.
|
||||||
|
//
|
||||||
|
// Returns `false` if an error occurs while writing to the stream.
|
||||||
|
bool orchard_merkle_frontier_serialize(
|
||||||
|
const OrchardMerkleFrontierPtr* tree_ptr,
|
||||||
|
void* stream,
|
||||||
|
write_callback_t write_cb);
|
||||||
|
|
||||||
|
// For each action in the provided bundle, append its
|
||||||
|
// commitment to the frontier.
|
||||||
|
//
|
||||||
|
// Returns `true` if the append succeeds, `false` if the
|
||||||
|
// tree is full.
|
||||||
|
bool orchard_merkle_frontier_append_bundle(
|
||||||
|
OrchardMerkleFrontierPtr* tree_ptr,
|
||||||
|
const OrchardBundlePtr* bundle);
|
||||||
|
|
||||||
|
// Computes the root of the provided orchard Merkle frontier
|
||||||
|
void orchard_merkle_frontier_root(
|
||||||
|
const OrchardMerkleFrontierPtr* tree_ptr,
|
||||||
|
unsigned char* digest_ret);
|
||||||
|
|
||||||
|
// The total number of leaves that have been appended to obtain
|
||||||
|
// the current state of the frontier. Subtract 1 from this value
|
||||||
|
// to obtain the position of the most recently appended leaf.
|
||||||
|
size_t orchard_merkle_frontier_num_leaves(
|
||||||
|
const OrchardMerkleFrontierPtr* tree_ptr);
|
||||||
|
|
||||||
|
// Estimate the amount of memory consumed by the merkle frontier.
|
||||||
|
size_t orchard_merkle_frontier_dynamic_mem_usage(
|
||||||
|
const OrchardMerkleFrontierPtr* tree_ptr);
|
||||||
|
|
||||||
|
// Computes the empty leaf value for the incremental Merkle tree.
|
||||||
|
void orchard_merkle_tree_empty_root(
|
||||||
|
unsigned char* digest_ret);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // ZCASH_RUST_INCLUDE_RUST_ORCHARD_INCREMENTAL_MERKLE_TREE_H
|
|
@ -1,149 +0,0 @@
|
||||||
// Copyright (c) 2021 The Zcash developers
|
|
||||||
// Distributed under the MIT software license, see the accompanying
|
|
||||||
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
|
||||||
|
|
||||||
#ifndef ZCASH_RUST_INCLUDE_RUST_ORCHARD_INCREMENTAL_SINSEMILLA_TREE_H
|
|
||||||
#define ZCASH_RUST_INCLUDE_RUST_ORCHARD_INCREMENTAL_SINSEMILLA_TREE_H
|
|
||||||
|
|
||||||
#include "rust/streams.h"
|
|
||||||
#include "rust/orchard.h"
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SINSEMILLA_DIGEST_LEN 32U
|
|
||||||
|
|
||||||
/// Pointer to an Orchard incremental merkle tree frontier
|
|
||||||
struct OrchardMerkleFrontierPtr;
|
|
||||||
typedef struct OrchardMerkleFrontierPtr OrchardMerkleFrontierPtr;
|
|
||||||
|
|
||||||
// Create an empty Orchard Merkle frontier.
|
|
||||||
//
|
|
||||||
// Memory allocated to the resulting value must be manually freed.
|
|
||||||
OrchardMerkleFrontierPtr* orchard_merkle_frontier_empty();
|
|
||||||
|
|
||||||
// Clones the given Orchard Merkle frontier and returns
|
|
||||||
// a pointer to the newly created tree. Both the original
|
|
||||||
// tree's memory and the newly allocated one need to be freed
|
|
||||||
// independently.
|
|
||||||
OrchardMerkleFrontierPtr* orchard_merkle_frontier_clone(
|
|
||||||
const OrchardMerkleFrontierPtr* tree_ptr);
|
|
||||||
|
|
||||||
// Free the memory allocated for the given Orchard Merkle frontier.
|
|
||||||
void orchard_merkle_frontier_free(
|
|
||||||
OrchardMerkleFrontierPtr* tree_ptr);
|
|
||||||
|
|
||||||
// Parses an Orchard Merkle frontier from a stream. If parsing
|
|
||||||
// fails, this will return the null pointer.
|
|
||||||
//
|
|
||||||
// Memory allocated to the resulting value must be manually freed.
|
|
||||||
OrchardMerkleFrontierPtr* orchard_merkle_frontier_parse(
|
|
||||||
void* stream,
|
|
||||||
read_callback_t read_cb);
|
|
||||||
|
|
||||||
// Serializes an Orchard Merkle frontier to a stream.
|
|
||||||
//
|
|
||||||
// Returns `false` if an error occurs while writing to the stream.
|
|
||||||
bool orchard_merkle_frontier_serialize(
|
|
||||||
const OrchardMerkleFrontierPtr* tree_ptr,
|
|
||||||
void* stream,
|
|
||||||
write_callback_t write_cb);
|
|
||||||
|
|
||||||
// For each action in the provided bundle, append its
|
|
||||||
// commitment to the frontier.
|
|
||||||
//
|
|
||||||
// Returns `true` if the append succeeds, `false` if the
|
|
||||||
// tree is full.
|
|
||||||
bool orchard_merkle_frontier_append_bundle(
|
|
||||||
OrchardMerkleFrontierPtr* tree_ptr,
|
|
||||||
const OrchardBundlePtr* bundle);
|
|
||||||
|
|
||||||
// Computes the root of the provided orchard Merkle frontier
|
|
||||||
void orchard_merkle_frontier_root(
|
|
||||||
const OrchardMerkleFrontierPtr* tree_ptr,
|
|
||||||
unsigned char* digest_ret);
|
|
||||||
|
|
||||||
// The total number of leaves that have been appended to obtain
|
|
||||||
// the current state of the frontier. Subtract 1 from this value
|
|
||||||
// to obtain the position of the most recently appended leaf.
|
|
||||||
size_t orchard_merkle_frontier_num_leaves(
|
|
||||||
const OrchardMerkleFrontierPtr* tree_ptr);
|
|
||||||
|
|
||||||
// Estimate the amount of memory consumed by the merkle frontier.
|
|
||||||
size_t orchard_merkle_frontier_dynamic_mem_usage(
|
|
||||||
const OrchardMerkleFrontierPtr* tree_ptr);
|
|
||||||
|
|
||||||
/// Pointer to an Orchard incremental Sinsemilla tree
|
|
||||||
struct IncrementalSinsemillaTreePtr;
|
|
||||||
typedef struct IncrementalSinsemillaTreePtr IncrementalSinsemillaTreePtr;
|
|
||||||
|
|
||||||
// Create an empty incremental Sinsemilla tree.
|
|
||||||
//
|
|
||||||
// Memory allocated to the resulting value must be manually freed.
|
|
||||||
IncrementalSinsemillaTreePtr* incremental_sinsemilla_tree_empty();
|
|
||||||
|
|
||||||
// Clones the given incremental Sinsemilla tree and returns
|
|
||||||
// a pointer to the newly created tree. Both the original
|
|
||||||
// tree's memory and the newly allocated one need to be freed
|
|
||||||
// independently.
|
|
||||||
IncrementalSinsemillaTreePtr* incremental_sinsemilla_tree_clone(
|
|
||||||
const IncrementalSinsemillaTreePtr* tree_ptr);
|
|
||||||
|
|
||||||
// Free the memory allocated for the given incremental Sinsemilla tree.
|
|
||||||
void incremental_sinsemilla_tree_free(
|
|
||||||
IncrementalSinsemillaTreePtr* tree_ptr);
|
|
||||||
|
|
||||||
// Parses an incremental Sinsemilla tree from a stream. If parsing
|
|
||||||
// fails, this will return the null pointer.
|
|
||||||
//
|
|
||||||
// Memory allocated to the resulting value must be manually freed.
|
|
||||||
IncrementalSinsemillaTreePtr* incremental_sinsemilla_tree_parse(
|
|
||||||
void* stream,
|
|
||||||
read_callback_t read_cb);
|
|
||||||
|
|
||||||
// Serializes an incremental Sinsemilla tree to a stream.
|
|
||||||
//
|
|
||||||
// Returns false if an error occurs while writing to the stream.
|
|
||||||
bool incremental_sinsemilla_tree_serialize(
|
|
||||||
const IncrementalSinsemillaTreePtr* tree_ptr,
|
|
||||||
void* stream,
|
|
||||||
write_callback_t write_cb);
|
|
||||||
|
|
||||||
// For each action in the provided bundle, append its
|
|
||||||
// commitment to the incremental Merkle tree.
|
|
||||||
//
|
|
||||||
// Returns `true` if the append succeeds, `false` if the
|
|
||||||
// tree is full.
|
|
||||||
bool incremental_sinsemilla_tree_append_bundle(
|
|
||||||
IncrementalSinsemillaTreePtr* tree_ptr,
|
|
||||||
const OrchardBundlePtr* bundle);
|
|
||||||
|
|
||||||
// Save the current state of the incremental merkle tree
|
|
||||||
// as a point to which the tree can be rewound.
|
|
||||||
void incremental_sinsemilla_tree_checkpoint(
|
|
||||||
IncrementalSinsemillaTreePtr* tree_ptr);
|
|
||||||
|
|
||||||
// Rewind the incremental merkle tree to the latest checkpoint.
|
|
||||||
//
|
|
||||||
// Returns `true` if the rewind succeeds, `false` if the attempted
|
|
||||||
// rewind would require the destruction of witness data.
|
|
||||||
bool incremental_sinsemilla_tree_rewind(
|
|
||||||
IncrementalSinsemillaTreePtr* tree_ptr);
|
|
||||||
|
|
||||||
// Computes the root of the provided incremental Sinsemilla tree.
|
|
||||||
void incremental_sinsemilla_tree_root(
|
|
||||||
const IncrementalSinsemillaTreePtr* tree_ptr,
|
|
||||||
unsigned char* digest_ret);
|
|
||||||
|
|
||||||
// Computes the empty leaf value for the incremental Sinsemilla tree.
|
|
||||||
void incremental_sinsemilla_tree_empty_root(
|
|
||||||
unsigned char* digest_ret);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // ZCASH_RUST_INCLUDE_RUST_ORCHARD_INCREMENTAL_SINSEMILLA_TREE_H
|
|
|
@ -1,21 +1,17 @@
|
||||||
use incrementalmerkletree::{
|
use incrementalmerkletree::{bridgetree, Altitude, Frontier, Hashable};
|
||||||
bridgetree::{self, BridgeTree},
|
|
||||||
Altitude, Frontier, Hashable, Tree,
|
|
||||||
};
|
|
||||||
use std::mem::size_of_val;
|
use std::mem::size_of_val;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
use orchard::{bundle::Authorized, tree::MerkleHashOrchard};
|
use orchard::{bundle::Authorized, tree::MerkleHashOrchard};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
merkle_tree::incremental::{read_frontier_v1, read_tree, write_frontier_v1, write_tree},
|
merkle_tree::incremental::{read_frontier_v1, write_frontier_v1},
|
||||||
transaction::components::Amount,
|
transaction::components::Amount,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::streams_ffi::{CppStreamReader, CppStreamWriter, ReadCb, StreamObj, WriteCb};
|
use crate::streams_ffi::{CppStreamReader, CppStreamWriter, ReadCb, StreamObj, WriteCb};
|
||||||
|
|
||||||
pub const MERKLE_DEPTH: u8 = 32;
|
pub const MERKLE_DEPTH: u8 = 32;
|
||||||
pub const MAX_CHECKPOINTS: usize = 100;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Operations on Merkle frontiers.
|
// Operations on Merkle frontiers.
|
||||||
|
@ -148,139 +144,8 @@ pub extern "C" fn orchard_merkle_frontier_dynamic_mem_usage(
|
||||||
size_of_val(tree) + tree.dynamic_memory_usage()
|
size_of_val(tree) + tree.dynamic_memory_usage()
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Operations on incremental merkle trees with interstitial
|
|
||||||
// witnesses.
|
|
||||||
//
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_empty(
|
pub extern "C" fn orchard_merkle_tree_empty_root(root_ret: *mut [u8; 32]) {
|
||||||
) -> *mut BridgeTree<MerkleHashOrchard, MERKLE_DEPTH> {
|
|
||||||
let empty_tree = BridgeTree::<MerkleHashOrchard, MERKLE_DEPTH>::new(MAX_CHECKPOINTS);
|
|
||||||
Box::into_raw(Box::new(empty_tree))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_clone(
|
|
||||||
tree: *const BridgeTree<MerkleHashOrchard, MERKLE_DEPTH>,
|
|
||||||
) -> *mut BridgeTree<MerkleHashOrchard, MERKLE_DEPTH> {
|
|
||||||
unsafe { tree.as_ref() }
|
|
||||||
.map(|tree| Box::into_raw(Box::new(tree.clone())))
|
|
||||||
.unwrap_or(std::ptr::null_mut())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_free(
|
|
||||||
tree: *mut BridgeTree<MerkleHashOrchard, MERKLE_DEPTH>,
|
|
||||||
) {
|
|
||||||
if !tree.is_null() {
|
|
||||||
drop(unsafe { Box::from_raw(tree) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_parse(
|
|
||||||
stream: Option<StreamObj>,
|
|
||||||
read_cb: Option<ReadCb>,
|
|
||||||
) -> *mut BridgeTree<MerkleHashOrchard, MERKLE_DEPTH> {
|
|
||||||
let reader = CppStreamReader::from_raw_parts(stream, read_cb.unwrap());
|
|
||||||
|
|
||||||
match read_tree(reader) {
|
|
||||||
Ok(parsed) => Box::into_raw(Box::new(parsed)),
|
|
||||||
Err(e) => {
|
|
||||||
error!("Failed to parse Orchard bundle: {}", e);
|
|
||||||
ptr::null_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_serialize(
|
|
||||||
tree: *const BridgeTree<MerkleHashOrchard, MERKLE_DEPTH>,
|
|
||||||
stream: Option<StreamObj>,
|
|
||||||
write_cb: Option<WriteCb>,
|
|
||||||
) -> bool {
|
|
||||||
let tree = unsafe {
|
|
||||||
tree.as_ref()
|
|
||||||
.expect("Orchard note commitment tree pointer may not be null.")
|
|
||||||
};
|
|
||||||
|
|
||||||
let writer = CppStreamWriter::from_raw_parts(stream, write_cb.unwrap());
|
|
||||||
match write_tree(writer, tree) {
|
|
||||||
Ok(()) => true,
|
|
||||||
Err(e) => {
|
|
||||||
error!("{}", e);
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_append_bundle(
|
|
||||||
tree: *mut BridgeTree<MerkleHashOrchard, MERKLE_DEPTH>,
|
|
||||||
bundle: *const orchard::Bundle<Authorized, Amount>,
|
|
||||||
) -> bool {
|
|
||||||
let tree = unsafe {
|
|
||||||
tree.as_mut()
|
|
||||||
.expect("Orchard note commitment tree pointer may not be null.")
|
|
||||||
};
|
|
||||||
if let Some(bundle) = unsafe { bundle.as_ref() } {
|
|
||||||
for action in bundle.actions().iter() {
|
|
||||||
if !tree.append(&MerkleHashOrchard::from_cmx(action.cmx())) {
|
|
||||||
error!("Orchard note commitment tree is full.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_checkpoint(
|
|
||||||
tree: *mut BridgeTree<MerkleHashOrchard, MERKLE_DEPTH>,
|
|
||||||
) {
|
|
||||||
let tree = unsafe {
|
|
||||||
tree.as_mut()
|
|
||||||
.expect("Orchard note commitment tree pointer may not be null.")
|
|
||||||
};
|
|
||||||
|
|
||||||
tree.checkpoint()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_rewind(
|
|
||||||
tree: *mut BridgeTree<MerkleHashOrchard, MERKLE_DEPTH>,
|
|
||||||
) -> bool {
|
|
||||||
let tree = unsafe {
|
|
||||||
tree.as_mut()
|
|
||||||
.expect("Orchard note commitment tree pointer may not be null.")
|
|
||||||
};
|
|
||||||
|
|
||||||
tree.rewind()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_root(
|
|
||||||
tree: *const BridgeTree<MerkleHashOrchard, MERKLE_DEPTH>,
|
|
||||||
root_ret: *mut [u8; 32],
|
|
||||||
) {
|
|
||||||
let tree = unsafe {
|
|
||||||
tree.as_ref()
|
|
||||||
.expect("Orchard note commitment tree pointer may not be null.")
|
|
||||||
};
|
|
||||||
|
|
||||||
let root_ret = unsafe {
|
|
||||||
root_ret
|
|
||||||
.as_mut()
|
|
||||||
.expect("Cannot return to the null pointer.")
|
|
||||||
};
|
|
||||||
|
|
||||||
*root_ret = tree.root().to_bytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn incremental_sinsemilla_tree_empty_root(root_ret: *mut [u8; 32]) {
|
|
||||||
let root_ret = unsafe {
|
let root_ret = unsafe {
|
||||||
root_ret
|
root_ret
|
||||||
.as_mut()
|
.as_mut()
|
|
@ -70,7 +70,7 @@ mod tracing_ffi;
|
||||||
|
|
||||||
mod address_ffi;
|
mod address_ffi;
|
||||||
mod history_ffi;
|
mod history_ffi;
|
||||||
mod incremental_sinsemilla_tree_ffi;
|
mod incremental_merkle_tree_ffi;
|
||||||
mod orchard_ffi;
|
mod orchard_ffi;
|
||||||
mod transaction_ffi;
|
mod transaction_ffi;
|
||||||
mod zip339_ffi;
|
mod zip339_ffi;
|
||||||
|
|
|
@ -32,7 +32,7 @@ class CCoinsViewTest : public CCoinsView
|
||||||
std::map<uint256, CCoins> map_;
|
std::map<uint256, CCoins> map_;
|
||||||
std::map<uint256, SproutMerkleTree> mapSproutAnchors_;
|
std::map<uint256, SproutMerkleTree> mapSproutAnchors_;
|
||||||
std::map<uint256, SaplingMerkleTree> mapSaplingAnchors_;
|
std::map<uint256, SaplingMerkleTree> mapSaplingAnchors_;
|
||||||
std::map<uint256, OrchardMerkleTree> mapOrchardAnchors_;
|
std::map<uint256, OrchardMerkleFrontier> mapOrchardAnchors_;
|
||||||
std::map<uint256, bool> mapSproutNullifiers_;
|
std::map<uint256, bool> mapSproutNullifiers_;
|
||||||
std::map<uint256, bool> mapSaplingNullifiers_;
|
std::map<uint256, bool> mapSaplingNullifiers_;
|
||||||
std::map<uint256, bool> mapOrchardNullifiers_;
|
std::map<uint256, bool> mapOrchardNullifiers_;
|
||||||
|
@ -41,7 +41,7 @@ public:
|
||||||
CCoinsViewTest() {
|
CCoinsViewTest() {
|
||||||
hashBestSproutAnchor_ = SproutMerkleTree::empty_root();
|
hashBestSproutAnchor_ = SproutMerkleTree::empty_root();
|
||||||
hashBestSaplingAnchor_ = SaplingMerkleTree::empty_root();
|
hashBestSaplingAnchor_ = SaplingMerkleTree::empty_root();
|
||||||
hashBestOrchardAnchor_ = OrchardMerkleTree::empty_root();
|
hashBestOrchardAnchor_ = OrchardMerkleFrontier::empty_root();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetSproutAnchorAt(const uint256& rt, SproutMerkleTree &tree) const {
|
bool GetSproutAnchorAt(const uint256& rt, SproutMerkleTree &tree) const {
|
||||||
|
@ -76,14 +76,14 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetOrchardAnchorAt(const uint256& rt, OrchardMerkleTree &tree) const {
|
bool GetOrchardAnchorAt(const uint256& rt, OrchardMerkleFrontier &tree) const {
|
||||||
if (rt == OrchardMerkleTree::empty_root()) {
|
if (rt == OrchardMerkleFrontier::empty_root()) {
|
||||||
OrchardMerkleTree new_tree;
|
OrchardMerkleFrontier new_tree;
|
||||||
tree = new_tree;
|
tree = new_tree;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<uint256, OrchardMerkleTree>::const_iterator it = mapOrchardAnchors_.find(rt);
|
std::map<uint256, OrchardMerkleFrontier>::const_iterator it = mapOrchardAnchors_.find(rt);
|
||||||
if (it == mapOrchardAnchors_.end()) {
|
if (it == mapOrchardAnchors_.end()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -217,7 +217,7 @@ public:
|
||||||
|
|
||||||
BatchWriteAnchors<SproutMerkleTree, CAnchorsSproutMap, CAnchorsSproutCacheEntry>(mapSproutAnchors, mapSproutAnchors_);
|
BatchWriteAnchors<SproutMerkleTree, CAnchorsSproutMap, CAnchorsSproutCacheEntry>(mapSproutAnchors, mapSproutAnchors_);
|
||||||
BatchWriteAnchors<SaplingMerkleTree, CAnchorsSaplingMap, CAnchorsSaplingCacheEntry>(mapSaplingAnchors, mapSaplingAnchors_);
|
BatchWriteAnchors<SaplingMerkleTree, CAnchorsSaplingMap, CAnchorsSaplingCacheEntry>(mapSaplingAnchors, mapSaplingAnchors_);
|
||||||
BatchWriteAnchors<OrchardMerkleTree, CAnchorsOrchardMap, CAnchorsOrchardCacheEntry>(mapOrchardAnchors, mapOrchardAnchors_);
|
BatchWriteAnchors<OrchardMerkleFrontier, CAnchorsOrchardMap, CAnchorsOrchardCacheEntry>(mapOrchardAnchors, mapOrchardAnchors_);
|
||||||
|
|
||||||
BatchWriteNullifiers(mapSproutNullifiers, mapSproutNullifiers_);
|
BatchWriteNullifiers(mapSproutNullifiers, mapSproutNullifiers_);
|
||||||
BatchWriteNullifiers(mapSaplingNullifiers, mapSaplingNullifiers_);
|
BatchWriteNullifiers(mapSaplingNullifiers, mapSaplingNullifiers_);
|
||||||
|
|
10
src/txdb.cpp
10
src/txdb.cpp
|
@ -81,9 +81,9 @@ bool CCoinsViewDB::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCoinsViewDB::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const {
|
bool CCoinsViewDB::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const {
|
||||||
if (rt == OrchardMerkleTree::empty_root()) {
|
if (rt == OrchardMerkleFrontier::empty_root()) {
|
||||||
OrchardMerkleTree new_tree;
|
OrchardMerkleFrontier new_tree;
|
||||||
tree = new_tree;
|
tree = new_tree;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ uint256 CCoinsViewDB::GetBestAnchor(ShieldedType type) const {
|
||||||
break;
|
break;
|
||||||
case ORCHARD:
|
case ORCHARD:
|
||||||
if (!db.Read(DB_BEST_ORCHARD_ANCHOR, hashBestAnchor))
|
if (!db.Read(DB_BEST_ORCHARD_ANCHOR, hashBestAnchor))
|
||||||
return OrchardMerkleTree::empty_root();
|
return OrchardMerkleFrontier::empty_root();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw runtime_error("Unknown shielded type");
|
throw runtime_error("Unknown shielded type");
|
||||||
|
@ -291,7 +291,7 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins,
|
||||||
|
|
||||||
::BatchWriteAnchors<CAnchorsSproutMap, CAnchorsSproutMap::iterator, CAnchorsSproutCacheEntry, SproutMerkleTree>(batch, mapSproutAnchors, DB_SPROUT_ANCHOR);
|
::BatchWriteAnchors<CAnchorsSproutMap, CAnchorsSproutMap::iterator, CAnchorsSproutCacheEntry, SproutMerkleTree>(batch, mapSproutAnchors, DB_SPROUT_ANCHOR);
|
||||||
::BatchWriteAnchors<CAnchorsSaplingMap, CAnchorsSaplingMap::iterator, CAnchorsSaplingCacheEntry, SaplingMerkleTree>(batch, mapSaplingAnchors, DB_SAPLING_ANCHOR);
|
::BatchWriteAnchors<CAnchorsSaplingMap, CAnchorsSaplingMap::iterator, CAnchorsSaplingCacheEntry, SaplingMerkleTree>(batch, mapSaplingAnchors, DB_SAPLING_ANCHOR);
|
||||||
::BatchWriteAnchors<CAnchorsOrchardMap, CAnchorsOrchardMap::iterator, CAnchorsOrchardCacheEntry, OrchardMerkleTree>(batch, mapOrchardAnchors, DB_ORCHARD_ANCHOR);
|
::BatchWriteAnchors<CAnchorsOrchardMap, CAnchorsOrchardMap::iterator, CAnchorsOrchardCacheEntry, OrchardMerkleFrontier>(batch, mapOrchardAnchors, DB_ORCHARD_ANCHOR);
|
||||||
|
|
||||||
::BatchWriteNullifiers(batch, mapSproutNullifiers, DB_NULLIFIER);
|
::BatchWriteNullifiers(batch, mapSproutNullifiers, DB_NULLIFIER);
|
||||||
::BatchWriteNullifiers(batch, mapSaplingNullifiers, DB_SAPLING_NULLIFIER);
|
::BatchWriteNullifiers(batch, mapSaplingNullifiers, DB_SAPLING_NULLIFIER);
|
||||||
|
|
|
@ -83,7 +83,7 @@ public:
|
||||||
|
|
||||||
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const;
|
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const;
|
||||||
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
||||||
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const;
|
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const;
|
||||||
bool GetNullifier(const uint256 &nf, ShieldedType type) const;
|
bool GetNullifier(const uint256 &nf, ShieldedType type) const;
|
||||||
bool GetCoins(const uint256 &txid, CCoins &coins) const;
|
bool GetCoins(const uint256 &txid, CCoins &coins) const;
|
||||||
bool HaveCoins(const uint256 &txid) const;
|
bool HaveCoins(const uint256 &txid) const;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "zcash/util.h"
|
#include "zcash/util.h"
|
||||||
|
|
||||||
#include <primitives/orchard.h>
|
#include <primitives/orchard.h>
|
||||||
#include <rust/orchard/incremental_sinsemilla_tree.h>
|
#include <rust/orchard/incremental_merkle_tree.h>
|
||||||
|
|
||||||
namespace libzcash {
|
namespace libzcash {
|
||||||
|
|
||||||
|
@ -259,28 +259,28 @@ typedef libzcash::IncrementalMerkleTree<INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, l
|
||||||
typedef libzcash::IncrementalWitness<SAPLING_INCREMENTAL_MERKLE_TREE_DEPTH, libzcash::PedersenHash> SaplingWitness;
|
typedef libzcash::IncrementalWitness<SAPLING_INCREMENTAL_MERKLE_TREE_DEPTH, libzcash::PedersenHash> SaplingWitness;
|
||||||
typedef libzcash::IncrementalWitness<INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, libzcash::PedersenHash> SaplingTestingWitness;
|
typedef libzcash::IncrementalWitness<INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, libzcash::PedersenHash> SaplingTestingWitness;
|
||||||
|
|
||||||
class OrchardMerkleTree
|
class OrchardMerkleFrontier
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/// An incremental Sinsemilla tree; this pointer may never be null.
|
/// An incremental Sinsemilla tree; this pointer may never be null.
|
||||||
/// Memory is allocated by Rust.
|
/// Memory is allocated by Rust.
|
||||||
std::unique_ptr<OrchardMerkleFrontierPtr, decltype(&orchard_merkle_frontier_free)> inner;
|
std::unique_ptr<OrchardMerkleFrontierPtr, decltype(&orchard_merkle_frontier_free)> inner;
|
||||||
public:
|
public:
|
||||||
OrchardMerkleTree() : inner(orchard_merkle_frontier_empty(), orchard_merkle_frontier_free) {}
|
OrchardMerkleFrontier() : inner(orchard_merkle_frontier_empty(), orchard_merkle_frontier_free) {}
|
||||||
|
|
||||||
OrchardMerkleTree(OrchardMerkleTree&& frontier) : inner(std::move(frontier.inner)) {}
|
OrchardMerkleFrontier(OrchardMerkleFrontier&& frontier) : inner(std::move(frontier.inner)) {}
|
||||||
|
|
||||||
OrchardMerkleTree(const OrchardMerkleTree& frontier) :
|
OrchardMerkleFrontier(const OrchardMerkleFrontier& frontier) :
|
||||||
inner(orchard_merkle_frontier_clone(frontier.inner.get()), orchard_merkle_frontier_free) {}
|
inner(orchard_merkle_frontier_clone(frontier.inner.get()), orchard_merkle_frontier_free) {}
|
||||||
|
|
||||||
OrchardMerkleTree& operator=(OrchardMerkleTree&& frontier)
|
OrchardMerkleFrontier& operator=(OrchardMerkleFrontier&& frontier)
|
||||||
{
|
{
|
||||||
if (this != &frontier) {
|
if (this != &frontier) {
|
||||||
inner = std::move(frontier.inner);
|
inner = std::move(frontier.inner);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
OrchardMerkleTree& operator=(const OrchardMerkleTree& frontier)
|
OrchardMerkleFrontier& operator=(const OrchardMerkleFrontier& frontier)
|
||||||
{
|
{
|
||||||
if (this != &frontier) {
|
if (this != &frontier) {
|
||||||
inner.reset(orchard_merkle_frontier_clone(frontier.inner.get()));
|
inner.reset(orchard_merkle_frontier_clone(frontier.inner.get()));
|
||||||
|
@ -323,7 +323,7 @@ public:
|
||||||
|
|
||||||
static uint256 empty_root() {
|
static uint256 empty_root() {
|
||||||
uint256 value;
|
uint256 value;
|
||||||
incremental_sinsemilla_tree_empty_root(value.begin());
|
orchard_merkle_tree_empty_root(value.begin());
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -448,7 +448,7 @@ class FakeCoinsViewDB : public CCoinsView {
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
SproutMerkleTree sproutTree;
|
SproutMerkleTree sproutTree;
|
||||||
SaplingMerkleTree saplingTree;
|
SaplingMerkleTree saplingTree;
|
||||||
OrchardMerkleTree orchardTree;
|
OrchardMerkleFrontier orchardTree;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FakeCoinsViewDB(std::string dbName, uint256& hash) : db(GetDataDir() / dbName, 100, false, false), hash(hash) {}
|
FakeCoinsViewDB(std::string dbName, uint256& hash) : db(GetDataDir() / dbName, 100, false, false), hash(hash) {}
|
||||||
|
@ -469,7 +469,7 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const {
|
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const {
|
||||||
if (rt == orchardTree.root()) {
|
if (rt == orchardTree.root()) {
|
||||||
tree = orchardTree;
|
tree = orchardTree;
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue