diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 6e73f2a1a..953f738ef 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -49,6 +49,8 @@ #include #include +#include + using namespace std; using namespace libzcash; @@ -2998,60 +3000,61 @@ void CWallet::WitnessNoteCommitment(std::vector commitments, * re-added during intial load rescan. */ -void CWallet::ReorderWalletTransactions(std::map, CWalletTx> &mapSorted, int64_t &maxOrderPos) { +void CWallet::ReorderWalletTransactions(std::map, CWalletTx*> &mapSorted, int64_t &maxOrderPos) +{ LOCK2(cs_main, cs_wallet); int maxSortNumber = chainActive.Tip()->GetHeight() + 1; for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { - CWalletTx wtx = it->second; - int confirms = wtx.GetDepthInMainChain(); - maxOrderPos = max(maxOrderPos, wtx.nOrderPos); + CWalletTx* pwtx = &(it->second); + int confirms = pwtx->GetDepthInMainChain(); + maxOrderPos = max(maxOrderPos, pwtx->nOrderPos); if (confirms > 0) { - int wtxHeight = mapBlockIndex[wtx.hashBlock]->GetHeight(); - auto key = std::make_pair(wtxHeight, wtx.nIndex); - mapSorted.insert(make_pair(key, wtx)); + int wtxHeight = mapBlockIndex[pwtx->hashBlock]->GetHeight(); + auto key = std::make_pair(wtxHeight, pwtx->nIndex); + mapSorted.insert(make_pair(key, pwtx)); } else { - auto key = std::make_pair(maxSortNumber, 0); - mapSorted.insert(std::make_pair(key, wtx)); - maxSortNumber++; + auto key = std::make_pair(maxSortNumber, 0); + mapSorted.insert(std::make_pair(key, pwtx)); + maxSortNumber++; } } } /**Update the nOrderPos with passed in ordered map. */ -void CWallet::UpdateWalletTransactionOrder(std::map, CWalletTx> &mapSorted, bool resetOrder) { +void CWallet::UpdateWalletTransactionOrder(std::map, CWalletTx*> &mapSorted, bool resetOrder) { LOCK2(cs_main, cs_wallet); int64_t previousPosition = 0; - std::map mapUpdatedTxs; + std::map mapUpdatedTxs; //Check the postion of each transaction relative to the previous one. - for (map, CWalletTx>::iterator it = mapSorted.begin(); it != mapSorted.end(); ++it) { - CWalletTx wtx = it->second; - const uint256 wtxid = wtx.GetHash(); +for (map, CWalletTx*>::iterator it = mapSorted.begin(); it != mapSorted.end(); ++it) { + CWalletTx* pwtx = it->second; + const uint256 wtxid = pwtx->GetHash(); - if (wtx.nOrderPos <= previousPosition || resetOrder) { + if (pwtx->nOrderPos <= previousPosition || resetOrder) { previousPosition++; - wtx.nOrderPos = previousPosition; - mapUpdatedTxs.insert(std::make_pair(wtxid, wtx)); + pwtx->nOrderPos = previousPosition; + mapUpdatedTxs.insert(std::make_pair(wtxid, pwtx)); } else { - previousPosition = wtx.nOrderPos; + previousPosition = pwtx->nOrderPos; } } //Update transactions nOrderPos for transactions that changed CWalletDB walletdb(strWalletFile, "r+", false); - for (map::iterator it = mapUpdatedTxs.begin(); it != mapUpdatedTxs.end(); ++it) { - CWalletTx wtx = it->second; - LogPrint("deletetx","Reorder Tx - Updating Positon to %i for Tx %s\n ", wtx.nOrderPos, wtx.GetHash().ToString()); - wtx.WriteToDisk(&walletdb); - mapWallet[wtx.GetHash()].nOrderPos = wtx.nOrderPos; + for (map::iterator it = mapUpdatedTxs.begin(); it != mapUpdatedTxs.end(); ++it) { + CWalletTx* pwtx = it->second; + LogPrint("deletetx","Reorder Tx - Updating Positon to %i for Tx %s\n ", pwtx->nOrderPos, pwtx->GetHash().ToString()); + pwtx->WriteToDisk(&walletdb); + mapWallet[pwtx->GetHash()].nOrderPos = pwtx->nOrderPos; } //Update Next Wallet Tx Positon @@ -3078,6 +3081,8 @@ void CWallet::DeleteTransactions(std::vector &removeTxs) { return; } } + // Miodrag: release memory back to the OS + malloc_trim(0); } void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { @@ -3103,7 +3108,7 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { //Sort Transactions by block and block index int64_t maxOrderPos = 0; - std::map, CWalletTx> mapSorted; + std::map, CWalletTx*> mapSorted; ReorderWalletTransactions(mapSorted, maxOrderPos); if (maxOrderPos > int64_t(mapSorted.size())*10) { //reset the postion when the max postion is 10x bigger than the @@ -3125,25 +3130,25 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { for (auto & item : mapSorted) { - CWalletTx& wtx = item.second; - const uint256& wtxid = wtx.GetHash(); + CWalletTx* pwtx = item.second; + const uint256& wtxid = pwtx->GetHash(); bool deleteTx = true; txCount += 1; - int wtxDepth = wtx.GetDepthInMainChain(); + int wtxDepth = pwtx->GetDepthInMainChain(); //Keep anything newer than N Blocks if (wtxDepth == 0) txUnConfirmed++; if (wtxDepth < nDeleteAfter && wtxDepth >= 0) { - LogPrint("deletetx","DeleteTx - Transaction above minimum depth, tx %s\n", wtx.GetHash().ToString()); + LogPrint("deletetx","DeleteTx - Transaction above minimum depth, tx %s\n", pwtx->GetHash().ToString()); deleteTx = false; txSaveCount++; continue; } else if (wtxDepth == -1) { //Enabled by default if (!fTxConflictDeleteEnabled) { - LogPrint("deletetx","DeleteTx - Conflict delete is not enabled tx %s\n", wtx.GetHash().ToString()); + LogPrint("deletetx","DeleteTx - Conflict delete is not enabled tx %s\n", pwtx->GetHash().ToString()); deleteTx = false; txSaveCount++; continue; @@ -3153,10 +3158,10 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { } else { //Check for unspent inputs or spend less than N Blocks ago. (Sapling) - for (auto & pair : wtx.mapSaplingNoteData) { + for (auto & pair : pwtx->mapSaplingNoteData) { SaplingNoteData nd = pair.second; if (!nd.nullifier || pwalletMain->GetSaplingSpendDepth(*nd.nullifier) <= fDeleteTransactionsAfterNBlocks) { - LogPrint("deletetx","DeleteTx - Unspent sapling input tx %s\n", wtx.GetHash().ToString()); + LogPrint("deletetx","DeleteTx - Unspent sapling input tx %s\n", pwtx->GetHash().ToString()); deleteTx = false; continue; } @@ -3168,13 +3173,13 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { } //Check for outputs that no longer have parents in the wallet. Exclude parents that are in the same transaction. (Sapling) - for (int i = 0; i < wtx.vShieldedSpend.size(); i++) { - const SpendDescription& spendDesc = wtx.vShieldedSpend[i]; + for (int i = 0; i < pwtx->vShieldedSpend.size(); i++) { + const SpendDescription& spendDesc = pwtx->vShieldedSpend[i]; if (pwalletMain->IsSaplingNullifierFromMe(spendDesc.nullifier)) { const uint256& parentHash = pwalletMain->mapSaplingNullifiersToNotes[spendDesc.nullifier].hash; const CWalletTx* parent = pwalletMain->GetWalletTx(parentHash); if (parent != NULL && parentHash != wtxid) { - LogPrint("deletetx","DeleteTx - Parent of sapling tx %s found\n", wtx.GetHash().ToString()); + LogPrint("deletetx","DeleteTx - Parent of sapling tx %s found\n", pwtx->GetHash().ToString()); deleteTx = false; continue; } @@ -3187,10 +3192,10 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { } //Check for unspent inputs or spend less than N Blocks ago. (Sprout) - for (auto & pair : wtx.mapSproutNoteData) { + for (auto & pair : pwtx->mapSproutNoteData) { SproutNoteData nd = pair.second; if (!nd.nullifier || pwalletMain->GetSproutSpendDepth(*nd.nullifier) <= fDeleteTransactionsAfterNBlocks) { - LogPrint("deletetx","DeleteTx - Unspent sprout input tx %s\n", wtx.GetHash().ToString()); + LogPrint("deletetx","DeleteTx - Unspent sprout input tx %s\n", pwtx->GetHash().ToString()); deleteTx = false; continue; } @@ -3202,15 +3207,15 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { } //Check for outputs that no longer have parents in the wallet. Exclude parents that are in the same transaction. (Sprout) - for (int i = 0; i < wtx.vjoinsplit.size(); i++) { - const JSDescription& jsdesc = wtx.vjoinsplit[i]; + for (int i = 0; i < pwtx->vjoinsplit.size(); i++) { + const JSDescription& jsdesc = pwtx->vjoinsplit[i]; for (const uint256 &nullifier : jsdesc.nullifiers) { // JSOutPoint op = pwalletMain->mapSproutNullifiersToNotes[nullifier]; if (pwalletMain->IsSproutNullifierFromMe(nullifier)) { const uint256& parentHash = pwalletMain->mapSproutNullifiersToNotes[nullifier].hash; const CWalletTx* parent = pwalletMain->GetWalletTx(parentHash); if (parent != NULL && parentHash != wtxid) { - LogPrint("deletetx","DeleteTx - Parent of sprout tx %s found\n", wtx.GetHash().ToString()); + LogPrint("deletetx","DeleteTx - Parent of sprout tx %s found\n", pwtx->GetHash().ToString()); deleteTx = false; continue; } @@ -3224,12 +3229,12 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { } //Check for unspent inputs or spend less than N Blocks ago. (Transparent) - for (unsigned int i = 0; i < wtx.vout.size(); i++) { + for (unsigned int i = 0; i < pwtx->vout.size(); i++) { CTxDestination address; - ExtractDestination(wtx.vout[i].scriptPubKey, address); - if(IsMine(wtx.vout[i])) { - if (pwalletMain->GetSpendDepth(wtx.GetHash(), i) <= fDeleteTransactionsAfterNBlocks) { - LogPrint("deletetx","DeleteTx - Unspent transparent input tx %s\n", wtx.GetHash().ToString()); + ExtractDestination(pwtx->vout[i].scriptPubKey, address); + if(IsMine(pwtx->vout[i])) { + if (pwalletMain->GetSpendDepth(pwtx->GetHash(), i) <= fDeleteTransactionsAfterNBlocks) { + LogPrint("deletetx","DeleteTx - Unspent transparent input tx %s\n", pwtx->GetHash().ToString()); deleteTx = false; continue; } @@ -3242,12 +3247,12 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { } //Chcek for output with that no longer have parents in the wallet. (Transparent) - for (int i = 0; i < wtx.vin.size(); i++) { - const CTxIn& txin = wtx.vin[i]; + for (int i = 0; i < pwtx->vin.size(); i++) { + const CTxIn& txin = pwtx->vin[i]; const uint256& parentHash = txin.prevout.hash; const CWalletTx* parent = pwalletMain->GetWalletTx(txin.prevout.hash); if (parent != NULL && parentHash != wtxid) { - LogPrint("deletetx","DeleteTx - Parent of transparent tx %s found\n", wtx.GetHash().ToString()); + LogPrint("deletetx","DeleteTx - Parent of transparent tx %s found\n", pwtx->GetHash().ToString()); deleteTx = false; continue; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 0946d452b..79d24a86d 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1183,8 +1183,8 @@ public: std::vector commitments, std::vector>& witnesses, uint256 &final_anchor); - void ReorderWalletTransactions(std::map, CWalletTx> &mapSorted, int64_t &maxOrderPos); - void UpdateWalletTransactionOrder(std::map, CWalletTx> &mapSorted, bool resetOrder); + void ReorderWalletTransactions(std::map, CWalletTx*> &mapSorted, int64_t &maxOrderPos); + void UpdateWalletTransactionOrder(std::map, CWalletTx*> &mapSorted, bool resetOrder); void DeleteTransactions(std::vector &removeTxs); void DeleteWalletTransactions(const CBlockIndex* pindex); int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);