Skip to content

Commit a7492c1

Browse files
UdjinM6codablock
authored andcommitted
Handle coin type via CCoinControl (#3172)
1 parent 5107582 commit a7492c1

File tree

11 files changed

+95
-72
lines changed

11 files changed

+95
-72
lines changed

src/privatesend/privatesend-client.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,21 +1433,23 @@ bool CPrivateSendClientSession::MakeCollateralAmounts(const CompactTallyItem& ta
14331433
CCoinControl coinControl;
14341434
coinControl.fAllowOtherInputs = false;
14351435
coinControl.fAllowWatchOnly = false;
1436+
coinControl.nCoinType = CoinType::ONLY_NONDENOMINATED;
14361437
// send change to the same address so that we were able create more denoms out of it later
14371438
coinControl.destChange = tallyItem.txdest;
14381439
for (const auto& outpoint : tallyItem.vecOutPoints) {
14391440
coinControl.Select(outpoint);
14401441
}
14411442

14421443
bool fSuccess = vpwallets[0]->CreateTransaction(vecSend, wtx, reservekeyChange,
1443-
nFeeRet, nChangePosRet, strFail, coinControl, true, ONLY_NONDENOMINATED);
1444+
nFeeRet, nChangePosRet, strFail, coinControl);
14441445
if (!fSuccess) {
14451446
LogPrint(BCLog::PRIVATESEND, "CPrivateSendClientSession::MakeCollateralAmounts -- ONLY_NONDENOMINATED: %s\n", strFail);
14461447
// If we failed then most likely there are not enough funds on this address.
14471448
if (fTryDenominated) {
14481449
// Try to also use denominated coins (we can't mix denominated without collaterals anyway).
1450+
coinControl.nCoinType = CoinType::ALL_COINS;
14491451
if (!vpwallets[0]->CreateTransaction(vecSend, wtx, reservekeyChange,
1450-
nFeeRet, nChangePosRet, strFail, coinControl, true, ALL_COINS)) {
1452+
nFeeRet, nChangePosRet, strFail, coinControl)) {
14511453
LogPrint(BCLog::PRIVATESEND, "CPrivateSendClientSession::MakeCollateralAmounts -- ALL_COINS Error: %s\n", strFail);
14521454
reservekeyCollateral.ReturnKey();
14531455
return false;
@@ -1594,6 +1596,7 @@ bool CPrivateSendClientSession::CreateDenominated(CAmount nBalanceToDenominate,
15941596
CCoinControl coinControl;
15951597
coinControl.fAllowOtherInputs = false;
15961598
coinControl.fAllowWatchOnly = false;
1599+
coinControl.nCoinType = CoinType::ONLY_NONDENOMINATED;
15971600
// send change to the same address so that we were able create more denoms out of it later
15981601
coinControl.destChange = tallyItem.txdest;
15991602
for (const auto& outpoint : tallyItem.vecOutPoints) {
@@ -1608,7 +1611,7 @@ bool CPrivateSendClientSession::CreateDenominated(CAmount nBalanceToDenominate,
16081611
CReserveKey reservekeyChange(vpwallets[0]);
16091612

16101613
bool fSuccess = vpwallets[0]->CreateTransaction(vecSend, wtx, reservekeyChange,
1611-
nFeeRet, nChangePosRet, strFail, coinControl, true, ONLY_NONDENOMINATED, 0);
1614+
nFeeRet, nChangePosRet, strFail, coinControl);
16121615
if (!fSuccess) {
16131616
LogPrint(BCLog::PRIVATESEND, "CPrivateSendClientSession::CreateDenominated -- Error: %s\n", strFail);
16141617
keyHolderStorageDenom.ReturnAll();

src/qt/coincontroldialog.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -430,11 +430,11 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column)
430430
else {
431431
coinControl->Select(outpt);
432432
int nRounds = vpwallets[0]->GetRealOutpointPrivateSendRounds(outpt);
433-
if (coinControl->fUsePrivateSend && nRounds < privateSendClient.nPrivateSendRounds) {
433+
if (coinControl->IsUsingPrivateSend() && nRounds < privateSendClient.nPrivateSendRounds) {
434434
QMessageBox::warning(this, windowTitle(),
435435
tr("Non-anonymized input selected. <b>PrivateSend will be disabled.</b><br><br>If you still want to use PrivateSend, please deselect all non-anonymized inputs first and then check the PrivateSend checkbox again."),
436436
QMessageBox::Ok, QMessageBox::Ok);
437-
coinControl->fUsePrivateSend = false;
437+
coinControl->UsePrivateSend(false);
438438
}
439439
}
440440

@@ -554,7 +554,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
554554
nChange = nAmount - nPayAmount;
555555

556556
// PrivateSend Fee = overpay
557-
if(coinControl->fUsePrivateSend && nChange > 0)
557+
if(coinControl->IsUsingPrivateSend() && nChange > 0)
558558
{
559559
nPayFee = std::max(nChange, nPayFee);
560560
nChange = 0;

src/qt/sendcoinsdialog.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,11 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *_platformStyle, QWidget *p
109109
if (!privateSendClient.fEnablePrivateSend) {
110110
ui->checkUsePrivateSend->setChecked(false);
111111
ui->checkUsePrivateSend->setVisible(false);
112-
CoinControlDialog::coinControl->fUsePrivateSend = false;
112+
CoinControlDialog::coinControl->UsePrivateSend(false);
113113
} else {
114114
bool fUsePrivateSend = settings.value("bUsePrivateSend").toBool();
115115
ui->checkUsePrivateSend->setChecked(fUsePrivateSend);
116-
CoinControlDialog::coinControl->fUsePrivateSend = fUsePrivateSend;
116+
CoinControlDialog::coinControl->UsePrivateSend(fUsePrivateSend);
117117
connect(ui->checkUsePrivateSend, SIGNAL(stateChanged ( int )), this, SLOT(updateDisplayUnit()));
118118
}
119119

@@ -287,10 +287,6 @@ void SendCoinsDialog::on_sendButton_clicked()
287287
strFunds = tr("using") + " <b>" + tr("any available funds (not anonymous)") + "</b>";
288288
}
289289

290-
for (SendCoinsRecipient& rcp : recipients) {
291-
rcp.inputType = ui->checkUsePrivateSend->isChecked() ? ONLY_DENOMINATED : ALL_COINS;
292-
}
293-
294290
fNewRecipientAllowed = false;
295291
// request unlock only if was locked or unlocked for mixing:
296292
// this way we let users unlock by walletpassphrase or by menu
@@ -326,6 +322,8 @@ void SendCoinsDialog::send(QList<SendCoinsRecipient> recipients, QString strFee,
326322

327323
updateCoinControlState(ctrl);
328324

325+
ctrl.UsePrivateSend(ui->checkUsePrivateSend->isChecked());
326+
329327
prepareStatus = model->prepareTransaction(currentTransaction, ctrl);
330328

331329
// process prepareStatus and on error generate message shown to user
@@ -610,7 +608,7 @@ void SendCoinsDialog::updateDisplayUnit()
610608
{
611609
setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(), model->getAnonymizedBalance(),
612610
model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance());
613-
CoinControlDialog::coinControl->fUsePrivateSend = ui->checkUsePrivateSend->isChecked();
611+
CoinControlDialog::coinControl->UsePrivateSend(ui->checkUsePrivateSend->isChecked());
614612
coinControlUpdateLabels();
615613
ui->customFee->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
616614
updateMinFeeLabel();
@@ -922,7 +920,7 @@ void SendCoinsDialog::coinControlUpdateLabels()
922920
}
923921
}
924922

925-
ui->checkUsePrivateSend->setChecked(CoinControlDialog::coinControl->fUsePrivateSend);
923+
ui->checkUsePrivateSend->setChecked(CoinControlDialog::coinControl->IsUsingPrivateSend());
926924

927925
if (CoinControlDialog::coinControl->HasSelected())
928926
{

src/qt/walletmodel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
321321
CWalletTx* newTx = transaction.getTransaction();
322322
CReserveKey *keyChange = transaction.getPossibleKeyChange();
323323

324-
fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl, true, recipients[0].inputType);
324+
fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl);
325325
transaction.setTransactionFee(nFeeRequired);
326326
if (fSubtractFeeFromAmount && fCreated)
327327
transaction.reassignAmounts();

src/qt/walletmodel.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ class SendCoinsRecipient
5151
// Todo: This is a hack, should be replaced with a cleaner solution!
5252
QString address;
5353
QString label;
54-
#ifdef ENABLE_WALLET
55-
AvailableCoinsType inputType;
56-
#endif // ENABLE_WALLET
5754
CAmount amount;
5855
// If from a payment request, this is used for storing the memo
5956
QString message;

src/rpc/masternode.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "utilmoneystr.h"
2020
#include "txmempool.h"
2121

22+
#include "wallet/coincontrol.h"
2223
#include "wallet/rpcwallet.h"
2324

2425
#include "evo/specialtx.h"
@@ -365,7 +366,9 @@ UniValue masternode_outputs(const JSONRPCRequest& request)
365366

366367
// Find possible candidates
367368
std::vector<COutput> vPossibleCoins;
368-
pwallet->AvailableCoins(vPossibleCoins, true, nullptr, 1, MAX_MONEY, MAX_MONEY, 0, 0, 9999999, ONLY_1000);
369+
CCoinControl coin_control;
370+
coin_control.nCoinType = CoinType::ONLY_1000;
371+
pwallet->AvailableCoins(vPossibleCoins, true, &coin_control);
369372

370373
UniValue obj(UniValue::VOBJ);
371374
for (const auto& out : vPossibleCoins) {

src/rpc/rpcevo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ static void FundSpecialTx(CWallet* pwallet, CMutableTransaction& tx, const Speci
212212
int nChangePos = -1;
213213
std::string strFailReason;
214214

215-
if (!pwallet->CreateTransaction(vecSend, wtx, reservekey, nFee, nChangePos, strFailReason, coinControl, false, ALL_COINS, tx.vExtraPayload.size())) {
215+
if (!pwallet->CreateTransaction(vecSend, wtx, reservekey, nFee, nChangePos, strFailReason, coinControl, false, tx.vExtraPayload.size())) {
216216
throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason);
217217
}
218218

src/wallet/coincontrol.h

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,20 @@
1111

1212
#include <boost/optional.hpp>
1313

14+
enum class CoinType
15+
{
16+
ALL_COINS,
17+
ONLY_DENOMINATED,
18+
ONLY_NONDENOMINATED,
19+
ONLY_1000, // find masternode outputs including locked ones (use with caution)
20+
ONLY_PRIVATESEND_COLLATERAL,
21+
};
22+
1423
/** Coin Control Features. */
1524
class CCoinControl
1625
{
1726
public:
1827
CTxDestination destChange;
19-
bool fUsePrivateSend;
2028
//! If false, allows unselected inputs, but requires all selected inputs be used if fAllowOtherInputs is true (default)
2129
bool fAllowOtherInputs;
2230
//! If false, only include as many inputs as necessary to fulfill a coin selection request. Only usable together with fAllowOtherInputs
@@ -31,6 +39,8 @@ class CCoinControl
3139
boost::optional<unsigned int> m_confirm_target;
3240
//! Fee estimation mode to control arguments to estimateSmartFee
3341
FeeEstimateMode m_fee_mode;
42+
//! Controls which types of coins are allowed to be used (default: ALL_COINS)
43+
CoinType nCoinType;
3444

3545
CCoinControl()
3646
{
@@ -44,11 +54,11 @@ class CCoinControl
4454
fRequireAllInputs = true;
4555
fAllowWatchOnly = false;
4656
setSelected.clear();
47-
fUsePrivateSend = true;
4857
m_feerate.reset();
4958
fOverrideFeeRate = false;
5059
m_confirm_target.reset();
5160
m_fee_mode = FeeEstimateMode::UNSET;
61+
nCoinType = CoinType::ALL_COINS;
5262
}
5363

5464
bool HasSelected() const
@@ -81,6 +91,18 @@ class CCoinControl
8191
vOutpoints.assign(setSelected.begin(), setSelected.end());
8292
}
8393

94+
// Dash-specific helpers
95+
96+
void UsePrivateSend(bool fUsePrivateSend)
97+
{
98+
nCoinType = fUsePrivateSend ? CoinType::ONLY_DENOMINATED : CoinType::ALL_COINS;
99+
}
100+
101+
bool IsUsingPrivateSend() const
102+
{
103+
return nCoinType == CoinType::ONLY_DENOMINATED;
104+
}
105+
84106
private:
85107
std::set<COutPoint> setSelected;
86108
};

src/wallet/rpcwallet.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ UniValue getaddressesbyaccount(const JSONRPCRequest& request)
373373
return ret;
374374
}
375375

376-
static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew, const CCoinControl& coin_control, bool fUsePrivateSend = false)
376+
static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew, const CCoinControl& coin_control)
377377
{
378378
CAmount curBalance = pwallet->GetBalance();
379379

@@ -400,7 +400,7 @@ static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CA
400400
CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
401401
vecSend.push_back(recipient);
402402
if (!pwallet->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet,
403-
strError, coin_control, true, fUsePrivateSend ? ONLY_DENOMINATED : ALL_COINS)) {
403+
strError, coin_control)) {
404404
if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance)
405405
strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired));
406406
throw JSONRPCError(RPC_WALLET_ERROR, strError);
@@ -475,9 +475,8 @@ UniValue sendtoaddress(const JSONRPCRequest& request)
475475

476476
CCoinControl coin_control;
477477

478-
bool fUsePrivateSend = false;
479478
if (request.params.size() > 6 && !request.params[6].isNull()) {
480-
fUsePrivateSend = request.params[6].get_bool();
479+
coin_control.UsePrivateSend(request.params[6].get_bool());
481480
}
482481

483482
if (request.params.size() > 7 && !request.params[7].isNull()) {
@@ -492,7 +491,7 @@ UniValue sendtoaddress(const JSONRPCRequest& request)
492491

493492
EnsureWalletIsUnlocked(pwallet);
494493

495-
SendMoney(pwallet, address.Get(), nAmount, fSubtractFeeFromAmount, wtx, coin_control, fUsePrivateSend);
494+
SendMoney(pwallet, address.Get(), nAmount, fSubtractFeeFromAmount, wtx, coin_control);
496495

497496
return wtx.GetHash().GetHex();
498497
}
@@ -1047,9 +1046,8 @@ UniValue sendmany(const JSONRPCRequest& request)
10471046

10481047
CCoinControl coin_control;
10491048

1050-
bool fUsePrivateSend = false;
10511049
if (request.params.size() > 7 && !request.params[7].isNull()) {
1052-
fUsePrivateSend = request.params[7].get_bool();
1050+
coin_control.UsePrivateSend(request.params[7].get_bool());
10531051
}
10541052

10551053
if (request.params.size() > 8 && !request.params[8].isNull()) {
@@ -1108,7 +1106,7 @@ UniValue sendmany(const JSONRPCRequest& request)
11081106
std::string strFailReason;
11091107

11101108
bool fCreated = pwallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason,
1111-
coin_control, true, fUsePrivateSend ? ONLY_DENOMINATED : ALL_COINS);
1109+
coin_control);
11121110
if (!fCreated)
11131111
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
11141112
CValidationState state;

0 commit comments

Comments
 (0)