Merge pull request #83 from DenioD/duke

resource friendly tx reorder ported from 58b05de90d
This commit is contained in:
Duke Leto
2020-02-18 03:05:49 -08:00
committed by GitHub
2 changed files with 55 additions and 50 deletions

View File

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

View File

@@ -1183,8 +1183,8 @@ public:
std::vector<uint256> commitments, std::vector<uint256> commitments,
std::vector<boost::optional<SproutWitness>>& witnesses, std::vector<boost::optional<SproutWitness>>& witnesses,
uint256 &final_anchor); uint256 &final_anchor);
void ReorderWalletTransactions(std::map<std::pair<int,int>, CWalletTx> &mapSorted, int64_t &maxOrderPos); void ReorderWalletTransactions(std::map<std::pair<int,int>, CWalletTx*> &mapSorted, int64_t &maxOrderPos);
void UpdateWalletTransactionOrder(std::map<std::pair<int,int>, CWalletTx> &mapSorted, bool resetOrder); void UpdateWalletTransactionOrder(std::map<std::pair<int,int>, CWalletTx*> &mapSorted, bool resetOrder);
void DeleteTransactions(std::vector<uint256> &removeTxs); void DeleteTransactions(std::vector<uint256> &removeTxs);
void DeleteWalletTransactions(const CBlockIndex* pindex); void DeleteWalletTransactions(const CBlockIndex* pindex);
int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);