Integrate new incremental merkle tree implementation into consensus.
This commit is contained in:
parent
e1ff849d8d
commit
434f328446
|
@ -40,7 +40,7 @@ bool CCoins::Spend(uint32_t nPos)
|
||||||
Cleanup();
|
Cleanup();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool CCoinsView::GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMerkleTree &tree) const { return false; }
|
bool CCoinsView::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { return false; }
|
||||||
bool CCoinsView::GetSerial(const uint256 &serial) const { return false; }
|
bool CCoinsView::GetSerial(const uint256 &serial) 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; }
|
||||||
|
@ -56,7 +56,7 @@ bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; }
|
||||||
|
|
||||||
CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { }
|
CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { }
|
||||||
|
|
||||||
bool CCoinsViewBacked::GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMerkleTree &tree) const { return base->GetAnchorAt(rt, tree); }
|
bool CCoinsViewBacked::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { return base->GetAnchorAt(rt, tree); }
|
||||||
bool CCoinsViewBacked::GetSerial(const uint256 &serial) const { return base->GetSerial(serial); }
|
bool CCoinsViewBacked::GetSerial(const uint256 &serial) const { return base->GetSerial(serial); }
|
||||||
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); }
|
||||||
|
@ -102,11 +102,11 @@ CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CCoinsViewCache::GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMerkleTree &tree) const {
|
bool CCoinsViewCache::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const {
|
||||||
CAnchorsMap::const_iterator it = cacheAnchors.find(rt);
|
CAnchorsMap::const_iterator it = cacheAnchors.find(rt);
|
||||||
if (it != cacheAnchors.end()) {
|
if (it != cacheAnchors.end()) {
|
||||||
if (it->second.entered) {
|
if (it->second.entered) {
|
||||||
tree.setTo(it->second.tree);
|
tree = it->second.tree;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -119,7 +119,7 @@ bool CCoinsViewCache::GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMer
|
||||||
|
|
||||||
CAnchorsMap::iterator ret = cacheAnchors.insert(std::make_pair(rt, CAnchorsCacheEntry())).first;
|
CAnchorsMap::iterator ret = cacheAnchors.insert(std::make_pair(rt, CAnchorsCacheEntry())).first;
|
||||||
ret->second.entered = true;
|
ret->second.entered = true;
|
||||||
ret->second.tree.setTo(tree);
|
ret->second.tree = tree;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -140,10 +140,8 @@ bool CCoinsViewCache::GetSerial(const uint256 &serial) const {
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCoinsViewCache::PushAnchor(const libzerocash::IncrementalMerkleTree &tree) {
|
void CCoinsViewCache::PushAnchor(const ZCIncrementalMerkleTree &tree) {
|
||||||
std::vector<unsigned char> newrt_v(32);
|
uint256 newrt = tree.root();
|
||||||
tree.getRootValue(newrt_v);
|
|
||||||
uint256 newrt(newrt_v);
|
|
||||||
|
|
||||||
auto currentRoot = GetBestAnchor();
|
auto currentRoot = GetBestAnchor();
|
||||||
|
|
||||||
|
@ -156,7 +154,7 @@ void CCoinsViewCache::PushAnchor(const libzerocash::IncrementalMerkleTree &tree)
|
||||||
CAnchorsMap::iterator ret = cacheAnchors.insert(std::make_pair(newrt, CAnchorsCacheEntry())).first;
|
CAnchorsMap::iterator ret = cacheAnchors.insert(std::make_pair(newrt, CAnchorsCacheEntry())).first;
|
||||||
|
|
||||||
ret->second.entered = true;
|
ret->second.entered = true;
|
||||||
ret->second.tree.setTo(tree);
|
ret->second.tree = tree;
|
||||||
ret->second.flags = CAnchorsCacheEntry::DIRTY;
|
ret->second.flags = CAnchorsCacheEntry::DIRTY;
|
||||||
|
|
||||||
hashAnchor = newrt;
|
hashAnchor = newrt;
|
||||||
|
@ -302,7 +300,7 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins,
|
||||||
|
|
||||||
CAnchorsCacheEntry& entry = cacheAnchors[child_it->first];
|
CAnchorsCacheEntry& entry = cacheAnchors[child_it->first];
|
||||||
entry.entered = true;
|
entry.entered = true;
|
||||||
entry.tree.setTo(child_it->second.tree);
|
entry.tree = child_it->second.tree;
|
||||||
entry.flags = CAnchorsCacheEntry::DIRTY;
|
entry.flags = CAnchorsCacheEntry::DIRTY;
|
||||||
|
|
||||||
// TODO: cache usage
|
// TODO: cache usage
|
||||||
|
@ -399,7 +397,7 @@ bool CCoinsViewCache::HavePourRequirements(const CTransaction& tx) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
libzerocash::IncrementalMerkleTree tree(INCREMENTAL_MERKLE_TREE_DEPTH);
|
ZCIncrementalMerkleTree tree;
|
||||||
if (!GetAnchorAt(pour.anchor, tree)) {
|
if (!GetAnchorAt(pour.anchor, tree)) {
|
||||||
// If we do not have the anchor for the pour,
|
// If we do not have the anchor for the pour,
|
||||||
// it is invalid.
|
// it is invalid.
|
||||||
|
|
12
src/coins.h
12
src/coins.h
|
@ -300,14 +300,14 @@ struct CCoinsCacheEntry
|
||||||
struct CAnchorsCacheEntry
|
struct CAnchorsCacheEntry
|
||||||
{
|
{
|
||||||
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
|
||||||
libzerocash::IncrementalMerkleTree tree; // The tree itself
|
ZCIncrementalMerkleTree tree; // The tree itself
|
||||||
unsigned char flags;
|
unsigned char flags;
|
||||||
|
|
||||||
enum Flags {
|
enum Flags {
|
||||||
DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view.
|
DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view.
|
||||||
};
|
};
|
||||||
|
|
||||||
CAnchorsCacheEntry() : entered(false), flags(0), tree(INCREMENTAL_MERKLE_TREE_DEPTH) {}
|
CAnchorsCacheEntry() : entered(false), flags(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CSerialsCacheEntry
|
struct CSerialsCacheEntry
|
||||||
|
@ -345,7 +345,7 @@ class CCoinsView
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//! Retrieve the tree at a particular anchored root in the chain
|
//! Retrieve the tree at a particular anchored root in the chain
|
||||||
virtual bool GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMerkleTree &tree) const;
|
virtual bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const;
|
||||||
|
|
||||||
//! Determine whether a serial is spent or not
|
//! Determine whether a serial is spent or not
|
||||||
virtual bool GetSerial(const uint256 &serial) const;
|
virtual bool GetSerial(const uint256 &serial) const;
|
||||||
|
@ -387,7 +387,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CCoinsViewBacked(CCoinsView *viewIn);
|
CCoinsViewBacked(CCoinsView *viewIn);
|
||||||
bool GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMerkleTree &tree) const;
|
bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const;
|
||||||
bool GetSerial(const uint256 &serial) const;
|
bool GetSerial(const uint256 &serial) 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;
|
||||||
|
@ -451,7 +451,7 @@ public:
|
||||||
~CCoinsViewCache();
|
~CCoinsViewCache();
|
||||||
|
|
||||||
// Standard CCoinsView methods
|
// Standard CCoinsView methods
|
||||||
bool GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMerkleTree &tree) const;
|
bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const;
|
||||||
bool GetSerial(const uint256 &serial) const;
|
bool GetSerial(const uint256 &serial) 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;
|
||||||
|
@ -467,7 +467,7 @@ public:
|
||||||
|
|
||||||
// Adds the tree to mapAnchors and sets the current commitment
|
// Adds the tree to mapAnchors and sets the current commitment
|
||||||
// root to this root.
|
// root to this root.
|
||||||
void PushAnchor(const libzerocash::IncrementalMerkleTree &tree);
|
void PushAnchor(const ZCIncrementalMerkleTree &tree);
|
||||||
|
|
||||||
// Removes the current commitment root from mapAnchors and sets
|
// Removes the current commitment root from mapAnchors and sets
|
||||||
// the new current root.
|
// the new current root.
|
||||||
|
|
15
src/main.cpp
15
src/main.cpp
|
@ -2013,7 +2013,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||||
// Construct the incremental merkle tree at the current
|
// Construct the incremental merkle tree at the current
|
||||||
// block position,
|
// block position,
|
||||||
auto old_tree_root = view.GetBestAnchor();
|
auto old_tree_root = view.GetBestAnchor();
|
||||||
libzerocash::IncrementalMerkleTree tree(INCREMENTAL_MERKLE_TREE_DEPTH);
|
ZCIncrementalMerkleTree tree;
|
||||||
// This should never fail: we should always be able to get the root
|
// This should never fail: we should always be able to get the root
|
||||||
// that is on the tip of our chain
|
// that is on the tip of our chain
|
||||||
assert(view.GetAnchorAt(old_tree_root, tree));
|
assert(view.GetAnchorAt(old_tree_root, tree));
|
||||||
|
@ -2021,11 +2021,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||||
{
|
{
|
||||||
// Consistency check: the root of the tree we're given should
|
// Consistency check: the root of the tree we're given should
|
||||||
// match what we asked for.
|
// match what we asked for.
|
||||||
std::vector<unsigned char> newrt_v(32);
|
assert(tree.root() == old_tree_root);
|
||||||
tree.getRootValue(newrt_v);
|
|
||||||
uint256 anchor_received = uint256(newrt_v);
|
|
||||||
|
|
||||||
assert(anchor_received == old_tree_root);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < block.vtx.size(); i++)
|
for (unsigned int i = 0; i < block.vtx.size(); i++)
|
||||||
|
@ -2078,11 +2074,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||||
BOOST_FOREACH(const uint256 &bucket_commitment, pour.commitments) {
|
BOOST_FOREACH(const uint256 &bucket_commitment, pour.commitments) {
|
||||||
// Insert the bucket commitments into our temporary tree.
|
// Insert the bucket commitments into our temporary tree.
|
||||||
|
|
||||||
std::vector<bool> index;
|
tree.append(bucket_commitment);
|
||||||
std::vector<unsigned char> commitment_value(bucket_commitment.begin(), bucket_commitment.end());
|
|
||||||
std::vector<bool> commitment_bv(ZC_CM_SIZE * 8);
|
|
||||||
libzerocash::convertBytesVectorToVector(commitment_value, commitment_bv);
|
|
||||||
tree.insertElement(commitment_bv, index);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2090,7 +2082,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||||
pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
|
pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
tree.prune(); // prune it, so we don't cache intermediate states we don't need
|
|
||||||
view.PushAnchor(tree);
|
view.PushAnchor(tree);
|
||||||
blockundo.old_tree_root = old_tree_root;
|
blockundo.old_tree_root = old_tree_root;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include "zerocash/IncrementalMerkleTree.h"
|
#include "zcash/IncrementalMerkleTree.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -20,22 +20,22 @@ class CCoinsViewTest : public CCoinsView
|
||||||
uint256 hashBestBlock_;
|
uint256 hashBestBlock_;
|
||||||
uint256 hashBestAnchor_;
|
uint256 hashBestAnchor_;
|
||||||
std::map<uint256, CCoins> map_;
|
std::map<uint256, CCoins> map_;
|
||||||
std::map<uint256, libzerocash::IncrementalMerkleTree> mapAnchors_;
|
std::map<uint256, ZCIncrementalMerkleTree> mapAnchors_;
|
||||||
std::map<uint256, bool> mapSerials_;
|
std::map<uint256, bool> mapSerials_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool GetAnchorAt(const uint256& rt, libzerocash::IncrementalMerkleTree &tree) const {
|
bool GetAnchorAt(const uint256& rt, ZCIncrementalMerkleTree &tree) const {
|
||||||
if (rt.IsNull()) {
|
if (rt.IsNull()) {
|
||||||
IncrementalMerkleTree new_tree(INCREMENTAL_MERKLE_TREE_DEPTH);
|
ZCIncrementalMerkleTree new_tree;
|
||||||
tree.setTo(new_tree);
|
tree = new_tree;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<uint256, libzerocash::IncrementalMerkleTree>::const_iterator it = mapAnchors_.find(rt);
|
std::map<uint256, ZCIncrementalMerkleTree>::const_iterator it = mapAnchors_.find(rt);
|
||||||
if (it == mapAnchors_.end()) {
|
if (it == mapAnchors_.end()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
tree.setTo(it->second);
|
tree = it->second;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,10 +93,10 @@ public:
|
||||||
}
|
}
|
||||||
for (CAnchorsMap::iterator it = mapAnchors.begin(); it != mapAnchors.end(); ) {
|
for (CAnchorsMap::iterator it = mapAnchors.begin(); it != mapAnchors.end(); ) {
|
||||||
if (it->second.entered) {
|
if (it->second.entered) {
|
||||||
std::map<uint256, libzerocash::IncrementalMerkleTree>::iterator ret =
|
std::map<uint256, ZCIncrementalMerkleTree>::iterator ret =
|
||||||
mapAnchors_.insert(std::make_pair(it->first, IncrementalMerkleTree(INCREMENTAL_MERKLE_TREE_DEPTH))).first;
|
mapAnchors_.insert(std::make_pair(it->first, ZCIncrementalMerkleTree())).first;
|
||||||
|
|
||||||
ret->second.setTo(it->second.tree);
|
ret->second = it->second.tree;
|
||||||
} else {
|
} else {
|
||||||
mapAnchors_.erase(it->first);
|
mapAnchors_.erase(it->first);
|
||||||
}
|
}
|
||||||
|
@ -164,16 +164,12 @@ BOOST_AUTO_TEST_CASE(serials_test)
|
||||||
BOOST_CHECK(!cache3.GetSerial(myserial));
|
BOOST_CHECK(!cache3.GetSerial(myserial));
|
||||||
}
|
}
|
||||||
|
|
||||||
void appendRandomCommitment(IncrementalMerkleTree &tree)
|
void appendRandomCommitment(ZCIncrementalMerkleTree &tree)
|
||||||
{
|
{
|
||||||
Address addr = Address::CreateNewRandomAddress();
|
Address addr = Address::CreateNewRandomAddress();
|
||||||
Coin coin(addr.getPublicAddress(), 100);
|
Coin coin(addr.getPublicAddress(), 100);
|
||||||
|
|
||||||
std::vector<bool> commitment(ZC_CM_SIZE * 8);
|
tree.append(uint256(coin.getCoinCommitment().getCommitmentValue()));
|
||||||
convertBytesVectorToVector(coin.getCoinCommitment().getCommitmentValue(), commitment);
|
|
||||||
|
|
||||||
std::vector<bool> index;
|
|
||||||
tree.insertElement(commitment, index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(anchors_flush_test)
|
BOOST_AUTO_TEST_CASE(anchors_flush_test)
|
||||||
|
@ -182,15 +178,11 @@ BOOST_AUTO_TEST_CASE(anchors_flush_test)
|
||||||
uint256 newrt;
|
uint256 newrt;
|
||||||
{
|
{
|
||||||
CCoinsViewCacheTest cache(&base);
|
CCoinsViewCacheTest cache(&base);
|
||||||
IncrementalMerkleTree tree(INCREMENTAL_MERKLE_TREE_DEPTH);
|
ZCIncrementalMerkleTree tree;
|
||||||
BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree));
|
BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree));
|
||||||
appendRandomCommitment(tree);
|
appendRandomCommitment(tree);
|
||||||
|
|
||||||
{
|
newrt = tree.root();
|
||||||
std::vector<unsigned char> newrt_v(32);
|
|
||||||
tree.getRootValue(newrt_v);
|
|
||||||
newrt = uint256(newrt_v);
|
|
||||||
}
|
|
||||||
|
|
||||||
cache.PushAnchor(tree);
|
cache.PushAnchor(tree);
|
||||||
cache.Flush();
|
cache.Flush();
|
||||||
|
@ -198,18 +190,13 @@ BOOST_AUTO_TEST_CASE(anchors_flush_test)
|
||||||
|
|
||||||
{
|
{
|
||||||
CCoinsViewCacheTest cache(&base);
|
CCoinsViewCacheTest cache(&base);
|
||||||
IncrementalMerkleTree tree(INCREMENTAL_MERKLE_TREE_DEPTH);
|
ZCIncrementalMerkleTree tree;
|
||||||
BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree));
|
BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree));
|
||||||
|
|
||||||
// Get the cached entry.
|
// Get the cached entry.
|
||||||
BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree));
|
BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree));
|
||||||
|
|
||||||
uint256 check_rt;
|
uint256 check_rt = tree.root();
|
||||||
{
|
|
||||||
std::vector<unsigned char> newrt_v(32);
|
|
||||||
tree.getRootValue(newrt_v);
|
|
||||||
check_rt = uint256(newrt_v);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_CHECK(check_rt == newrt);
|
BOOST_CHECK(check_rt == newrt);
|
||||||
}
|
}
|
||||||
|
@ -226,7 +213,7 @@ BOOST_AUTO_TEST_CASE(anchors_test)
|
||||||
BOOST_CHECK(cache.GetBestAnchor() == uint256());
|
BOOST_CHECK(cache.GetBestAnchor() == uint256());
|
||||||
|
|
||||||
{
|
{
|
||||||
IncrementalMerkleTree tree(INCREMENTAL_MERKLE_TREE_DEPTH);
|
ZCIncrementalMerkleTree tree;
|
||||||
|
|
||||||
BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree));
|
BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree));
|
||||||
appendRandomCommitment(tree);
|
appendRandomCommitment(tree);
|
||||||
|
@ -236,96 +223,50 @@ BOOST_AUTO_TEST_CASE(anchors_test)
|
||||||
appendRandomCommitment(tree);
|
appendRandomCommitment(tree);
|
||||||
appendRandomCommitment(tree);
|
appendRandomCommitment(tree);
|
||||||
appendRandomCommitment(tree);
|
appendRandomCommitment(tree);
|
||||||
tree.prune();
|
|
||||||
|
|
||||||
IncrementalMerkleTree save_tree_for_later(INCREMENTAL_MERKLE_TREE_DEPTH);
|
ZCIncrementalMerkleTree save_tree_for_later;
|
||||||
save_tree_for_later.setTo(tree);
|
save_tree_for_later = tree;
|
||||||
|
|
||||||
uint256 newrt;
|
uint256 newrt = tree.root();
|
||||||
uint256 newrt2;
|
uint256 newrt2;
|
||||||
{
|
|
||||||
std::vector<unsigned char> newrt_v(32);
|
|
||||||
tree.getRootValue(newrt_v);
|
|
||||||
|
|
||||||
newrt = uint256(newrt_v);
|
|
||||||
}
|
|
||||||
|
|
||||||
cache.PushAnchor(tree);
|
cache.PushAnchor(tree);
|
||||||
BOOST_CHECK(cache.GetBestAnchor() == newrt);
|
BOOST_CHECK(cache.GetBestAnchor() == newrt);
|
||||||
|
|
||||||
{
|
{
|
||||||
IncrementalMerkleTree confirm_same(INCREMENTAL_MERKLE_TREE_DEPTH);
|
ZCIncrementalMerkleTree confirm_same;
|
||||||
BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), confirm_same));
|
BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), confirm_same));
|
||||||
|
|
||||||
uint256 confirm_rt;
|
BOOST_CHECK(confirm_same.root() == newrt);
|
||||||
{
|
|
||||||
std::vector<unsigned char> newrt_v(32);
|
|
||||||
confirm_same.getRootValue(newrt_v);
|
|
||||||
|
|
||||||
confirm_rt = uint256(newrt_v);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_CHECK(confirm_rt == newrt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
appendRandomCommitment(tree);
|
appendRandomCommitment(tree);
|
||||||
appendRandomCommitment(tree);
|
appendRandomCommitment(tree);
|
||||||
tree.prune();
|
|
||||||
|
|
||||||
{
|
newrt2 = tree.root();
|
||||||
std::vector<unsigned char> newrt_v(32);
|
|
||||||
tree.getRootValue(newrt_v);
|
|
||||||
|
|
||||||
newrt2 = uint256(newrt_v);
|
|
||||||
}
|
|
||||||
|
|
||||||
cache.PushAnchor(tree);
|
cache.PushAnchor(tree);
|
||||||
BOOST_CHECK(cache.GetBestAnchor() == newrt2);
|
BOOST_CHECK(cache.GetBestAnchor() == newrt2);
|
||||||
|
|
||||||
IncrementalMerkleTree test_tree(INCREMENTAL_MERKLE_TREE_DEPTH);
|
ZCIncrementalMerkleTree test_tree;
|
||||||
BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), test_tree));
|
BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), test_tree));
|
||||||
|
|
||||||
{
|
BOOST_CHECK(tree.root() == test_tree.root());
|
||||||
std::vector<unsigned char> a(32);
|
|
||||||
std::vector<unsigned char> b(32);
|
|
||||||
tree.getRootValue(a);
|
|
||||||
test_tree.getRootValue(b);
|
|
||||||
|
|
||||||
BOOST_CHECK(a == b);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> a(32);
|
ZCIncrementalMerkleTree test_tree2;
|
||||||
std::vector<unsigned char> b(32);
|
|
||||||
IncrementalMerkleTree test_tree2(INCREMENTAL_MERKLE_TREE_DEPTH);
|
|
||||||
cache.GetAnchorAt(newrt, test_tree2);
|
cache.GetAnchorAt(newrt, test_tree2);
|
||||||
|
|
||||||
uint256 recovered_rt;
|
BOOST_CHECK(test_tree2.root() == newrt);
|
||||||
{
|
|
||||||
std::vector<unsigned char> newrt_v(32);
|
|
||||||
test_tree2.getRootValue(newrt_v);
|
|
||||||
|
|
||||||
recovered_rt = uint256(newrt_v);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_CHECK(recovered_rt == newrt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
cache.PopAnchor(newrt);
|
cache.PopAnchor(newrt);
|
||||||
IncrementalMerkleTree obtain_tree(INCREMENTAL_MERKLE_TREE_DEPTH);
|
ZCIncrementalMerkleTree obtain_tree;
|
||||||
assert(!cache.GetAnchorAt(newrt2, obtain_tree)); // should have been popped off
|
assert(!cache.GetAnchorAt(newrt2, obtain_tree)); // should have been popped off
|
||||||
assert(cache.GetAnchorAt(newrt, obtain_tree));
|
assert(cache.GetAnchorAt(newrt, obtain_tree));
|
||||||
|
|
||||||
uint256 recovered_rt;
|
assert(obtain_tree.root() == newrt);
|
||||||
{
|
|
||||||
std::vector<unsigned char> newrt_v(32);
|
|
||||||
obtain_tree.getRootValue(newrt_v);
|
|
||||||
|
|
||||||
recovered_rt = uint256(newrt_v);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(recovered_rt == newrt);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
src/txdb.cpp
22
src/txdb.cpp
|
@ -33,13 +33,13 @@ static const char DB_LAST_BLOCK = 'l';
|
||||||
|
|
||||||
void static BatchWriteAnchor(CLevelDBBatch &batch,
|
void static BatchWriteAnchor(CLevelDBBatch &batch,
|
||||||
const uint256 &croot,
|
const uint256 &croot,
|
||||||
const libzerocash::IncrementalMerkleTree &tree,
|
const ZCIncrementalMerkleTree &tree,
|
||||||
const bool &entered)
|
const bool &entered)
|
||||||
{
|
{
|
||||||
if (!entered)
|
if (!entered)
|
||||||
batch.Erase(make_pair(DB_ANCHOR, croot));
|
batch.Erase(make_pair(DB_ANCHOR, croot));
|
||||||
else {
|
else {
|
||||||
batch.Write(make_pair(DB_ANCHOR, croot), tree.serialize());
|
batch.Write(make_pair(DB_ANCHOR, croot), tree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,24 +69,16 @@ CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(Get
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CCoinsViewDB::GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMerkleTree &tree) const {
|
bool CCoinsViewDB::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const {
|
||||||
if (rt.IsNull()) {
|
if (rt.IsNull()) {
|
||||||
IncrementalMerkleTree new_tree(INCREMENTAL_MERKLE_TREE_DEPTH);
|
ZCIncrementalMerkleTree new_tree;
|
||||||
tree.setTo(new_tree);
|
tree = new_tree;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<unsigned char> tree_serialized;
|
bool read = db.Read(make_pair(DB_ANCHOR, rt), tree);
|
||||||
|
|
||||||
bool read = db.Read(make_pair(DB_ANCHOR, rt), tree_serialized);
|
return read;
|
||||||
|
|
||||||
if (!read) return read;
|
|
||||||
|
|
||||||
auto tree_deserialized = IncrementalMerkleTreeCompact::deserialize(tree_serialized);
|
|
||||||
|
|
||||||
tree.fromCompactRepresentation(tree_deserialized);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCoinsViewDB::GetSerial(const uint256 &serial) const {
|
bool CCoinsViewDB::GetSerial(const uint256 &serial) const {
|
||||||
|
|
|
@ -36,7 +36,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false);
|
CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false);
|
||||||
|
|
||||||
bool GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMerkleTree &tree) const;
|
bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const;
|
||||||
bool GetSerial(const uint256 &serial) const;
|
bool GetSerial(const uint256 &serial) 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;
|
||||||
|
|
|
@ -320,7 +320,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: chained pours
|
// TODO: chained pours
|
||||||
libzerocash::IncrementalMerkleTree tree(INCREMENTAL_MERKLE_TREE_DEPTH);
|
ZCIncrementalMerkleTree tree;
|
||||||
assert(pcoins->GetAnchorAt(pour.anchor, tree));
|
assert(pcoins->GetAnchorAt(pour.anchor, tree));
|
||||||
}
|
}
|
||||||
if (fDependsWait)
|
if (fDependsWait)
|
||||||
|
|
|
@ -1096,7 +1096,7 @@ bool CWallet::WitnessBucketCommitment(uint256 &commitment,
|
||||||
|
|
||||||
// Consistency check: we should be able to find the current tree
|
// Consistency check: we should be able to find the current tree
|
||||||
// in our CCoins view.
|
// in our CCoins view.
|
||||||
libzerocash::IncrementalMerkleTree dummy_tree(INCREMENTAL_MERKLE_TREE_DEPTH);
|
ZCIncrementalMerkleTree dummy_tree;
|
||||||
assert(pcoinsTip->GetAnchorAt(current_anchor, dummy_tree));
|
assert(pcoinsTip->GetAnchorAt(current_anchor, dummy_tree));
|
||||||
|
|
||||||
pindex = chainActive.Next(pindex);
|
pindex = chainActive.Next(pindex);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include "zerocash/IncrementalMerkleTree.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include "zerocash/ZerocashParams.h"
|
#include "zerocash/ZerocashParams.h"
|
||||||
|
|
Loading…
Reference in New Issue