Auto merge of #3258 - Eirik0:3056-anchor-test-cases, r=str4d
Add tests for sapling anchors Closes #3253
This commit is contained in:
@@ -222,7 +222,8 @@ void CCoinsViewCache::AbstractPushAnchor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCoinsViewCache::PushSproutAnchor(const ZCIncrementalMerkleTree &tree) {
|
template<> void CCoinsViewCache::PushAnchor(const ZCIncrementalMerkleTree &tree)
|
||||||
|
{
|
||||||
AbstractPushAnchor<ZCIncrementalMerkleTree, CAnchorsSproutMap, CAnchorsSproutMap::iterator, CAnchorsSproutCacheEntry>(
|
AbstractPushAnchor<ZCIncrementalMerkleTree, CAnchorsSproutMap, CAnchorsSproutMap::iterator, CAnchorsSproutCacheEntry>(
|
||||||
tree,
|
tree,
|
||||||
SPROUT,
|
SPROUT,
|
||||||
@@ -231,7 +232,8 @@ void CCoinsViewCache::PushSproutAnchor(const ZCIncrementalMerkleTree &tree) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCoinsViewCache::PushSaplingAnchor(const ZCSaplingIncrementalMerkleTree &tree) {
|
template<> void CCoinsViewCache::PushAnchor(const ZCSaplingIncrementalMerkleTree &tree)
|
||||||
|
{
|
||||||
AbstractPushAnchor<ZCSaplingIncrementalMerkleTree, CAnchorsSaplingMap, CAnchorsSaplingMap::iterator, CAnchorsSaplingCacheEntry>(
|
AbstractPushAnchor<ZCSaplingIncrementalMerkleTree, CAnchorsSaplingMap, CAnchorsSaplingMap::iterator, CAnchorsSaplingCacheEntry>(
|
||||||
tree,
|
tree,
|
||||||
SAPLING,
|
SAPLING,
|
||||||
|
|||||||
10
src/coins.h
10
src/coins.h
@@ -478,13 +478,9 @@ public:
|
|||||||
CNullifiersMap &mapSaplingNullifiers);
|
CNullifiersMap &mapSaplingNullifiers);
|
||||||
|
|
||||||
|
|
||||||
// Adds the tree to mapSproutAnchors and sets the current commitment
|
// Adds the tree to mapSproutAnchors (or mapSaplingAnchors based on the type of tree)
|
||||||
// root to this root.
|
// and sets the current commitment root to this root.
|
||||||
void PushSproutAnchor(const ZCIncrementalMerkleTree &tree);
|
template<typename Tree> void PushAnchor(const Tree &tree);
|
||||||
|
|
||||||
// Adds the tree to mapSaplingAnchors and sets the current commitment
|
|
||||||
// root to this root.
|
|
||||||
void PushSaplingAnchor(const ZCSaplingIncrementalMerkleTree &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.
|
||||||
|
|||||||
@@ -2514,8 +2514,8 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
view.PushSproutAnchor(sprout_tree);
|
view.PushAnchor(sprout_tree);
|
||||||
view.PushSaplingAnchor(sapling_tree);
|
view.PushAnchor(sapling_tree);
|
||||||
if (!fJustCheck) {
|
if (!fJustCheck) {
|
||||||
pindex->hashFinalSproutRoot = sprout_tree.root();
|
pindex->hashFinalSproutRoot = sprout_tree.root();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,6 +142,20 @@ public:
|
|||||||
mapNullifiers.clear();
|
mapNullifiers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Tree, typename Map>
|
||||||
|
void BatchWriteAnchors(Map& mapAnchors, std::map<uint256, Tree>& cacheAnchors)
|
||||||
|
{
|
||||||
|
for (auto it = mapAnchors.begin(); it != mapAnchors.end(); ) {
|
||||||
|
if (it->second.entered) {
|
||||||
|
auto ret = cacheAnchors.insert(std::make_pair(it->first, Tree())).first;
|
||||||
|
ret->second = it->second.tree;
|
||||||
|
} else {
|
||||||
|
cacheAnchors.erase(it->first);
|
||||||
|
}
|
||||||
|
mapAnchors.erase(it++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool BatchWrite(CCoinsMap& mapCoins,
|
bool BatchWrite(CCoinsMap& mapCoins,
|
||||||
const uint256& hashBlock,
|
const uint256& hashBlock,
|
||||||
const uint256& hashSproutAnchor,
|
const uint256& hashSproutAnchor,
|
||||||
@@ -159,28 +173,9 @@ public:
|
|||||||
}
|
}
|
||||||
mapCoins.erase(it++);
|
mapCoins.erase(it++);
|
||||||
}
|
}
|
||||||
for (CAnchorsSproutMap::iterator it = mapSproutAnchors.begin(); it != mapSproutAnchors.end(); ) {
|
|
||||||
if (it->second.entered) {
|
|
||||||
std::map<uint256, ZCIncrementalMerkleTree>::iterator ret =
|
|
||||||
mapSproutAnchors_.insert(std::make_pair(it->first, ZCIncrementalMerkleTree())).first;
|
|
||||||
|
|
||||||
ret->second = it->second.tree;
|
BatchWriteAnchors<ZCIncrementalMerkleTree, CAnchorsSproutMap>(mapSproutAnchors, mapSproutAnchors_);
|
||||||
} else {
|
BatchWriteAnchors<ZCSaplingIncrementalMerkleTree, CAnchorsSaplingMap>(mapSaplingAnchors, mapSaplingAnchors_);
|
||||||
mapSproutAnchors_.erase(it->first);
|
|
||||||
}
|
|
||||||
mapSproutAnchors.erase(it++);
|
|
||||||
}
|
|
||||||
for (CAnchorsSaplingMap::iterator it = mapSaplingAnchors.begin(); it != mapSaplingAnchors.end(); ) {
|
|
||||||
if (it->second.entered) {
|
|
||||||
std::map<uint256, ZCSaplingIncrementalMerkleTree>::iterator ret =
|
|
||||||
mapSaplingAnchors_.insert(std::make_pair(it->first, ZCSaplingIncrementalMerkleTree())).first;
|
|
||||||
|
|
||||||
ret->second = it->second.tree;
|
|
||||||
} else {
|
|
||||||
mapSaplingAnchors_.erase(it->first);
|
|
||||||
}
|
|
||||||
mapSaplingAnchors.erase(it++);
|
|
||||||
}
|
|
||||||
|
|
||||||
BatchWriteNullifiers(mapSproutNullifiers, mapSproutNullifiers_);
|
BatchWriteNullifiers(mapSproutNullifiers, mapSproutNullifiers_);
|
||||||
BatchWriteNullifiers(mapSaplingNullifiers, mapSaplingNullifiers_);
|
BatchWriteNullifiers(mapSaplingNullifiers, mapSaplingNullifiers_);
|
||||||
@@ -245,7 +240,7 @@ public:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 appendRandomCommitment(ZCIncrementalMerkleTree &tree)
|
uint256 appendRandomSproutCommitment(ZCIncrementalMerkleTree &tree)
|
||||||
{
|
{
|
||||||
libzcash::SproutSpendingKey k = libzcash::SproutSpendingKey::random();
|
libzcash::SproutSpendingKey k = libzcash::SproutSpendingKey::random();
|
||||||
libzcash::SproutPaymentAddress addr = k.address();
|
libzcash::SproutPaymentAddress addr = k.address();
|
||||||
@@ -257,6 +252,10 @@ uint256 appendRandomCommitment(ZCIncrementalMerkleTree &tree)
|
|||||||
return cm;
|
return cm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Tree> bool GetAnchorAt(const CCoinsViewCacheTest &cache, const uint256 &rt, Tree &tree);
|
||||||
|
template<> bool GetAnchorAt(const CCoinsViewCacheTest &cache, const uint256 &rt, ZCIncrementalMerkleTree &tree) { return cache.GetSproutAnchorAt(rt, tree); }
|
||||||
|
template<> bool GetAnchorAt(const CCoinsViewCacheTest &cache, const uint256 &rt, ZCSaplingIncrementalMerkleTree &tree) { return cache.GetSaplingAnchorAt(rt, tree); }
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(coins_tests, BasicTestingSetup)
|
BOOST_FIXTURE_TEST_SUITE(coins_tests, BasicTestingSetup)
|
||||||
|
|
||||||
void checkNullifierCache(const CCoinsViewCacheTest &cache, const TxWithNullifiers &txWithNullifiers, bool shouldBeInCache) {
|
void checkNullifierCache(const CCoinsViewCacheTest &cache, const TxWithNullifiers &txWithNullifiers, bool shouldBeInCache) {
|
||||||
@@ -358,7 +357,7 @@ BOOST_AUTO_TEST_CASE(nullifier_regression_test)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(anchor_pop_regression_test)
|
template<typename Tree> void anchorPopRegressionTestImpl(ShieldedType type)
|
||||||
{
|
{
|
||||||
// Correct behavior:
|
// Correct behavior:
|
||||||
{
|
{
|
||||||
@@ -366,27 +365,26 @@ BOOST_AUTO_TEST_CASE(anchor_pop_regression_test)
|
|||||||
CCoinsViewCacheTest cache1(&base);
|
CCoinsViewCacheTest cache1(&base);
|
||||||
|
|
||||||
// Create dummy anchor/commitment
|
// Create dummy anchor/commitment
|
||||||
ZCIncrementalMerkleTree tree;
|
Tree tree;
|
||||||
uint256 cm = GetRandHash();
|
tree.append(GetRandHash());
|
||||||
tree.append(cm);
|
|
||||||
|
|
||||||
// Add the anchor
|
// Add the anchor
|
||||||
cache1.PushSproutAnchor(tree);
|
cache1.PushAnchor(tree);
|
||||||
cache1.Flush();
|
cache1.Flush();
|
||||||
|
|
||||||
// Remove the anchor
|
// Remove the anchor
|
||||||
cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT);
|
cache1.PopAnchor(Tree::empty_root(), type);
|
||||||
cache1.Flush();
|
cache1.Flush();
|
||||||
|
|
||||||
// Add the anchor back
|
// Add the anchor back
|
||||||
cache1.PushSproutAnchor(tree);
|
cache1.PushAnchor(tree);
|
||||||
cache1.Flush();
|
cache1.Flush();
|
||||||
|
|
||||||
// The base contains the anchor, of course!
|
// The base contains the anchor, of course!
|
||||||
{
|
{
|
||||||
ZCIncrementalMerkleTree checktree;
|
Tree checkTree;
|
||||||
BOOST_CHECK(cache1.GetSproutAnchorAt(tree.root(), checktree));
|
BOOST_CHECK(GetAnchorAt(cache1, tree.root(), checkTree));
|
||||||
BOOST_CHECK(checktree.root() == tree.root());
|
BOOST_CHECK(checkTree.root() == tree.root());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,20 +394,19 @@ BOOST_AUTO_TEST_CASE(anchor_pop_regression_test)
|
|||||||
CCoinsViewCacheTest cache1(&base);
|
CCoinsViewCacheTest cache1(&base);
|
||||||
|
|
||||||
// Create dummy anchor/commitment
|
// Create dummy anchor/commitment
|
||||||
ZCIncrementalMerkleTree tree;
|
Tree tree;
|
||||||
uint256 cm = GetRandHash();
|
tree.append(GetRandHash());
|
||||||
tree.append(cm);
|
|
||||||
|
|
||||||
// Add the anchor and flush to disk
|
// Add the anchor and flush to disk
|
||||||
cache1.PushSproutAnchor(tree);
|
cache1.PushAnchor(tree);
|
||||||
cache1.Flush();
|
cache1.Flush();
|
||||||
|
|
||||||
// Remove the anchor, but don't flush yet!
|
// Remove the anchor, but don't flush yet!
|
||||||
cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT);
|
cache1.PopAnchor(Tree::empty_root(), type);
|
||||||
|
|
||||||
{
|
{
|
||||||
CCoinsViewCacheTest cache2(&cache1); // Build cache on top
|
CCoinsViewCacheTest cache2(&cache1); // Build cache on top
|
||||||
cache2.PushSproutAnchor(tree); // Put the same anchor back!
|
cache2.PushAnchor(tree); // Put the same anchor back!
|
||||||
cache2.Flush(); // Flush to cache1
|
cache2.Flush(); // Flush to cache1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,8 +414,8 @@ BOOST_AUTO_TEST_CASE(anchor_pop_regression_test)
|
|||||||
// tree is there, but it didn't bring down the correct
|
// tree is there, but it didn't bring down the correct
|
||||||
// treestate...
|
// treestate...
|
||||||
{
|
{
|
||||||
ZCIncrementalMerkleTree checktree;
|
Tree checktree;
|
||||||
BOOST_CHECK(cache1.GetSproutAnchorAt(tree.root(), checktree));
|
BOOST_CHECK(GetAnchorAt(cache1, tree.root(), checktree));
|
||||||
BOOST_CHECK(checktree.root() == tree.root()); // Oh, shucks.
|
BOOST_CHECK(checktree.root() == tree.root()); // Oh, shucks.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,14 +423,24 @@ BOOST_AUTO_TEST_CASE(anchor_pop_regression_test)
|
|||||||
// permanent.
|
// permanent.
|
||||||
cache1.Flush();
|
cache1.Flush();
|
||||||
{
|
{
|
||||||
ZCIncrementalMerkleTree checktree;
|
Tree checktree;
|
||||||
BOOST_CHECK(cache1.GetSproutAnchorAt(tree.root(), checktree));
|
BOOST_CHECK(GetAnchorAt(cache1, tree.root(), checktree));
|
||||||
BOOST_CHECK(checktree.root() == tree.root()); // Oh, shucks.
|
BOOST_CHECK(checktree.root() == tree.root()); // Oh, shucks.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(anchor_regression_test)
|
BOOST_AUTO_TEST_CASE(anchor_pop_regression_test)
|
||||||
|
{
|
||||||
|
BOOST_TEST_CONTEXT("Sprout") {
|
||||||
|
anchorPopRegressionTestImpl<ZCIncrementalMerkleTree>(SPROUT);
|
||||||
|
}
|
||||||
|
BOOST_TEST_CONTEXT("Sapling") {
|
||||||
|
anchorPopRegressionTestImpl<ZCSaplingIncrementalMerkleTree>(SAPLING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Tree> void anchorRegressionTestImpl(ShieldedType type)
|
||||||
{
|
{
|
||||||
// Correct behavior:
|
// Correct behavior:
|
||||||
{
|
{
|
||||||
@@ -441,15 +448,15 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test)
|
|||||||
CCoinsViewCacheTest cache1(&base);
|
CCoinsViewCacheTest cache1(&base);
|
||||||
|
|
||||||
// Insert anchor into base.
|
// Insert anchor into base.
|
||||||
ZCIncrementalMerkleTree tree;
|
Tree tree;
|
||||||
uint256 cm = GetRandHash();
|
tree.append(GetRandHash());
|
||||||
tree.append(cm);
|
|
||||||
cache1.PushSproutAnchor(tree);
|
cache1.PushAnchor(tree);
|
||||||
cache1.Flush();
|
cache1.Flush();
|
||||||
|
|
||||||
cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT);
|
cache1.PopAnchor(Tree::empty_root(), type);
|
||||||
BOOST_CHECK(cache1.GetBestAnchor(SPROUT) == ZCIncrementalMerkleTree::empty_root());
|
BOOST_CHECK(cache1.GetBestAnchor(type) == Tree::empty_root());
|
||||||
BOOST_CHECK(!cache1.GetSproutAnchorAt(tree.root(), tree));
|
BOOST_CHECK(!GetAnchorAt(cache1, tree.root(), tree));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also correct behavior:
|
// Also correct behavior:
|
||||||
@@ -458,16 +465,15 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test)
|
|||||||
CCoinsViewCacheTest cache1(&base);
|
CCoinsViewCacheTest cache1(&base);
|
||||||
|
|
||||||
// Insert anchor into base.
|
// Insert anchor into base.
|
||||||
ZCIncrementalMerkleTree tree;
|
Tree tree;
|
||||||
uint256 cm = GetRandHash();
|
tree.append(GetRandHash());
|
||||||
tree.append(cm);
|
cache1.PushAnchor(tree);
|
||||||
cache1.PushSproutAnchor(tree);
|
|
||||||
cache1.Flush();
|
cache1.Flush();
|
||||||
|
|
||||||
cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT);
|
cache1.PopAnchor(Tree::empty_root(), type);
|
||||||
cache1.Flush();
|
cache1.Flush();
|
||||||
BOOST_CHECK(cache1.GetBestAnchor(SPROUT) == ZCIncrementalMerkleTree::empty_root());
|
BOOST_CHECK(cache1.GetBestAnchor(type) == Tree::empty_root());
|
||||||
BOOST_CHECK(!cache1.GetSproutAnchorAt(tree.root(), tree));
|
BOOST_CHECK(!GetAnchorAt(cache1, tree.root(), tree));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Works because we bring the anchor in from parent cache.
|
// Works because we bring the anchor in from parent cache.
|
||||||
@@ -476,22 +482,21 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test)
|
|||||||
CCoinsViewCacheTest cache1(&base);
|
CCoinsViewCacheTest cache1(&base);
|
||||||
|
|
||||||
// Insert anchor into base.
|
// Insert anchor into base.
|
||||||
ZCIncrementalMerkleTree tree;
|
Tree tree;
|
||||||
uint256 cm = GetRandHash();
|
tree.append(GetRandHash());
|
||||||
tree.append(cm);
|
cache1.PushAnchor(tree);
|
||||||
cache1.PushSproutAnchor(tree);
|
|
||||||
cache1.Flush();
|
cache1.Flush();
|
||||||
|
|
||||||
{
|
{
|
||||||
// Pop anchor.
|
// Pop anchor.
|
||||||
CCoinsViewCacheTest cache2(&cache1);
|
CCoinsViewCacheTest cache2(&cache1);
|
||||||
BOOST_CHECK(cache2.GetSproutAnchorAt(tree.root(), tree));
|
BOOST_CHECK(GetAnchorAt(cache2, tree.root(), tree));
|
||||||
cache2.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT);
|
cache2.PopAnchor(Tree::empty_root(), type);
|
||||||
cache2.Flush();
|
cache2.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CHECK(cache1.GetBestAnchor(SPROUT) == ZCIncrementalMerkleTree::empty_root());
|
BOOST_CHECK(cache1.GetBestAnchor(type) == Tree::empty_root());
|
||||||
BOOST_CHECK(!cache1.GetSproutAnchorAt(tree.root(), tree));
|
BOOST_CHECK(!GetAnchorAt(cache1, tree.root(), tree));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Was broken:
|
// Was broken:
|
||||||
@@ -500,21 +505,30 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test)
|
|||||||
CCoinsViewCacheTest cache1(&base);
|
CCoinsViewCacheTest cache1(&base);
|
||||||
|
|
||||||
// Insert anchor into base.
|
// Insert anchor into base.
|
||||||
ZCIncrementalMerkleTree tree;
|
Tree tree;
|
||||||
uint256 cm = GetRandHash();
|
tree.append(GetRandHash());
|
||||||
tree.append(cm);
|
cache1.PushAnchor(tree);
|
||||||
cache1.PushSproutAnchor(tree);
|
|
||||||
cache1.Flush();
|
cache1.Flush();
|
||||||
|
|
||||||
{
|
{
|
||||||
// Pop anchor.
|
// Pop anchor.
|
||||||
CCoinsViewCacheTest cache2(&cache1);
|
CCoinsViewCacheTest cache2(&cache1);
|
||||||
cache2.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT);
|
cache2.PopAnchor(Tree::empty_root(), type);
|
||||||
cache2.Flush();
|
cache2.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CHECK(cache1.GetBestAnchor(SPROUT) == ZCIncrementalMerkleTree::empty_root());
|
BOOST_CHECK(cache1.GetBestAnchor(type) == Tree::empty_root());
|
||||||
BOOST_CHECK(!cache1.GetSproutAnchorAt(tree.root(), tree));
|
BOOST_CHECK(!GetAnchorAt(cache1, tree.root(), tree));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(anchor_regression_test)
|
||||||
|
{
|
||||||
|
BOOST_TEST_CONTEXT("Sprout") {
|
||||||
|
anchorRegressionTestImpl<ZCIncrementalMerkleTree>(SPROUT);
|
||||||
|
}
|
||||||
|
BOOST_TEST_CONTEXT("Sapling") {
|
||||||
|
anchorRegressionTestImpl<ZCSaplingIncrementalMerkleTree>(SAPLING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,29 +555,29 @@ BOOST_AUTO_TEST_CASE(nullifiers_test)
|
|||||||
checkNullifierCache(cache3, txWithNullifiers, false);
|
checkNullifierCache(cache3, txWithNullifiers, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(anchors_flush_test)
|
template<typename Tree> void anchorsFlushImpl(ShieldedType type)
|
||||||
{
|
{
|
||||||
CCoinsViewTest base;
|
CCoinsViewTest base;
|
||||||
uint256 newrt;
|
uint256 newrt;
|
||||||
{
|
{
|
||||||
CCoinsViewCacheTest cache(&base);
|
CCoinsViewCacheTest cache(&base);
|
||||||
ZCIncrementalMerkleTree tree;
|
Tree tree;
|
||||||
BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(SPROUT), tree));
|
BOOST_CHECK(GetAnchorAt(cache, cache.GetBestAnchor(type), tree));
|
||||||
appendRandomCommitment(tree);
|
tree.append(GetRandHash());
|
||||||
|
|
||||||
newrt = tree.root();
|
newrt = tree.root();
|
||||||
|
|
||||||
cache.PushSproutAnchor(tree);
|
cache.PushAnchor(tree);
|
||||||
cache.Flush();
|
cache.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
CCoinsViewCacheTest cache(&base);
|
CCoinsViewCacheTest cache(&base);
|
||||||
ZCIncrementalMerkleTree tree;
|
Tree tree;
|
||||||
BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(SPROUT), tree));
|
BOOST_CHECK(GetAnchorAt(cache, cache.GetBestAnchor(type), tree));
|
||||||
|
|
||||||
// Get the cached entry.
|
// Get the cached entry.
|
||||||
BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(SPROUT), tree));
|
BOOST_CHECK(GetAnchorAt(cache, cache.GetBestAnchor(type), tree));
|
||||||
|
|
||||||
uint256 check_rt = tree.root();
|
uint256 check_rt = tree.root();
|
||||||
|
|
||||||
@@ -571,8 +585,19 @@ BOOST_AUTO_TEST_CASE(anchors_flush_test)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(anchors_flush_test)
|
||||||
|
{
|
||||||
|
BOOST_TEST_CONTEXT("Sprout") {
|
||||||
|
anchorsFlushImpl<ZCIncrementalMerkleTree>(SPROUT);
|
||||||
|
}
|
||||||
|
BOOST_TEST_CONTEXT("Sapling") {
|
||||||
|
anchorsFlushImpl<ZCSaplingIncrementalMerkleTree>(SAPLING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(chained_joinsplits)
|
BOOST_AUTO_TEST_CASE(chained_joinsplits)
|
||||||
{
|
{
|
||||||
|
// TODO update this or add a similar test when the SaplingNote class exist
|
||||||
CCoinsViewTest base;
|
CCoinsViewTest base;
|
||||||
CCoinsViewCacheTest cache(&base);
|
CCoinsViewCacheTest cache(&base);
|
||||||
|
|
||||||
@@ -580,8 +605,8 @@ BOOST_AUTO_TEST_CASE(chained_joinsplits)
|
|||||||
|
|
||||||
JSDescription js1;
|
JSDescription js1;
|
||||||
js1.anchor = tree.root();
|
js1.anchor = tree.root();
|
||||||
js1.commitments[0] = appendRandomCommitment(tree);
|
js1.commitments[0] = appendRandomSproutCommitment(tree);
|
||||||
js1.commitments[1] = appendRandomCommitment(tree);
|
js1.commitments[1] = appendRandomSproutCommitment(tree);
|
||||||
|
|
||||||
// Although it's not possible given our assumptions, if
|
// Although it's not possible given our assumptions, if
|
||||||
// two joinsplits create the same treestate twice, we should
|
// two joinsplits create the same treestate twice, we should
|
||||||
@@ -597,11 +622,11 @@ BOOST_AUTO_TEST_CASE(chained_joinsplits)
|
|||||||
js2.anchor = tree.root();
|
js2.anchor = tree.root();
|
||||||
js3.anchor = tree.root();
|
js3.anchor = tree.root();
|
||||||
|
|
||||||
js2.commitments[0] = appendRandomCommitment(tree);
|
js2.commitments[0] = appendRandomSproutCommitment(tree);
|
||||||
js2.commitments[1] = appendRandomCommitment(tree);
|
js2.commitments[1] = appendRandomSproutCommitment(tree);
|
||||||
|
|
||||||
js3.commitments[0] = appendRandomCommitment(tree);
|
js3.commitments[0] = appendRandomSproutCommitment(tree);
|
||||||
js3.commitments[1] = appendRandomCommitment(tree);
|
js3.commitments[1] = appendRandomSproutCommitment(tree);
|
||||||
|
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx;
|
CMutableTransaction mtx;
|
||||||
@@ -648,7 +673,7 @@ BOOST_AUTO_TEST_CASE(chained_joinsplits)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(anchors_test)
|
template<typename Tree> void anchorsTestImpl(ShieldedType type)
|
||||||
{
|
{
|
||||||
// TODO: These tests should be more methodical.
|
// TODO: These tests should be more methodical.
|
||||||
// Or, integrate with Bitcoin's tests later.
|
// Or, integrate with Bitcoin's tests later.
|
||||||
@@ -656,68 +681,78 @@ BOOST_AUTO_TEST_CASE(anchors_test)
|
|||||||
CCoinsViewTest base;
|
CCoinsViewTest base;
|
||||||
CCoinsViewCacheTest cache(&base);
|
CCoinsViewCacheTest cache(&base);
|
||||||
|
|
||||||
BOOST_CHECK(cache.GetBestAnchor(SPROUT) == ZCIncrementalMerkleTree::empty_root());
|
BOOST_CHECK(cache.GetBestAnchor(type) == Tree::empty_root());
|
||||||
|
|
||||||
{
|
{
|
||||||
ZCIncrementalMerkleTree tree;
|
Tree tree;
|
||||||
|
|
||||||
BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(SPROUT), tree));
|
BOOST_CHECK(GetAnchorAt(cache, cache.GetBestAnchor(type), tree));
|
||||||
BOOST_CHECK(cache.GetBestAnchor(SPROUT) == tree.root());
|
BOOST_CHECK(cache.GetBestAnchor(type) == tree.root());
|
||||||
appendRandomCommitment(tree);
|
tree.append(GetRandHash());
|
||||||
appendRandomCommitment(tree);
|
tree.append(GetRandHash());
|
||||||
appendRandomCommitment(tree);
|
tree.append(GetRandHash());
|
||||||
appendRandomCommitment(tree);
|
tree.append(GetRandHash());
|
||||||
appendRandomCommitment(tree);
|
tree.append(GetRandHash());
|
||||||
appendRandomCommitment(tree);
|
tree.append(GetRandHash());
|
||||||
appendRandomCommitment(tree);
|
tree.append(GetRandHash());
|
||||||
|
|
||||||
ZCIncrementalMerkleTree save_tree_for_later;
|
Tree save_tree_for_later;
|
||||||
save_tree_for_later = tree;
|
save_tree_for_later = tree;
|
||||||
|
|
||||||
uint256 newrt = tree.root();
|
uint256 newrt = tree.root();
|
||||||
uint256 newrt2;
|
uint256 newrt2;
|
||||||
|
|
||||||
cache.PushSproutAnchor(tree);
|
cache.PushAnchor(tree);
|
||||||
BOOST_CHECK(cache.GetBestAnchor(SPROUT) == newrt);
|
BOOST_CHECK(cache.GetBestAnchor(type) == newrt);
|
||||||
|
|
||||||
{
|
{
|
||||||
ZCIncrementalMerkleTree confirm_same;
|
Tree confirm_same;
|
||||||
BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(SPROUT), confirm_same));
|
BOOST_CHECK(GetAnchorAt(cache, cache.GetBestAnchor(type), confirm_same));
|
||||||
|
|
||||||
BOOST_CHECK(confirm_same.root() == newrt);
|
BOOST_CHECK(confirm_same.root() == newrt);
|
||||||
}
|
}
|
||||||
|
|
||||||
appendRandomCommitment(tree);
|
tree.append(GetRandHash());
|
||||||
appendRandomCommitment(tree);
|
tree.append(GetRandHash());
|
||||||
|
|
||||||
newrt2 = tree.root();
|
newrt2 = tree.root();
|
||||||
|
|
||||||
cache.PushSproutAnchor(tree);
|
cache.PushAnchor(tree);
|
||||||
BOOST_CHECK(cache.GetBestAnchor(SPROUT) == newrt2);
|
BOOST_CHECK(cache.GetBestAnchor(type) == newrt2);
|
||||||
|
|
||||||
ZCIncrementalMerkleTree test_tree;
|
Tree test_tree;
|
||||||
BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(SPROUT), test_tree));
|
BOOST_CHECK(GetAnchorAt(cache, cache.GetBestAnchor(type), test_tree));
|
||||||
|
|
||||||
BOOST_CHECK(tree.root() == test_tree.root());
|
BOOST_CHECK(tree.root() == test_tree.root());
|
||||||
|
|
||||||
{
|
{
|
||||||
ZCIncrementalMerkleTree test_tree2;
|
Tree test_tree2;
|
||||||
cache.GetSproutAnchorAt(newrt, test_tree2);
|
GetAnchorAt(cache, newrt, test_tree2);
|
||||||
|
|
||||||
BOOST_CHECK(test_tree2.root() == newrt);
|
BOOST_CHECK(test_tree2.root() == newrt);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
cache.PopAnchor(newrt, SPROUT);
|
cache.PopAnchor(newrt, type);
|
||||||
ZCIncrementalMerkleTree obtain_tree;
|
Tree obtain_tree;
|
||||||
assert(!cache.GetSproutAnchorAt(newrt2, obtain_tree)); // should have been popped off
|
assert(!GetAnchorAt(cache, newrt2, obtain_tree)); // should have been popped off
|
||||||
assert(cache.GetSproutAnchorAt(newrt, obtain_tree));
|
assert(GetAnchorAt(cache, newrt, obtain_tree));
|
||||||
|
|
||||||
assert(obtain_tree.root() == newrt);
|
assert(obtain_tree.root() == newrt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(anchors_test)
|
||||||
|
{
|
||||||
|
BOOST_TEST_CONTEXT("Sprout") {
|
||||||
|
anchorsTestImpl<ZCIncrementalMerkleTree>(SPROUT);
|
||||||
|
}
|
||||||
|
BOOST_TEST_CONTEXT("Sapling") {
|
||||||
|
anchorsTestImpl<ZCSaplingIncrementalMerkleTree>(SAPLING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const unsigned int NUM_SIMULATION_ITERATIONS = 40000;
|
static const unsigned int NUM_SIMULATION_ITERATIONS = 40000;
|
||||||
|
|
||||||
// This is a large randomized insert/remove simulation test on a variable-size
|
// This is a large randomized insert/remove simulation test on a variable-size
|
||||||
|
|||||||
Reference in New Issue
Block a user