diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp
index de991126f62c..0f90823a1b4c 100644
--- a/src/qt/addresstablemodel.cpp
+++ b/src/qt/addresstablemodel.cpp
@@ -345,7 +345,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
else if(type == Receive)
{
// Generate a new address to associate with given label
- WalletModel::UnlockContext ctx(walletModel->requestUnlock());
+ WalletModel::UnlockContext ctx(walletModel->requestUnlock(true));
if(!ctx.isValid())
{
// Unlock wallet failed or was cancelled
diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp
index e17ba810a0c0..9abffcd673cd 100644
--- a/src/qt/askpassphrasedialog.cpp
+++ b/src/qt/askpassphrasedialog.cpp
@@ -25,7 +25,7 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) :
ui->passEdit2->installEventFilter(this);
ui->passEdit3->installEventFilter(this);
- switch(mode)
+ switch(mode)
{
case Encrypt: // Ask passphrase x2
ui->passLabel1->hide();
@@ -33,6 +33,9 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) :
ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.
Please use a passphrase of 10 or more random characters, or eight or more words."));
setWindowTitle(tr("Encrypt wallet"));
break;
+ case UnlockAnonymize:
+ ui->anonymizationCheckBox->setChecked(true);
+ ui->anonymizationCheckBox->show();
case Unlock: // Ask passphrase
ui->warningLabel->setText(tr("This operation needs your wallet passphrase to unlock the wallet."));
ui->passLabel2->hide();
@@ -73,6 +76,7 @@ AskPassphraseDialog::~AskPassphraseDialog()
void AskPassphraseDialog::setModel(WalletModel *model)
{
this->model = model;
+ ui->anonymizationCheckBox->setChecked(model->isAnonymizeOnlyUnlocked());
}
void AskPassphraseDialog::accept()
@@ -138,8 +142,9 @@ void AskPassphraseDialog::accept()
QDialog::reject(); // Cancelled
}
} break;
+ case UnlockAnonymize:
case Unlock:
- if(!model->setWalletLocked(false, oldpass))
+ if(!model->setWalletLocked(false, oldpass, ui->anonymizationCheckBox->isChecked()))
{
QMessageBox::critical(this, tr("Wallet unlock failed"),
tr("The passphrase entered for the wallet decryption was incorrect."));
@@ -193,6 +198,7 @@ void AskPassphraseDialog::textChanged()
case Encrypt: // New passphrase x2
acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
break;
+ case UnlockAnonymize: // Old passphrase x1
case Unlock: // Old passphrase x1
case Decrypt:
acceptable = !ui->passEdit1->text().isEmpty();
diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h
index 9df002da2cea..290067de61cf 100644
--- a/src/qt/askpassphrasedialog.h
+++ b/src/qt/askpassphrasedialog.h
@@ -17,6 +17,7 @@ class AskPassphraseDialog : public QDialog
public:
enum Mode {
Encrypt, /**< Ask passphrase twice and encrypt */
+ UnlockAnonymize, /**< Ask passphrase and unlock only for anonymization */
Unlock, /**< Ask passphrase and unlock */
ChangePass, /**< Ask old passphrase + new passphrase twice */
Decrypt /**< Ask passphrase and decrypt wallet */
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index b14fa017fa79..59557261858e 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -240,6 +240,10 @@ void BitcoinGUI::createActions()
backupWalletAction->setStatusTip(tr("Backup wallet to another location"));
changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase..."), this);
changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption"));
+ unlockWalletAction = new QAction(tr("&Unlock Wallet..."), this);
+ unlockWalletAction->setToolTip(tr("Unlock wallet"));
+ lockWalletAction = new QAction(tr("&Lock Wallet"), this);
+ lockWalletAction->setToolTip(tr("Lock wallet"));
signMessageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message..."), this);
signMessageAction->setStatusTip(tr("Sign messages with your DarkCoin addresses to prove you own them"));
verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this);
@@ -256,6 +260,8 @@ void BitcoinGUI::createActions()
connect(encryptWalletAction, SIGNAL(triggered(bool)), walletFrame, SLOT(encryptWallet(bool)));
connect(backupWalletAction, SIGNAL(triggered()), walletFrame, SLOT(backupWallet()));
connect(changePassphraseAction, SIGNAL(triggered()), walletFrame, SLOT(changePassphrase()));
+ connect(unlockWalletAction, SIGNAL(triggered()), walletFrame, SLOT(unlockWallet()));
+ connect(lockWalletAction, SIGNAL(triggered()), walletFrame, SLOT(lockWallet()));
connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab()));
connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab()));
}
@@ -281,6 +287,8 @@ void BitcoinGUI::createMenuBar()
QMenu *settings = appMenuBar->addMenu(tr("&Settings"));
settings->addAction(encryptWalletAction);
settings->addAction(changePassphraseAction);
+ settings->addAction(unlockWalletAction);
+ settings->addAction(lockWalletAction);
settings->addSeparator();
settings->addAction(optionsAction);
@@ -810,6 +818,8 @@ void BitcoinGUI::setEncryptionStatus(int status)
labelEncryptionIcon->hide();
encryptWalletAction->setChecked(false);
changePassphraseAction->setEnabled(false);
+ unlockWalletAction->setVisible(false);
+ lockWalletAction->setVisible(false);
encryptWalletAction->setEnabled(true);
break;
case WalletModel::Unlocked:
@@ -818,6 +828,18 @@ void BitcoinGUI::setEncryptionStatus(int status)
labelEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently unlocked"));
encryptWalletAction->setChecked(true);
changePassphraseAction->setEnabled(true);
+ unlockWalletAction->setVisible(false);
+ lockWalletAction->setVisible(true);
+ encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
+ break;
+ case WalletModel::UnlockedForAnonymizationOnly:
+ labelEncryptionIcon->show();
+ labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+ labelEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently unlocked for anonimization only"));
+ encryptWalletAction->setChecked(true);
+ changePassphraseAction->setEnabled(true);
+ unlockWalletAction->setVisible(true);
+ lockWalletAction->setVisible(true);
encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
break;
case WalletModel::Locked:
@@ -826,6 +848,8 @@ void BitcoinGUI::setEncryptionStatus(int status)
labelEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently locked"));
encryptWalletAction->setChecked(true);
changePassphraseAction->setEnabled(true);
+ unlockWalletAction->setVisible(true);
+ lockWalletAction->setVisible(false);
encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
break;
}
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index ab89410155b1..94103b94e18b 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -101,6 +101,8 @@ class BitcoinGUI : public QMainWindow
QAction *encryptWalletAction;
QAction *backupWalletAction;
QAction *changePassphraseAction;
+ QAction *unlockWalletAction;
+ QAction *lockWalletAction;
QAction *aboutQtAction;
QAction *openRPCConsoleAction;
diff --git a/src/qt/forms/askpassphrasedialog.ui b/src/qt/forms/askpassphrasedialog.ui
index 25169042a102..72da2a4e2e46 100644
--- a/src/qt/forms/askpassphrasedialog.ui
+++ b/src/qt/forms/askpassphrasedialog.ui
@@ -99,6 +99,22 @@
+ -
+
+
+ true
+
+
+ Serves to disable the trivial sendmoney when OS account compromised. Provides no real security.
+
+
+ For anonymization only
+
+
+ false
+
+
+
-
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index 38fdb789300c..277e5a273c14 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -183,7 +183,7 @@ void OptionsDialog::setSaveButtonState(bool fState)
ui->okButton->setEnabled(fState);
}
-void OptionsDialog::on_resetButton_clicked()
+/*void OptionsDialog::on_resetButton_clicked()
{
if(model)
{
@@ -197,18 +197,18 @@ void OptionsDialog::on_resetButton_clicked()
disableApplyButton();
- /* disable restart warning messages display */
+ // disable restart warning messages display
fRestartWarningDisplayed_Lang = fRestartWarningDisplayed_Proxy = true;
- /* reset all options and save the default values (QSettings) */
+ // reset all options and save the default values (QSettings)
model->Reset();
mapper->toFirst();
mapper->submit();
- /* re-enable restart warning messages display */
+ // re-enable restart warning messages display
fRestartWarningDisplayed_Lang = fRestartWarningDisplayed_Proxy = false;
}
-}
+}*/
void OptionsDialog::on_okButton_clicked()
{
diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h
index d64ed0b57fe1..1c278030f57f 100644
--- a/src/qt/optionsdialog.h
+++ b/src/qt/optionsdialog.h
@@ -36,7 +36,7 @@ private slots:
void disableSaveButtons();
/* set apply button and OK button state (enabled / disabled) */
void setSaveButtonState(bool fState);
- void on_resetButton_clicked();
+// void on_resetButton_clicked();
void on_okButton_clicked();
void on_cancelButton_clicked();
void on_applyButton_clicked();
diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp
index 020a3ba89305..2b0d364bb7e2 100644
--- a/src/qt/overviewpage.cpp
+++ b/src/qt/overviewpage.cpp
@@ -285,6 +285,7 @@ void OverviewPage::darkSendStatus()
ui->darksendEnabled->setText("Disabled");
ui->darksendStatus->setText("");
+ ui->toggleDarksend->setText("Start Darksend Mixing");
}
return;
@@ -298,17 +299,21 @@ void OverviewPage::darkSendStatus()
if (pwalletMain->GetBalance() - pwalletMain->GetAnonymizedBalance() > 2*COIN){
if (walletModel->getEncryptionStatus() != WalletModel::Unencrypted){
- if((nAnonymizeDarkcoinAmount*COIN)-pwalletMain->GetAnonymizedBalance() > 1.1*COIN && walletModel->getEncryptionStatus() == WalletModel::Locked){
- WalletModel::UnlockContext ctx(walletModel->requestUnlock());
+ if((nAnonymizeDarkcoinAmount*COIN)-pwalletMain->GetAnonymizedBalance() > 1.1*COIN &&
+ walletModel->getEncryptionStatus() == WalletModel::Locked){
+
+ WalletModel::UnlockContext ctx(walletModel->requestUnlock(false));
if(!ctx.isValid()){
//unlock was cancelled
fEnableDarksend = false;
+ darkSendPool.cachedNumBlocks = 0;
LogPrintf("Wallet is locked and user declined to unlock. Disabling Darksend.\n");
}
}
if((nAnonymizeDarkcoinAmount*COIN)-pwalletMain->GetAnonymizedBalance() <= 1.1*COIN &&
- walletModel->getEncryptionStatus() == WalletModel::Unlocked &&
+ walletModel->getEncryptionStatus() == WalletModel::Unlocked &&
darkSendPool.GetMyTransactionCount() == 0){
+
LogPrintf("Darksend is complete, locking wallet.\n");
walletModel->Lock();
}
@@ -413,4 +418,4 @@ void OverviewPage::toggleDarksend(){
darkSendPool.DoAutomaticDenominating();
}
-}
\ No newline at end of file
+}
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 61e9f076af30..753d8d60f507 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -184,7 +184,7 @@ void SendCoinsDialog::on_sendButton_clicked()
return;
}
- WalletModel::UnlockContext ctx(model->requestUnlock());
+ WalletModel::UnlockContext ctx(model->requestUnlock(true));
if(!ctx.isValid())
{
// Unlock wallet was cancelled
@@ -235,6 +235,11 @@ void SendCoinsDialog::on_sendButton_clicked()
tr("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."),
QMessageBox::Ok, QMessageBox::Ok);
break;
+ case WalletModel::AnonymizeOnlyUnlocked:
+ QMessageBox::warning(this, tr("Send Coins"),
+ tr("Error: The wallet was unlocked only to anonymize coins."),
+ QMessageBox::Ok, QMessageBox::Ok);
+ break;
case WalletModel::Aborted: // User aborted, nothing to do
break;
case WalletModel::OK:
diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp
index 6e3b4eba07f6..1e33b97e49bd 100644
--- a/src/qt/signverifymessagedialog.cpp
+++ b/src/qt/signverifymessagedialog.cpp
@@ -122,7 +122,7 @@ void SignVerifyMessageDialog::on_signMessageButton_SM_clicked()
return;
}
- WalletModel::UnlockContext ctx(model->requestUnlock());
+ WalletModel::UnlockContext ctx(model->requestUnlock(true));
if (!ctx.isValid())
{
ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
index dc074e8883f0..d0d707f37ea9 100644
--- a/src/qt/walletframe.cpp
+++ b/src/qt/walletframe.cpp
@@ -147,6 +147,13 @@ void WalletFrame::unlockWallet()
walletView->unlockWallet();
}
+void WalletFrame::lockWallet()
+{
+ WalletView *walletView = currentWalletView();
+ if (walletView)
+ walletView->lockWallet();
+}
+
void WalletFrame::setEncryptionStatus()
{
WalletView *walletView = currentWalletView();
diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h
index 74454b1a991c..5e9a67cbbca4 100644
--- a/src/qt/walletframe.h
+++ b/src/qt/walletframe.h
@@ -66,6 +66,8 @@ public slots:
void changePassphrase();
/** Ask for passphrase to unlock wallet temporarily */
void unlockWallet();
+ /** Lock wallet */
+ void lockWallet();
/** Set the encryption status as shown in the UI.
@param[in] status current encryption status
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 16ad9c342d45..3d91584c338a 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -157,6 +157,11 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QListfWalletUnlockAnonymizeOnly)
+ {
+ return UnlockedForAnonymizationOnly;
+ }
else
{
return Unlocked;
@@ -310,17 +319,18 @@ bool WalletModel::setWalletEncrypted(bool encrypted, const SecureString &passphr
}
}
-bool WalletModel::setWalletLocked(bool locked, const SecureString &passPhrase)
+bool WalletModel::setWalletLocked(bool locked, const SecureString &passPhrase, bool anonymizeOnly)
{
if(locked)
{
// Lock
- return false; //wallet->Lock();
+ // return false; //wallet->Lock();
+ return wallet->Lock();
}
else
{
// Unlock
- return wallet->Unlock(passPhrase);
+ return wallet->Unlock(passPhrase, anonymizeOnly);
}
}
@@ -329,6 +339,11 @@ void WalletModel::Lock()
wallet->Lock();
}
+bool WalletModel::isAnonymizeOnlyUnlocked()
+{
+ return wallet->fWalletUnlockAnonymizeOnly;
+}
+
bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureString &newPass)
{
bool retval;
@@ -396,9 +411,16 @@ void WalletModel::unsubscribeFromCoreSignals()
}
// WalletModel::UnlockContext implementation
-WalletModel::UnlockContext WalletModel::requestUnlock()
+WalletModel::UnlockContext WalletModel::requestUnlock(bool relock)
{
bool was_locked = getEncryptionStatus() == Locked;
+
+ if (!was_locked && isAnonymizeOnlyUnlocked())
+ {
+ setWalletLocked(true);
+ was_locked = getEncryptionStatus() == Locked;
+ }
+
if(was_locked)
{
// Request UI to unlock wallet
@@ -407,7 +429,8 @@ WalletModel::UnlockContext WalletModel::requestUnlock()
// If wallet is still locked, unlock was failed or cancelled, mark context as invalid
bool valid = getEncryptionStatus() != Locked;
- return UnlockContext(this, valid, was_locked);
+ return UnlockContext(this, valid, relock);
+// return UnlockContext(this, valid, was_locked && !isAnonymizeOnlyUnlocked());
}
WalletModel::UnlockContext::UnlockContext(WalletModel *wallet, bool valid, bool relock):
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index df8c6a11d5af..fa0d9d8494d8 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -51,14 +51,16 @@ class WalletModel : public QObject
DuplicateAddress,
TransactionCreationFailed, // Error returned when wallet is still locked
TransactionCommitFailed,
- Aborted
+ Aborted,
+ AnonymizeOnlyUnlocked
};
enum EncryptionStatus
{
Unencrypted, // !wallet->IsCrypted()
Locked, // wallet->IsCrypted() && wallet->IsLocked()
- Unlocked // wallet->IsCrypted() && !wallet->IsLocked()
+ Unlocked, // wallet->IsCrypted() && !wallet->IsLocked()
+ UnlockedForAnonymizationOnly // wallet->IsCrypted() && !wallet->IsLocked() && wallet->fWalletUnlockAnonymizeOnly
};
OptionsModel *getOptionsModel();
@@ -93,9 +95,11 @@ class WalletModel : public QObject
// Wallet encryption
bool setWalletEncrypted(bool encrypted, const SecureString &passphrase);
// Passphrase only needed when unlocking
- bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString());
+ bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString(), bool anonymizeOnly = true);
void Lock();
bool changePassphrase(const SecureString &oldPass, const SecureString &newPass);
+ // Is wallet unlocked for anonymization only?
+ bool isAnonymizeOnlyUnlocked();
// Wallet backup
bool backupWallet(const QString &filename);
@@ -119,7 +123,7 @@ class WalletModel : public QObject
void CopyFrom(const UnlockContext& rhs);
};
- UnlockContext requestUnlock();
+ UnlockContext requestUnlock(bool relock);
bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
void getOutputs(const std::vector& vOutpoints, std::vector& vOutputs);
diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp
index dd2034c34d28..618b917ec259 100644
--- a/src/qt/walletview.cpp
+++ b/src/qt/walletview.cpp
@@ -266,10 +266,18 @@ void WalletView::unlockWallet()
if(!walletModel)
return;
// Unlock wallet when requested by wallet model
- if (walletModel->getEncryptionStatus() == WalletModel::Locked)
+ if (walletModel->getEncryptionStatus() == WalletModel::Locked || walletModel->getEncryptionStatus() == WalletModel::UnlockedForAnonymizationOnly)
{
- AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this);
+ AskPassphraseDialog dlg(AskPassphraseDialog::UnlockAnonymize, this);
dlg.setModel(walletModel);
dlg.exec();
}
}
+
+void WalletView::lockWallet()
+{
+ if(!walletModel)
+ return;
+
+ walletModel->setWalletLocked(true);
+}
diff --git a/src/qt/walletview.h b/src/qt/walletview.h
index 6ad5180d567c..8604d2206b59 100644
--- a/src/qt/walletview.h
+++ b/src/qt/walletview.h
@@ -97,6 +97,8 @@ public slots:
void changePassphrase();
/** Ask for passphrase to unlock wallet temporarily */
void unlockWallet();
+ /** Lock wallet */
+ void lockWallet();
void setEncryptionStatus();
diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp
index 0fce39e66c80..9859258e1d24 100644
--- a/src/rpcdump.cpp
+++ b/src/rpcdump.cpp
@@ -51,6 +51,8 @@ Value importprivkey(const Array& params, bool fHelp)
bool fGood = vchSecret.SetString(strSecret);
if (!fGood) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
+ if (pwalletMain->fWalletUnlockAnonymizeOnly)
+ throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Wallet is unlocked for anonymization only");
CKey key = vchSecret.GetKey();
CPubKey pubkey = key.GetPubKey();
@@ -84,6 +86,8 @@ Value dumpprivkey(const Array& params, bool fHelp)
CBitcoinAddress address;
if (!address.SetString(strAddress))
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid DarkCoin address");
+ if (pwalletMain->fWalletUnlockAnonymizeOnly)
+ throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Wallet is unlocked for anonymization only");
CKeyID keyID;
if (!address.GetKeyID(keyID))
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key");
diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp
index 0b29635be8f3..a1ebcffa49f8 100644
--- a/src/rpcwallet.cpp
+++ b/src/rpcwallet.cpp
@@ -30,6 +30,8 @@ void EnsureWalletIsUnlocked()
{
if (pwalletMain->IsLocked())
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
+ if (pwalletMain->fWalletUnlockAnonymizeOnly)
+ throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Wallet is unlocked for anonymization only");
}
void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
@@ -1350,16 +1352,17 @@ void ThreadCleanWalletPassphrase(void* parg)
Value walletpassphrase(const Array& params, bool fHelp)
{
- if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
+ if (pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 3))
throw runtime_error(
- "walletpassphrase \n"
- "Stores the wallet decryption key in memory for seconds.");
+ "walletpassphrase [anonymizenonly]\n"
+ "Stores the wallet decryption key in memory for seconds.\n"
+ "if [anonymizeonly] is true sending functions are disabled.");
if (fHelp)
return true;
if (!pwalletMain->IsCrypted())
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
- if (!pwalletMain->IsLocked())
+ if (!pwalletMain->IsLocked() && !pwalletMain->fWalletUnlockAnonymizeOnly)
throw JSONRPCError(RPC_WALLET_ALREADY_UNLOCKED, "Error: Wallet is already unlocked.");
// Note that the walletpassphrase is stored in params[0] which is not mlock()ed
@@ -1371,13 +1374,23 @@ Value walletpassphrase(const Array& params, bool fHelp)
if (strWalletPass.length() > 0)
{
- if (!pwalletMain->Unlock(strWalletPass))
+ bool anonymizeOnly;
+ if (params.size() == 3)
+ anonymizeOnly = params[2].get_bool();
+ else
+ anonymizeOnly = false;
+
+ if (!pwalletMain->IsLocked() && pwalletMain->fWalletUnlockAnonymizeOnly && anonymizeOnly)
+ throw JSONRPCError(RPC_WALLET_ALREADY_UNLOCKED, "Error: Wallet is already unlocked.");
+
+ if (!pwalletMain->Unlock(strWalletPass, anonymizeOnly))
throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
}
else
throw runtime_error(
- "walletpassphrase \n"
- "Stores the wallet decryption key in memory for seconds.");
+ "walletpassphrase [anonymizeonly]\n"
+ "Stores the wallet decryption key in memory for seconds.\n"
+ "if [anonymizeonly] is true sending functions are disabled.");
NewThread(ThreadTopUpKeyPool, NULL);
int64* pnSleepTime = new int64(params[1].get_int64());
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 5a72eb19ab98..4f0eaa532d67 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -90,10 +90,14 @@ bool CWallet::AddCScript(const CScript& redeemScript)
return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript);
}
-bool CWallet::Unlock(const SecureString& strWalletPassphrase)
+bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool anonymizeOnly)
{
+
if (!IsLocked())
- return false;
+ {
+ fWalletUnlockAnonymizeOnly = anonymizeOnly;
+ return true;
+ }
CCrypter crypter;
CKeyingMaterial vMasterKey;
@@ -107,7 +111,10 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase)
if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
return false;
if (CCryptoKeyStore::Unlock(vMasterKey))
+ {
+ fWalletUnlockAnonymizeOnly = anonymizeOnly;
return true;
+ }
}
}
return false;
@@ -1691,7 +1698,13 @@ string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew,
if (IsLocked())
{
string strError = _("Error: Wallet locked, unable to create transaction!");
- LogPrintf("SendMoney() : %s", strError.c_str());
+ LogPrintf("SendMoney() : %s\n", strError.c_str());
+ return strError;
+ }
+ if (fWalletUnlockAnonymizeOnly)
+ {
+ string strError = _("Error: Wallet unlocked for anonymization only, unable to create transaction.");
+ LogPrintf("SendMoney() : %s\n", strError.c_str());
return strError;
}
diff --git a/src/wallet.h b/src/wallet.h
index b14a5f48e288..46c7f99574d4 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -103,6 +103,7 @@ class CWallet : public CCryptoKeyStore
mutable CCriticalSection cs_wallet;
bool fFileBacked;
+ bool fWalletUnlockAnonymizeOnly;
std::string strWalletFile;
std::set setKeyPool;
@@ -117,6 +118,7 @@ class CWallet : public CCryptoKeyStore
nWalletVersion = FEATURE_BASE;
nWalletMaxVersion = FEATURE_BASE;
fFileBacked = false;
+ fWalletUnlockAnonymizeOnly = false;
nMasterKeyMaxID = 0;
pwalletdbEncryption = NULL;
nOrderPosNext = 0;
@@ -127,6 +129,7 @@ class CWallet : public CCryptoKeyStore
nWalletMaxVersion = FEATURE_BASE;
strWalletFile = strWalletFileIn;
fFileBacked = true;
+ fWalletUnlockAnonymizeOnly = false;
nMasterKeyMaxID = 0;
pwalletdbEncryption = NULL;
nOrderPosNext = 0;
@@ -171,7 +174,7 @@ class CWallet : public CCryptoKeyStore
bool AddCScript(const CScript& redeemScript);
bool LoadCScript(const CScript& redeemScript) { return CCryptoKeyStore::AddCScript(redeemScript); }
- bool Unlock(const SecureString& strWalletPassphrase);
+ bool Unlock(const SecureString& strWalletPassphrase, bool anonimizeOnly = false);
bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
bool EncryptWallet(const SecureString& strWalletPassphrase);