aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/chainparams.cpp1
-rw-r--r--src/httprpc.cpp3
-rw-r--r--src/init.cpp11
-rw-r--r--src/miner.cpp4
-rw-r--r--src/qt/bitcoin.cpp26
-rw-r--r--src/qt/bitcoingui.cpp54
-rw-r--r--src/qt/bitcoingui.h18
-rw-r--r--src/qt/forms/debugwindow.ui16
-rw-r--r--src/qt/receivecoinsdialog.cpp4
-rw-r--r--src/qt/receiverequestdialog.cpp9
-rw-r--r--src/qt/receiverequestdialog.h6
-rw-r--r--src/qt/rpcconsole.cpp58
-rw-r--r--src/qt/rpcconsole.h11
-rw-r--r--src/qt/sendcoinsdialog.cpp5
-rw-r--r--src/qt/walletframe.cpp11
-rw-r--r--src/qt/walletframe.h3
-rw-r--r--src/qt/walletmodel.cpp20
-rw-r--r--src/qt/walletmodel.h7
-rw-r--r--src/qt/walletview.cpp14
-rw-r--r--src/qt/walletview.h7
-rw-r--r--src/wallet/wallet.cpp37
21 files changed, 234 insertions, 91 deletions
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index c2b3480f9d..6067503b0b 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -135,6 +135,7 @@ public:
vSeeds.emplace_back("seed.bitcoinstats.com"); // Christian Decker, supports x1 - xf
vSeeds.emplace_back("seed.bitcoin.jonasschnelli.ch"); // Jonas Schnelli, only supports x1, x5, x9, and xd
vSeeds.emplace_back("seed.btc.petertodd.org"); // Peter Todd, only supports x1, x5, x9, and xd
+ vSeeds.emplace_back("seed.bitcoin.sprovoost.nl"); // Sjors Provoost
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,0);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5);
diff --git a/src/httprpc.cpp b/src/httprpc.cpp
index 82ae733006..ed0a030701 100644
--- a/src/httprpc.cpp
+++ b/src/httprpc.cpp
@@ -252,6 +252,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();
diff --git a/src/init.cpp b/src/init.cpp
index 30ee0e694c..e5443eef0e 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -491,8 +491,6 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-whitelistrelay", strprintf(_("Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d)"), DEFAULT_WHITELISTRELAY));
strUsage += HelpMessageGroup(_("Block creation options:"));
- if (showDebug)
- strUsage += HelpMessageOpt("-blockmaxsize=<n>", "Set maximum BIP141 block weight to this * 4. Deprecated, use blockmaxweight");
strUsage += HelpMessageOpt("-blockmaxweight=<n>", strprintf(_("Set maximum BIP141 block weight (default: %d)"), DEFAULT_BLOCK_MAX_WEIGHT));
strUsage += HelpMessageOpt("-blockmintxfee=<amt>", strprintf(_("Set lowest fee rate (in %s/kB) for transactions to be included in block creation. (default: %s)"), CURRENCY_UNIT, FormatMoney(DEFAULT_BLOCK_MIN_TX_FEE)));
if (showDebug)
@@ -798,15 +796,6 @@ void InitParameterInteraction()
if (gArgs.SoftSetBoolArg("-whitelistrelay", true))
LogPrintf("%s: parameter interaction: -whitelistforcerelay=1 -> setting -whitelistrelay=1\n", __func__);
}
-
- if (gArgs.IsArgSet("-blockmaxsize")) {
- unsigned int max_size = gArgs.GetArg("-blockmaxsize", 0);
- if (gArgs.SoftSetArg("blockmaxweight", strprintf("%d", max_size * WITNESS_SCALE_FACTOR))) {
- LogPrintf("%s: parameter interaction: -blockmaxsize=%d -> setting -blockmaxweight=%d (-blockmaxsize is deprecated!)\n", __func__, max_size, max_size * WITNESS_SCALE_FACTOR);
- } else {
- LogPrintf("%s: Ignoring blockmaxsize setting which is overridden by blockmaxweight", __func__);
- }
- }
}
static std::string ResolveErrMsg(const char * const optname, const std::string& strBind)
diff --git a/src/miner.cpp b/src/miner.cpp
index 4b86446774..0660df928c 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -68,9 +68,7 @@ BlockAssembler::BlockAssembler(const CChainParams& params, const Options& option
static BlockAssembler::Options DefaultOptions(const CChainParams& params)
{
// Block resource limits
- // If neither -blockmaxsize or -blockmaxweight is given, limit to DEFAULT_BLOCK_MAX_*
- // If only one is given, only restrict the specified resource.
- // If both are given, restrict both.
+ // If -blockmaxweight is not given, limit to DEFAULT_BLOCK_MAX_WEIGHT
BlockAssembler::Options options;
options.nBlockMaxWeight = gArgs.GetArg("-blockmaxweight", DEFAULT_BLOCK_MAX_WEIGHT);
if (gArgs.IsArgSet("-blockmintxfee")) {
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index ab381bfb5d..df1be35c8d 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -251,7 +251,7 @@ private:
QTimer *pollShutdownTimer;
#ifdef ENABLE_WALLET
PaymentServer* paymentServer;
- WalletModel *walletModel;
+ std::vector<WalletModel*> m_wallet_models;
#endif
int returnValue;
const PlatformStyle *platformStyle;
@@ -333,7 +333,7 @@ BitcoinApplication::BitcoinApplication(int &argc, char **argv):
pollShutdownTimer(0),
#ifdef ENABLE_WALLET
paymentServer(0),
- walletModel(0),
+ m_wallet_models(),
#endif
returnValue(0)
{
@@ -451,8 +451,10 @@ void BitcoinApplication::requestShutdown()
#ifdef ENABLE_WALLET
window->removeAllWallets();
- delete walletModel;
- walletModel = 0;
+ for (WalletModel *walletModel : m_wallet_models) {
+ delete walletModel;
+ }
+ m_wallet_models.clear();
#endif
delete clientModel;
clientModel = 0;
@@ -481,16 +483,20 @@ void BitcoinApplication::initializeResult(bool success)
window->setClientModel(clientModel);
#ifdef ENABLE_WALLET
- // TODO: Expose secondary wallets
- if (!vpwallets.empty())
- {
- walletModel = new WalletModel(platformStyle, vpwallets[0], optionsModel);
+ bool fFirstWallet = true;
+ for (CWalletRef pwallet : vpwallets) {
+ WalletModel * const walletModel = new WalletModel(platformStyle, pwallet, optionsModel);
- window->addWallet(BitcoinGUI::DEFAULT_WALLET, walletModel);
- window->setCurrentWallet(BitcoinGUI::DEFAULT_WALLET);
+ window->addWallet(walletModel);
+ if (fFirstWallet) {
+ window->setCurrentWallet(walletModel->getWalletName());
+ fFirstWallet = false;
+ }
connect(walletModel, SIGNAL(coinsSent(CWallet*,SendCoinsRecipient,QByteArray)),
paymentServer, SLOT(fetchPaymentACK(CWallet*,const SendCoinsRecipient&,QByteArray)));
+
+ m_wallet_models.push_back(walletModel);
}
#endif
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 427eb95a84..4707fcceb9 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -21,6 +21,7 @@
#ifdef ENABLE_WALLET
#include <qt/walletframe.h>
#include <qt/walletmodel.h>
+#include <qt/walletview.h>
#endif // ENABLE_WALLET
#ifdef Q_OS_MAC
@@ -36,6 +37,7 @@
#include <QAction>
#include <QApplication>
+#include <QComboBox>
#include <QDateTime>
#include <QDesktopWidget>
#include <QDragEnterEvent>
@@ -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),
@@ -88,6 +86,7 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *_platformStyle, const NetworkStyle *
progressBar(0),
progressDialog(0),
appMenuBar(0),
+ appToolBar(0),
overviewAction(0),
historyAction(0),
quitAction(0),
@@ -455,6 +454,7 @@ void BitcoinGUI::createToolBars()
if(walletFrame)
{
QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
+ appToolBar = toolbar;
toolbar->setContextMenuPolicy(Qt::PreventContextMenu);
toolbar->setMovable(false);
toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
@@ -463,6 +463,15 @@ void BitcoinGUI::createToolBars()
toolbar->addAction(receiveCoinsAction);
toolbar->addAction(historyAction);
overviewAction->setChecked(true);
+
+#ifdef ENABLE_WALLET
+ QWidget *spacer = new QWidget();
+ spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ toolbar->addWidget(spacer);
+
+ m_wallet_selector = new QComboBox();
+ connect(m_wallet_selector, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(setCurrentWallet(const QString&)));
+#endif
}
}
@@ -529,12 +538,22 @@ 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_label = new QLabel();
+ m_wallet_selector_label->setText(tr("Wallet:") + " ");
+ m_wallet_selector_label->setBuddy(m_wallet_selector);
+ appToolBar->addWidget(m_wallet_selector_label);
+ appToolBar->addWidget(m_wallet_selector);
+ }
+ rpcConsole->addWallet(walletModel);
+ return walletFrame->addWallet(walletModel);
}
bool BitcoinGUI::setCurrentWallet(const QString& name)
@@ -983,12 +1002,15 @@ 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)
{
// On new transaction, make an info balloon
QString msg = tr("Date: %1\n").arg(date) +
- tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(unit, amount, true)) +
- tr("Type: %1\n").arg(type);
+ tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(unit, amount, true));
+ if (WalletModel::isMultiwallet() && !walletName.isEmpty()) {
+ msg += tr("Wallet: %1\n").arg(walletName);
+ }
+ msg += tr("Type: %1\n").arg(type);
if (!label.isEmpty())
msg += tr("Label: %1\n").arg(label);
else if (!address.isEmpty())
@@ -1079,6 +1101,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)
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index ddb7ecb76a..b9e92f2d5b 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -33,6 +33,7 @@ class ModalOverlay;
QT_BEGIN_NAMESPACE
class QAction;
+class QComboBox;
class QProgressBar;
class QProgressDialog;
QT_END_NAMESPACE
@@ -46,7 +47,6 @@ class BitcoinGUI : public QMainWindow
Q_OBJECT
public:
- static const QString DEFAULT_WALLET;
static const std::string DEFAULT_UIPLATFORM;
explicit BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent = 0);
@@ -62,8 +62,7 @@ public:
The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending
functionality.
*/
- bool addWallet(const QString& name, WalletModel *walletModel);
- bool setCurrentWallet(const QString& name);
+ bool addWallet(WalletModel *walletModel);
void removeAllWallets();
#endif // ENABLE_WALLET
bool enableWallet;
@@ -90,6 +89,7 @@ private:
QProgressDialog *progressDialog;
QMenuBar *appMenuBar;
+ QToolBar *appToolBar;
QAction *overviewAction;
QAction *historyAction;
QAction *quitAction;
@@ -112,6 +112,9 @@ private:
QAction *openAction;
QAction *showHelpMessageAction;
+ QLabel *m_wallet_selector_label;
+ QComboBox *m_wallet_selector;
+
QSystemTrayIcon *trayIcon;
QMenu *trayIconMenu;
Notificator *notificator;
@@ -171,6 +174,12 @@ public Q_SLOTS:
void message(const QString &title, const QString &message, unsigned int style, bool *ret = nullptr);
#ifdef ENABLE_WALLET
+ bool setCurrentWallet(const QString& name);
+ /** Set the UI status indicators based on the currently selected wallet.
+ */
+ void updateWalletStatus();
+
+private:
/** Set the encryption status as shown in the UI.
@param[in] status current encryption status
@see WalletModel::EncryptionStatus
@@ -183,10 +192,11 @@ public Q_SLOTS:
*/
void setHDStatus(int hdEnabled);
+public Q_SLOTS:
bool handlePaymentRequest(const SendCoinsRecipient& recipient);
/** Show incoming transaction notification for new transactions. */
- void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label);
+ void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName);
#endif // ENABLE_WALLET
private Q_SLOTS:
diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui
index bba822882e..695ed61228 100644
--- a/src/qt/forms/debugwindow.ui
+++ b/src/qt/forms/debugwindow.ui
@@ -413,6 +413,22 @@
<number>4</number>
</property>
<item>
+ <widget class="QLabel" name="WalletSelectorLabel">
+ <property name="text">
+ <string>Wallet: </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="WalletSelector">
+ <item>
+ <property name="text">
+ <string>(none)</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp
index 132fb54d66..c8b6366db0 100644
--- a/src/qt/receivecoinsdialog.cpp
+++ b/src/qt/receivecoinsdialog.cpp
@@ -153,7 +153,7 @@ void ReceiveCoinsDialog::on_receiveButton_clicked()
ui->reqAmount->value(), ui->reqMessage->text());
ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose);
- dialog->setModel(model->getOptionsModel());
+ dialog->setModel(model);
dialog->setInfo(info);
dialog->show();
clear();
@@ -166,7 +166,7 @@ void ReceiveCoinsDialog::on_recentRequestsView_doubleClicked(const QModelIndex &
{
const RecentRequestsTableModel *submodel = model->getRecentRequestsTableModel();
ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
- dialog->setModel(model->getOptionsModel());
+ dialog->setModel(model);
dialog->setInfo(submodel->entry(index.row()).recipient);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->show();
diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp
index d4cb0e5ba2..75146e2214 100644
--- a/src/qt/receiverequestdialog.cpp
+++ b/src/qt/receiverequestdialog.cpp
@@ -108,12 +108,12 @@ ReceiveRequestDialog::~ReceiveRequestDialog()
delete ui;
}
-void ReceiveRequestDialog::setModel(OptionsModel *_model)
+void ReceiveRequestDialog::setModel(WalletModel *_model)
{
this->model = _model;
if (_model)
- connect(_model, SIGNAL(displayUnitChanged(int)), this, SLOT(update()));
+ connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(update()));
// update the display unit if necessary
update();
@@ -143,11 +143,14 @@ void ReceiveRequestDialog::update()
html += "<a href=\""+uri+"\">" + GUIUtil::HtmlEscape(uri) + "</a><br>";
html += "<b>"+tr("Address")+"</b>: " + GUIUtil::HtmlEscape(info.address) + "<br>";
if(info.amount)
- html += "<b>"+tr("Amount")+"</b>: " + BitcoinUnits::formatHtmlWithUnit(model->getDisplayUnit(), info.amount) + "<br>";
+ html += "<b>"+tr("Amount")+"</b>: " + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), info.amount) + "<br>";
if(!info.label.isEmpty())
html += "<b>"+tr("Label")+"</b>: " + GUIUtil::HtmlEscape(info.label) + "<br>";
if(!info.message.isEmpty())
html += "<b>"+tr("Message")+"</b>: " + GUIUtil::HtmlEscape(info.message) + "<br>";
+ if(model->isMultiwallet()) {
+ html += "<b>"+tr("Wallet")+"</b>: " + GUIUtil::HtmlEscape(model->getWalletName()) + "<br>";
+ }
ui->outUri->setText(html);
#ifdef USE_QRCODE
diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h
index 21bbf1edb7..23c5529535 100644
--- a/src/qt/receiverequestdialog.h
+++ b/src/qt/receiverequestdialog.h
@@ -12,8 +12,6 @@
#include <QLabel>
#include <QPainter>
-class OptionsModel;
-
namespace Ui {
class ReceiveRequestDialog;
}
@@ -53,7 +51,7 @@ public:
explicit ReceiveRequestDialog(QWidget *parent = 0);
~ReceiveRequestDialog();
- void setModel(OptionsModel *model);
+ void setModel(WalletModel *model);
void setInfo(const SendCoinsRecipient &info);
private Q_SLOTS:
@@ -64,7 +62,7 @@ private Q_SLOTS:
private:
Ui::ReceiveRequestDialog *ui;
- OptionsModel *model;
+ WalletModel *model;
SendCoinsRecipient info;
};
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 1aa4de03ca..c41e19f6f5 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -12,6 +12,7 @@
#include <qt/bantablemodel.h>
#include <qt/clientmodel.h>
#include <qt/platformstyle.h>
+#include <qt/walletmodel.h>
#include <chainparams.h>
#include <netbase.h>
#include <rpc/server.h>
@@ -84,7 +85,7 @@ class RPCExecutor : public QObject
Q_OBJECT
public Q_SLOTS:
- void request(const QString &command);
+ void request(const QString &command, const QString &walletID);
Q_SIGNALS:
void reply(int category, const QString &command);
@@ -145,7 +146,7 @@ public:
* @param[out] pstrFilteredOut Command line, filtered to remove any sensitive data
*/
-bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &strCommand, const bool fExecute, std::string * const pstrFilteredOut)
+bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &strCommand, const bool fExecute, std::string * const pstrFilteredOut, const std::string *walletID)
{
std::vector< std::vector<std::string> > stack;
stack.push_back(std::vector<std::string>());
@@ -303,10 +304,8 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
req.params = RPCConvertValues(stack.back()[0], std::vector<std::string>(stack.back().begin() + 1, stack.back().end()));
req.strMethod = stack.back()[0];
#ifdef ENABLE_WALLET
- // TODO: Move this logic to WalletModel
- if (!vpwallets.empty()) {
- // in Qt, use always the wallet with index 0 when running with multiple wallets
- QByteArray encodedName = QUrl::toPercentEncoding(QString::fromStdString(vpwallets[0]->GetName()));
+ if (walletID && !walletID->empty()) {
+ QByteArray encodedName = QUrl::toPercentEncoding(QString::fromStdString(*walletID));
req.URI = "/wallet/"+std::string(encodedName.constData(), encodedName.length());
}
#endif
@@ -385,7 +384,7 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
}
}
-void RPCExecutor::request(const QString &command)
+void RPCExecutor::request(const QString &command, const QString &walletID)
{
try
{
@@ -416,7 +415,8 @@ void RPCExecutor::request(const QString &command)
" example: getblock(getblockhash(0),true)[tx][0]\n\n")));
return;
}
- if(!RPCConsole::RPCExecuteCommandLine(result, executableCommand))
+ std::string wallet_id = walletID.toStdString();
+ if(!RPCConsole::RPCExecuteCommandLine(result, executableCommand, nullptr, &wallet_id))
{
Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \""));
return;
@@ -478,6 +478,10 @@ RPCConsole::RPCConsole(const PlatformStyle *_platformStyle, QWidget *parent) :
connect(ui->fontSmallerButton, SIGNAL(clicked()), this, SLOT(fontSmaller()));
connect(ui->btnClearTrafficGraph, SIGNAL(clicked()), ui->trafficGraph, SLOT(clear()));
+ // disable the wallet selector by default
+ ui->WalletSelector->setVisible(false);
+ ui->WalletSelectorLabel->setVisible(false);
+
// set library version labels
#ifdef ENABLE_WALLET
ui->berkeleyDBVersion->setText(DbEnv::version(0, 0, 0));
@@ -687,6 +691,23 @@ void RPCConsole::setClientModel(ClientModel *model)
}
}
+#ifdef ENABLE_WALLET
+void RPCConsole::addWallet(WalletModel * const walletModel)
+{
+ const QString name = walletModel->getWalletName();
+ // use name for text and internal data object (to allow to move to a wallet id later)
+ ui->WalletSelector->addItem(name, name);
+ if (ui->WalletSelector->count() == 2 && !isVisible()) {
+ // First wallet added, set to default so long as the window isn't presently visible (and potentially in use)
+ ui->WalletSelector->setCurrentIndex(1);
+ }
+ if (ui->WalletSelector->count() > 2) {
+ ui->WalletSelector->setVisible(true);
+ ui->WalletSelectorLabel->setVisible(true);
+ }
+}
+#endif
+
static QString categoryClass(int category)
{
switch(category)
@@ -874,8 +895,25 @@ void RPCConsole::on_lineEdit_returnPressed()
cmdBeforeBrowsing = QString();
+ QString walletID;
+#ifdef ENABLE_WALLET
+ const int wallet_index = ui->WalletSelector->currentIndex();
+ if (wallet_index > 0) {
+ walletID = (QString)ui->WalletSelector->itemData(wallet_index).value<QString>();
+ }
+
+ if (m_last_wallet_id != walletID) {
+ if (walletID.isEmpty()) {
+ message(CMD_REQUEST, tr("Executing command without any wallet"));
+ } else {
+ message(CMD_REQUEST, tr("Executing command using \"%1\" wallet").arg(walletID));
+ }
+ m_last_wallet_id = walletID;
+ }
+#endif
+
message(CMD_REQUEST, QString::fromStdString(strFilteredCmd));
- Q_EMIT cmdRequest(cmd);
+ Q_EMIT cmdRequest(cmd, walletID);
cmd = QString::fromStdString(strFilteredCmd);
@@ -923,7 +961,7 @@ void RPCConsole::startExecutor()
// Replies from executor object must go to this object
connect(executor, SIGNAL(reply(int,QString)), this, SLOT(message(int,QString)));
// Requests from this object must go to executor
- connect(this, SIGNAL(cmdRequest(QString)), executor, SLOT(request(QString)));
+ connect(this, SIGNAL(cmdRequest(QString, QString)), executor, SLOT(request(QString, QString)));
// On stopExecutor signal
// - quit the Qt event loop in the execution thread
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index c41cbb0933..c97260b2c3 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -17,6 +17,7 @@
class ClientModel;
class PlatformStyle;
class RPCTimerInterface;
+class WalletModel;
namespace Ui {
class RPCConsole;
@@ -36,12 +37,13 @@ public:
explicit RPCConsole(const PlatformStyle *platformStyle, QWidget *parent);
~RPCConsole();
- static bool RPCParseCommandLine(std::string &strResult, const std::string &strCommand, bool fExecute, std::string * const pstrFilteredOut = nullptr);
- static bool RPCExecuteCommandLine(std::string &strResult, const std::string &strCommand, std::string * const pstrFilteredOut = nullptr) {
- return RPCParseCommandLine(strResult, strCommand, true, pstrFilteredOut);
+ static bool RPCParseCommandLine(std::string &strResult, const std::string &strCommand, bool fExecute, std::string * const pstrFilteredOut = nullptr, const std::string *walletID = nullptr);
+ static bool RPCExecuteCommandLine(std::string &strResult, const std::string &strCommand, std::string * const pstrFilteredOut = nullptr, const std::string *walletID = nullptr) {
+ return RPCParseCommandLine(strResult, strCommand, true, pstrFilteredOut, walletID);
}
void setClientModel(ClientModel *model);
+ void addWallet(WalletModel * const walletModel);
enum MessageClass {
MC_ERROR,
@@ -120,7 +122,7 @@ public Q_SLOTS:
Q_SIGNALS:
// For RPC command executor
void stopExecutor();
- void cmdRequest(const QString &command);
+ void cmdRequest(const QString &command, const QString &walletID);
private:
void startExecutor();
@@ -151,6 +153,7 @@ private:
int consoleFontSize;
QCompleter *autoCompleter;
QThread thread;
+ QString m_last_wallet_id;
/** Update UI with latest network info from model. */
void updateNetworkState();
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index ec7edd48cd..8a52aadbb0 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -277,8 +277,11 @@ void SendCoinsDialog::on_sendButton_clicked()
QStringList formatted;
for (const SendCoinsRecipient &rcp : currentTransaction.getRecipients())
{
- // generate bold amount string
+ // generate bold amount string with wallet name in case of multiwallet
QString amount = "<b>" + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount);
+ if (model->isMultiwallet()) {
+ amount.append(" <u>"+tr("from wallet %1").arg(GUIUtil::HtmlEscape(model->getWalletName()))+"</u> ");
+ }
amount.append("</b>");
// generate monospace address string
QString address = "<span style='font-family: monospace;'>" + rcp.address;
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
index c0b9d04269..5b13353d7b 100644
--- a/src/qt/walletframe.cpp
+++ b/src/qt/walletframe.cpp
@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <qt/walletframe.h>
+#include <qt/walletmodel.h>
#include <qt/bitcoingui.h>
#include <qt/walletview.h>
@@ -39,10 +40,16 @@ void WalletFrame::setClientModel(ClientModel *_clientModel)
this->clientModel = _clientModel;
}
-bool WalletFrame::addWallet(const QString& name, WalletModel *walletModel)
+bool WalletFrame::addWallet(WalletModel *walletModel)
{
- if (!gui || !clientModel || !walletModel || mapWalletViews.count(name) > 0)
+ if (!gui || !clientModel || !walletModel) {
return false;
+ }
+
+ const QString name = walletModel->getWalletName();
+ if (mapWalletViews.count(name) > 0) {
+ return false;
+ }
WalletView *walletView = new WalletView(platformStyle, this);
walletView->setBitcoinGUI(gui);
diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h
index 42ce69fea1..6eedcf370c 100644
--- a/src/qt/walletframe.h
+++ b/src/qt/walletframe.h
@@ -36,7 +36,7 @@ public:
void setClientModel(ClientModel *clientModel);
- bool addWallet(const QString& name, WalletModel *walletModel);
+ bool addWallet(WalletModel *walletModel);
bool setCurrentWallet(const QString& name);
bool removeWallet(const QString &name);
void removeAllWallets();
@@ -59,6 +59,7 @@ private:
const PlatformStyle *platformStyle;
+public:
WalletView *currentWalletView();
public Q_SLOTS:
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index d092ebedfb..555a21e8c5 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -110,8 +110,9 @@ void WalletModel::updateStatus()
{
EncryptionStatus newEncryptionStatus = getEncryptionStatus();
- if(cachedEncryptionStatus != newEncryptionStatus)
- Q_EMIT encryptionStatusChanged(newEncryptionStatus);
+ if(cachedEncryptionStatus != newEncryptionStatus) {
+ Q_EMIT encryptionStatusChanged();
+ }
}
void WalletModel::pollBalanceChanged()
@@ -743,3 +744,18 @@ int WalletModel::getDefaultConfirmTarget() const
{
return nTxConfirmTarget;
}
+
+QString WalletModel::getWalletName() const
+{
+ LOCK(wallet->cs_wallet);
+ QString walletName = QString::fromStdString(wallet->GetName());
+ if (walletName.endsWith(".dat")) {
+ walletName.truncate(walletName.size() - 4);
+ }
+ return walletName;
+}
+
+bool WalletModel::isMultiwallet()
+{
+ return gArgs.GetArgs("-wallet").size() > 1;
+}
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index 64813e0f5a..ff4b38a804 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -136,6 +136,8 @@ public:
TransactionTableModel *getTransactionTableModel();
RecentRequestsTableModel *getRecentRequestsTableModel();
+ CWallet *getWallet() const { return wallet; };
+
CAmount getBalance(const CCoinControl *coinControl = nullptr) const;
CAmount getUnconfirmedBalance() const;
CAmount getImmatureBalance() const;
@@ -225,6 +227,9 @@ public:
int getDefaultConfirmTarget() const;
+ QString getWalletName() const;
+
+ static bool isMultiwallet();
private:
CWallet *wallet;
bool fHaveWatchOnly;
@@ -260,7 +265,7 @@ Q_SIGNALS:
const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance);
// Encryption status of wallet changed
- void encryptionStatusChanged(int status);
+ void encryptionStatusChanged();
// Signal emitted when wallet needs to be unlocked
// It is valid behaviour for listeners to keep the wallet locked after this signal;
diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp
index 64497a3431..cc4300a7a1 100644
--- a/src/qt/walletview.cpp
+++ b/src/qt/walletview.cpp
@@ -101,13 +101,13 @@ void WalletView::setBitcoinGUI(BitcoinGUI *gui)
connect(this, SIGNAL(message(QString,QString,unsigned int)), gui, SLOT(message(QString,QString,unsigned int)));
// Pass through encryption status changed signals
- connect(this, SIGNAL(encryptionStatusChanged(int)), gui, SLOT(setEncryptionStatus(int)));
+ connect(this, SIGNAL(encryptionStatusChanged()), gui, SLOT(updateWalletStatus()));
// Pass through transaction notifications
- connect(this, SIGNAL(incomingTransaction(QString,int,CAmount,QString,QString,QString)), gui, SLOT(incomingTransaction(QString,int,CAmount,QString,QString,QString)));
+ connect(this, SIGNAL(incomingTransaction(QString,int,CAmount,QString,QString,QString,QString)), gui, SLOT(incomingTransaction(QString,int,CAmount,QString,QString,QString,QString)));
// Connect HD enabled state signal
- connect(this, SIGNAL(hdEnabledStatusChanged(int)), gui, SLOT(setHDStatus(int)));
+ connect(this, SIGNAL(hdEnabledStatusChanged()), gui, SLOT(updateWalletStatus()));
}
}
@@ -137,11 +137,11 @@ void WalletView::setWalletModel(WalletModel *_walletModel)
connect(_walletModel, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int)));
// Handle changes in encryption status
- connect(_walletModel, SIGNAL(encryptionStatusChanged(int)), this, SIGNAL(encryptionStatusChanged(int)));
+ connect(_walletModel, SIGNAL(encryptionStatusChanged()), this, SIGNAL(encryptionStatusChanged()));
updateEncryptionStatus();
// update HD status
- Q_EMIT hdEnabledStatusChanged(_walletModel->hdEnabled());
+ Q_EMIT hdEnabledStatusChanged();
// Balloon pop-up for new transaction
connect(_walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
@@ -172,7 +172,7 @@ void WalletView::processNewTransaction(const QModelIndex& parent, int start, int
QString address = ttm->data(index, TransactionTableModel::AddressRole).toString();
QString label = ttm->data(index, TransactionTableModel::LabelRole).toString();
- Q_EMIT incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address, label);
+ Q_EMIT incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address, label, walletModel->getWalletName());
}
void WalletView::gotoOverviewPage()
@@ -234,7 +234,7 @@ void WalletView::showOutOfSyncWarning(bool fShow)
void WalletView::updateEncryptionStatus()
{
- Q_EMIT encryptionStatusChanged(walletModel->getEncryptionStatus());
+ Q_EMIT encryptionStatusChanged();
}
void WalletView::encryptWallet(bool status)
diff --git a/src/qt/walletview.h b/src/qt/walletview.h
index 30d68e4eff..878a5966d6 100644
--- a/src/qt/walletview.h
+++ b/src/qt/walletview.h
@@ -44,6 +44,7 @@ public:
The client model represents the part of the core that communicates with the P2P network, and is wallet-agnostic.
*/
void setClientModel(ClientModel *clientModel);
+ WalletModel *getWalletModel() { return walletModel; }
/** Set the wallet model.
The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending
functionality.
@@ -119,11 +120,11 @@ Q_SIGNALS:
/** Fired when a message should be reported to the user */
void message(const QString &title, const QString &message, unsigned int style);
/** Encryption status of wallet changed */
- void encryptionStatusChanged(int status);
+ void encryptionStatusChanged();
/** HD-Enabled status of wallet changed (only possible during startup) */
- void hdEnabledStatusChanged(int hdEnabled);
+ void hdEnabledStatusChanged();
/** Notify that a new transaction appeared */
- void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label);
+ void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName);
/** Notify that the out of sync warning icon has been pressed */
void outOfSyncWarningClicked();
};
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index b37a411ef4..a80875e7ed 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -2890,20 +2890,11 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
nChangePosInOut = -1;
}
- // Fill vin
+ // Dummy fill vin for maximum size estimation
//
- // Note how the sequence number is set to non-maxint so that
- // the nLockTime set above actually works.
- //
- // BIP125 defines opt-in RBF as any nSequence < maxint-1, so
- // we use the highest possible value in that range (maxint-2)
- // to avoid conflicting with other possible uses of nSequence,
- // and in the spirit of "smallest possible change from prior
- // behavior."
- const uint32_t nSequence = coin_control.signalRbf ? MAX_BIP125_RBF_SEQUENCE : (CTxIn::SEQUENCE_FINAL - 1);
- for (const auto& coin : setCoins)
- txNew.vin.push_back(CTxIn(coin.outpoint,CScript(),
- nSequence));
+ for (const auto& coin : setCoins) {
+ txNew.vin.push_back(CTxIn(coin.outpoint,CScript()));
+ }
nBytes = CalculateMaximumSignedTxSize(txNew, this);
if (nBytes < 0) {
@@ -2993,11 +2984,29 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
if (nChangePosInOut == -1) reservekey.ReturnKey(); // Return any reserved key if we don't have change
+ // Shuffle selected coins and fill in final vin
+ txNew.vin.clear();
+ std::vector<CInputCoin> selected_coins(setCoins.begin(), setCoins.end());
+ std::shuffle(selected_coins.begin(), selected_coins.end(), FastRandomContext());
+
+ // Note how the sequence number is set to non-maxint so that
+ // the nLockTime set above actually works.
+ //
+ // BIP125 defines opt-in RBF as any nSequence < maxint-1, so
+ // we use the highest possible value in that range (maxint-2)
+ // to avoid conflicting with other possible uses of nSequence,
+ // and in the spirit of "smallest possible change from prior
+ // behavior."
+ const uint32_t nSequence = coin_control.signalRbf ? MAX_BIP125_RBF_SEQUENCE : (CTxIn::SEQUENCE_FINAL - 1);
+ for (const auto& coin : selected_coins) {
+ txNew.vin.push_back(CTxIn(coin.outpoint, CScript(), nSequence));
+ }
+
if (sign)
{
CTransaction txNewConst(txNew);
int nIn = 0;
- for (const auto& coin : setCoins)
+ for (const auto& coin : selected_coins)
{
const CScript& scriptPubKey = coin.txout.scriptPubKey;
SignatureData sigdata;