diff --git a/src/coins.cpp b/src/coins.cpp index 5c01d8eba..29172cb9f 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -281,13 +281,27 @@ void CCoinsViewCache::AbstractPopAnchor( } } -void CCoinsViewCache::PopAnchor(const uint256 &newrt) { - AbstractPopAnchor( - newrt, - SPROUT, - cacheSproutAnchors, - hashSproutAnchor - ); +void CCoinsViewCache::PopAnchor(const uint256 &newrt, ShieldedType type) { + switch (type) { + case SPROUT: + AbstractPopAnchor( + newrt, + SPROUT, + cacheSproutAnchors, + hashSproutAnchor + ); + break; + case SAPLING: + AbstractPopAnchor( + newrt, + SAPLING, + cacheSaplingAnchors, + hashSaplingAnchor + ); + break; + default: + throw std::runtime_error("Unknown shielded type " + type); + } } void CCoinsViewCache::SetNullifiers(const CTransaction& tx, bool spent) { diff --git a/src/coins.h b/src/coins.h index 11f758c34..513f9140b 100644 --- a/src/coins.h +++ b/src/coins.h @@ -484,7 +484,7 @@ public: // Removes the current commitment root from mapAnchors and sets // the new current root. - void PopAnchor(const uint256 &rt); + void PopAnchor(const uint256 &rt, ShieldedType type); // Marks nullifiers for a given transaction as spent or not. void SetNullifiers(const CTransaction& tx, bool spent); diff --git a/src/main.cpp b/src/main.cpp index 931deb44c..6a409402c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2150,7 +2150,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex } // set the old best anchor back - view.PopAnchor(blockUndo.old_tree_root); + view.PopAnchor(blockUndo.old_tree_root, SPROUT); // move best block pointer to prevout block view.SetBestBlock(pindex->pprev->GetBlockHash()); diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index daae2e009..b7f7f6efd 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -344,7 +344,7 @@ BOOST_AUTO_TEST_CASE(anchor_pop_regression_test) cache1.Flush(); // Remove the anchor - cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root()); + cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT); cache1.Flush(); // Add the anchor back @@ -374,7 +374,7 @@ BOOST_AUTO_TEST_CASE(anchor_pop_regression_test) cache1.Flush(); // Remove the anchor, but don't flush yet! - cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root()); + cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT); { CCoinsViewCacheTest cache2(&cache1); // Build cache on top @@ -416,7 +416,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) cache1.PushSproutAnchor(tree); cache1.Flush(); - cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root()); + cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT); BOOST_CHECK(cache1.GetBestAnchor(SPROUT) == ZCIncrementalMerkleTree::empty_root()); BOOST_CHECK(!cache1.GetSproutAnchorAt(tree.root(), tree)); } @@ -433,7 +433,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) cache1.PushSproutAnchor(tree); cache1.Flush(); - cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root()); + cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT); cache1.Flush(); BOOST_CHECK(cache1.GetBestAnchor(SPROUT) == ZCIncrementalMerkleTree::empty_root()); BOOST_CHECK(!cache1.GetSproutAnchorAt(tree.root(), tree)); @@ -455,7 +455,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) // Pop anchor. CCoinsViewCacheTest cache2(&cache1); BOOST_CHECK(cache2.GetSproutAnchorAt(tree.root(), tree)); - cache2.PopAnchor(ZCIncrementalMerkleTree::empty_root()); + cache2.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT); cache2.Flush(); } @@ -478,7 +478,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) { // Pop anchor. CCoinsViewCacheTest cache2(&cache1); - cache2.PopAnchor(ZCIncrementalMerkleTree::empty_root()); + cache2.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT); cache2.Flush(); } @@ -677,7 +677,7 @@ BOOST_AUTO_TEST_CASE(anchors_test) } { - cache.PopAnchor(newrt); + cache.PopAnchor(newrt, SPROUT); ZCIncrementalMerkleTree obtain_tree; assert(!cache.GetSproutAnchorAt(newrt2, obtain_tree)); // should have been popped off assert(cache.GetSproutAnchorAt(newrt, obtain_tree));