Create one PS manager per wallet

This commit is contained in:
UdjinM6 2020-07-16 15:23:58 +03:00 committed by pasta
parent 11255fd86e
commit a7e0957c82
No known key found for this signature in database
GPG Key ID: 52527BEDABE87984
11 changed files with 98 additions and 62 deletions

View File

@ -62,7 +62,9 @@ void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, con
CPrivateSend::UpdatedBlockTip(pindexNew);
#ifdef ENABLE_WALLET
privateSendClientManager.UpdatedBlockTip(pindexNew);
for (auto& pair : privateSendClientManagers) {
pair.second->UpdatedBlockTip(pindexNew);
}
#endif // ENABLE_WALLET
llmq::quorumInstantSendManager->UpdatedBlockTip(pindexNew);

View File

@ -24,7 +24,9 @@ void CMasternodeUtils::ProcessMasternodeConnections(CConnman& connman)
{
std::vector<CDeterministicMNCPtr> vecDmns; // will be empty when no wallet
#ifdef ENABLE_WALLET
privateSendClientManager.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

View File

@ -3543,7 +3543,9 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
//probably one the extensions
#ifdef ENABLE_WALLET
privateSendClientQueueManager.ProcessMessage(pfrom, strCommand, vRecv, *connman, enable_bip61);
privateSendClientManager.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);

View File

@ -22,7 +22,7 @@
#include <memory>
#include <univalue.h>
CPrivateSendClientManager privateSendClientManager;
std::map<const std::string, CPrivateSendClientManager*> privateSendClientManagers;
CPrivateSendClientQueueManager privateSendClientQueueManager;
CPrivateSendClientOptions privateSendClientOptions;
@ -84,9 +84,11 @@ void CPrivateSendClientQueueManager::ProcessMessage(CNode* pfrom, const std::str
// if the queue is ready, submit if we can
if (dsq.fReady) {
if (privateSendClientManager.TrySubmitDenominate(dmn->pdmnState->addr, connman)) {
LogPrint(BCLog::PRIVATESEND, "DSQUEUE -- PrivateSend queue (%s) is ready on masternode %s\n", dsq.ToString(), dmn->pdmnState->addr.ToString());
return;
for (auto& pair : privateSendClientManagers) {
if (pair.second->TrySubmitDenominate(dmn->pdmnState->addr, connman)) {
LogPrint(BCLog::PRIVATESEND, "DSQUEUE -- PrivateSend queue (%s) is ready on masternode %s\n", dsq.ToString(), dmn->pdmnState->addr.ToString());
return;
}
}
} else {
int64_t nLastDsq = mmetaman.GetMetaInfo(dmn->proTxHash)->GetLastDsq();
@ -102,7 +104,11 @@ void CPrivateSendClientQueueManager::ProcessMessage(CNode* pfrom, const std::str
LogPrint(BCLog::PRIVATESEND, "DSQUEUE -- new PrivateSend queue (%s) from masternode %s\n", dsq.ToString(), dmn->pdmnState->addr.ToString());
privateSendClientManager.MarkAlreadyJoinedQueueAsTried(dsq);
for (const auto& pair : privateSendClientManagers) {
if (pair.second->MarkAlreadyJoinedQueueAsTried(dsq)) {
break;
}
}
TRY_LOCK(cs_vecqueue, lockRecv);
if (!lockRecv) return;
@ -666,7 +672,7 @@ void CPrivateSendClientSession::CompletedTransaction(PoolMessage nMessageID)
if (nMessageID == MSG_SUCCESS) {
LogPrint(BCLog::PRIVATESEND, "CompletedTransaction -- success\n");
privateSendClientManager.UpdatedSuccessBlock();
privateSendClientManagers.at(mixingWallet->GetName())->UpdatedSuccessBlock();
keyHolderStorage.KeepAll();
} else {
LogPrint(BCLog::PRIVATESEND, "CompletedTransaction -- error\n");
@ -1068,7 +1074,7 @@ bool CPrivateSendClientSession::JoinExistingQueue(CAmount nBalanceNeedsAnonymize
continue;
}
privateSendClientManager.AddUsedMasternode(dsq.masternodeOutpoint);
privateSendClientManagers.at(mixingWallet->GetName())->AddUsedMasternode(dsq.masternodeOutpoint);
if (connman.IsMasternodeOrDisconnectRequested(dmn->pdmnState->addr)) {
LogPrint(BCLog::PRIVATESEND, "CPrivateSendClientSession::JoinExistingQueue -- skipping masternode connection, addr=%s\n", dmn->pdmnState->addr.ToString());
@ -1111,7 +1117,7 @@ bool CPrivateSendClientSession::StartNewQueue(CAmount nBalanceNeedsAnonymized, C
// otherwise, try one randomly
while (nTries < 10) {
auto dmn = privateSendClientManager.GetRandomNotUsedMasternode();
auto dmn = privateSendClientManagers.at(mixingWallet->GetName())->GetRandomNotUsedMasternode();
if (!dmn) {
LogPrint(BCLog::PRIVATESEND, "CPrivateSendClientSession::StartNewQueue -- Can't find random masternode!\n");
@ -1119,7 +1125,7 @@ bool CPrivateSendClientSession::StartNewQueue(CAmount nBalanceNeedsAnonymized, C
return false;
}
privateSendClientManager.AddUsedMasternode(dmn->collateralOutpoint);
privateSendClientManagers.at(mixingWallet->GetName())->AddUsedMasternode(dmn->collateralOutpoint);
// skip next mn payments winners
if (dmn->pdmnState->nLastPaidHeight + nMnCount < mnList.GetHeight() + 8) {
@ -1496,12 +1502,12 @@ bool CPrivateSendClientSession::MakeCollateralAmounts(const CompactTallyItem& ta
// use the same nCachedLastSuccessBlock as for DS mixing to prevent race
CValidationState state;
if (!GetMixingWallet()->CommitTransaction(wtx, reservekeyChange, &connman, state)) {
if (!mixingWallet->CommitTransaction(wtx, reservekeyChange, &connman, state)) {
LogPrint(BCLog::PRIVATESEND, "CPrivateSendClientSession::MakeCollateralAmounts -- CommitTransaction failed! Reason given: %s\n", state.GetRejectReason());
return false;
}
privateSendClientManager.UpdatedSuccessBlock();
privateSendClientManagers.at(mixingWallet->GetName())->UpdatedSuccessBlock();
return true;
}
@ -1741,13 +1747,13 @@ bool CPrivateSendClientSession::CreateDenominated(CAmount nBalanceToDenominate,
keyHolderStorageDenom.KeepAll();
CValidationState state;
if (!GetMixingWallet()->CommitTransaction(wtx, reservekeyChange, &connman, state)) {
if (!mixingWallet->CommitTransaction(wtx, reservekeyChange, &connman, state)) {
LogPrint(BCLog::PRIVATESEND, "CPrivateSendClientSession::CreateDenominated -- CommitTransaction failed! Reason given: %s\n", state.GetRejectReason());
return false;
}
// use the same nCachedLastSuccessBlock as for DS mixing to prevent race
privateSendClientManager.UpdatedSuccessBlock();
privateSendClientManagers.at(mixingWallet->GetName())->UpdatedSuccessBlock();
LogPrint(BCLog::PRIVATESEND, "CPrivateSendClientSession::CreateDenominated -- txid=%s\n", wtx.GetHash().GetHex());
return true;
@ -1842,5 +1848,7 @@ void CPrivateSendClientManager::GetJsonInfo(UniValue& obj) const
void DoPrivateSendMaintenance(CConnman& connman)
{
privateSendClientQueueManager.DoMaintenance();
privateSendClientManager.DoMaintenance(connman);
for (auto& pair : privateSendClientManagers) {
pair.second->DoMaintenance(connman);
}
}

View File

@ -56,7 +56,7 @@ static const int PRIVATESEND_KEYS_THRESHOLD_WARNING = 100;
static const int PRIVATESEND_KEYS_THRESHOLD_STOP = 50;
// The main object for accessing mixing
extern CPrivateSendClientManager privateSendClientManager;
extern std::map<const std::string, CPrivateSendClientManager*> privateSendClientManagers;
// The object to track mixing queues
extern CPrivateSendClientQueueManager privateSendClientQueueManager;

View File

@ -1049,7 +1049,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 |= privateSendClientManager.IsMixing();
for (const auto& pair : privateSendClientManagers) {
disableAppNap |= pair.second->IsMixing();
}
#endif // ENABLE_WALLET
if (disableAppNap) {
m_app_nap_inhibitor->disableAppNap();

View File

@ -288,9 +288,10 @@ void OptionsDialog::on_okButton_clicked()
{
mapper->submit();
#ifdef ENABLE_WALLET
privateSendClientManager.nCachedNumBlocks = std::numeric_limits<int>::max();
if(HasWallets())
GetWallets()[0]->MarkDirty();
for (auto& pwallet : GetWallets()) {
privateSendClientManagers.at(pwallet->GetName())->nCachedNumBlocks = std::numeric_limits<int>::max();
pwallet->MarkDirty();
}
#endif // ENABLE_WALLET
accept();
updateDefaultProxyNets();

View File

@ -181,14 +181,16 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent)
ui->labelPrivateSendEnabled->setToolTip(tr("Automatic backups are disabled, no mixing available!"));
}
} else {
if(!privateSendClientManager.IsMixing()){
ui->togglePrivateSend->setText(tr("Start Mixing"));
} else {
ui->togglePrivateSend->setText(tr("Stop Mixing"));
}
// Disable privateSendClient builtin support for automatic backups while we are in GUI,
// we'll handle automatic backups and user warnings in privateSendStatus()
privateSendClientManager.fCreateAutoBackups = false;
for (auto& pair : privateSendClientManagers) {
if (!pair.second->IsMixing()) {
ui->togglePrivateSend->setText(tr("Start Mixing"));
} else {
ui->togglePrivateSend->setText(tr("Stop Mixing"));
}
pair.second->fCreateAutoBackups = false;
}
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(privateSendStatus()));
@ -490,8 +492,10 @@ void OverviewPage::privateSendStatus(bool fForce)
static int64_t nLastDSProgressBlockTime = 0;
int nBestHeight = clientModel->getNumBlocks();
CPrivateSendClientManager* privateSendClientManager = privateSendClientManagers.find(walletModel->getWallet()->GetName())->second;
// We are processing more than 1 block per second, we'll just leave
if(nBestHeight > privateSendClientManager.nCachedNumBlocks && GetTime() - nLastDSProgressBlockTime <= 1) return;
if(nBestHeight > privateSendClientManager->nCachedNumBlocks && GetTime() - nLastDSProgressBlockTime <= 1) return;
nLastDSProgressBlockTime = GetTime();
QString strKeysLeftText(tr("keys left: %1").arg(walletModel->getKeysLeftSinceAutoBackup()));
@ -500,9 +504,9 @@ void OverviewPage::privateSendStatus(bool fForce)
}
ui->labelPrivateSendEnabled->setToolTip(strKeysLeftText);
if (!privateSendClientManager.IsMixing()) {
if (nBestHeight != privateSendClientManager.nCachedNumBlocks) {
privateSendClientManager.nCachedNumBlocks = nBestHeight;
if (!privateSendClientManager->IsMixing()) {
if (nBestHeight != privateSendClientManager->nCachedNumBlocks) {
privateSendClientManager->nCachedNumBlocks = nBestHeight;
updatePrivateSendProgress();
}
@ -557,7 +561,7 @@ void OverviewPage::privateSendStatus(bool fForce)
}
}
QString strEnabled = privateSendClientManager.IsMixing() ? tr("Enabled") : tr("Disabled");
QString strEnabled = privateSendClientManager->IsMixing() ? tr("Enabled") : tr("Disabled");
// Show how many keys left in advanced PS UI mode only
if(fShowAdvancedPSUI) strEnabled += ", " + strKeysLeftText;
ui->labelPrivateSendEnabled->setText(strEnabled);
@ -579,15 +583,15 @@ void OverviewPage::privateSendStatus(bool fForce)
}
// check privatesend status and unlock if needed
if(nBestHeight != privateSendClientManager.nCachedNumBlocks) {
if(nBestHeight != privateSendClientManager->nCachedNumBlocks) {
// Balance and number of transactions might have changed
privateSendClientManager.nCachedNumBlocks = nBestHeight;
privateSendClientManager->nCachedNumBlocks = nBestHeight;
updatePrivateSendProgress();
}
setWidgetsVisible(true);
ui->labelSubmittedDenom->setText(QString(privateSendClientManager.GetSessionDenoms().c_str()));
ui->labelSubmittedDenom->setText(QString(privateSendClientManager->GetSessionDenoms().c_str()));
}
void OverviewPage::togglePrivateSend(){
@ -600,7 +604,10 @@ void OverviewPage::togglePrivateSend(){
QMessageBox::Ok, QMessageBox::Ok);
settings.setValue("hasMixed", "hasMixed");
}
if(!privateSendClientManager.IsMixing()){
CPrivateSendClientManager* privateSendClientManager = privateSendClientManagers.find(walletModel->getWallet()->GetName())->second;
if (!privateSendClientManager->IsMixing()) {
const CAmount nMinAmount = CPrivateSend::GetSmallestDenomination() + CPrivateSend::GetMaxCollateralAmount();
if(currentBalance < nMinAmount){
QString strMinAmount(BitcoinUnits::formatWithUnit(nDisplayUnit, nMinAmount));
@ -617,7 +624,7 @@ void OverviewPage::togglePrivateSend(){
if(!ctx.isValid())
{
//unlock was cancelled
privateSendClientManager.nCachedNumBlocks = std::numeric_limits<int>::max();
privateSendClientManager->nCachedNumBlocks = std::numeric_limits<int>::max();
QMessageBox::warning(this, tr("PrivateSend"),
tr("Wallet is locked and user declined to unlock. Disabling PrivateSend."),
QMessageBox::Ok, QMessageBox::Ok);
@ -628,15 +635,15 @@ void OverviewPage::togglePrivateSend(){
}
privateSendClientManager.nCachedNumBlocks = std::numeric_limits<int>::max();
privateSendClientManager->nCachedNumBlocks = std::numeric_limits<int>::max();
if (privateSendClientManager.IsMixing()) {
if (privateSendClientManager->IsMixing()) {
ui->togglePrivateSend->setText(tr("Start Mixing"));
privateSendClientManager.ResetPool();
privateSendClientManager.StopMixing();
privateSendClientManager->ResetPool();
privateSendClientManager->StopMixing();
} else {
ui->togglePrivateSend->setText(tr("Stop Mixing"));
privateSendClientManager.StartMixing(walletModel->getWallet());
privateSendClientManager->StartMixing(walletModel->getWallet());
}
}
@ -664,5 +671,5 @@ void OverviewPage::DisablePrivateSendCompletely() {
if (nWalletBackups <= 0) {
ui->labelPrivateSendEnabled->setText("<span style='" + GUIUtil::getThemedStyleQString(GUIUtil::ThemedStyle::TS_ERROR) + "'>(" + tr("Disabled") + ")</span>");
}
privateSendClientManager.StopMixing();
privateSendClientManagers.at(walletModel->getWallet()->GetName())->StopMixing();
}

View File

@ -43,6 +43,8 @@ UniValue privatesend(const JSONRPCRequest& request)
}
}
auto it = privateSendClientManagers.find(pwallet->GetName());
if (request.params[0].get_str() == "start") {
{
LOCK(pwallet->cs_wallet);
@ -50,21 +52,21 @@ UniValue privatesend(const JSONRPCRequest& request)
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please unlock wallet for mixing with walletpassphrase first.");
}
if (!privateSendClientManager.StartMixing(pwallet)) {
if (!it->second->StartMixing(pwallet)) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Mixing has been started already.");
}
bool result = privateSendClientManager.DoAutomaticDenominating(*g_connman);
return "Mixing " + (result ? "started successfully" : ("start failed: " + privateSendClientManager.GetStatuses() + ", will retry"));
bool result = it->second->DoAutomaticDenominating(*g_connman);
return "Mixing " + (result ? "started successfully" : ("start failed: " + it->second->GetStatuses() + ", will retry"));
}
if (request.params[0].get_str() == "stop") {
privateSendClientManager.StopMixing();
it->second->StopMixing();
return "Mixing was stopped";
}
if (request.params[0].get_str() == "reset") {
privateSendClientManager.ResetPool();
it->second->ResetPool();
return "Mixing was reset";
}
@ -148,7 +150,7 @@ UniValue getprivatesendinfo(const JSONRPCRequest& request)
return obj;
}
privateSendClientManager.GetJsonInfo(obj);
privateSendClientManagers.at(pwallet->GetName())->GetJsonInfo(obj);
obj.pushKV("keys_left", pwallet->nKeysLeftSinceAutoBackup);
obj.push_back(Pair("warnings", pwallet->nKeysLeftSinceAutoBackup < PRIVATESEND_KEYS_THRESHOLD_WARNING

View File

@ -371,12 +371,13 @@ void WalletInit::Start(CScheduler& scheduler)
void WalletInit::Flush()
{
if (privateSendClientOptions.fEnablePrivateSend) {
// Stop PrivateSend, release keys
privateSendClientManager.ResetPool();
privateSendClientManager.StopMixing();
}
for (CWallet* pwallet : GetWallets()) {
if (privateSendClientOptions.fEnablePrivateSend) {
// Stop PrivateSend, release keys
auto it = privateSendClientManagers.find(pwallet->GetName());
it->second->ResetPool();
it->second->StopMixing();
}
pwallet->Flush(false);
}
}
@ -408,13 +409,17 @@ void WalletInit::InitPrivateSendSettings()
{
if (!HasWallets()) {
privateSendClientOptions.fEnablePrivateSend = false;
privateSendClientManager.StopMixing();
} else {
privateSendClientOptions.fEnablePrivateSend = gArgs.GetBoolArg("-enableprivatesend", true);
if (GetWallets()[0]->IsLocked()) {
privateSendClientManager.StopMixing();
} else if (gArgs.GetBoolArg("-privatesendautostart", DEFAULT_PRIVATESEND_AUTOSTART)) {
privateSendClientManager.StartMixing(GetWallets()[0]);
}
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);
}
}
}
privateSendClientOptions.fPrivateSendMultiSession = gArgs.GetBoolArg("-privatesendmultisession", DEFAULT_PRIVATESEND_MULTISESSION);
@ -427,7 +432,7 @@ void WalletInit::InitPrivateSendSettings()
if (privateSendClientOptions.fEnablePrivateSend) {
LogPrintf("PrivateSend: autostart=%d, multisession=%d," /* Continued */
"sessions=%d, rounds=%d, amount=%d, denoms_goal=%d, denoms_hardcap=%d\n",
privateSendClientManager.IsMixing(), privateSendClientOptions.fPrivateSendMultiSession,
fAutoStart, privateSendClientOptions.fPrivateSendMultiSession,
privateSendClientOptions.nPrivateSendSessions, privateSendClientOptions.nPrivateSendRounds,
privateSendClientOptions.nPrivateSendAmount,
privateSendClientOptions.nPrivateSendDenomsGoal, privateSendClientOptions.nPrivateSendDenomsHardCap);

View File

@ -53,6 +53,7 @@ bool AddWallet(CWallet* wallet)
std::vector<CWallet*>::const_iterator i = std::find(vpwallets.begin(), vpwallets.end(), wallet);
if (i != vpwallets.end()) return false;
vpwallets.push_back(wallet);
privateSendClientManagers.emplace(std::make_pair(wallet->GetName(), new CPrivateSendClientManager()));
return true;
}
@ -63,6 +64,10 @@ bool RemoveWallet(CWallet* wallet)
std::vector<CWallet*>::iterator i = std::find(vpwallets.begin(), vpwallets.end(), wallet);
if (i == vpwallets.end()) return false;
vpwallets.erase(i);
auto it = privateSendClientManagers.find(wallet->GetName());
delete it->second;
it->second = nullptr;
privateSendClientManagers.erase(it);
return true;
}
@ -4342,7 +4347,7 @@ bool CWallet::NewKeyPool()
batch.ErasePool(nIndex);
}
setExternalKeyPool.clear();
privateSendClientManager.StopMixing();
privateSendClientManagers.at(GetName())->StopMixing();
nKeysLeftSinceAutoBackup = 0;
m_pool_key_to_index.clear();