Skip to content

Commit

Permalink
privatesend|qt|rpc|wallet: Improve CPrivateSendClientOptions
Browse files Browse the repository at this point in the history
- Makes it singleton to make sure we always only have one instance of it
- Protects its members by making them private and adding set/getters
- Makes it thread safe
  • Loading branch information
xdustinface committed Jul 17, 2020
1 parent d1451d5 commit e46c2f0
Show file tree
Hide file tree
Showing 11 changed files with 179 additions and 119 deletions.
136 changes: 94 additions & 42 deletions src/privatesend/privatesend-client.cpp

Large diffs are not rendered by default.

30 changes: 26 additions & 4 deletions src/privatesend/privatesend-client.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,6 @@ extern std::map<const std::string, CPrivateSendClientManager*> privateSendClient
// The object to track mixing queues
extern CPrivateSendClientQueueManager privateSendClientQueueManager;

// The object to store application wide mixing options
extern CPrivateSendClientOptions privateSendClientOptions;

class CPendingDsaRequest
{
private:
Expand Down Expand Up @@ -281,6 +278,27 @@ class CPrivateSendClientManager
class CPrivateSendClientOptions
{
public:
static int GetSessions() { return CPrivateSendClientOptions::Get().nPrivateSendSessions; }
static int GetRounds() { return CPrivateSendClientOptions::Get().nPrivateSendRounds; }
static int GetAmount() { return CPrivateSendClientOptions::Get().nPrivateSendAmount; }
static int GetDenomsGoal() { return CPrivateSendClientOptions::Get().nPrivateSendDenomsGoal; }
static int GetDenomsHardCap() { return CPrivateSendClientOptions::Get().nPrivateSendDenomsHardCap; }

static void SetEnabled(bool fEnabled);
static void SetMultiSessionEnabled(bool fEnabled);
static void SetRounds(int nRounds);
static void SetAmount(CAmount amount);

static int IsEnabled() { return CPrivateSendClientOptions::Get().fEnablePrivateSend; }
static int IsMultiSessionEnabled() { return CPrivateSendClientOptions::Get().fPrivateSendMultiSession; }

static void GetJsonInfo(UniValue& obj);

private:
static CPrivateSendClientOptions* _instance;
static std::once_flag onceFlag;

CCriticalSection cs_ps_options;
int nPrivateSendSessions;
int nPrivateSendRounds;
int nPrivateSendAmount;
Expand All @@ -299,7 +317,11 @@ class CPrivateSendClientOptions
{
}

void GetJsonInfo(UniValue& obj) const;
CPrivateSendClientOptions(const CPrivateSendClientOptions& other) = delete;
CPrivateSendClientOptions& operator=(const CPrivateSendClientOptions&) = delete;

static CPrivateSendClientOptions& Get();
static void Init();
};

void DoPrivateSendMaintenance(CConnman& connman);
Expand Down
4 changes: 2 additions & 2 deletions src/qt/bitcoingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -781,8 +781,8 @@ void BitcoinGUI::setWalletActionsEnabled(bool enabled)
sendCoinsAction->setEnabled(enabled);
sendCoinsMenuAction->setEnabled(enabled);
#ifdef ENABLE_WALLET
privateSendCoinsAction->setEnabled(enabled && privateSendClientOptions.fEnablePrivateSend);
privateSendCoinsMenuAction->setEnabled(enabled && privateSendClientOptions.fEnablePrivateSend);
privateSendCoinsAction->setEnabled(enabled && CPrivateSendClientOptions::IsEnabled());
privateSendCoinsMenuAction->setEnabled(enabled && CPrivateSendClientOptions::IsEnabled());
#else
privateSendCoinsAction->setEnabled(enabled);
privateSendCoinsMenuAction->setEnabled(enabled);
Expand Down
4 changes: 2 additions & 2 deletions src/qt/coincontroldialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
// unselect non-fully-mixed, this can happen when users switch from Send to PrivateSend
if (coinControl()->IsUsingPrivateSend()) {
int nRounds = model->getRealOutpointPrivateSendRounds(outpt);
if (nRounds < privateSendClientOptions.nPrivateSendRounds) {
if (nRounds < CPrivateSendClientOptions::GetRounds()) {
coinControl()->UnSelect(outpt);
fUnselectedNonMixed = true;
continue;
Expand Down Expand Up @@ -707,7 +707,7 @@ void CoinControlDialog::updateView()
COutPoint outpoint = COutPoint(out.tx->tx->GetHash(), out.i);
int nRounds = model->getRealOutpointPrivateSendRounds(outpoint);

if ((coinControl()->IsUsingPrivateSend() && nRounds >= privateSendClientOptions.nPrivateSendRounds) || !(coinControl()->IsUsingPrivateSend())) {
if ((coinControl()->IsUsingPrivateSend() && nRounds >= CPrivateSendClientOptions::GetRounds()) || !(coinControl()->IsUsingPrivateSend())) {
nSum += out.tx->tx->vout[out.i].nValue;
nChildren++;

Expand Down
18 changes: 9 additions & 9 deletions src/qt/optionsmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ void OptionsModel::Init(bool resetSettings)
settings.setValue("nPrivateSendRounds", DEFAULT_PRIVATESEND_ROUNDS);
if (!gArgs.SoftSetArg("-privatesendrounds", settings.value("nPrivateSendRounds").toString().toStdString()))
addOverriddenOption("-privatesendrounds");
privateSendClientOptions.nPrivateSendRounds = settings.value("nPrivateSendRounds").toInt();
CPrivateSendClientOptions::SetRounds(settings.value("nPrivateSendRounds").toInt());

if (!settings.contains("nPrivateSendAmount")) {
// for migration from old settings
Expand All @@ -149,13 +149,13 @@ void OptionsModel::Init(bool resetSettings)
}
if (!gArgs.SoftSetArg("-privatesendamount", settings.value("nPrivateSendAmount").toString().toStdString()))
addOverriddenOption("-privatesendamount");
privateSendClientOptions.nPrivateSendAmount = settings.value("nPrivateSendAmount").toInt();
CPrivateSendClientOptions::SetAmount(settings.value("nPrivateSendAmount").toInt());

if (!settings.contains("fPrivateSendMultiSession"))
settings.setValue("fPrivateSendMultiSession", DEFAULT_PRIVATESEND_MULTISESSION);
if (!gArgs.SoftSetBoolArg("-privatesendmultisession", settings.value("fPrivateSendMultiSession").toBool()))
addOverriddenOption("-privatesendmultisession");
privateSendClientOptions.fPrivateSendMultiSession = settings.value("fPrivateSendMultiSession").toBool();
CPrivateSendClientOptions::SetMultiSessionEnabled(settings.value("fPrivateSendMultiSession").toBool());
#endif

// Network
Expand Down Expand Up @@ -470,24 +470,24 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
case PrivateSendRounds:
if (settings.value("nPrivateSendRounds") != value)
{
privateSendClientOptions.nPrivateSendRounds = value.toInt();
settings.setValue("nPrivateSendRounds", privateSendClientOptions.nPrivateSendRounds);
CPrivateSendClientOptions::SetRounds(value.toInt());
settings.setValue("nPrivateSendRounds", CPrivateSendClientOptions::GetRounds());
Q_EMIT privateSendRoundsChanged();
}
break;
case PrivateSendAmount:
if (settings.value("nPrivateSendAmount") != value)
{
privateSendClientOptions.nPrivateSendAmount = value.toInt();
settings.setValue("nPrivateSendAmount", privateSendClientOptions.nPrivateSendAmount);
CPrivateSendClientOptions::SetAmount(value.toInt());
settings.setValue("nPrivateSendAmount", CPrivateSendClientOptions::GetAmount());
Q_EMIT privateSentAmountChanged();
}
break;
case PrivateSendMultiSession:
if (settings.value("fPrivateSendMultiSession") != value)
{
privateSendClientOptions.fPrivateSendMultiSession = value.toBool();
settings.setValue("fPrivateSendMultiSession", privateSendClientOptions.fPrivateSendMultiSession);
CPrivateSendClientOptions::SetMultiSessionEnabled(value.toBool());
settings.setValue("fPrivateSendMultiSession", CPrivateSendClientOptions::IsMultiSessionEnabled());
}
break;
#endif
Expand Down
24 changes: 12 additions & 12 deletions src/qt/overviewpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent)
// start with displaying the "out of sync" warnings
showOutOfSyncWarning(true);

if(!privateSendClientOptions.fEnablePrivateSend) return;
if (!CPrivateSendClientOptions::IsEnabled()) return;

// Disable any PS UI for masternode or when autobackup is disabled or failed for whatever reason
if(fMasternodeMode || nWalletBackups <= 0){
Expand Down Expand Up @@ -307,7 +307,7 @@ void OverviewPage::setWalletModel(WalletModel *model)
// explicitly update PS frame and transaction list to reflect actual settings
updateAdvancedPSUI(model->getOptionsModel()->getShowAdvancedPSUI());

if(!privateSendClientOptions.fEnablePrivateSend) return;
if (!CPrivateSendClientOptions::IsEnabled()) return;

connect(model->getOptionsModel(), SIGNAL(privateSendRoundsChanged()), this, SLOT(updatePrivateSendProgress()));
connect(model->getOptionsModel(), SIGNAL(privateSentAmountChanged()), this, SLOT(updatePrivateSendProgress()));
Expand Down Expand Up @@ -356,7 +356,7 @@ void OverviewPage::updatePrivateSendProgress()
if(!walletModel) return;

QString strAmountAndRounds;
QString strPrivateSendAmount = BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, privateSendClientOptions.nPrivateSendAmount * COIN, false, BitcoinUnits::separatorAlways);
QString strPrivateSendAmount = BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, CPrivateSendClientOptions::GetAmount() * COIN, false, BitcoinUnits::separatorAlways);

if(currentBalance == 0)
{
Expand All @@ -365,7 +365,7 @@ void OverviewPage::updatePrivateSendProgress()

// when balance is zero just show info from settings
strPrivateSendAmount = strPrivateSendAmount.remove(strPrivateSendAmount.indexOf("."), BitcoinUnits::decimals(nDisplayUnit) + 1);
strAmountAndRounds = strPrivateSendAmount + " / " + tr("%n Rounds", "", privateSendClientOptions.nPrivateSendRounds);
strAmountAndRounds = strPrivateSendAmount + " / " + tr("%n Rounds", "", CPrivateSendClientOptions::GetRounds());

ui->labelAmountRounds->setToolTip(tr("No inputs detected"));
ui->labelAmountRounds->setText(strAmountAndRounds);
Expand All @@ -377,15 +377,15 @@ void OverviewPage::updatePrivateSendProgress()
CAmount nMaxToAnonymize = nAnonymizableBalance + currentAnonymizedBalance;

// If it's more than the anon threshold, limit to that.
if(nMaxToAnonymize > privateSendClientOptions.nPrivateSendAmount*COIN) nMaxToAnonymize = privateSendClientOptions.nPrivateSendAmount*COIN;
if (nMaxToAnonymize > CPrivateSendClientOptions::GetAmount() * COIN) nMaxToAnonymize = CPrivateSendClientOptions::GetAmount() * COIN;

if(nMaxToAnonymize == 0) return;

if(nMaxToAnonymize >= privateSendClientOptions.nPrivateSendAmount * COIN) {
if (nMaxToAnonymize >= CPrivateSendClientOptions::GetAmount() * COIN) {
ui->labelAmountRounds->setToolTip(tr("Found enough compatible inputs to mix %1")
.arg(strPrivateSendAmount));
strPrivateSendAmount = strPrivateSendAmount.remove(strPrivateSendAmount.indexOf("."), BitcoinUnits::decimals(nDisplayUnit) + 1);
strAmountAndRounds = strPrivateSendAmount + " / " + tr("%n Rounds", "", privateSendClientOptions.nPrivateSendRounds);
strAmountAndRounds = strPrivateSendAmount + " / " + tr("%n Rounds", "", CPrivateSendClientOptions::GetRounds());
} else {
QString strMaxToAnonymize = BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, nMaxToAnonymize, false, BitcoinUnits::separatorAlways);
ui->labelAmountRounds->setToolTip(tr("Not enough compatible inputs to mix <span style='%1'>%2</span>,<br>"
Expand All @@ -396,7 +396,7 @@ void OverviewPage::updatePrivateSendProgress()
strMaxToAnonymize = strMaxToAnonymize.remove(strMaxToAnonymize.indexOf("."), BitcoinUnits::decimals(nDisplayUnit) + 1);
strAmountAndRounds = "<span style='" + GUIUtil::getThemedStyleQString(GUIUtil::ThemedStyle::TS_ERROR) + "'>" +
QString(BitcoinUnits::factor(nDisplayUnit) == 1 ? "" : "~") + strMaxToAnonymize +
" / " + tr("%n Rounds", "", privateSendClientOptions.nPrivateSendRounds) + "</span>";
" / " + tr("%n Rounds", "", CPrivateSendClientOptions::GetRounds()) + "</span>";
}
ui->labelAmountRounds->setText(strAmountAndRounds);

Expand Down Expand Up @@ -435,7 +435,7 @@ void OverviewPage::updatePrivateSendProgress()

// apply some weights to them ...
float denomWeight = 1;
float anonNormWeight = privateSendClientOptions.nPrivateSendRounds;
float anonNormWeight = CPrivateSendClientOptions::GetRounds();
float anonFullWeight = 2;
float fullWeight = denomWeight + anonNormWeight + anonFullWeight;
// ... and calculate the whole progress
Expand All @@ -451,18 +451,18 @@ void OverviewPage::updatePrivateSendProgress()
tr("Denominated") + ": %2%<br/>" +
tr("Partially mixed") + ": %3%<br/>" +
tr("Mixed") + ": %4%<br/>" +
tr("Denominated inputs have %5 of %n rounds on average", "", privateSendClientOptions.nPrivateSendRounds))
tr("Denominated inputs have %5 of %n rounds on average", "", CPrivateSendClientOptions::GetRounds()))
.arg(progress).arg(denomPart).arg(anonNormPart).arg(anonFullPart)
.arg(nAverageAnonymizedRounds);
ui->privateSendProgress->setToolTip(strToolPip);
}

void OverviewPage::updateAdvancedPSUI(bool fShowAdvancedPSUI) {
this->fShowAdvancedPSUI = fShowAdvancedPSUI;
int nNumItems = (!privateSendClientOptions.fEnablePrivateSend || !fShowAdvancedPSUI) ? NUM_ITEMS : NUM_ITEMS_ADV;
int nNumItems = (!CPrivateSendClientOptions::IsEnabled() || !fShowAdvancedPSUI) ? NUM_ITEMS : NUM_ITEMS_ADV;
SetupTransactionList(nNumItems);

if (!privateSendClientOptions.fEnablePrivateSend) return;
if (!CPrivateSendClientOptions::IsEnabled()) return;

ui->framePrivateSend->setVisible(true);
ui->labelCompletitionText->setVisible(fShowAdvancedPSUI);
Expand Down
5 changes: 2 additions & 3 deletions src/qt/walletmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,12 @@ void WalletModel::pollBalanceChanged()
if(!lockWallet)
return;

if(fForceCheckBalanceChanged || chainActive.Height() != cachedNumBlocks || privateSendClientOptions.nPrivateSendRounds != cachedPrivateSendRounds)
{
if (fForceCheckBalanceChanged || chainActive.Height() != cachedNumBlocks || CPrivateSendClientOptions::GetRounds() != cachedPrivateSendRounds) {
fForceCheckBalanceChanged = false;

// Balance and number of transactions might have changed
cachedNumBlocks = chainActive.Height();
cachedPrivateSendRounds = privateSendClientOptions.nPrivateSendRounds;
cachedPrivateSendRounds = CPrivateSendClientOptions::GetRounds();

checkBalanceChanged();
if(transactionTableModel)
Expand Down
4 changes: 2 additions & 2 deletions src/rpc/privatesend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ UniValue privatesend(const JSONRPCRequest& request)
if (fMasternodeMode)
throw JSONRPCError(RPC_INTERNAL_ERROR, "Client-side mixing is not supported on masternodes");

if (!privateSendClientOptions.fEnablePrivateSend) {
if (!CPrivateSendClientOptions::IsEnabled()) {
if (!gArgs.GetBoolArg("-enableprivatesend", true)) {
// otherwise it's on by default, unless cmd line option says otherwise
throw JSONRPCError(RPC_INTERNAL_ERROR, "Mixing is disabled via -enableprivatesend=0 command line option, remove it to enable mixing again");
Expand Down Expand Up @@ -136,7 +136,7 @@ UniValue getprivatesendinfo(const JSONRPCRequest& request)

#ifdef ENABLE_WALLET

privateSendClientOptions.GetJsonInfo(obj);
CPrivateSendClientOptions::GetJsonInfo(obj);

obj.pushKV("queue_size", privateSendClientQueueManager.GetQueueSize());

Expand Down
45 changes: 16 additions & 29 deletions src/wallet/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,15 +364,15 @@ void WalletInit::Start(CScheduler& scheduler)
// Run a thread to flush wallet periodically
scheduler.scheduleEvery(MaybeCompactWalletDB, 500);

if (!fMasternodeMode && privateSendClientOptions.fEnablePrivateSend) {
if (!fMasternodeMode && CPrivateSendClientOptions::IsEnabled()) {
scheduler.scheduleEvery(std::bind(&DoPrivateSendMaintenance, std::ref(*g_connman)), 1 * 1000);
}
}

void WalletInit::Flush()
{
for (CWallet* pwallet : GetWallets()) {
if (privateSendClientOptions.fEnablePrivateSend) {
if (CPrivateSendClientOptions::IsEnabled()) {
// Stop PrivateSend, release keys
auto it = privateSendClientManagers.find(pwallet->GetName());
it->second->ResetPool();
Expand Down Expand Up @@ -407,37 +407,24 @@ void WalletInit::AutoLockMasternodeCollaterals()

void WalletInit::InitPrivateSendSettings()
{
if (!HasWallets()) {
privateSendClientOptions.fEnablePrivateSend = false;
} else {
privateSendClientOptions.fEnablePrivateSend = gArgs.GetBoolArg("-enableprivatesend", true);
CPrivateSendClientOptions::SetEnabled(HasWallets() ? gArgs.GetBoolArg("-enableprivatesend", true) : false);
if (!CPrivateSendClientOptions::IsEnabled()) {
return;
}
bool fAutoStart = gArgs.GetBoolArg("-privatesendautostart", DEFAULT_PRIVATESEND_AUTOSTART);
if (privateSendClientOptions.fEnablePrivateSend) {
for (auto& pwallet : GetWallets()) {
if (pwallet->IsLocked()) {
privateSendClientManagers.at(pwallet->GetName())->StopMixing();
} else if (fAutoStart) {
privateSendClientManagers.at(pwallet->GetName())->StartMixing(pwallet);
}
for (auto& pwallet : GetWallets()) {
if (pwallet->IsLocked()) {
privateSendClientManagers.at(pwallet->GetName())->StopMixing();
} else if (fAutoStart) {
privateSendClientManagers.at(pwallet->GetName())->StartMixing(pwallet);
}
}
privateSendClientOptions.fPrivateSendMultiSession = gArgs.GetBoolArg("-privatesendmultisession", DEFAULT_PRIVATESEND_MULTISESSION);
privateSendClientOptions.nPrivateSendSessions = std::min(std::max((int)gArgs.GetArg("-privatesendsessions", DEFAULT_PRIVATESEND_SESSIONS), MIN_PRIVATESEND_SESSIONS), MAX_PRIVATESEND_SESSIONS);
privateSendClientOptions.nPrivateSendRounds = std::min(std::max((int)gArgs.GetArg("-privatesendrounds", DEFAULT_PRIVATESEND_ROUNDS), MIN_PRIVATESEND_ROUNDS), MAX_PRIVATESEND_ROUNDS);
privateSendClientOptions.nPrivateSendAmount = std::min(std::max((int)gArgs.GetArg("-privatesendamount", DEFAULT_PRIVATESEND_AMOUNT), MIN_PRIVATESEND_AMOUNT), MAX_PRIVATESEND_AMOUNT);
privateSendClientOptions.nPrivateSendDenomsGoal = std::min(std::max((int)gArgs.GetArg("-privatesenddenomsgoal", DEFAULT_PRIVATESEND_DENOMS_GOAL), MIN_PRIVATESEND_DENOMS_GOAL), MAX_PRIVATESEND_DENOMS_GOAL);
privateSendClientOptions.nPrivateSendDenomsHardCap = std::min(std::max((int)gArgs.GetArg("-privatesenddenomshardcap", DEFAULT_PRIVATESEND_DENOMS_HARDCAP), MIN_PRIVATESEND_DENOMS_HARDCAP), MAX_PRIVATESEND_DENOMS_HARDCAP);

if (privateSendClientOptions.fEnablePrivateSend) {
LogPrintf("PrivateSend: autostart=%d, multisession=%d," /* Continued */
"sessions=%d, rounds=%d, amount=%d, denoms_goal=%d, denoms_hardcap=%d\n",
fAutoStart, privateSendClientOptions.fPrivateSendMultiSession,
privateSendClientOptions.nPrivateSendSessions, privateSendClientOptions.nPrivateSendRounds,
privateSendClientOptions.nPrivateSendAmount,
privateSendClientOptions.nPrivateSendDenomsGoal, privateSendClientOptions.nPrivateSendDenomsHardCap);
}

LogPrintf("PrivateSend: autostart=%d, multisession=%d," /* Continued */
"sessions=%d, rounds=%d, amount=%d, denoms_goal=%d, denoms_hardcap=%d\n",
fAutoStart, CPrivateSendClientOptions::IsMultiSessionEnabled(),
CPrivateSendClientOptions::GetSessions(), CPrivateSendClientOptions::GetRounds(),
CPrivateSendClientOptions::GetAmount(), CPrivateSendClientOptions::GetDenomsGoal(),
CPrivateSendClientOptions::GetDenomsHardCap());
}

void WalletInit::InitKeePass()
Expand Down
4 changes: 2 additions & 2 deletions src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2682,7 +2682,7 @@ UniValue setprivatesendrounds(const JSONRPCRequest& request)
if (nRounds > MAX_PRIVATESEND_ROUNDS || nRounds < MIN_PRIVATESEND_ROUNDS)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid number of rounds");

privateSendClientOptions.nPrivateSendRounds = nRounds;
CPrivateSendClientOptions::SetRounds(nRounds);

return NullUniValue;
}
Expand Down Expand Up @@ -2710,7 +2710,7 @@ UniValue setprivatesendamount(const JSONRPCRequest& request)
if (nAmount > MAX_PRIVATESEND_AMOUNT || nAmount < MIN_PRIVATESEND_AMOUNT)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount of " + CURRENCY_UNIT + " as mixing goal amount");

privateSendClientOptions.nPrivateSendAmount = nAmount;
CPrivateSendClientOptions::SetAmount(nAmount);

return NullUniValue;
}
Expand Down

0 comments on commit e46c2f0

Please sign in to comment.