Skip to content

Commit

Permalink
Merge pull request #3604 from PastaPastaPasta/backport-12610
Browse files Browse the repository at this point in the history
Backport 12610 + PrivateSend multiwallet support.
  • Loading branch information
UdjinM6 committed Jul 21, 2020
2 parents 83726d2 + 449b4a8 commit 95f925f
Show file tree
Hide file tree
Showing 30 changed files with 707 additions and 323 deletions.
4 changes: 3 additions & 1 deletion src/dsnotificationinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, con

CPrivateSend::UpdatedBlockTip(pindexNew);
#ifdef ENABLE_WALLET
privateSendClient.UpdatedBlockTip(pindexNew);
for (auto& pair : privateSendClientManagers) {
pair.second->UpdatedBlockTip(pindexNew);
}
#endif // ENABLE_WALLET

llmq::quorumInstantSendManager->UpdatedBlockTip(pindexNew);
Expand Down
3 changes: 3 additions & 0 deletions src/httprpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ void StopHTTPRPC()
{
LogPrint(BCLog::RPC, "Stopping HTTP RPC server\n");
UnregisterHTTPHandler("/", true);
#ifdef ENABLE_WALLET
UnregisterHTTPHandler("/wallet/", false);
#endif
if (httpRPCTimerInterface) {
RPCUnsetTimerInterface(httpRPCTimerInterface.get());
httpRPCTimerInterface.reset();
Expand Down
4 changes: 3 additions & 1 deletion src/masternode/masternode-utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ void CMasternodeUtils::ProcessMasternodeConnections(CConnman& connman)
{
std::vector<CDeterministicMNCPtr> vecDmns; // will be empty when no wallet
#ifdef ENABLE_WALLET
privateSendClient.GetMixingMasternodesInfo(vecDmns);
for (const auto& pair : privateSendClientManagers) {
pair.second->GetMixingMasternodesInfo(vecDmns);
}
#endif // ENABLE_WALLET

// Don't disconnect masternode connections when we have less then the desired amount of outbound nodes
Expand Down
5 changes: 4 additions & 1 deletion src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3542,7 +3542,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
{
//probably one the extensions
#ifdef ENABLE_WALLET
privateSendClient.ProcessMessage(pfrom, strCommand, vRecv, *connman, enable_bip61);
privateSendClientQueueManager.ProcessMessage(pfrom, strCommand, vRecv, *connman, enable_bip61);
for (auto& pair : privateSendClientManagers) {
pair.second->ProcessMessage(pfrom, strCommand, vRecv, *connman, enable_bip61);
}
#endif // ENABLE_WALLET
privateSendServer.ProcessMessage(pfrom, strCommand, vRecv, *connman, enable_bip61);
sporkManager.ProcessSpork(pfrom, strCommand, vRecv, *connman);
Expand Down
367 changes: 246 additions & 121 deletions src/privatesend/privatesend-client.cpp

Large diffs are not rendered by default.

107 changes: 86 additions & 21 deletions src/privatesend/privatesend-client.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@

#include <evo/deterministicmns.h>

class CPrivateSendClientOptions;
class CPrivateSendClientManager;
class CPrivateSendClientQueueManager;

class CConnman;
class CNode;

class UniValue;

static const int MIN_PRIVATESEND_SESSIONS = 1;
Expand Down Expand Up @@ -52,7 +56,10 @@ static const int PRIVATESEND_KEYS_THRESHOLD_WARNING = 100;
static const int PRIVATESEND_KEYS_THRESHOLD_STOP = 50;

// The main object for accessing mixing
extern CPrivateSendClientManager privateSendClient;
extern std::map<const std::string, CPrivateSendClientManager*> privateSendClientManagers;

// The object to track mixing queues
extern CPrivateSendClientQueueManager privateSendClientQueueManager;

class CPendingDsaRequest
{
Expand Down Expand Up @@ -110,6 +117,8 @@ class CPrivateSendClientSession : public CPrivateSendBaseSession

CKeyHolderStorage keyHolderStorage; // storage for keys used in PrepareDenominate

CWallet* mixingWallet;

/// Create denominations
bool CreateDenominated(CAmount nBalanceToDenominate, CConnman& connman);
bool CreateDenominated(CAmount nBalanceToDenominate, const CompactTallyItem& tallyItem, bool fCreateMixingCollaterals, CConnman& connman);
Expand Down Expand Up @@ -143,14 +152,15 @@ class CPrivateSendClientSession : public CPrivateSendBaseSession
void SetNull();

public:
CPrivateSendClientSession() :
CPrivateSendClientSession(CWallet* pwallet) :
vecOutPointLocked(),
strLastMessage(),
strAutoDenomResult(),
mixingMasternode(),
txMyCollateral(),
pendingDsaRequest(),
keyHolderStorage()
keyHolderStorage(),
mixingWallet(pwallet)
{
}

Expand All @@ -177,9 +187,19 @@ class CPrivateSendClientSession : public CPrivateSendBaseSession
void GetJsonInfo(UniValue& obj) const;
};

/** Used to keep track of mixing queues
*/
class CPrivateSendClientQueueManager : public CPrivateSendBaseManager
{
public:
void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman, bool enable_bip61);

void DoMaintenance();
};

/** Used to keep track of current status of mixing pool
*/
class CPrivateSendClientManager : public CPrivateSendBaseManager
class CPrivateSendClientManager
{
private:
// Keep track of the used Masternodes
Expand All @@ -193,6 +213,8 @@ class CPrivateSendClientManager : public CPrivateSendBaseManager
int nMinBlocksToWait; // how many blocks to wait after one successful mixing tx in non-multisession mode
std::string strAutoDenomResult;

CWallet* mixingWallet;

// Keep track of current block height
int nCachedBlockHeight;

Expand All @@ -202,15 +224,6 @@ class CPrivateSendClientManager : public CPrivateSendBaseManager
bool CheckAutomaticBackup();

public:
int nPrivateSendSessions;
int nPrivateSendRounds;
int nPrivateSendAmount;
int nPrivateSendDenomsGoal;
int nPrivateSendDenomsHardCap;
bool fEnablePrivateSend;
bool fPrivateSendRunning;
bool fPrivateSendMultiSession;

int nCachedNumBlocks; //used for the overview screen
bool fCreateAutoBackups; //builtin support for automatic backups

Expand All @@ -221,20 +234,17 @@ class CPrivateSendClientManager : public CPrivateSendBaseManager
nMinBlocksToWait(1),
strAutoDenomResult(),
nCachedBlockHeight(0),
nPrivateSendRounds(DEFAULT_PRIVATESEND_ROUNDS),
nPrivateSendAmount(DEFAULT_PRIVATESEND_AMOUNT),
nPrivateSendDenomsGoal(DEFAULT_PRIVATESEND_DENOMS_GOAL),
nPrivateSendDenomsHardCap(DEFAULT_PRIVATESEND_DENOMS_HARDCAP),
fEnablePrivateSend(false),
fPrivateSendRunning(false),
fPrivateSendMultiSession(DEFAULT_PRIVATESEND_MULTISESSION),
nCachedNumBlocks(std::numeric_limits<int>::max()),
fCreateAutoBackups(true)
fCreateAutoBackups(true),
mixingWallet(nullptr)
{
}

void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman, bool enable_bip61);

bool StartMixing(CWallet* pwallet);
void StopMixing();
bool IsMixing() const;
void ResetPool();

std::string GetStatuses();
Expand All @@ -245,6 +255,9 @@ class CPrivateSendClientManager : public CPrivateSendBaseManager
/// Passively run mixing in the background according to the configuration in settings
bool DoAutomaticDenominating(CConnman& connman, bool fDryRun = false);

bool TrySubmitDenominate(const CService& mnAddr, CConnman& connman);
bool MarkAlreadyJoinedQueueAsTried(CPrivateSendQueue& dsq) const;

void CheckTimeout();

void ProcessPendingDsaRequest(CConnman& connman);
Expand All @@ -261,4 +274,56 @@ class CPrivateSendClientManager : public CPrivateSendBaseManager
void GetJsonInfo(UniValue& obj) const;
};

/* Application wide mixing options */
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;
int nPrivateSendDenomsGoal;
int nPrivateSendDenomsHardCap;
bool fEnablePrivateSend;
bool fPrivateSendMultiSession;

CPrivateSendClientOptions() :
nPrivateSendRounds(DEFAULT_PRIVATESEND_ROUNDS),
nPrivateSendAmount(DEFAULT_PRIVATESEND_AMOUNT),
nPrivateSendDenomsGoal(DEFAULT_PRIVATESEND_DENOMS_GOAL),
nPrivateSendDenomsHardCap(DEFAULT_PRIVATESEND_DENOMS_HARDCAP),
fEnablePrivateSend(false),
fPrivateSendMultiSession(DEFAULT_PRIVATESEND_MULTISESSION)
{
}

CPrivateSendClientOptions(const CPrivateSendClientOptions& other) = delete;
CPrivateSendClientOptions& operator=(const CPrivateSendClientOptions&) = delete;

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

void DoPrivateSendMaintenance(CConnman& connman);

#endif // BITCOIN_PRIVATESEND_PRIVATESEND_CLIENT_H
70 changes: 56 additions & 14 deletions src/qt/bitcoingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <privatesend/privatesend-client.h>
#include <qt/walletframe.h>
#include <qt/walletmodel.h>
#include <qt/walletview.h>
#endif // ENABLE_WALLET

#ifdef Q_OS_MAC
Expand All @@ -41,6 +42,7 @@
#include <QAction>
#include <QApplication>
#include <QButtonGroup>
#include <QComboBox>
#include <QDateTime>
#include <QDesktopWidget>
#include <QDragEnterEvent>
Expand Down Expand Up @@ -70,10 +72,6 @@ const std::string BitcoinGUI::DEFAULT_UIPLATFORM =
#endif
;

/** Display name for default wallet name. Uses tilde to avoid name
* collisions in the future with additional wallets */
const QString BitcoinGUI::DEFAULT_WALLET = "~Default";

BitcoinGUI::BitcoinGUI(const PlatformStyle *_platformStyle, const NetworkStyle *networkStyle, QWidget *parent) :
QMainWindow(parent),
enableWallet(false),
Expand All @@ -88,6 +86,8 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *_platformStyle, const NetworkStyle *
progressBar(0),
progressDialog(0),
appMenuBar(0),
appToolBar(0),
appToolBarLogoAction(0),
overviewAction(0),
historyAction(0),
masternodeAction(0),
Expand Down Expand Up @@ -588,6 +588,7 @@ void BitcoinGUI::createToolBars()
if(walletFrame)
{
QToolBar *toolbar = new QToolBar(tr("Tabs toolbar"));
appToolBar = toolbar;
toolbar->setContextMenuPolicy(Qt::PreventContextMenu);
toolbar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
toolbar->setToolButtonStyle(Qt::ToolButtonTextOnly);
Expand All @@ -612,11 +613,17 @@ void BitcoinGUI::createToolBars()
toolbar->setMovable(false); // remove unused icon in upper left corner
overviewAction->setChecked(true);

#ifdef ENABLE_WALLET
m_wallet_selector = new QComboBox(this);
m_wallet_selector->setHidden(true);
connect(m_wallet_selector, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(setCurrentWallet(const QString&)));
#endif

QLabel *logoLabel = new QLabel();
logoLabel->setObjectName("lblToolbarLogo");
logoLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);

toolbar->addWidget(logoLabel);
appToolBarLogoAction = toolbar->addWidget(logoLabel);

/** Create additional container for toolbar and walletFrame and make it the central widget.
This is a workaround mostly for toolbar styling on Mac OS but should work fine for every other OSes too.
Expand Down Expand Up @@ -729,12 +736,28 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel)
}

#ifdef ENABLE_WALLET
bool BitcoinGUI::addWallet(const QString& name, WalletModel *walletModel)
bool BitcoinGUI::addWallet(WalletModel *walletModel)
{
if(!walletFrame)
return false;
const QString name = walletModel->getWalletName();
setWalletActionsEnabled(true);
return walletFrame->addWallet(name, walletModel);
m_wallet_selector->addItem(name);
if (m_wallet_selector->count() == 2) {
m_wallet_selector->setHidden(false);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(m_wallet_selector);
layout->setSpacing(0);
layout->setMargin(0);
layout->setContentsMargins(5, 0, 5, 0);
QWidget* walletSelector = new QWidget(this);
walletSelector->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
walletSelector->setObjectName("walletSelector");
walletSelector->setLayout(layout);
appToolBar->insertWidget(appToolBarLogoAction, walletSelector);
}
rpcConsole->addWallet(walletModel);
return walletFrame->addWallet(walletModel);
}

bool BitcoinGUI::setCurrentWallet(const QString& name)
Expand All @@ -759,8 +782,8 @@ void BitcoinGUI::setWalletActionsEnabled(bool enabled)
sendCoinsAction->setEnabled(enabled);
sendCoinsMenuAction->setEnabled(enabled);
#ifdef ENABLE_WALLET
privateSendCoinsAction->setEnabled(enabled && privateSendClient.fEnablePrivateSend);
privateSendCoinsMenuAction->setEnabled(enabled && privateSendClient.fEnablePrivateSend);
privateSendCoinsAction->setEnabled(enabled && CPrivateSendClientOptions::IsEnabled());
privateSendCoinsMenuAction->setEnabled(enabled && CPrivateSendClientOptions::IsEnabled());
#else
privateSendCoinsAction->setEnabled(enabled);
privateSendCoinsMenuAction->setEnabled(enabled);
Expand Down Expand Up @@ -1028,7 +1051,9 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer
// Disabling macOS App Nap on initial sync, disk, reindex operations and mixing.
bool disableAppNap = !masternodeSync.IsSynced();
#ifdef ENABLE_WALLET
disableAppNap |= privateSendClient.fPrivateSendRunning;
for (const auto& pair : privateSendClientManagers) {
disableAppNap |= pair.second->IsMixing();
}
#endif // ENABLE_WALLET
if (disableAppNap) {
m_app_nap_inhibitor->disableAppNap();
Expand Down Expand Up @@ -1317,10 +1342,10 @@ void BitcoinGUI::showEvent(QShowEvent *event)
}

#ifdef ENABLE_WALLET
void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label)
void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName)
{
IncomingTransactionMessage itx = {
date, unit, amount, type, address, label
date, unit, amount, type, address, label, walletName
};
incomingTransactions.emplace_back(itx);

Expand Down Expand Up @@ -1386,8 +1411,11 @@ void BitcoinGUI::showIncomingTransactions()
for (auto& itx : txs) {
// On new transaction, make an info balloon
QString msg = tr("Date: %1\n").arg(itx.date) +
tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(itx.unit, itx.amount, true)) +
tr("Type: %1\n").arg(itx.type);
tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(itx.unit, itx.amount, true));
if (WalletModel::isMultiwallet() && !itx.walletName.isEmpty()) {
msg += tr("Wallet: %1\n").arg(itx.walletName);
}
msg += tr("Type: %1\n").arg(itx.type);
if (!itx.label.isEmpty())
msg += tr("Label: %1\n").arg(itx.label);
else if (!itx.address.isEmpty())
Expand Down Expand Up @@ -1496,6 +1524,20 @@ void BitcoinGUI::setEncryptionStatus(int status)
break;
}
}

void BitcoinGUI::updateWalletStatus()
{
if (!walletFrame) {
return;
}
WalletView * const walletView = walletFrame->currentWalletView();
if (!walletView) {
return;
}
WalletModel * const walletModel = walletView->getWalletModel();
setEncryptionStatus(walletModel->getEncryptionStatus());
setHDStatus(walletModel->hdEnabled());
}
#endif // ENABLE_WALLET

void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
Expand Down

0 comments on commit 95f925f

Please sign in to comment.