Pass sapling merkle tree when incrementing witnesses

This commit is contained in:
Eirik Ogilvie-Wigley 2018-07-17 11:56:01 -06:00 committed by Simon
parent 4a0bc6047e
commit f86ee1c252
7 changed files with 71 additions and 48 deletions

View File

@ -2824,15 +2824,17 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) {
// Update chainActive and related variables. // Update chainActive and related variables.
UpdateTip(pindexDelete->pprev); UpdateTip(pindexDelete->pprev);
// Get the current commitment tree // Get the current commitment tree
ZCIncrementalMerkleTree newTree; ZCIncrementalMerkleTree newSproutTree;
assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), newTree)); ZCSaplingIncrementalMerkleTree newSaplingTree;
assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), newSproutTree));
assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), newSaplingTree));
// Let wallets know transactions went from 1-confirmed to // Let wallets know transactions went from 1-confirmed to
// 0-confirmed or conflicted: // 0-confirmed or conflicted:
BOOST_FOREACH(const CTransaction &tx, block.vtx) { BOOST_FOREACH(const CTransaction &tx, block.vtx) {
SyncWithWallets(tx, NULL); SyncWithWallets(tx, NULL);
} }
// Update cached incremental witnesses // Update cached incremental witnesses
GetMainSignals().ChainTip(pindexDelete, &block, newTree, false); GetMainSignals().ChainTip(pindexDelete, &block, newSproutTree, newSaplingTree, false);
return true; return true;
} }
@ -2858,8 +2860,10 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
pblock = █ pblock = █
} }
// Get the current commitment tree // Get the current commitment tree
ZCIncrementalMerkleTree oldTree; ZCIncrementalMerkleTree oldSproutTree;
assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), oldTree)); ZCSaplingIncrementalMerkleTree oldSaplingTree;
assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), oldSproutTree));
assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), oldSaplingTree));
// Apply the block atomically to the chain state. // Apply the block atomically to the chain state.
int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1; int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
int64_t nTime3; int64_t nTime3;
@ -2904,7 +2908,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
SyncWithWallets(tx, pblock); SyncWithWallets(tx, pblock);
} }
// Update cached incremental witnesses // Update cached incremental witnesses
GetMainSignals().ChainTip(pindexNew, pblock, oldTree, true); GetMainSignals().ChainTip(pindexNew, pblock, oldSproutTree, oldSaplingTree, true);
EnforceNodeDeprecation(pindexNew->nHeight); EnforceNodeDeprecation(pindexNew->nHeight);

View File

@ -17,7 +17,7 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) {
g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1));
g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
g_signals.ChainTip.connect(boost::bind(&CValidationInterface::ChainTip, pwalletIn, _1, _2, _3, _4)); g_signals.ChainTip.connect(boost::bind(&CValidationInterface::ChainTip, pwalletIn, _1, _2, _3, _4, _5));
g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1)); g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1));
@ -28,7 +28,7 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1)); g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1));
g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
g_signals.ChainTip.disconnect(boost::bind(&CValidationInterface::ChainTip, pwalletIn, _1, _2, _3, _4)); g_signals.ChainTip.disconnect(boost::bind(&CValidationInterface::ChainTip, pwalletIn, _1, _2, _3, _4, _5));
g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1));

View File

@ -34,7 +34,7 @@ protected:
virtual void UpdatedBlockTip(const CBlockIndex *pindex) {} virtual void UpdatedBlockTip(const CBlockIndex *pindex) {}
virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {} virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {}
virtual void EraseFromWallet(const uint256 &hash) {} virtual void EraseFromWallet(const uint256 &hash) {}
virtual void ChainTip(const CBlockIndex *pindex, const CBlock *pblock, ZCIncrementalMerkleTree tree, bool added) {} virtual void ChainTip(const CBlockIndex *pindex, const CBlock *pblock, ZCIncrementalMerkleTree sproutTree, ZCSaplingIncrementalMerkleTree saplingTree, bool added) {}
virtual void SetBestChain(const CBlockLocator &locator) {} virtual void SetBestChain(const CBlockLocator &locator) {}
virtual void UpdatedTransaction(const uint256 &hash) {} virtual void UpdatedTransaction(const uint256 &hash) {}
virtual void Inventory(const uint256 &hash) {} virtual void Inventory(const uint256 &hash) {}
@ -55,7 +55,7 @@ struct CMainSignals {
/** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */ /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */
boost::signals2::signal<void (const uint256 &)> UpdatedTransaction; boost::signals2::signal<void (const uint256 &)> UpdatedTransaction;
/** Notifies listeners of a change to the tip of the active block chain. */ /** Notifies listeners of a change to the tip of the active block chain. */
boost::signals2::signal<void (const CBlockIndex *, const CBlock *, ZCIncrementalMerkleTree, bool)> ChainTip; boost::signals2::signal<void (const CBlockIndex *, const CBlock *, ZCIncrementalMerkleTree, ZCSaplingIncrementalMerkleTree, bool)> ChainTip;
/** Notifies listeners of a new active block chain. */ /** Notifies listeners of a new active block chain. */
boost::signals2::signal<void (const CBlockLocator &)> SetBestChain; boost::signals2::signal<void (const CBlockLocator &)> SetBestChain;
/** Notifies listeners about an inventory item being seen on the network. */ /** Notifies listeners about an inventory item being seen on the network. */

View File

@ -51,8 +51,9 @@ public:
void IncrementNoteWitnesses(const CBlockIndex* pindex, void IncrementNoteWitnesses(const CBlockIndex* pindex,
const CBlock* pblock, const CBlock* pblock,
ZCIncrementalMerkleTree& tree) { ZCIncrementalMerkleTree& sproutTree,
CWallet::IncrementNoteWitnesses(pindex, pblock, tree); ZCSaplingIncrementalMerkleTree& saplingTree) {
CWallet::IncrementNoteWitnesses(pindex, pblock, sproutTree, saplingTree);
} }
void DecrementNoteWitnesses(const CBlockIndex* pindex) { void DecrementNoteWitnesses(const CBlockIndex* pindex) {
CWallet::DecrementNoteWitnesses(pindex); CWallet::DecrementNoteWitnesses(pindex);
@ -86,7 +87,8 @@ JSOutPoint CreateValidBlock(TestWallet& wallet,
const libzcash::SproutSpendingKey& sk, const libzcash::SproutSpendingKey& sk,
const CBlockIndex& index, const CBlockIndex& index,
CBlock& block, CBlock& block,
ZCIncrementalMerkleTree& tree) { ZCIncrementalMerkleTree& sproutTree,
ZCSaplingIncrementalMerkleTree& saplingTree) {
auto wtx = GetValidReceive(sk, 50, true); auto wtx = GetValidReceive(sk, 50, true);
auto note = GetNote(sk, wtx, 0, 1); auto note = GetNote(sk, wtx, 0, 1);
auto nullifier = note.nullifier(sk); auto nullifier = note.nullifier(sk);
@ -99,7 +101,7 @@ JSOutPoint CreateValidBlock(TestWallet& wallet,
wallet.AddToWallet(wtx, true, NULL); wallet.AddToWallet(wtx, true, NULL);
block.vtx.push_back(wtx); block.vtx.push_back(wtx);
wallet.IncrementNoteWitnesses(&index, &block, tree); wallet.IncrementNoteWitnesses(&index, &block, sproutTree, saplingTree);
return jsoutpt; return jsoutpt;
} }
@ -572,8 +574,9 @@ TEST(wallet_tests, cached_witnesses_empty_chain) {
CBlock block; CBlock block;
block.vtx.push_back(wtx); block.vtx.push_back(wtx);
CBlockIndex index(block); CBlockIndex index(block);
ZCIncrementalMerkleTree tree; ZCIncrementalMerkleTree sproutTree;
wallet.IncrementNoteWitnesses(&index, &block, tree); ZCSaplingIncrementalMerkleTree saplingTree;
wallet.IncrementNoteWitnesses(&index, &block, sproutTree, saplingTree);
witnesses.clear(); witnesses.clear();
wallet.GetNoteWitnesses(notes, witnesses, anchor); wallet.GetNoteWitnesses(notes, witnesses, anchor);
EXPECT_TRUE((bool) witnesses[0]); EXPECT_TRUE((bool) witnesses[0]);
@ -588,7 +591,8 @@ TEST(wallet_tests, cached_witnesses_chain_tip) {
TestWallet wallet; TestWallet wallet;
uint256 anchor1; uint256 anchor1;
CBlock block1; CBlock block1;
ZCIncrementalMerkleTree tree; ZCIncrementalMerkleTree sproutTree;
ZCSaplingIncrementalMerkleTree saplingTree;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSpendingKey(sk);
@ -597,7 +601,7 @@ TEST(wallet_tests, cached_witnesses_chain_tip) {
// First block (case tested in _empty_chain) // First block (case tested in _empty_chain)
CBlockIndex index1(block1); CBlockIndex index1(block1);
index1.nHeight = 1; index1.nHeight = 1;
auto jsoutpt = CreateValidBlock(wallet, sk, index1, block1, tree); auto jsoutpt = CreateValidBlock(wallet, sk, index1, block1, sproutTree, saplingTree);
// Called to fetch anchor // Called to fetch anchor
std::vector<JSOutPoint> notes {jsoutpt}; std::vector<JSOutPoint> notes {jsoutpt};
@ -631,8 +635,9 @@ TEST(wallet_tests, cached_witnesses_chain_tip) {
block2.vtx.push_back(wtx); block2.vtx.push_back(wtx);
CBlockIndex index2(block2); CBlockIndex index2(block2);
index2.nHeight = 2; index2.nHeight = 2;
ZCIncrementalMerkleTree tree2 {tree}; ZCIncrementalMerkleTree sproutTree2 {sproutTree};
wallet.IncrementNoteWitnesses(&index2, &block2, tree2); ZCSaplingIncrementalMerkleTree saplingTree2 {saplingTree};
wallet.IncrementNoteWitnesses(&index2, &block2, sproutTree2, saplingTree2);
witnesses.clear(); witnesses.clear();
wallet.GetNoteWitnesses(notes, witnesses, anchor2); wallet.GetNoteWitnesses(notes, witnesses, anchor2);
EXPECT_TRUE((bool) witnesses[0]); EXPECT_TRUE((bool) witnesses[0]);
@ -649,7 +654,7 @@ TEST(wallet_tests, cached_witnesses_chain_tip) {
// Re-incrementing with the same block should give the same result // Re-incrementing with the same block should give the same result
uint256 anchor4; uint256 anchor4;
wallet.IncrementNoteWitnesses(&index2, &block2, tree); wallet.IncrementNoteWitnesses(&index2, &block2, sproutTree, saplingTree);
witnesses.clear(); witnesses.clear();
wallet.GetNoteWitnesses(notes, witnesses, anchor4); wallet.GetNoteWitnesses(notes, witnesses, anchor4);
EXPECT_TRUE((bool) witnesses[0]); EXPECT_TRUE((bool) witnesses[0]);
@ -657,7 +662,7 @@ TEST(wallet_tests, cached_witnesses_chain_tip) {
// Incrementing with the same block again should not change the cache // Incrementing with the same block again should not change the cache
uint256 anchor5; uint256 anchor5;
wallet.IncrementNoteWitnesses(&index2, &block2, tree); wallet.IncrementNoteWitnesses(&index2, &block2, sproutTree, saplingTree);
std::vector<boost::optional<ZCIncrementalWitness>> witnesses5; std::vector<boost::optional<ZCIncrementalWitness>> witnesses5;
wallet.GetNoteWitnesses(notes, witnesses5, anchor5); wallet.GetNoteWitnesses(notes, witnesses5, anchor5);
EXPECT_EQ(witnesses, witnesses5); EXPECT_EQ(witnesses, witnesses5);
@ -670,7 +675,8 @@ TEST(wallet_tests, CachedWitnessesDecrementFirst) {
uint256 anchor2; uint256 anchor2;
CBlock block2; CBlock block2;
CBlockIndex index2(block2); CBlockIndex index2(block2);
ZCIncrementalMerkleTree tree; ZCIncrementalMerkleTree sproutTree;
ZCSaplingIncrementalMerkleTree saplingTree;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSpendingKey(sk);
@ -680,13 +686,13 @@ TEST(wallet_tests, CachedWitnessesDecrementFirst) {
CBlock block1; CBlock block1;
CBlockIndex index1(block1); CBlockIndex index1(block1);
index1.nHeight = 1; index1.nHeight = 1;
CreateValidBlock(wallet, sk, index1, block1, tree); CreateValidBlock(wallet, sk, index1, block1, sproutTree, saplingTree);
} }
{ {
// Second block (case tested in _chain_tip) // Second block (case tested in _chain_tip)
index2.nHeight = 2; index2.nHeight = 2;
auto jsoutpt = CreateValidBlock(wallet, sk, index2, block2, tree); auto jsoutpt = CreateValidBlock(wallet, sk, index2, block2, sproutTree, saplingTree);
// Called to fetch anchor // Called to fetch anchor
std::vector<JSOutPoint> notes {jsoutpt}; std::vector<JSOutPoint> notes {jsoutpt};
@ -726,7 +732,7 @@ TEST(wallet_tests, CachedWitnessesDecrementFirst) {
// Re-incrementing with the same block should give the same result // Re-incrementing with the same block should give the same result
uint256 anchor5; uint256 anchor5;
wallet.IncrementNoteWitnesses(&index2, &block2, tree); wallet.IncrementNoteWitnesses(&index2, &block2, sproutTree, saplingTree);
witnesses.clear(); witnesses.clear();
wallet.GetNoteWitnesses(notes, witnesses, anchor5); wallet.GetNoteWitnesses(notes, witnesses, anchor5);
EXPECT_FALSE((bool) witnesses[0]); EXPECT_FALSE((bool) witnesses[0]);
@ -740,8 +746,10 @@ TEST(wallet_tests, CachedWitnessesCleanIndex) {
std::vector<CBlockIndex> indices; std::vector<CBlockIndex> indices;
std::vector<JSOutPoint> notes; std::vector<JSOutPoint> notes;
std::vector<uint256> anchors; std::vector<uint256> anchors;
ZCIncrementalMerkleTree tree; ZCIncrementalMerkleTree sproutTree;
ZCIncrementalMerkleTree riTree = tree; ZCIncrementalMerkleTree sproutRiTree = sproutTree;
ZCSaplingIncrementalMerkleTree saplingTree;
ZCSaplingIncrementalMerkleTree saplingRiTree = saplingTree;
std::vector<boost::optional<ZCIncrementalWitness>> witnesses; std::vector<boost::optional<ZCIncrementalWitness>> witnesses;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
@ -753,9 +761,9 @@ TEST(wallet_tests, CachedWitnessesCleanIndex) {
indices.resize(numBlocks); indices.resize(numBlocks);
for (size_t i = 0; i < numBlocks; i++) { for (size_t i = 0; i < numBlocks; i++) {
indices[i].nHeight = i; indices[i].nHeight = i;
auto old = tree.root(); auto old = sproutTree.root();
auto jsoutpt = CreateValidBlock(wallet, sk, indices[i], blocks[i], tree); auto jsoutpt = CreateValidBlock(wallet, sk, indices[i], blocks[i], sproutTree, saplingTree);
EXPECT_NE(old, tree.root()); EXPECT_NE(old, sproutTree.root());
notes.push_back(jsoutpt); notes.push_back(jsoutpt);
witnesses.clear(); witnesses.clear();
@ -770,8 +778,9 @@ TEST(wallet_tests, CachedWitnessesCleanIndex) {
// Now pretend we are reindexing: the chain is cleared, and each block is // Now pretend we are reindexing: the chain is cleared, and each block is
// used to increment witnesses again. // used to increment witnesses again.
for (size_t i = 0; i < numBlocks; i++) { for (size_t i = 0; i < numBlocks; i++) {
ZCIncrementalMerkleTree riPrevTree {riTree}; ZCIncrementalMerkleTree sproutRiPrevTree {sproutRiTree};
wallet.IncrementNoteWitnesses(&(indices[i]), &(blocks[i]), riTree); ZCSaplingIncrementalMerkleTree saplingRiPrevTree {saplingRiTree};
wallet.IncrementNoteWitnesses(&(indices[i]), &(blocks[i]), sproutRiTree, saplingRiTree);
witnesses.clear(); witnesses.clear();
uint256 anchor; uint256 anchor;
wallet.GetNoteWitnesses(notes, witnesses, anchor); wallet.GetNoteWitnesses(notes, witnesses, anchor);
@ -796,7 +805,7 @@ TEST(wallet_tests, CachedWitnessesCleanIndex) {
} }
{ {
wallet.IncrementNoteWitnesses(&(indices[i]), &(blocks[i]), riPrevTree); wallet.IncrementNoteWitnesses(&(indices[i]), &(blocks[i]), sproutRiPrevTree, saplingRiPrevTree);
witnesses.clear(); witnesses.clear();
uint256 anchor; uint256 anchor;
wallet.GetNoteWitnesses(notes, witnesses, anchor); wallet.GetNoteWitnesses(notes, witnesses, anchor);

View File

@ -449,11 +449,14 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase,
return false; return false;
} }
void CWallet::ChainTip(const CBlockIndex *pindex, const CBlock *pblock, void CWallet::ChainTip(const CBlockIndex *pindex,
ZCIncrementalMerkleTree tree, bool added) const CBlock *pblock,
ZCIncrementalMerkleTree sproutTree,
ZCSaplingIncrementalMerkleTree saplingTree,
bool added)
{ {
if (added) { if (added) {
IncrementNoteWitnesses(pindex, pblock, tree); IncrementNoteWitnesses(pindex, pblock, sproutTree, saplingTree);
} else { } else {
DecrementNoteWitnesses(pindex); DecrementNoteWitnesses(pindex);
} }
@ -844,7 +847,8 @@ void UpdateWitnessHeights(NoteDataMap& noteDataMap, int indexHeight, int64_t nWi
void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex, void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex,
const CBlock* pblockIn, const CBlock* pblockIn,
ZCIncrementalMerkleTree& tree) ZCIncrementalMerkleTree& sproutTree,
ZCSaplingIncrementalMerkleTree& saplingTree)
{ {
LOCK(cs_wallet); LOCK(cs_wallet);
for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) { for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
@ -869,7 +873,7 @@ void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex,
const JSDescription& jsdesc = tx.vjoinsplit[i]; const JSDescription& jsdesc = tx.vjoinsplit[i];
for (uint8_t j = 0; j < jsdesc.commitments.size(); j++) { for (uint8_t j = 0; j < jsdesc.commitments.size(); j++) {
const uint256& note_commitment = jsdesc.commitments[j]; const uint256& note_commitment = jsdesc.commitments[j];
tree.append(note_commitment); sproutTree.append(note_commitment);
// Increment existing witnesses // Increment existing witnesses
for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) { for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
@ -879,7 +883,7 @@ void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex,
// If this is our note, witness it // If this is our note, witness it
if (txIsOurs) { if (txIsOurs) {
JSOutPoint jsoutpt {hash, i, j}; JSOutPoint jsoutpt {hash, i, j};
::WitnessNoteIfMine(mapWallet[hash].mapSproutNoteData, pindex->nHeight, nWitnessCacheSize, jsoutpt, tree.witness()); ::WitnessNoteIfMine(mapWallet[hash].mapSproutNoteData, pindex->nHeight, nWitnessCacheSize, jsoutpt, sproutTree.witness());
} }
} }
} }
@ -1919,12 +1923,16 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
ret++; ret++;
} }
ZCIncrementalMerkleTree tree; ZCIncrementalMerkleTree sproutTree;
ZCSaplingIncrementalMerkleTree saplingTree;
// This should never fail: we should always be able to get the tree // This should never fail: we should always be able to get the tree
// state on the path to the tip of our chain // state on the path to the tip of our chain
assert(pcoinsTip->GetSproutAnchorAt(pindex->hashSproutAnchor, tree)); assert(pcoinsTip->GetSproutAnchorAt(pindex->hashSproutAnchor, sproutTree));
if (pindex->pprev) {
assert(pcoinsTip->GetSaplingAnchorAt(pindex->pprev->hashFinalSaplingRoot, saplingTree));
}
// Increment note witness caches // Increment note witness caches
IncrementNoteWitnesses(pindex, &block, tree); IncrementNoteWitnesses(pindex, &block, sproutTree, saplingTree);
pindex = chainActive.Next(pindex); pindex = chainActive.Next(pindex);
if (GetTime() >= nNow + 60) { if (GetTime() >= nNow + 60) {

View File

@ -730,7 +730,8 @@ protected:
*/ */
void IncrementNoteWitnesses(const CBlockIndex* pindex, void IncrementNoteWitnesses(const CBlockIndex* pindex,
const CBlock* pblock, const CBlock* pblock,
ZCIncrementalMerkleTree& tree); ZCIncrementalMerkleTree& sproutTree,
ZCSaplingIncrementalMerkleTree& saplingTree);
/** /**
* pindex is the old tip being disconnected. * pindex is the old tip being disconnected.
*/ */
@ -1084,7 +1085,7 @@ public:
CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const; CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const;
CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const; CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const;
CAmount GetChange(const CTransaction& tx) const; CAmount GetChange(const CTransaction& tx) const;
void ChainTip(const CBlockIndex *pindex, const CBlock *pblock, ZCIncrementalMerkleTree tree, bool added); void ChainTip(const CBlockIndex *pindex, const CBlock *pblock, ZCIncrementalMerkleTree sproutTree, ZCSaplingIncrementalMerkleTree saplingTree, bool added);
/** Saves witness caches and best block locator to disk. */ /** Saves witness caches and best block locator to disk. */
void SetBestChain(const CBlockLocator& loc); void SetBestChain(const CBlockLocator& loc);
std::set<std::pair<libzcash::PaymentAddress, uint256>> GetNullifiersForAddresses(const std::set<libzcash::PaymentAddress> & addresses); std::set<std::pair<libzcash::PaymentAddress, uint256>> GetNullifiersForAddresses(const std::set<libzcash::PaymentAddress> & addresses);

View File

@ -298,7 +298,8 @@ double benchmark_try_decrypt_notes(size_t nAddrs)
double benchmark_increment_note_witnesses(size_t nTxs) double benchmark_increment_note_witnesses(size_t nTxs)
{ {
CWallet wallet; CWallet wallet;
ZCIncrementalMerkleTree tree; ZCIncrementalMerkleTree sproutTree;
ZCSaplingIncrementalMerkleTree saplingTree;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSpendingKey(sk);
@ -323,7 +324,7 @@ double benchmark_increment_note_witnesses(size_t nTxs)
index1.nHeight = 1; index1.nHeight = 1;
// Increment to get transactions witnessed // Increment to get transactions witnessed
wallet.ChainTip(&index1, &block1, tree, true); wallet.ChainTip(&index1, &block1, sproutTree, saplingTree, true);
// Second block // Second block
CBlock block2; CBlock block2;
@ -347,7 +348,7 @@ double benchmark_increment_note_witnesses(size_t nTxs)
struct timeval tv_start; struct timeval tv_start;
timer_start(tv_start); timer_start(tv_start);
wallet.ChainTip(&index2, &block2, tree, true); wallet.ChainTip(&index2, &block2, sproutTree, saplingTree, true);
return timer_stop(tv_start); return timer_stop(tv_start);
} }