Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 66 additions & 74 deletions src/darksend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1415,66 +1415,77 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)

// ** find the coins we'll use
std::vector<CTxIn> vCoins;
int64 nValueMin = 0.01*COIN;
int64 nValueMax = DARKSEND_POOL_MAX;
int64 nValueMin = 0.1*COIN + 1; // select at least one smallest denom
int64 nValueIn = 0;
int minRounds = -2; //non denominated funds are rounds of less than 0
int maxRounds = 2;
int maxAmount = DARKSEND_POOL_MAX/COIN;
int maxRounds = 0;
int64 balance = pwalletMain->GetBalance();
int64 balanceNeedsDenominated = nAnonymizeDarkcoinAmount*COIN; // set target value on init
int64 balanceNeedsAnonymized = nAnonymizeDarkcoinAmount*COIN; // set target value on init
bool hasFeeInput = false;

// if we have more denominated funds (of any maturity) than the nAnonymizeDarkcoinAmount, we should use use those
if(pwalletMain->GetDenominatedBalance(true) >= nAnonymizeDarkcoinAmount*COIN ||
pwalletMain->GetDenominatedBalance(true) >= pwalletMain->GetBalance()*.9) {
// do we have enough balance?
if(balanceNeedsDenominated > balance) balanceNeedsDenominated = balance;
if(balanceNeedsAnonymized > balance) balanceNeedsAnonymized = balance;

// count in what is already done
balanceNeedsDenominated -= pwalletMain->GetDenominatedBalance(true);
balanceNeedsAnonymized -= pwalletMain->GetAnonymizedBalance();

// is there anything left to do?
// if no more denomination needed do not select non-denom inputs
if(balanceNeedsDenominated <= 0) {
minRounds = 0;
maxRounds = nDarksendRounds;
}
//if we're set to less than a thousand, don't submit for than that to the pool
if(nAnonymizeDarkcoinAmount < DARKSEND_POOL_MAX/COIN) maxAmount = nAnonymizeDarkcoinAmount;

int64 balanceNeedsAnonymized = pwalletMain->GetBalance() - pwalletMain->GetAnonymizedBalance();
if(balanceNeedsAnonymized > maxAmount*COIN) balanceNeedsAnonymized= maxAmount*COIN;
if(balanceNeedsAnonymized < COIN*2.5 ||
(vecDisabledDenominations.size() > 0 && balanceNeedsAnonymized < COIN*12.5)){
LogPrintf("DoAutomaticDenominating : No funds detected in need of denominating \n");
// is amount to anonymize still higher then pool allows?
if(balanceNeedsAnonymized > DARKSEND_POOL_MAX) balanceNeedsAnonymized = DARKSEND_POOL_MAX;

// if there is nothing more to anonymize
if(balanceNeedsAnonymized <= 1*COIN){
LogPrintf("DoAutomaticDenominating : No funds detected in need of anonymizing \n");
return false;
}

// if the balance is more the pool max, take the pool max
if(balanceNeedsAnonymized > nValueMax) {
balanceNeedsAnonymized = nValueMax;
}

// select coins that should be given to the pool
if (!pwalletMain->SelectCoinsDark(nValueMin, maxAmount*COIN, vCoins, nValueIn, minRounds, maxRounds, hasFeeInput))
if (!pwalletMain->SelectCoinsDark(nValueMin, balanceNeedsAnonymized, vCoins, nValueIn, minRounds, maxRounds, hasFeeInput))
{
nValueIn = 0;
vCoins.clear();

// look for inputs larger than the max amount, if we find anything we need to split it up
if (pwalletMain->SelectCoinsDark(maxAmount*COIN, 9999999*COIN, vCoins, nValueIn, minRounds, maxRounds, hasFeeInput))
// fall back to non-denom
minRounds = -2;
maxRounds = 0;
if (!pwalletMain->SelectCoinsDark(nValueMin, balanceNeedsAnonymized, vCoins, nValueIn, minRounds, maxRounds, hasFeeInput))
{
if(!fDryRun) SplitUpMoney();
return true;
}
nValueIn = 0;
vCoins.clear();

LogPrintf("DoAutomaticDenominating : No funds detected in need of denominating (2)\n");
return false;
// look for inputs larger than the max amount, if we find anything we need to split it up
if (pwalletMain->SelectCoinsDark(balanceNeedsAnonymized, 9999999*COIN, vCoins, nValueIn, minRounds, maxRounds, hasFeeInput))
{
if(!fDryRun) SplitUpMoney();
return true;
}

LogPrintf("DoAutomaticDenominating : No funds detected in need of denominating \n");
return false;
}
}

// the darksend pool can only take 2.5DRK minimum
if(nValueIn < COIN*2.5 ||
(vecDisabledDenominations.size() > 0 && nValueIn < COIN*12.5)
){
//simply look for non-denominated coins
if (pwalletMain->SelectCoinsDark(maxAmount*COIN, 9999999*COIN, vCoins, nValueIn, minRounds, maxRounds, hasFeeInput))
{
if(!fDryRun) SplitUpMoney();
return true;
if(vecDisabledDenominations.size() == 0){
//if we have 20x 0.1DRk and 1DRK inputs, we can start just anonymizing 10DRK and 100DRK inputs only.
if(pwalletMain->CountInputsWithAmount((1 * COIN)+1) >= 20 &&
pwalletMain->CountInputsWithAmount((.1 * COIN)+1) >= 20){
vecDisabledDenominations.push_back((1 * COIN)+1);
vecDisabledDenominations.push_back((.1 * COIN)+1);
}
}

LogPrintf("DoAutomaticDenominating : Too little to denominate \n");
return false;
// but if we tried to split last time and didn't find anything
// then this time we'll fall back to 1s and 0.1s to complete anonymization
if(nValueIn < 10*COIN){
vecDisabledDenominations.clear();
LogPrintf("DoAutomaticDenominating : falling back to 0.1s and 1s\n");
}

//check to see if we have the fee sized inputs, it requires these
Expand All @@ -1485,15 +1496,6 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)

if(fDryRun) return true;

if(vecDisabledDenominations.size() == 0){
//if we have 20x 0.1DRk and 1DRK inputs, we can start just anonymizing 10DRK inputs.
if(pwalletMain->CountInputsWithAmount((1 * COIN)+1) >= 20 &&
pwalletMain->CountInputsWithAmount((.1 * COIN)+1) >= 20){
vecDisabledDenominations.push_back((1 * COIN)+1);
vecDisabledDenominations.push_back((.1 * COIN)+1);
}
}

// initial phase, find a masternode
if(!sessionFoundMasternode){
int nUseQueue = rand()%100;
Expand All @@ -1502,10 +1504,10 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)

//randomize the amounts we mix
// if we have minRounds set, or if our non-demon is less than 5% of denom coins
if(minRounds == 0 ||
if(minRounds == 0 ||
pwalletMain->GetDenominatedBalance(true) * 0.05 > pwalletMain->GetDenominatedBalance(false)) {
for(int a = 0; a < 10; a++){ //try 10 amounts and see if we match a queue
int r = (rand()%(maxAmount-(nValueMin/COIN)))+(nValueMin/COIN);
int r = (rand()%((balanceNeedsAnonymized-nValueMin)/COIN))+(nValueMin/COIN);

vCoins.clear();
nValueIn = 0;
Expand Down Expand Up @@ -1533,7 +1535,7 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
}
}
}
if(sessionTotalValue > maxAmount*COIN) sessionTotalValue = maxAmount*COIN;
if(sessionTotalValue > balanceNeedsAnonymized) sessionTotalValue = balanceNeedsAnonymized;

double fDarkcoinSubmitted = sessionTotalValue / COIN;

Expand All @@ -1544,6 +1546,16 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
return false;
}

if(minRounds >= 0){
//use same denominations
std::vector<int64> vecAmounts;
pwalletMain->ConvertList(vCoins, vecAmounts);
sessionDenom = GetDenominationsByAmounts(vecAmounts);
} else {
//use all possible denominations
sessionDenom = GetDenominationsByAmount(sessionTotalValue);
}

//don't use the queues all of the time for mixing
if(nUseQueue > 33){

Expand All @@ -1566,8 +1578,8 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
}

// If we don't match the denominations, we don't want to submit our inputs
if(dsq.nDenom != GetDenominationsByAmount(sessionTotalValue)) {
if(fDebug) LogPrintf(" dsq.nDenom != GetDenominationsByAmount %d %d \n", dsq.nDenom, GetDenominationsByAmount(sessionTotalValue));
if(dsq.nDenom != sessionDenom) {
if(fDebug) LogPrintf(" dsq.nDenom != GetDenominationsByAmount %d %d \n", dsq.nDenom, sessionDenom);
continue;
}
dsq.time = 0; //remove node
Expand All @@ -1590,16 +1602,6 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)

vecMasternodesUsed.push_back(dsq.vin);

if(minRounds >= 0){
//use same denominations
std::vector<int64> vecAmounts;
pwalletMain->ConvertList(vCoins, vecAmounts);
sessionDenom = GetDenominationsByAmounts(vecAmounts);
} else {
//use all possible denominations
sessionDenom = GetDenominationsByAmount(sessionTotalValue);
}

pnode->PushMessage("dsa", sessionDenom, txCollateral);
LogPrintf("DoAutomaticDenominating --- connected (from queue), sending dsa for %d %d - %s\n", sessionDenom, GetDenominationsByAmount(sessionTotalValue), pnode->addr.ToString().c_str());
return true;
Expand Down Expand Up @@ -1652,16 +1654,6 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)

vecMasternodesUsed.push_back(darkSendMasterNodes[i].vin);

if(minRounds >= 0){
//use same denominations
std::vector<int64> vecAmounts;
pwalletMain->ConvertList(vCoins, vecAmounts);
sessionDenom = GetDenominationsByAmounts(vecAmounts);
} else {
//use all possible denominations
sessionDenom = GetDenominationsByAmount(sessionTotalValue);
}

pnode->PushMessage("dsa", sessionDenom, txCollateral);
LogPrintf("DoAutomaticDenominating --- connected, sending dsa for %d - denom %d\n", sessionDenom, GetDenominationsByAmount(sessionTotalValue));
return true;
Expand Down
31 changes: 16 additions & 15 deletions src/qt/overviewpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,21 +246,22 @@ void OverviewPage::updateDarksendProgress(){
}

std::ostringstream convert;
//Get average rounds of inputs
double a = ((double)pwalletMain->GetAverageAnonymizedRounds() / (double)nDarksendRounds)*100;
//Get the anon threshold
double max = nAnonymizeDarkcoinAmount;
//If it's more than the wallet amount, limit to that.
if(max > (double)(pwalletMain->GetBalance()/COIN)-1) max = (double)(pwalletMain->GetBalance()/COIN)-1;
//denominated balance / anon threshold -- the percentage that we've completed
double b = ((double)(pwalletMain->GetDenominatedBalance()/COIN) / max);

double val = a*b;
if(val < 0) val = 0;
if(val > 100) val = 100;

ui->darksendProgress->setValue(val);//rounds avg * denom progress
convert << "Inputs have an average of " << pwalletMain->GetAverageAnonymizedRounds() << " of " << nDarksendRounds << " rounds (" << a << "/" << b << ")";

// Get the anon threshold
int64 max = nAnonymizeDarkcoinAmount*COIN;

// If it's more than the wallet amount, limit to that.
if(max > balance) max = balance;

if(max == 0) return;

// calculate progress
int progress = 100 * pwalletMain->GetNormalizedAnonymizedBalance() / max;

if(progress > 100) progress = 100;

ui->darksendProgress->setValue(progress);
convert << "Inputs have an average of " << pwalletMain->GetAverageAnonymizedRounds() << " of " << nDarksendRounds << " rounds";
QString s(convert.str().c_str());
ui->darksendProgress->setToolTip(s);
}
Expand Down
51 changes: 41 additions & 10 deletions src/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,33 @@ double CWallet::GetAverageAnonymizedRounds() const
return fTotal/fCount;
}

int64 CWallet::GetNormalizedAnonymizedBalance() const
{
int64 nTotal = 0;

{
LOCK(cs_wallet);
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{
const CWalletTx* pcoin = &(*it).second;
for (unsigned int i = 0; i < pcoin->vout.size(); i++) {

COutput out = COutput(pcoin, i, pcoin->GetDepthInMainChain());
CTxIn vin = CTxIn(out.tx->GetHash(), out.i);

if(pcoin->IsSpent(i) || !IsMine(pcoin->vout[i]) || !IsDenominated(vin)) continue;

int rounds = GetInputDarksendRounds(vin);
if(rounds < nDarksendRounds)
nTotal += pcoin->vout[i].nValue * rounds / nDarksendRounds / 2;
else
nTotal += pcoin->vout[i].nValue;
}
}
}

return nTotal;
}

int64 CWallet::GetDenominatedBalance(bool onlyDenom, bool onlyUnconfirmed) const
{
Expand All @@ -1049,21 +1076,25 @@ int64 CWallet::GetDenominatedBalance(bool onlyDenom, bool onlyUnconfirmed) const
{
const CWalletTx* pcoin = &(*it).second;

bool isDenom = false;
for (unsigned int i = 0; i < pcoin->vout.size(); i++)
for (unsigned int i = 0; i < pcoin->vout.size(); i++){

if(pcoin->IsSpent(i) || !IsMine(pcoin->vout[i])) continue;

bool isDenom = false;
BOOST_FOREACH(int64 d, darkSendDenominations)
if(pcoin->vout[i].nValue == d)
isDenom = true;

if(onlyUnconfirmed){
if (!pcoin->IsFinal() || !pcoin->IsConfirmed()){
if(onlyDenom == isDenom){
nTotal += pcoin->GetAvailableCredit();
if(onlyUnconfirmed){
if (!pcoin->IsFinal() || !pcoin->IsConfirmed()){
if(onlyDenom == isDenom){
nTotal += pcoin->vout[i].nValue;
}
}
} else if (pcoin->IsConfirmed()) {
if(onlyDenom == isDenom) {
nTotal += pcoin->vout[i].nValue;
}
}
} else if (pcoin->IsConfirmed()) {
if(onlyDenom == isDenom) {
nTotal += pcoin->GetAvailableCredit();
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ class CWallet : public CCryptoKeyStore
int64 GetBalance() const;
int64 GetAnonymizedBalance() const;
double GetAverageAnonymizedRounds() const;
int64 GetNormalizedAnonymizedBalance() const;
int64 GetDenominatedBalance(bool onlyDenom=true, bool onlyUnconfirmed=false) const;
int64 GetUnconfirmedBalance() const;
int64 GetImmatureBalance() const;
Expand Down