Browse Source

Porting AddToSifted() and AppendSingleSaplingCommitment()

This is still WIP/testing. Not recommended to test with any significant amounts or important wallets.
asyncnotedecryption
fekt 2 months ago
parent
commit
63b5513781
  1. 62
      src/wallet/wallet.cpp
  2. 3
      src/wallet/wallet.h

62
src/wallet/wallet.cpp

@ -960,6 +960,13 @@ int64_t CWallet::NullifierCount()
return pcoinsTip->getNullifiers().size(); return pcoinsTip->getNullifiers().size();
} }
void CWallet::AddToSifted(const uint256& wtxid)
{
CWalletTx& wtx = mapWallet.at(wtxid);
if (!wtx.mapSaplingNoteData.empty())
setSiftedSapling.emplace(wtxid);
}
void CWallet::ClearNoteWitnessCache() void CWallet::ClearNoteWitnessCache()
{ {
@ -1132,6 +1139,13 @@ int CWallet::VerifyAndSetInitialWitness(const CBlockIndex* pindex, bool witnessO
return nMinimumHeight; return nMinimumHeight;
} }
static SaplingWitness AppendSingleSaplingCommitment(const SaplingWitness& witness, const uint256& commitment)
{
SaplingWitness sw(witness);
sw.append(commitment);
return sw;
}
void CWallet::BuildWitnessCache(const CBlockIndex* pindex, bool witnessOnly) void CWallet::BuildWitnessCache(const CBlockIndex* pindex, bool witnessOnly)
{ {
@ -1169,12 +1183,26 @@ void CWallet::BuildWitnessCache(const CBlockIndex* pindex, bool witnessOnly)
pcoinsTip->GetSaplingAnchorAt(saplingRoot, saplingTree); pcoinsTip->GetSaplingAnchorAt(saplingRoot, saplingTree);
//Cycle through blocks and transactions building sapling tree until the commitment needed is reached //Cycle through blocks and transactions building sapling tree until the commitment needed is reached
const CBlock *pblock;
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, pblockindex, 1)) { if (!ReadBlockFromDisk(block, pblockindex, 1)) {
throw std::runtime_error( throw std::runtime_error(
strprintf("Cannot read block height %d (%s) from disk", pindex->GetHeight(), pindex->GetBlockHash().GetHex())); strprintf("Cannot read block height %d (%s) from disk", pindex->GetHeight(), pindex->GetBlockHash().GetHex()));
} }
else {
pblock = █
}
std::vector<uint256> vSaplingCommitments;
std::vector<SaplingNoteData*> vSaplingNoteData;
if (setSiftedSapling.size()) {
for (const CTransaction &tx : pblock->vtx) {
for (const OutputDescription &outdesc : tx.vShieldedOutput) {
vSaplingCommitments.emplace_back(outdesc.cm);
}
}
for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) { for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
if (wtxItem.second.mapSaplingNoteData.empty()) if (wtxItem.second.mapSaplingNoteData.empty())
@ -1192,18 +1220,29 @@ void CWallet::BuildWitnessCache(const CBlockIndex* pindex, bool witnessOnly)
while (nd->witnesses.size() > WITNESS_CACHE_SIZE) { while (nd->witnesses.size() > WITNESS_CACHE_SIZE) {
nd->witnesses.pop_back(); nd->witnesses.pop_back();
} }
for (const CTransaction& tx : block.vtx) { // for async append of commitments
for (uint32_t i = 0; i < tx.vShieldedOutput.size(); i++) { vSaplingNoteData.push_back(nd);
const uint256& note_commitment = tx.vShieldedOutput[i].cm;
nd->witnesses.front().append(note_commitment);
}
}
nd->witnessHeight = pblockindex->GetHeight(); nd->witnessHeight = pblockindex->GetHeight();
} }
} }
} }
// Parallelization with std::async
std::vector<std::future<SaplingWitness>> vSaplingWitnessFutures;
for (const auto& commitment : vSaplingCommitments) {
for (auto pnd : vSaplingNoteData) {
vSaplingWitnessFutures.emplace_back(std::async(std::launch::async, AppendSingleSaplingCommitment, pnd->witnesses.front(), commitment));
}
assert(vSaplingWitnessFutures.size() == vSaplingNoteData.size());
for (int i = 0; i < vSaplingWitnessFutures.size(); i++) {
vSaplingNoteData.at(i)->witnesses.front() = vSaplingWitnessFutures.at(i).get();
}
vSaplingWitnessFutures.resize(0);
}
} }
if (pblockindex == pindex) if (pblockindex == pindex)
@ -1212,7 +1251,7 @@ void CWallet::BuildWitnessCache(const CBlockIndex* pindex, bool witnessOnly)
pblockindex = chainActive.Next(pblockindex); pblockindex = chainActive.Next(pblockindex);
} }
}
} }
bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
@ -1466,6 +1505,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD
mapWallet[hash].BindWallet(this); mapWallet[hash].BindWallet(this);
UpdateNullifierNoteMapWithTx(mapWallet[hash]); UpdateNullifierNoteMapWithTx(mapWallet[hash]);
AddToSpends(hash); AddToSpends(hash);
AddToSifted(hash);
} }
else else
{ {
@ -1558,9 +1598,13 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD
// Write to disk // Write to disk
if (fInsertedNew || fUpdated) if (fInsertedNew || fUpdated)
{
AddToSifted(hash);
if (!wtx.WriteToDisk(pwalletdb)) if (!wtx.WriteToDisk(pwalletdb))
return false; return false;
}
// Break debit/credit balance caches: // Break debit/credit balance caches:
wtx.MarkDirty(); wtx.MarkDirty();

3
src/wallet/wallet.h

@ -1015,6 +1015,9 @@ public:
std::map<uint256, SaplingOutPoint> mapSaplingNullifiersToNotes; std::map<uint256, SaplingOutPoint> mapSaplingNullifiersToNotes;
std::map<uint256, CWalletTx> mapWallet; std::map<uint256, CWalletTx> mapWallet;
std::set<uint256> setSiftedSapling;
void AddToSifted(const uint256& wtxid);
int64_t nOrderPosNext; int64_t nOrderPosNext;
std::map<CTxDestination, CAddressBookData> mapAddressBook; std::map<CTxDestination, CAddressBookData> mapAddressBook;

Loading…
Cancel
Save