Rename OrchardMerkleTree -> OrchardMerkleFrontier
Remove IncrementalSinsemillaTree; this will be replaced by a more full-featured OrchardWallet type which embeds the incremental merkle tree used in wallet operations.
This commit is contained in:
parent
f8e99e7ba5
commit
f49f4c73d8
|
@ -46,7 +46,7 @@ bool CCoins::Spend(uint32_t nPos)
|
|||
}
|
||||
bool CCoinsView::GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &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::GetCoins(const uint256 &txid, CCoins &coins) 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::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::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); }
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
if (it != cacheOrchardAnchors.end()) {
|
||||
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,
|
||||
ORCHARD,
|
||||
cacheOrchardAnchors,
|
||||
|
@ -352,7 +352,7 @@ void CCoinsViewCache::BringBestAnchorIntoCache(
|
|||
template<>
|
||||
void CCoinsViewCache::BringBestAnchorIntoCache(
|
||||
const uint256 ¤tRoot,
|
||||
OrchardMerkleTree &tree
|
||||
OrchardMerkleFrontier &tree
|
||||
)
|
||||
{
|
||||
assert(GetOrchardAnchorAt(currentRoot, tree));
|
||||
|
@ -1069,7 +1069,7 @@ std::optional<UnsatisfiedShieldedReq> CCoinsViewCache::HaveShieldedRequirements(
|
|||
|
||||
std::optional<uint256> root = tx.GetOrchardBundle().GetAnchor();
|
||||
if (root) {
|
||||
OrchardMerkleTree tree;
|
||||
OrchardMerkleFrontier tree;
|
||||
if (!GetOrchardAnchorAt(root.value(), tree)) {
|
||||
auto txid = tx.GetHash().ToString();
|
||||
auto anchor = root.value().ToString();
|
||||
|
|
|
@ -304,7 +304,7 @@ struct CAnchorsSaplingCacheEntry
|
|||
struct CAnchorsOrchardCacheEntry
|
||||
{
|
||||
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;
|
||||
|
||||
enum Flags {
|
||||
|
@ -368,7 +368,7 @@ public:
|
|||
virtual bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
||||
|
||||
//! 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
|
||||
virtual bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
||||
|
@ -428,7 +428,7 @@ public:
|
|||
CCoinsViewBacked(CCoinsView *viewIn);
|
||||
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &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 GetCoins(const uint256 &txid, CCoins &coins) const;
|
||||
bool HaveCoins(const uint256 &txid) const;
|
||||
|
@ -521,7 +521,7 @@ public:
|
|||
// Standard CCoinsView methods
|
||||
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &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 GetCoins(const uint256 &txid, CCoins &coins) const;
|
||||
bool HaveCoins(const uint256 &txid) const;
|
||||
|
|
|
@ -293,13 +293,13 @@ TEST(orchardMerkleTree, emptyroot) {
|
|||
// an integer, which is converted to little-endian internally.
|
||||
uint256 expected = uint256S("2fd8e51a03d9bbe2dd809831b1497aeb68a6e37ddf707ced4aa2d8dff13529ae");
|
||||
|
||||
ASSERT_EQ(OrchardMerkleTree::empty_root(), expected);
|
||||
ASSERT_EQ(OrchardMerkleFrontier::empty_root(), expected);
|
||||
}
|
||||
|
||||
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++) {
|
||||
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;
|
||||
assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree));
|
||||
|
||||
OrchardMerkleTree orchard_tree;
|
||||
OrchardMerkleFrontier orchard_tree;
|
||||
assert(view.GetOrchardAnchorAt(view.GetBestAnchor(ORCHARD), orchard_tree));
|
||||
|
||||
// Grab the consensus branch ID for this block and its parent
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <amount.h>
|
||||
#include <rust/orchard.h>
|
||||
|
||||
class OrchardMerkleTree;
|
||||
class OrchardMerkleFrontier;
|
||||
|
||||
/**
|
||||
* The Orchard component of a transaction.
|
||||
|
@ -22,7 +22,7 @@ private:
|
|||
/// Memory is allocated by Rust.
|
||||
std::unique_ptr<OrchardBundlePtr, decltype(&orchard_bundle_free)> inner;
|
||||
|
||||
friend class OrchardMerkleTree;
|
||||
friend class OrchardMerkleFrontier;
|
||||
public:
|
||||
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::{
|
||||
bridgetree::{self, BridgeTree},
|
||||
Altitude, Frontier, Hashable, Tree,
|
||||
};
|
||||
use incrementalmerkletree::{bridgetree, Altitude, Frontier, Hashable};
|
||||
use std::mem::size_of_val;
|
||||
use std::ptr;
|
||||
|
||||
use orchard::{bundle::Authorized, tree::MerkleHashOrchard};
|
||||
use tracing::error;
|
||||
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,
|
||||
};
|
||||
|
||||
use crate::streams_ffi::{CppStreamReader, CppStreamWriter, ReadCb, StreamObj, WriteCb};
|
||||
|
||||
pub const MERKLE_DEPTH: u8 = 32;
|
||||
pub const MAX_CHECKPOINTS: usize = 100;
|
||||
|
||||
//
|
||||
// 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()
|
||||
}
|
||||
|
||||
//
|
||||
// Operations on incremental merkle trees with interstitial
|
||||
// witnesses.
|
||||
//
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn incremental_sinsemilla_tree_empty(
|
||||
) -> *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]) {
|
||||
pub extern "C" fn orchard_merkle_tree_empty_root(root_ret: *mut [u8; 32]) {
|
||||
let root_ret = unsafe {
|
||||
root_ret
|
||||
.as_mut()
|
|
@ -70,7 +70,7 @@ mod tracing_ffi;
|
|||
|
||||
mod address_ffi;
|
||||
mod history_ffi;
|
||||
mod incremental_sinsemilla_tree_ffi;
|
||||
mod incremental_merkle_tree_ffi;
|
||||
mod orchard_ffi;
|
||||
mod transaction_ffi;
|
||||
mod zip339_ffi;
|
||||
|
|
|
@ -32,7 +32,7 @@ class CCoinsViewTest : public CCoinsView
|
|||
std::map<uint256, CCoins> map_;
|
||||
std::map<uint256, SproutMerkleTree> mapSproutAnchors_;
|
||||
std::map<uint256, SaplingMerkleTree> mapSaplingAnchors_;
|
||||
std::map<uint256, OrchardMerkleTree> mapOrchardAnchors_;
|
||||
std::map<uint256, OrchardMerkleFrontier> mapOrchardAnchors_;
|
||||
std::map<uint256, bool> mapSproutNullifiers_;
|
||||
std::map<uint256, bool> mapSaplingNullifiers_;
|
||||
std::map<uint256, bool> mapOrchardNullifiers_;
|
||||
|
@ -41,7 +41,7 @@ public:
|
|||
CCoinsViewTest() {
|
||||
hashBestSproutAnchor_ = SproutMerkleTree::empty_root();
|
||||
hashBestSaplingAnchor_ = SaplingMerkleTree::empty_root();
|
||||
hashBestOrchardAnchor_ = OrchardMerkleTree::empty_root();
|
||||
hashBestOrchardAnchor_ = OrchardMerkleFrontier::empty_root();
|
||||
}
|
||||
|
||||
bool GetSproutAnchorAt(const uint256& rt, SproutMerkleTree &tree) const {
|
||||
|
@ -76,14 +76,14 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
bool GetOrchardAnchorAt(const uint256& rt, OrchardMerkleTree &tree) const {
|
||||
if (rt == OrchardMerkleTree::empty_root()) {
|
||||
OrchardMerkleTree new_tree;
|
||||
bool GetOrchardAnchorAt(const uint256& rt, OrchardMerkleFrontier &tree) const {
|
||||
if (rt == OrchardMerkleFrontier::empty_root()) {
|
||||
OrchardMerkleFrontier new_tree;
|
||||
tree = new_tree;
|
||||
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()) {
|
||||
return false;
|
||||
} else {
|
||||
|
@ -217,7 +217,7 @@ public:
|
|||
|
||||
BatchWriteAnchors<SproutMerkleTree, CAnchorsSproutMap, CAnchorsSproutCacheEntry>(mapSproutAnchors, mapSproutAnchors_);
|
||||
BatchWriteAnchors<SaplingMerkleTree, CAnchorsSaplingMap, CAnchorsSaplingCacheEntry>(mapSaplingAnchors, mapSaplingAnchors_);
|
||||
BatchWriteAnchors<OrchardMerkleTree, CAnchorsOrchardMap, CAnchorsOrchardCacheEntry>(mapOrchardAnchors, mapOrchardAnchors_);
|
||||
BatchWriteAnchors<OrchardMerkleFrontier, CAnchorsOrchardMap, CAnchorsOrchardCacheEntry>(mapOrchardAnchors, mapOrchardAnchors_);
|
||||
|
||||
BatchWriteNullifiers(mapSproutNullifiers, mapSproutNullifiers_);
|
||||
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;
|
||||
}
|
||||
|
||||
bool CCoinsViewDB::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const {
|
||||
if (rt == OrchardMerkleTree::empty_root()) {
|
||||
OrchardMerkleTree new_tree;
|
||||
bool CCoinsViewDB::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const {
|
||||
if (rt == OrchardMerkleFrontier::empty_root()) {
|
||||
OrchardMerkleFrontier new_tree;
|
||||
tree = new_tree;
|
||||
return true;
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ uint256 CCoinsViewDB::GetBestAnchor(ShieldedType type) const {
|
|||
break;
|
||||
case ORCHARD:
|
||||
if (!db.Read(DB_BEST_ORCHARD_ANCHOR, hashBestAnchor))
|
||||
return OrchardMerkleTree::empty_root();
|
||||
return OrchardMerkleFrontier::empty_root();
|
||||
break;
|
||||
default:
|
||||
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<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, mapSaplingNullifiers, DB_SAPLING_NULLIFIER);
|
||||
|
|
|
@ -83,7 +83,7 @@ public:
|
|||
|
||||
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &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 GetCoins(const uint256 &txid, CCoins &coins) const;
|
||||
bool HaveCoins(const uint256 &txid) const;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "zcash/util.h"
|
||||
|
||||
#include <primitives/orchard.h>
|
||||
#include <rust/orchard/incremental_sinsemilla_tree.h>
|
||||
#include <rust/orchard/incremental_merkle_tree.h>
|
||||
|
||||
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<INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, libzcash::PedersenHash> SaplingTestingWitness;
|
||||
|
||||
class OrchardMerkleTree
|
||||
class OrchardMerkleFrontier
|
||||
{
|
||||
private:
|
||||
/// An incremental Sinsemilla tree; this pointer may never be null.
|
||||
/// Memory is allocated by Rust.
|
||||
std::unique_ptr<OrchardMerkleFrontierPtr, decltype(&orchard_merkle_frontier_free)> inner;
|
||||
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) {}
|
||||
|
||||
OrchardMerkleTree& operator=(OrchardMerkleTree&& frontier)
|
||||
OrchardMerkleFrontier& operator=(OrchardMerkleFrontier&& frontier)
|
||||
{
|
||||
if (this != &frontier) {
|
||||
inner = std::move(frontier.inner);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
OrchardMerkleTree& operator=(const OrchardMerkleTree& frontier)
|
||||
OrchardMerkleFrontier& operator=(const OrchardMerkleFrontier& frontier)
|
||||
{
|
||||
if (this != &frontier) {
|
||||
inner.reset(orchard_merkle_frontier_clone(frontier.inner.get()));
|
||||
|
@ -323,7 +323,7 @@ public:
|
|||
|
||||
static uint256 empty_root() {
|
||||
uint256 value;
|
||||
incremental_sinsemilla_tree_empty_root(value.begin());
|
||||
orchard_merkle_tree_empty_root(value.begin());
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -448,7 +448,7 @@ class FakeCoinsViewDB : public CCoinsView {
|
|||
uint256 hash;
|
||||
SproutMerkleTree sproutTree;
|
||||
SaplingMerkleTree saplingTree;
|
||||
OrchardMerkleTree orchardTree;
|
||||
OrchardMerkleFrontier orchardTree;
|
||||
|
||||
public:
|
||||
FakeCoinsViewDB(std::string dbName, uint256& hash) : db(GetDataDir() / dbName, 100, false, false), hash(hash) {}
|
||||
|
@ -469,7 +469,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleTree &tree) const {
|
||||
bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const {
|
||||
if (rt == orchardTree.root()) {
|
||||
tree = orchardTree;
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue