mirror of
https://github.com/dashpay/dash.git
synced 2024-12-27 04:52:59 +01:00
Merge pull request #177 from UdjinM6/v0.11.1.x_fix_gui_performance_issues
V0.11.2.x Performance and UI Fixes Pack
This commit is contained in:
commit
a9ff5617e9
@ -54,6 +54,7 @@ void CTxIn::print() const
|
|||||||
CTxOut::CTxOut(int64_t nValueIn, CScript scriptPubKeyIn)
|
CTxOut::CTxOut(int64_t nValueIn, CScript scriptPubKeyIn)
|
||||||
{
|
{
|
||||||
nValue = nValueIn;
|
nValue = nValueIn;
|
||||||
|
nRounds = -10; // an initial value, should be no way to get this by calculations
|
||||||
scriptPubKey = scriptPubKeyIn;
|
scriptPubKey = scriptPubKeyIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +153,7 @@ class CTxOut
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int64_t nValue;
|
int64_t nValue;
|
||||||
|
int nRounds;
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey;
|
||||||
|
|
||||||
CTxOut()
|
CTxOut()
|
||||||
@ -171,6 +172,7 @@ public:
|
|||||||
void SetNull()
|
void SetNull()
|
||||||
{
|
{
|
||||||
nValue = -1;
|
nValue = -1;
|
||||||
|
nRounds = -10; // an initial value, should be no way to get this by calculations
|
||||||
scriptPubKey.clear();
|
scriptPubKey.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,6 +199,7 @@ public:
|
|||||||
friend bool operator==(const CTxOut& a, const CTxOut& b)
|
friend bool operator==(const CTxOut& a, const CTxOut& b)
|
||||||
{
|
{
|
||||||
return (a.nValue == b.nValue &&
|
return (a.nValue == b.nValue &&
|
||||||
|
a.nRounds == b.nRounds &&
|
||||||
a.scriptPubKey == b.scriptPubKey);
|
a.scriptPubKey == b.scriptPubKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,41 +395,91 @@ int randomizeList (int i) { return std::rand()%i;}
|
|||||||
// Recursively determine the rounds of a given input (How deep is the darksend chain for a given input)
|
// Recursively determine the rounds of a given input (How deep is the darksend chain for a given input)
|
||||||
int GetInputDarksendRounds(CTxIn in, int rounds)
|
int GetInputDarksendRounds(CTxIn in, int rounds)
|
||||||
{
|
{
|
||||||
|
static std::map<uint256, CWalletTx> mDenomWtxes;
|
||||||
|
|
||||||
if(rounds >= 17) return rounds;
|
if(rounds >= 17) return rounds;
|
||||||
|
|
||||||
std::string padding = "";
|
uint256 hash = in.prevout.hash;
|
||||||
padding.insert(0, ((rounds+1)*5)+3, ' ');
|
uint nout = in.prevout.n;
|
||||||
|
|
||||||
CWalletTx tx;
|
CWalletTx wtx;
|
||||||
if(pwalletMain->GetTransaction(in.prevout.hash,tx))
|
if(pwalletMain->GetTransaction(hash, wtx))
|
||||||
{
|
{
|
||||||
// bounds check
|
std::map<uint256, CWalletTx>::const_iterator mdwi = mDenomWtxes.find(hash);
|
||||||
if(in.prevout.n >= tx.vout.size()) return -4;
|
// not known yet, let's add it
|
||||||
|
if(mdwi == mDenomWtxes.end())
|
||||||
|
{
|
||||||
|
if(fDebug) LogPrintf("GetInputDarksendRounds INSERTING %s\n", hash.ToString());
|
||||||
|
mDenomWtxes[hash] = wtx;
|
||||||
|
}
|
||||||
|
// found and it's not an initial value, just return it
|
||||||
|
else if(mDenomWtxes[hash].vout[nout].nRounds != -10)
|
||||||
|
{
|
||||||
|
if(fDebug) LogPrintf("GetInputDarksendRounds INFO %s %3d %d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds);
|
||||||
|
return mDenomWtxes[hash].vout[nout].nRounds;
|
||||||
|
}
|
||||||
|
|
||||||
if(tx.vout[in.prevout.n].nValue == DARKSEND_FEE) return -3;
|
|
||||||
|
// bounds check
|
||||||
|
if(nout >= wtx.vout.size())
|
||||||
|
{
|
||||||
|
mDenomWtxes[hash].vout[nout].nRounds = -4;
|
||||||
|
if(fDebug) LogPrintf("GetInputDarksendRounds UPDATED %s %3d %d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds);
|
||||||
|
return mDenomWtxes[hash].vout[nout].nRounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDenomWtxes[hash].vout[nout].nRounds = -3;
|
||||||
|
if(pwalletMain->IsCollateralAmount(wtx.vout[nout].nValue))
|
||||||
|
{
|
||||||
|
mDenomWtxes[hash].vout[nout].nRounds = -3;
|
||||||
|
if(fDebug) LogPrintf("GetInputDarksendRounds UPDATED %s %3d %d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds);
|
||||||
|
return mDenomWtxes[hash].vout[nout].nRounds;
|
||||||
|
}
|
||||||
|
|
||||||
//make sure the final output is non-denominate
|
//make sure the final output is non-denominate
|
||||||
if(rounds == 0 && !pwalletMain->IsDenominatedAmount(tx.vout[in.prevout.n].nValue)) return -2; //NOT DENOM
|
mDenomWtxes[hash].vout[nout].nRounds = -2;
|
||||||
|
if(/*rounds == 0 && */!pwalletMain->IsDenominatedAmount(wtx.vout[nout].nValue)) //NOT DENOM
|
||||||
bool found = false;
|
|
||||||
BOOST_FOREACH(CTxOut out, tx.vout)
|
|
||||||
{
|
{
|
||||||
found = pwalletMain->IsDenominatedAmount(out.nValue);
|
mDenomWtxes[hash].vout[nout].nRounds = -2;
|
||||||
if(found) break; // no need to loop more
|
if(fDebug) LogPrintf("GetInputDarksendRounds UPDATED %s %3d %d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds);
|
||||||
|
return mDenomWtxes[hash].vout[nout].nRounds;
|
||||||
}
|
}
|
||||||
if(!found) return rounds - 1; //NOT FOUND, "-1" because of the pre-mixing creation of denominated amounts
|
|
||||||
|
|
||||||
// find my vin and look that up
|
bool fAllDenoms = true;
|
||||||
BOOST_FOREACH(CTxIn in2, tx.vin)
|
BOOST_FOREACH(CTxOut out, wtx.vout)
|
||||||
|
{
|
||||||
|
fAllDenoms = fAllDenoms && pwalletMain->IsDenominatedAmount(out.nValue);
|
||||||
|
}
|
||||||
|
// this one is denominated but there is another non-denominated output found in the same tx
|
||||||
|
if(!fAllDenoms)
|
||||||
|
{
|
||||||
|
mDenomWtxes[hash].vout[nout].nRounds = 0;
|
||||||
|
if(fDebug) LogPrintf("GetInputDarksendRounds UPDATED %s %3d %d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds);
|
||||||
|
return mDenomWtxes[hash].vout[nout].nRounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nShortest = -10; // an initial value, should be no way to get this by calculations
|
||||||
|
bool fDenomFound = false;
|
||||||
|
// only denoms here so let's look up
|
||||||
|
BOOST_FOREACH(CTxIn in2, wtx.vin)
|
||||||
{
|
{
|
||||||
if(pwalletMain->IsMine(in2))
|
if(pwalletMain->IsMine(in2))
|
||||||
{
|
{
|
||||||
//LogPrintf("rounds :: %s %s %d NEXT\n", padding.c_str(), in.ToString().c_str(), rounds);
|
|
||||||
int n = GetInputDarksendRounds(in2, rounds+1);
|
int n = GetInputDarksendRounds(in2, rounds+1);
|
||||||
if(n != -3) return n;
|
// denom found, find the shortest chain or initially assign nShortest with the first found value
|
||||||
|
if(n >= 0 && (n < nShortest || nShortest == -10))
|
||||||
|
{
|
||||||
|
nShortest = n;
|
||||||
|
fDenomFound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mDenomWtxes[hash].vout[nout].nRounds = fDenomFound
|
||||||
|
? nShortest + 1 // good, we a +1 to the shortest one
|
||||||
|
: 0; // too bad, we are the fist one in that chain
|
||||||
|
if(fDebug) LogPrintf("GetInputDarksendRounds UPDATED %s %3d %d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds);
|
||||||
|
return mDenomWtxes[hash].vout[nout].nRounds;
|
||||||
|
}
|
||||||
|
|
||||||
return rounds-1;
|
return rounds-1;
|
||||||
}
|
}
|
||||||
|
@ -1776,7 +1776,7 @@ bool IsInitialBlockDownload()
|
|||||||
nLastUpdate = GetTime();
|
nLastUpdate = GetTime();
|
||||||
}
|
}
|
||||||
return (GetTime() - nLastUpdate < 10 &&
|
return (GetTime() - nLastUpdate < 10 &&
|
||||||
chainActive.Tip()->GetBlockTime() < GetTime() - 24 * 60 * 60);
|
chainActive.Tip()->GetBlockTime() < GetTime() - 6 * 60 * 60); // ~144 blocks behind -> 2 x fork detection time
|
||||||
}
|
}
|
||||||
|
|
||||||
CBlockIndex *pindexBestForkTip = NULL, *pindexBestForkBase = NULL;
|
CBlockIndex *pindexBestForkTip = NULL, *pindexBestForkBase = NULL;
|
||||||
@ -1789,7 +1789,7 @@ void CheckForkWarningConditions()
|
|||||||
if (IsInitialBlockDownload())
|
if (IsInitialBlockDownload())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If our best fork is no longer within 72 blocks (+/- 12 hours if no one mines it)
|
// If our best fork is no longer within 72 blocks (+/- 3 hours if no one mines it)
|
||||||
// of our head, drop it
|
// of our head, drop it
|
||||||
if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->nHeight >= 72)
|
if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->nHeight >= 72)
|
||||||
pindexBestForkTip = NULL;
|
pindexBestForkTip = NULL;
|
||||||
@ -1842,7 +1842,7 @@ void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We define a condition which we should warn the user about as a fork of at least 7 blocks
|
// We define a condition which we should warn the user about as a fork of at least 7 blocks
|
||||||
// who's tip is within 72 blocks (+/- 12 hours if no one mines it) of ours
|
// who's tip is within 72 blocks (+/- 3 hours if no one mines it) of ours
|
||||||
// We use 7 blocks rather arbitrarily as it represents just under 10% of sustained network
|
// We use 7 blocks rather arbitrarily as it represents just under 10% of sustained network
|
||||||
// hash rate operating on the fork.
|
// hash rate operating on the fork.
|
||||||
// or a chain that is entirely longer than ours and invalid (note that this should be detected by both)
|
// or a chain that is entirely longer than ours and invalid (note that this should be detected by both)
|
||||||
|
@ -170,7 +170,7 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) :
|
|||||||
// Progress bar and label for blocks download
|
// Progress bar and label for blocks download
|
||||||
progressBarLabel = new QLabel();
|
progressBarLabel = new QLabel();
|
||||||
progressBarLabel->setVisible(false);
|
progressBarLabel->setVisible(false);
|
||||||
progressBar = new QProgressBar();
|
progressBar = new GUIUtil::ProgressBar();
|
||||||
progressBar->setAlignment(Qt::AlignCenter);
|
progressBar->setAlignment(Qt::AlignCenter);
|
||||||
progressBar->setVisible(false);
|
progressBar->setVisible(false);
|
||||||
|
|
||||||
@ -670,7 +670,7 @@ void BitcoinGUI::setNumBlocks(int count)
|
|||||||
tooltip = tr("Processed %1 blocks of transaction history.").arg(count);
|
tooltip = tr("Processed %1 blocks of transaction history.").arg(count);
|
||||||
|
|
||||||
// Set icon state: spinning if catching up, tick otherwise
|
// Set icon state: spinning if catching up, tick otherwise
|
||||||
if(secs < 90*60)
|
if(secs < 25*60) // 90*60 for bitcoin but we are 4x times faster
|
||||||
{
|
{
|
||||||
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
|
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
|
||||||
labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
|
labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
|
||||||
|
@ -383,25 +383,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>10</x>
|
|
||||||
<y>10</y>
|
|
||||||
<width>66</width>
|
|
||||||
<height>20</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Darksend</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QPushButton" name="runAutoDenom">
|
<widget class="QPushButton" name="runAutoDenom">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
@ -943,6 +924,60 @@
|
|||||||
<string>Reset</string>
|
<string>Reset</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>10</y>
|
||||||
|
<width>431</width>
|
||||||
|
<height>22</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Darksend</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelDarksendSyncStatus">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>The displayed information may be out of date. Your wallet automatically synchronizes with the Darkcoin network after a connection is established, but this process has not completed yet.</string>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QLabel { color: red; }</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">(out of sync)</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -5,9 +5,11 @@
|
|||||||
#ifndef GUIUTIL_H
|
#ifndef GUIUTIL_H
|
||||||
#define GUIUTIL_H
|
#define GUIUTIL_H
|
||||||
|
|
||||||
|
#include <QEvent>
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QProgressBar>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QTableView>
|
#include <QTableView>
|
||||||
|
|
||||||
@ -177,6 +179,20 @@ namespace GUIUtil
|
|||||||
/* Convert OS specific boost path to QString through UTF-8 */
|
/* Convert OS specific boost path to QString through UTF-8 */
|
||||||
QString boostPathToQString(const boost::filesystem::path &path);
|
QString boostPathToQString(const boost::filesystem::path &path);
|
||||||
|
|
||||||
|
#if defined(Q_OS_MAC) && QT_VERSION >= 0x050000
|
||||||
|
// workaround for Qt OSX Bug:
|
||||||
|
// https://bugreports.qt-project.org/browse/QTBUG-15631
|
||||||
|
// QProgressBar uses around 10% CPU even when app is in background
|
||||||
|
class ProgressBar : public QProgressBar
|
||||||
|
{
|
||||||
|
bool event(QEvent *e) {
|
||||||
|
return (e->type() != QEvent::StyleAnimationUpdate) ? QProgressBar::event(e) : false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
typedef QProgressBar ProgressBar;
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace GUIUtil
|
} // namespace GUIUtil
|
||||||
|
|
||||||
#endif // GUIUTIL_H
|
#endif // GUIUTIL_H
|
||||||
|
@ -124,6 +124,7 @@ OverviewPage::OverviewPage(QWidget *parent) :
|
|||||||
|
|
||||||
// init "out of sync" warning labels
|
// init "out of sync" warning labels
|
||||||
ui->labelWalletStatus->setText("(" + tr("out of sync") + ")");
|
ui->labelWalletStatus->setText("(" + tr("out of sync") + ")");
|
||||||
|
ui->labelDarksendSyncStatus->setText("(" + tr("out of sync") + ")");
|
||||||
ui->labelTransactionsStatus->setText("(" + tr("out of sync") + ")");
|
ui->labelTransactionsStatus->setText("(" + tr("out of sync") + ")");
|
||||||
|
|
||||||
showingDarkSendMessage = 0;
|
showingDarkSendMessage = 0;
|
||||||
@ -253,6 +254,7 @@ void OverviewPage::updateAlerts(const QString &warnings)
|
|||||||
void OverviewPage::showOutOfSyncWarning(bool fShow)
|
void OverviewPage::showOutOfSyncWarning(bool fShow)
|
||||||
{
|
{
|
||||||
ui->labelWalletStatus->setVisible(fShow);
|
ui->labelWalletStatus->setVisible(fShow);
|
||||||
|
ui->labelDarksendSyncStatus->setVisible(fShow);
|
||||||
ui->labelTransactionsStatus->setVisible(fShow);
|
ui->labelTransactionsStatus->setVisible(fShow);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,7 +293,7 @@ void OverviewPage::updateDarksendProgress()
|
|||||||
float denomPart = 0;
|
float denomPart = 0;
|
||||||
if(denominatedBalance > 0)
|
if(denominatedBalance > 0)
|
||||||
{
|
{
|
||||||
denomPart = (float)pwalletMain->GetNormalizedAnonymizedBalance() / pwalletMain->GetDenominatedBalance();
|
denomPart = (float)pwalletMain->GetNormalizedAnonymizedBalance() / denominatedBalance;
|
||||||
denomPart = denomPart > 1 ? 1 : denomPart;
|
denomPart = denomPart > 1 ? 1 : denomPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,16 +91,10 @@ public:
|
|||||||
|
|
||||||
Call with transaction that was added, removed or changed.
|
Call with transaction that was added, removed or changed.
|
||||||
*/
|
*/
|
||||||
void updateWallet(const uint256 &hash, int status)
|
void updateWallet(const uint256 &hash, int status, bool showTransaction)
|
||||||
{
|
{
|
||||||
|
|
||||||
qDebug() << "TransactionTablePriv::updateWallet : " + QString::fromStdString(hash.ToString()) + " " + QString::number(status);
|
qDebug() << "TransactionTablePriv::updateWallet : " + QString::fromStdString(hash.ToString()) + " " + QString::number(status);
|
||||||
{
|
|
||||||
LOCK2(cs_main, wallet->cs_wallet);
|
|
||||||
|
|
||||||
// Find transaction in wallet
|
|
||||||
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash);
|
|
||||||
bool inWallet = mi != wallet->mapWallet.end();
|
|
||||||
|
|
||||||
// Find bounds of this transaction in model
|
// Find bounds of this transaction in model
|
||||||
QList<TransactionRecord>::iterator lower = qLowerBound(
|
QList<TransactionRecord>::iterator lower = qLowerBound(
|
||||||
@ -111,9 +105,6 @@ public:
|
|||||||
int upperIndex = (upper - cachedWallet.begin());
|
int upperIndex = (upper - cachedWallet.begin());
|
||||||
bool inModel = (lower != upper);
|
bool inModel = (lower != upper);
|
||||||
|
|
||||||
// Determine whether to show transaction or not
|
|
||||||
bool showTransaction = (inWallet && TransactionRecord::showTransaction(mi->second));
|
|
||||||
|
|
||||||
if(status == CT_UPDATED)
|
if(status == CT_UPDATED)
|
||||||
{
|
{
|
||||||
if(showTransaction && !inModel)
|
if(showTransaction && !inModel)
|
||||||
@ -122,7 +113,7 @@ public:
|
|||||||
status = CT_DELETED; /* In model, but want to hide, treat as deleted */
|
status = CT_DELETED; /* In model, but want to hide, treat as deleted */
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << " inWallet=" + QString::number(inWallet) + " inModel=" + QString::number(inModel) +
|
qDebug() << " inModel=" + QString::number(inModel) +
|
||||||
" Index=" + QString::number(lowerIndex) + "-" + QString::number(upperIndex) +
|
" Index=" + QString::number(lowerIndex) + "-" + QString::number(upperIndex) +
|
||||||
" showTransaction=" + QString::number(showTransaction) + " derivedStatus=" + QString::number(status);
|
" showTransaction=" + QString::number(showTransaction) + " derivedStatus=" + QString::number(status);
|
||||||
|
|
||||||
@ -131,16 +122,19 @@ public:
|
|||||||
case CT_NEW:
|
case CT_NEW:
|
||||||
if(inModel)
|
if(inModel)
|
||||||
{
|
{
|
||||||
qDebug() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is already in model";
|
qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is already in model";
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(!inWallet)
|
|
||||||
{
|
|
||||||
qDebug() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is not in wallet";
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(showTransaction)
|
if(showTransaction)
|
||||||
{
|
{
|
||||||
|
LOCK2(cs_main, wallet->cs_wallet);
|
||||||
|
// Find transaction in wallet
|
||||||
|
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash);
|
||||||
|
if(mi == wallet->mapWallet.end())
|
||||||
|
{
|
||||||
|
qDebug() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is not in wallet";
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Added -- insert at the right position
|
// Added -- insert at the right position
|
||||||
QList<TransactionRecord> toInsert =
|
QList<TransactionRecord> toInsert =
|
||||||
TransactionRecord::decomposeTransaction(wallet, mi->second);
|
TransactionRecord::decomposeTransaction(wallet, mi->second);
|
||||||
@ -160,7 +154,7 @@ public:
|
|||||||
case CT_DELETED:
|
case CT_DELETED:
|
||||||
if(!inModel)
|
if(!inModel)
|
||||||
{
|
{
|
||||||
qDebug() << "TransactionTablePriv::updateWallet : Warning: Got CT_DELETED, but transaction is not in model";
|
qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_DELETED, but transaction is not in model";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Removed -- remove entire transaction from table
|
// Removed -- remove entire transaction from table
|
||||||
@ -174,7 +168,6 @@ public:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int size()
|
int size()
|
||||||
{
|
{
|
||||||
@ -234,26 +227,30 @@ TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *paren
|
|||||||
QAbstractTableModel(parent),
|
QAbstractTableModel(parent),
|
||||||
wallet(wallet),
|
wallet(wallet),
|
||||||
walletModel(parent),
|
walletModel(parent),
|
||||||
priv(new TransactionTablePriv(wallet, this))
|
priv(new TransactionTablePriv(wallet, this)),
|
||||||
|
fProcessingQueuedTransactions(false)
|
||||||
{
|
{
|
||||||
columns << QString() << tr("Date") << tr("Type") << tr("Address") << tr("Amount");
|
columns << QString() << tr("Date") << tr("Type") << tr("Address") << tr("Amount");
|
||||||
|
|
||||||
priv->refreshWallet();
|
priv->refreshWallet();
|
||||||
|
|
||||||
connect(walletModel->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
connect(walletModel->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||||
|
|
||||||
|
subscribeToCoreSignals();
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionTableModel::~TransactionTableModel()
|
TransactionTableModel::~TransactionTableModel()
|
||||||
{
|
{
|
||||||
|
unsubscribeFromCoreSignals();
|
||||||
delete priv;
|
delete priv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransactionTableModel::updateTransaction(const QString &hash, int status)
|
void TransactionTableModel::updateTransaction(const QString &hash, int status, bool showTransaction)
|
||||||
{
|
{
|
||||||
uint256 updated;
|
uint256 updated;
|
||||||
updated.SetHex(hash.toStdString());
|
updated.SetHex(hash.toStdString());
|
||||||
|
|
||||||
priv->updateWallet(updated, status);
|
priv->updateWallet(updated, status, showTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransactionTableModel::updateConfirmations()
|
void TransactionTableModel::updateConfirmations()
|
||||||
@ -644,3 +641,82 @@ void TransactionTableModel::updateDisplayUnit()
|
|||||||
// emit dataChanged to update Amount column with the current unit
|
// emit dataChanged to update Amount column with the current unit
|
||||||
emit dataChanged(index(0, Amount), index(priv->size()-1, Amount));
|
emit dataChanged(index(0, Amount), index(priv->size()-1, Amount));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// queue notifications to show a non freezing progress dialog e.g. for rescan
|
||||||
|
struct TransactionNotification
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TransactionNotification() {}
|
||||||
|
TransactionNotification(uint256 hash, ChangeType status, bool showTransaction):
|
||||||
|
hash(hash), status(status), showTransaction(showTransaction) {}
|
||||||
|
|
||||||
|
void invoke(QObject *ttm)
|
||||||
|
{
|
||||||
|
QString strHash = QString::fromStdString(hash.GetHex());
|
||||||
|
qDebug() << "NotifyTransactionChanged : " + strHash + " status= " + QString::number(status);
|
||||||
|
QMetaObject::invokeMethod(ttm, "updateTransaction", Qt::QueuedConnection,
|
||||||
|
Q_ARG(QString, strHash),
|
||||||
|
Q_ARG(int, status),
|
||||||
|
Q_ARG(bool, showTransaction));
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
uint256 hash;
|
||||||
|
ChangeType status;
|
||||||
|
bool showTransaction;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool fQueueNotifications = false;
|
||||||
|
static std::vector< TransactionNotification > vQueueNotifications;
|
||||||
|
|
||||||
|
static void NotifyTransactionChanged(TransactionTableModel *ttm, CWallet *wallet, const uint256 &hash, ChangeType status)
|
||||||
|
{
|
||||||
|
// Find transaction in wallet
|
||||||
|
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash);
|
||||||
|
// Determine whether to show transaction or not (determine this here so that no relocking is needed in GUI thread)
|
||||||
|
bool inWallet = mi != wallet->mapWallet.end();
|
||||||
|
bool showTransaction = (inWallet && TransactionRecord::showTransaction(mi->second));
|
||||||
|
|
||||||
|
TransactionNotification notification(hash, status, showTransaction);
|
||||||
|
|
||||||
|
if (fQueueNotifications)
|
||||||
|
{
|
||||||
|
vQueueNotifications.push_back(notification);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
notification.invoke(ttm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ShowProgress(TransactionTableModel *ttm, const std::string &title, int nProgress)
|
||||||
|
{
|
||||||
|
if (nProgress == 0)
|
||||||
|
fQueueNotifications = true;
|
||||||
|
|
||||||
|
if (nProgress == 100)
|
||||||
|
{
|
||||||
|
fQueueNotifications = false;
|
||||||
|
if (vQueueNotifications.size() > 10) // prevent balloon spam, show maximum 10 balloons
|
||||||
|
QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true));
|
||||||
|
for (unsigned int i = 0; i < vQueueNotifications.size(); ++i)
|
||||||
|
{
|
||||||
|
if (vQueueNotifications.size() - i <= 10)
|
||||||
|
QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, false));
|
||||||
|
|
||||||
|
vQueueNotifications[i].invoke(ttm);
|
||||||
|
}
|
||||||
|
std::vector<TransactionNotification >().swap(vQueueNotifications); // clear
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransactionTableModel::subscribeToCoreSignals()
|
||||||
|
{
|
||||||
|
// Connect signals to wallet
|
||||||
|
wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
|
||||||
|
wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransactionTableModel::unsubscribeFromCoreSignals()
|
||||||
|
{
|
||||||
|
// Disconnect signals from wallet
|
||||||
|
wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
|
||||||
|
wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
|
||||||
|
}
|
||||||
|
@ -65,12 +65,17 @@ public:
|
|||||||
QVariant data(const QModelIndex &index, int role) const;
|
QVariant data(const QModelIndex &index, int role) const;
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||||
QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
|
QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
|
||||||
|
bool processingQueuedTransactions() { return fProcessingQueuedTransactions; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CWallet* wallet;
|
CWallet* wallet;
|
||||||
WalletModel *walletModel;
|
WalletModel *walletModel;
|
||||||
QStringList columns;
|
QStringList columns;
|
||||||
TransactionTablePriv *priv;
|
TransactionTablePriv *priv;
|
||||||
|
bool fProcessingQueuedTransactions;
|
||||||
|
|
||||||
|
void subscribeToCoreSignals();
|
||||||
|
void unsubscribeFromCoreSignals();
|
||||||
|
|
||||||
QString lookupAddress(const std::string &address, bool tooltip) const;
|
QString lookupAddress(const std::string &address, bool tooltip) const;
|
||||||
QVariant addressColor(const TransactionRecord *wtx) const;
|
QVariant addressColor(const TransactionRecord *wtx) const;
|
||||||
@ -84,9 +89,12 @@ private:
|
|||||||
QVariant txAddressDecoration(const TransactionRecord *wtx) const;
|
QVariant txAddressDecoration(const TransactionRecord *wtx) const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateTransaction(const QString &hash, int status);
|
/* New transaction, or transaction changed status */
|
||||||
|
void updateTransaction(const QString &hash, int status, bool showTransaction);
|
||||||
void updateConfirmations();
|
void updateConfirmations();
|
||||||
void updateDisplayUnit();
|
void updateDisplayUnit();
|
||||||
|
/* Needed to update fProcessingQueuedTransactions through a QueuedConnection */
|
||||||
|
void setProcessingQueuedTransactions(bool value) { fProcessingQueuedTransactions = value; }
|
||||||
|
|
||||||
friend class TransactionTablePriv;
|
friend class TransactionTablePriv;
|
||||||
};
|
};
|
||||||
|
@ -35,6 +35,8 @@ WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *p
|
|||||||
cachedEncryptionStatus(Unencrypted),
|
cachedEncryptionStatus(Unencrypted),
|
||||||
cachedNumBlocks(0)
|
cachedNumBlocks(0)
|
||||||
{
|
{
|
||||||
|
fForceCheckBalanceChanged = false;
|
||||||
|
|
||||||
addressTableModel = new AddressTableModel(wallet, this);
|
addressTableModel = new AddressTableModel(wallet, this);
|
||||||
transactionTableModel = new TransactionTableModel(wallet, this);
|
transactionTableModel = new TransactionTableModel(wallet, this);
|
||||||
recentRequestsTableModel = new RecentRequestsTableModel(wallet, this);
|
recentRequestsTableModel = new RecentRequestsTableModel(wallet, this);
|
||||||
@ -71,8 +73,8 @@ qint64 WalletModel::getBalance(const CCoinControl *coinControl) const
|
|||||||
|
|
||||||
qint64 WalletModel::getAnonymizedBalance() const
|
qint64 WalletModel::getAnonymizedBalance() const
|
||||||
{
|
{
|
||||||
qint64 ret = wallet->GetAnonymizedBalance();
|
if(fLiteMode) return 0;
|
||||||
return ret;
|
return wallet->GetAnonymizedBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 WalletModel::getUnconfirmedBalance() const
|
qint64 WalletModel::getUnconfirmedBalance() const
|
||||||
@ -149,11 +151,8 @@ void WalletModel::checkBalanceChanged()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WalletModel::updateTransaction(const QString &hash, int status)
|
void WalletModel::updateTransaction()
|
||||||
{
|
{
|
||||||
if(transactionTableModel)
|
|
||||||
transactionTableModel->updateTransaction(hash, status);
|
|
||||||
|
|
||||||
// Balance and number of transactions might have changed
|
// Balance and number of transactions might have changed
|
||||||
checkBalanceChanged();
|
checkBalanceChanged();
|
||||||
|
|
||||||
@ -485,23 +484,12 @@ static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet,
|
|||||||
Q_ARG(int, status));
|
Q_ARG(int, status));
|
||||||
}
|
}
|
||||||
|
|
||||||
// queue notifications to show a non freezing progress dialog e.g. for rescan
|
|
||||||
static bool fQueueNotifications = false;
|
|
||||||
static std::vector<std::pair<uint256, ChangeType> > vQueueNotifications;
|
|
||||||
static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, const uint256 &hash, ChangeType status)
|
static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, const uint256 &hash, ChangeType status)
|
||||||
{
|
{
|
||||||
if (fQueueNotifications)
|
Q_UNUSED(wallet);
|
||||||
{
|
Q_UNUSED(hash);
|
||||||
vQueueNotifications.push_back(make_pair(hash, status));
|
Q_UNUSED(status);
|
||||||
return;
|
QMetaObject::invokeMethod(walletmodel, "updateTransaction", Qt::QueuedConnection);
|
||||||
}
|
|
||||||
|
|
||||||
QString strHash = QString::fromStdString(hash.GetHex());
|
|
||||||
|
|
||||||
qDebug() << "NotifyTransactionChanged : " + strHash + " status= " + QString::number(status);
|
|
||||||
QMetaObject::invokeMethod(walletmodel, "updateTransaction", Qt::QueuedConnection,
|
|
||||||
Q_ARG(QString, strHash),
|
|
||||||
Q_ARG(int, status));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShowProgress(WalletModel *walletmodel, const std::string &title, int nProgress)
|
static void ShowProgress(WalletModel *walletmodel, const std::string &title, int nProgress)
|
||||||
@ -510,17 +498,6 @@ static void ShowProgress(WalletModel *walletmodel, const std::string &title, int
|
|||||||
QMetaObject::invokeMethod(walletmodel, "showProgress", Qt::QueuedConnection,
|
QMetaObject::invokeMethod(walletmodel, "showProgress", Qt::QueuedConnection,
|
||||||
Q_ARG(QString, QString::fromStdString(title)),
|
Q_ARG(QString, QString::fromStdString(title)),
|
||||||
Q_ARG(int, nProgress));
|
Q_ARG(int, nProgress));
|
||||||
|
|
||||||
if (nProgress == 0)
|
|
||||||
fQueueNotifications = true;
|
|
||||||
|
|
||||||
if (nProgress == 100)
|
|
||||||
{
|
|
||||||
fQueueNotifications = false;
|
|
||||||
BOOST_FOREACH(const PAIRTYPE(uint256, ChangeType)& notification, vQueueNotifications)
|
|
||||||
NotifyTransactionChanged(walletmodel, NULL, notification.first, notification.second);
|
|
||||||
std::vector<std::pair<uint256, ChangeType> >().swap(vQueueNotifications); // clear
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WalletModel::subscribeToCoreSignals()
|
void WalletModel::subscribeToCoreSignals()
|
||||||
|
@ -202,6 +202,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
CWallet *wallet;
|
CWallet *wallet;
|
||||||
|
bool fForceCheckBalanceChanged;
|
||||||
|
|
||||||
// Wallet has an options model for wallet-specific options
|
// Wallet has an options model for wallet-specific options
|
||||||
// (transaction fee, for example)
|
// (transaction fee, for example)
|
||||||
@ -256,7 +257,7 @@ public slots:
|
|||||||
/* Wallet status might have changed */
|
/* Wallet status might have changed */
|
||||||
void updateStatus();
|
void updateStatus();
|
||||||
/* New transaction, or transaction changed status */
|
/* New transaction, or transaction changed status */
|
||||||
void updateTransaction(const QString &hash, int status);
|
void updateTransaction();
|
||||||
/* New, updated or removed address book entry */
|
/* New, updated or removed address book entry */
|
||||||
void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
|
void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
|
||||||
/* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
|
/* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
|
||||||
|
@ -141,6 +141,8 @@ void WalletView::processNewTransaction(const QModelIndex& parent, int start, int
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
TransactionTableModel *ttm = walletModel->getTransactionTableModel();
|
TransactionTableModel *ttm = walletModel->getTransactionTableModel();
|
||||||
|
if (!ttm || ttm->processingQueuedTransactions())
|
||||||
|
return;
|
||||||
|
|
||||||
QString date = ttm->index(start, TransactionTableModel::Date, parent).data().toString();
|
QString date = ttm->index(start, TransactionTableModel::Date, parent).data().toString();
|
||||||
qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent).data(Qt::EditRole).toULongLong();
|
qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent).data(Qt::EditRole).toULongLong();
|
||||||
|
@ -1092,21 +1092,19 @@ int64_t CWallet::GetAnonymizedBalance() const
|
|||||||
{
|
{
|
||||||
int64_t nTotal = 0;
|
int64_t nTotal = 0;
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet);
|
LOCK2(cs_main, cs_wallet);
|
||||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||||
{
|
{
|
||||||
const CWalletTx* pcoin = &(*it).second;
|
const CWalletTx* pcoin = &(*it).second;
|
||||||
|
|
||||||
if (pcoin->IsTrusted())
|
if (pcoin->IsTrusted())
|
||||||
{
|
{
|
||||||
int nDepth = pcoin->GetDepthInMainChain(false);
|
uint256 hash = (*it).first;
|
||||||
|
for (unsigned int i = 0; i < pcoin->vout.size(); i++)
|
||||||
|
{
|
||||||
|
CTxIn vin = CTxIn(hash, i);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
|
if(IsSpent(hash, i) || !IsMine(pcoin->vout[i]) || !IsDenominated(vin)) continue;
|
||||||
|
|
||||||
COutput out = COutput(pcoin, i, nDepth);
|
|
||||||
CTxIn vin = CTxIn(out.tx->GetHash(), out.i);
|
|
||||||
|
|
||||||
if(IsSpent(out.tx->GetHash(), i) || !IsMine(pcoin->vout[i]) || !IsDenominated(vin)) continue;
|
|
||||||
|
|
||||||
int rounds = GetInputDarksendRounds(vin);
|
int rounds = GetInputDarksendRounds(vin);
|
||||||
if(rounds >= nDarksendRounds){
|
if(rounds >= nDarksendRounds){
|
||||||
@ -1126,21 +1124,20 @@ double CWallet::GetAverageAnonymizedRounds() const
|
|||||||
double fCount = 0;
|
double fCount = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet);
|
LOCK2(cs_main, cs_wallet);
|
||||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||||
{
|
{
|
||||||
const CWalletTx* pcoin = &(*it).second;
|
const CWalletTx* pcoin = &(*it).second;
|
||||||
|
|
||||||
if (pcoin->IsTrusted())
|
if (pcoin->IsTrusted())
|
||||||
{
|
{
|
||||||
int nDepth = pcoin->GetDepthInMainChain(false);
|
uint256 hash = (*it).first;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
|
for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
|
||||||
|
|
||||||
COutput out = COutput(pcoin, i, nDepth);
|
CTxIn vin = CTxIn(hash, i);
|
||||||
CTxIn vin = CTxIn(out.tx->GetHash(), out.i);
|
|
||||||
|
|
||||||
if(IsSpent(out.tx->GetHash(), i) || !IsMine(pcoin->vout[i]) || !IsDenominated(vin)) continue;
|
if(IsSpent(hash, i) || !IsMine(pcoin->vout[i]) || !IsDenominated(vin)) continue;
|
||||||
|
|
||||||
int rounds = GetInputDarksendRounds(vin);
|
int rounds = GetInputDarksendRounds(vin);
|
||||||
fTotal += (float)rounds;
|
fTotal += (float)rounds;
|
||||||
@ -1160,21 +1157,20 @@ int64_t CWallet::GetNormalizedAnonymizedBalance() const
|
|||||||
int64_t nTotal = 0;
|
int64_t nTotal = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet);
|
LOCK2(cs_main, cs_wallet);
|
||||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||||
{
|
{
|
||||||
const CWalletTx* pcoin = &(*it).second;
|
const CWalletTx* pcoin = &(*it).second;
|
||||||
|
|
||||||
if (pcoin->IsTrusted())
|
if (pcoin->IsTrusted())
|
||||||
{
|
{
|
||||||
int nDepth = pcoin->GetDepthInMainChain(false);
|
uint256 hash = (*it).first;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
|
for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
|
||||||
|
|
||||||
COutput out = COutput(pcoin, i, nDepth);
|
CTxIn vin = CTxIn(hash, i);
|
||||||
CTxIn vin = CTxIn(out.tx->GetHash(), out.i);
|
|
||||||
|
|
||||||
if(IsSpent(out.tx->GetHash(), i) || !IsMine(pcoin->vout[i]) || !IsDenominated(vin)) continue;
|
if(IsSpent(hash, i) || !IsMine(pcoin->vout[i]) || !IsDenominated(vin)) continue;
|
||||||
|
|
||||||
int rounds = GetInputDarksendRounds(vin);
|
int rounds = GetInputDarksendRounds(vin);
|
||||||
nTotal += pcoin->vout[i].nValue * rounds / nDarksendRounds;
|
nTotal += pcoin->vout[i].nValue * rounds / nDarksendRounds;
|
||||||
@ -1190,7 +1186,7 @@ int64_t CWallet::GetDenominatedBalance(bool onlyDenom, bool onlyUnconfirmed) con
|
|||||||
{
|
{
|
||||||
int64_t nTotal = 0;
|
int64_t nTotal = 0;
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet);
|
LOCK2(cs_main, cs_wallet);
|
||||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||||
{
|
{
|
||||||
const CWalletTx* pcoin = &(*it).second;
|
const CWalletTx* pcoin = &(*it).second;
|
||||||
@ -1202,12 +1198,11 @@ int64_t CWallet::GetDenominatedBalance(bool onlyDenom, bool onlyUnconfirmed) con
|
|||||||
|
|
||||||
bool unconfirmed = (!IsFinalTx(*pcoin) || (!pcoin->IsTrusted() && nDepth == 0));
|
bool unconfirmed = (!IsFinalTx(*pcoin) || (!pcoin->IsTrusted() && nDepth == 0));
|
||||||
if(onlyUnconfirmed != unconfirmed) continue;
|
if(onlyUnconfirmed != unconfirmed) continue;
|
||||||
|
uint256 hash = (*it).first;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < pcoin->vout.size(); i++)
|
for (unsigned int i = 0; i < pcoin->vout.size(); i++)
|
||||||
{
|
{
|
||||||
COutput out = COutput(pcoin, i, nDepth);
|
if(IsSpent(hash, i)) continue;
|
||||||
|
|
||||||
if(IsSpent(out.tx->GetHash(), i)) continue;
|
|
||||||
if(!IsMine(pcoin->vout[i])) continue;
|
if(!IsMine(pcoin->vout[i])) continue;
|
||||||
if(onlyDenom != IsDenominatedAmount(pcoin->vout[i].nValue)) continue;
|
if(onlyDenom != IsDenominatedAmount(pcoin->vout[i].nValue)) continue;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user