Merge pull request #323 from UdjinM6/v0.12.0.x_fix_ds_mixing

V0.12.0.x DS fixes
This commit is contained in:
evan82 2015-05-02 19:43:07 -07:00
commit a689f630ed
4 changed files with 109 additions and 25 deletions

View File

@ -1418,25 +1418,28 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
// ** find the coins we'll use
std::vector<CTxIn> vCoins;
int64_t nValueMin = CENT;
int64_t nValueIn = 0;
CAmount nValueMin = CENT;
CAmount nValueIn = 0;
CAmount nOnlyDenominatedBalance;
CAmount nBalanceNeedsDenominated;
// should not be less than fees in DARKSEND_COLLATERAL + few (lets say 5) smallest denoms
int64_t nLowestDenom = DARKSEND_COLLATERAL + darkSendDenominations[darkSendDenominations.size() - 1]*5;
CAmount nLowestDenom = DARKSEND_COLLATERAL + darkSendDenominations[darkSendDenominations.size() - 1]*5;
// if there are no DS collateral inputs yet
if(!pwalletMain->HasCollateralInputs())
// should have some additional amount for them
nLowestDenom += DARKSEND_COLLATERAL*4;
int64_t nBalanceNeedsAnonymized = nAnonymizeDarkcoinAmount*COIN - pwalletMain->GetAnonymizedBalance();
CAmount nBalanceNeedsAnonymized = nAnonymizeDarkcoinAmount*COIN - pwalletMain->GetAnonymizedBalance();
// if balanceNeedsAnonymized is more than pool max, take the pool max
if(nBalanceNeedsAnonymized > DARKSEND_POOL_MAX) nBalanceNeedsAnonymized = DARKSEND_POOL_MAX;
// if balanceNeedsAnonymized is more than non-anonymized, take non-anonymized
int64_t nBalanceNotYetAnonymized = pwalletMain->GetBalance() - pwalletMain->GetAnonymizedBalance();
if(nBalanceNeedsAnonymized > nBalanceNotYetAnonymized) nBalanceNeedsAnonymized = nBalanceNotYetAnonymized;
CAmount nAnonymizableBalance = pwalletMain->GetAnonymizableBalance();
if(nBalanceNeedsAnonymized > nAnonymizableBalance) nBalanceNeedsAnonymized = nAnonymizableBalance;
if(nBalanceNeedsAnonymized < nLowestDenom)
{
@ -1455,7 +1458,13 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
if (pwalletMain->SelectCoinsDark(nValueMin, 9999999*COIN, vCoins, nValueIn, -2, 0))
{
if(!fDryRun) return CreateDenominated(nBalanceNeedsAnonymized);
nOnlyDenominatedBalance = pwalletMain->GetDenominatedBalance(true, false, false);
nBalanceNeedsDenominated = nBalanceNeedsAnonymized - nOnlyDenominatedBalance;
if(nBalanceNeedsDenominated > nValueIn) nBalanceNeedsDenominated = nValueIn;
if(!fDryRun) return CreateDenominated(nBalanceNeedsDenominated);
return true;
} else {
LogPrintf("DoAutomaticDenominating : Can't denominate - no compatible inputs left\n");
@ -1465,6 +1474,11 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
}
nOnlyDenominatedBalance = pwalletMain->GetDenominatedBalance(true, false, false);
nBalanceNeedsDenominated = nBalanceNeedsAnonymized - nOnlyDenominatedBalance;
if(!fDryRun && nBalanceNeedsDenominated > nOnlyDenominatedBalance) return CreateDenominated(nBalanceNeedsDenominated);
//check to see if we have the collateral sized inputs, it requires these
if(!pwalletMain->HasCollateralInputs()){
if(!fDryRun) MakeCollateralAmounts();
@ -1622,7 +1636,7 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
pSubmittedToMasternode = pmn;
vecMasternodesUsed.push_back(pmn->vin);
std::vector<int64_t> vecAmounts;
std::vector<CAmount> vecAmounts;
pwalletMain->ConvertList(vCoins, vecAmounts);
sessionDenom = GetDenominationsByAmounts(vecAmounts);

View File

@ -313,6 +313,14 @@ void OverviewPage::updateDarksendProgress()
ui->darksendProgress->setValue(0);
QString s(tr("No inputs detected"));
ui->darksendProgress->setToolTip(s);
// when balance is zero just show info from settings
QString strSettings = BitcoinUnits::formatWithUnit(
walletModel->getOptionsModel()->getDisplayUnit(),
nAnonymizeDarkcoinAmount * COIN
) + " / " + tr("%n Rounds", "", nDarksendRounds);
ui->labelAmountRounds->setText(strSettings);
return;
}
@ -324,11 +332,10 @@ void OverviewPage::updateDarksendProgress()
return;
}
//Get the anon threshold
int64_t nMaxToAnonymize = nAnonymizeDarkcoinAmount*COIN;
int64_t nMaxToAnonymize = pwalletMain->GetAnonymizableBalance(true);
// If it's more than the wallet amount, limit to that.
if(nMaxToAnonymize > nBalance) nMaxToAnonymize = nBalance;
// If it's more than the anon threshold, limit to that.
if(nMaxToAnonymize > nAnonymizeDarkcoinAmount*COIN) nMaxToAnonymize = nAnonymizeDarkcoinAmount*COIN;
if(nMaxToAnonymize == 0) return;
@ -340,7 +347,6 @@ void OverviewPage::updateDarksendProgress()
{
denomPart = (float)pwalletMain->GetNormalizedAnonymizedBalance() / denominatedBalance;
denomPart = denomPart > 1 ? 1 : denomPart;
if(denomPart == 1 && nMaxToAnonymize > denominatedBalance) nMaxToAnonymize = denominatedBalance;
}
// % of fully anonymized balance
@ -360,6 +366,36 @@ void OverviewPage::updateDarksendProgress()
QString strToolPip = tr("Progress: %1% (inputs have an average of %2 of %n rounds)", "", nDarksendRounds).arg(progress).arg(pwalletMain->GetAverageAnonymizedRounds());
ui->darksendProgress->setToolTip(strToolPip);
QString strSettings;
if(nMaxToAnonymize >= nAnonymizeDarkcoinAmount * COIN) {
ui->labelAmountRounds->setToolTip(tr("Found enough compatible inputs to anonymize %1")
.arg(BitcoinUnits::formatWithUnit(
walletModel->getOptionsModel()->getDisplayUnit(),
nAnonymizeDarkcoinAmount * COIN
)));
strSettings = BitcoinUnits::formatWithUnit(
walletModel->getOptionsModel()->getDisplayUnit(),
nAnonymizeDarkcoinAmount * COIN
) + " / " + tr("%n Rounds", "", nDarksendRounds);
} else {
ui->labelAmountRounds->setToolTip(tr("Not enough compatible inputs to anonymize <span style='color:red;'>%1</span>,<br/>"
"will anonymize <span style='color:red;'>%2</span> instead")
.arg(BitcoinUnits::formatWithUnit(
walletModel->getOptionsModel()->getDisplayUnit(),
nAnonymizeDarkcoinAmount * COIN
))
.arg(BitcoinUnits::formatWithUnit(
walletModel->getOptionsModel()->getDisplayUnit(),
nMaxToAnonymize
)));
strSettings = "<span style='color:red;'>" + BitcoinUnits::formatWithUnit(
walletModel->getOptionsModel()->getDisplayUnit(),
nMaxToAnonymize
) + " / " + tr("%n Rounds", "", nDarksendRounds) + "</span>";
}
ui->labelAmountRounds->setText(strSettings);
}
@ -374,13 +410,6 @@ void OverviewPage::darkSendStatus()
lastNewBlock = GetTime();
updateDarksendProgress();
QString strSettings = BitcoinUnits::formatWithUnit(
walletModel->getOptionsModel()->getDisplayUnit(),
nAnonymizeDarkcoinAmount * COIN
) + " / " + tr("%n Rounds", "", nDarksendRounds);
ui->labelAmountRounds->setText(strSettings);
}
if(!fEnableDarksend) {

View File

@ -1172,6 +1172,40 @@ CAmount CWallet::GetBalance() const
return nTotal;
}
CAmount CWallet::GetAnonymizableBalance(bool includeAlreadyAnonymized) const
{
if(fLiteMode) return 0;
CAmount nTotal = 0;
{
LOCK2(cs_main, cs_wallet);
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{
const CWalletTx* pcoin = &(*it).second;
if (pcoin->IsTrusted())
{
uint256 hash = (*it).first;
for (unsigned int i = 0; i < pcoin->vout.size(); i++)
{
CTxIn vin = CTxIn(hash, i);
if(IsSpent(hash, i) || !IsMine(pcoin->vout[i])) continue;
if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0) continue; // do not count immature
if(pcoin->vout[i].nValue == 1000*COIN) continue; // do not count MN-like outputs
int rounds = GetInputDarksendRounds(vin);
if(rounds >=-2 && (rounds < nDarksendRounds || (includeAlreadyAnonymized && rounds >= nDarksendRounds))) {
nTotal += pcoin->vout[i].nValue;
}
}
}
}
}
return nTotal;
}
CAmount CWallet::GetAnonymizedBalance() const
{
if(fLiteMode) return 0;
@ -1268,7 +1302,7 @@ CAmount CWallet::GetNormalizedAnonymizedBalance() const
return nTotal;
}
CAmount CWallet::GetDenominatedBalance(bool onlyDenom, bool onlyUnconfirmed) const
CAmount CWallet::GetDenominatedBalance(bool onlyDenom, bool onlyUnconfirmed, bool includeAlreadyAnonymized) const
{
CAmount nTotal = 0;
{
@ -1292,6 +1326,10 @@ CAmount CWallet::GetDenominatedBalance(bool onlyDenom, bool onlyUnconfirmed) con
if(!IsMine(pcoin->vout[i])) continue;
if(onlyDenom != IsDenominatedAmount(pcoin->vout[i].nValue)) continue;
CTxIn vin = CTxIn(hash, i);
int rounds = GetInputDarksendRounds(vin);
if(!includeAlreadyAnonymized && rounds >= nDarksendRounds) continue;
nTotal += pcoin->vout[i].nValue;
}
}
@ -1749,7 +1787,7 @@ bool CWallet::SelectCoinsByDenominations(int nDenom, int64_t nValueMin, int64_t
return (nValueRet >= nValueMin && fFound100 && fFound10 && fFound1 && fFoundDot1);
}
bool CWallet::SelectCoinsDark(int64_t nValueMin, int64_t nValueMax, std::vector<CTxIn>& setCoinsRet, int64_t& nValueRet, int nDarksendRoundsMin, int nDarksendRoundsMax) const
bool CWallet::SelectCoinsDark(CAmount nValueMin, CAmount nValueMax, std::vector<CTxIn>& setCoinsRet, CAmount& nValueRet, int nDarksendRoundsMin, int nDarksendRoundsMax) const
{
CCoinControl *coinControl=NULL;
@ -1766,8 +1804,10 @@ bool CWallet::SelectCoinsDark(int64_t nValueMin, int64_t nValueMax, std::vector<
BOOST_FOREACH(const COutput& out, vCoins)
{
//there's no reason to allow inputs less than 1 COIN into DS (other than denominations smaller than that amount)
if(out.tx->vout[out.i].nValue < 1*COIN && !IsDenominatedAmount(out.tx->vout[out.i].nValue)) continue;
//do not allow inputs less than 1 CENT
if(out.tx->vout[out.i].nValue < CENT) continue;
//do not allow collaterals to be selected
if(IsCollateralAmount(out.tx->vout[out.i].nValue)) continue;
if(fMasterNode && out.tx->vout[out.i].nValue == 1000*COIN) continue; //masternode input
if(nValueRet + out.tx->vout[out.i].nValue <= nValueMax){

View File

@ -310,10 +310,11 @@ public:
CAmount GetBalance() const;
CAmount GetUnconfirmedBalance() const;
CAmount GetImmatureBalance() const;
CAmount GetAnonymizableBalance(bool includeAlreadyAnonymized=false) const;
CAmount GetAnonymizedBalance() const;
double GetAverageAnonymizedRounds() const;
CAmount GetNormalizedAnonymizedBalance() const;
CAmount GetDenominatedBalance(bool onlyDenom=true, bool onlyUnconfirmed=false) const;
CAmount GetDenominatedBalance(bool onlyDenom=true, bool onlyUnconfirmed=false, bool includeAlreadyAnonymized = true) const;
CAmount GetWatchOnlyBalance() const;
CAmount GetUnconfirmedWatchOnlyBalance() const;
CAmount GetImmatureWatchOnlyBalance() const;