diff options
-rw-r--r-- | src/init.cpp | 4 | ||||
-rw-r--r-- | src/qt/addresstablemodel.cpp | 2 | ||||
-rw-r--r-- | src/qt/coincontroldialog.cpp | 2 | ||||
-rw-r--r-- | src/qt/guiutil.cpp | 4 | ||||
-rw-r--r-- | src/qt/guiutil.h | 4 | ||||
-rw-r--r-- | src/qt/rpcconsole.cpp | 12 | ||||
-rw-r--r-- | src/qt/rpcconsole.h | 1 | ||||
-rw-r--r-- | src/qt/sendcoinsentry.cpp | 2 | ||||
-rw-r--r-- | src/qt/signverifymessagedialog.cpp | 4 | ||||
-rw-r--r-- | src/wallet/test/wallet_tests.cpp | 113 | ||||
-rw-r--r-- | src/wallet/wallet.cpp | 16 | ||||
-rw-r--r-- | src/wallet/wallet.h | 29 | ||||
-rw-r--r-- | src/zmq/zmqnotificationinterface.cpp | 11 | ||||
-rw-r--r-- | src/zmq/zmqnotificationinterface.h | 3 |
14 files changed, 133 insertions, 74 deletions
diff --git a/src/init.cpp b/src/init.cpp index d0f73a632b..4dd8090753 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -222,7 +222,6 @@ void Shutdown() #if ENABLE_ZMQ if (pzmqNotificationInterface) { UnregisterValidationInterface(pzmqNotificationInterface); - pzmqNotificationInterface->Shutdown(); delete pzmqNotificationInterface; pzmqNotificationInterface = NULL; } @@ -377,7 +376,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), 100)); if (showDebug) strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)", - CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK()))); + CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE))); strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup")); @@ -1180,7 +1179,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) pzmqNotificationInterface = CZMQNotificationInterface::CreateWithArguments(mapArgs); if (pzmqNotificationInterface) { - pzmqNotificationInterface->Initialize(); RegisterValidationInterface(pzmqNotificationInterface); } #endif diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index c5ac07cfc2..a488d298c4 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -218,7 +218,7 @@ QVariant AddressTableModel::data(const QModelIndex &index, int role) const QFont font; if(index.column() == Address) { - font = GUIUtil::bitcoinAddressFont(); + font = GUIUtil::fixedPitchFont(); } return font; } diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 51008ad2de..74bc8dbec9 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -567,7 +567,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) nChange -= nPayFee; // Never create dust outputs; if we would, just add the dust to the fee. - if (nChange > 0 && nChange < CENT) + if (nChange > 0 && nChange < MIN_CHANGE) { CTxOut txout(nChange, (CScript)std::vector<unsigned char>(24, 0)); if (txout.IsDust(::minRelayTxFee)) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 8917f77f22..1c0056a7bd 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -88,7 +88,7 @@ QString dateTimeStr(qint64 nTime) return dateTimeStr(QDateTime::fromTime_t((qint32)nTime)); } -QFont bitcoinAddressFont() +QFont fixedPitchFont() { QFont font("Monospace"); #if QT_VERSION >= 0x040800 @@ -103,7 +103,7 @@ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent) { parent->setFocusProxy(widget); - widget->setFont(bitcoinAddressFont()); + widget->setFont(fixedPitchFont()); #if QT_VERSION >= 0x040700 // We don't want translators to use own addresses in translations // and this is the only place, where this address is supplied. diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 0ac3db6327..ec678c4af2 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -37,8 +37,8 @@ namespace GUIUtil QString dateTimeStr(const QDateTime &datetime); QString dateTimeStr(qint64 nTime); - // Render Bitcoin addresses in monospace font - QFont bitcoinAddressFont(); + // Return a monospace font + QFont fixedPitchFont(); // Set up widgets for address and amounts void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent); diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index f387a3ec8c..8401701821 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -462,13 +462,19 @@ void RPCConsole::clear() } // Set default style sheet + QFontInfo fixedFontInfo(GUIUtil::fixedPitchFont()); + // Try to make fixed font adequately large on different OS + QString ptSize = QString("%1pt").arg(QFontInfo(QFont()).pointSize() * 8.5 / 9); ui->messagesWidget->document()->setDefaultStyleSheet( + QString( "table { }" "td.time { color: #808080; padding-top: 3px; } " + "td.message { font-family: %1; font-size: %2; white-space:pre-wrap; } " "td.cmd-request { color: #006060; } " "td.cmd-error { color: red; } " "b { color: #006060; } " - ); + ).arg(fixedFontInfo.family(), ptSize) + ); message(CMD_REPLY, (tr("Welcome to the Bitcoin Core RPC console.") + "<br>" + tr("Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.") + "<br>" + @@ -494,7 +500,7 @@ void RPCConsole::message(int category, const QString &message, bool html) if(html) out += message; else - out += GUIUtil::HtmlEscape(message, true); + out += GUIUtil::HtmlEscape(message, false); out += "</td></tr></table>"; ui->messagesWidget->append(out); } @@ -849,4 +855,4 @@ void RPCConsole::showOrHideBanTableIfRequired() bool visible = clientModel->getBanTableModel()->shouldShow(); ui->banlistWidget->setVisible(visible); ui->banHeading->setVisible(visible); -}
\ No newline at end of file +} diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index b86f776786..d5932ff149 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -71,6 +71,7 @@ private Q_SLOTS: public Q_SLOTS: void clear(); + /** Append the message to the message widget */ void message(int category, const QString &message, bool html = false); /** Set number of connections shown in the UI */ void setNumConnections(int count); diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 44aa8ad1af..4f4b5b70d5 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -40,7 +40,7 @@ SendCoinsEntry::SendCoinsEntry(const PlatformStyle *platformStyle, QWidget *pare // normal bitcoin address field GUIUtil::setupAddressWidget(ui->payTo, this); // just a label for displaying bitcoin address(es) - ui->payTo_is->setFont(GUIUtil::bitcoinAddressFont()); + ui->payTo_is->setFont(GUIUtil::fixedPitchFont()); // Connect signals connect(ui->payAmount, SIGNAL(valueChanged()), this, SIGNAL(payAmountChanged())); diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 60e8e36ebe..96f50a2656 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -51,8 +51,8 @@ SignVerifyMessageDialog::SignVerifyMessageDialog(const PlatformStyle *platformSt ui->messageIn_VM->installEventFilter(this); ui->signatureIn_VM->installEventFilter(this); - ui->signatureOut_SM->setFont(GUIUtil::bitcoinAddressFont()); - ui->signatureIn_VM->setFont(GUIUtil::bitcoinAddressFont()); + ui->signatureOut_SM->setFont(GUIUtil::fixedPitchFont()); + ui->signatureIn_VM->setFont(GUIUtil::fixedPitchFont()); } SignVerifyMessageDialog::~SignVerifyMessageDialog() diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index a5bc52b8dc..8b9292bd14 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -117,7 +117,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // try making 34 cents from 1,2,5,10,20 - we can't do it exactly BOOST_CHECK( wallet.SelectCoinsMinConf(34 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_GT(nValueRet, 34 * CENT); // but should get more than 34 cents + BOOST_CHECK_EQUAL(nValueRet, 35 * CENT); // but 35 cents is closest BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // the best should be 20+10+5. it's incredibly unlikely the 1 or 2 got included (but possible) // when we try making 7 cents, the smaller coins (1,2,5) are enough. We should see just 2+5 @@ -185,33 +185,34 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) BOOST_CHECK_EQUAL(nValueRet, 2 * COIN); // we should get 2 BTC in 1 coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); - // empty the wallet and start again, now with fractions of a cent, to test sub-cent change avoidance + // empty the wallet and start again, now with fractions of a cent, to test small change avoidance + empty_wallet(); - add_coin(0.1*CENT); - add_coin(0.2*CENT); - add_coin(0.3*CENT); - add_coin(0.4*CENT); - add_coin(0.5*CENT); - - // try making 1 cent from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 = 1.5 cents - // we'll get sub-cent change whatever happens, so can expect 1.0 exactly - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); + add_coin(0.1*MIN_CHANGE); + add_coin(0.2*MIN_CHANGE); + add_coin(0.3*MIN_CHANGE); + add_coin(0.4*MIN_CHANGE); + add_coin(0.5*MIN_CHANGE); + + // try making 1 * MIN_CHANGE from the 1.5 * MIN_CHANGE + // we'll get change smaller than MIN_CHANGE whatever happens, so can expect MIN_CHANGE exactly + BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE); - // but if we add a bigger coin, making it possible to avoid sub-cent change, things change: - add_coin(1111*CENT); + // but if we add a bigger coin, small change is avoided + add_coin(1111*MIN_CHANGE); - // try making 1 cent from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 1111 = 1112.5 cents - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount + // try making 1 from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 1111 = 1112.5 + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // we should get the exact amount - // if we add more sub-cent coins: - add_coin(0.6*CENT); - add_coin(0.7*CENT); + // if we add more small coins: + add_coin(0.6*MIN_CHANGE); + add_coin(0.7*MIN_CHANGE); - // and try again to make 1.0 cents, we can still make 1.0 cents - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount + // and try again to make 1.0 * MIN_CHANGE + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // we should get the exact amount // run the 'mtgox' test (see http://blockexplorer.com/tx/29a3efd3ef04f9153d47a990bd7b048a4b2d213daaa5fb8ed670fb85f13bdbcf) // they tried to consolidate 10 50k coins into one 500k coin, and ended up with 50k in change @@ -223,45 +224,65 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) BOOST_CHECK_EQUAL(nValueRet, 500000 * COIN); // we should get the exact amount BOOST_CHECK_EQUAL(setCoinsRet.size(), 10U); // in ten coins - // if there's not enough in the smaller coins to make at least 1 cent change (0.5+0.6+0.7 < 1.0+1.0), + // if there's not enough in the smaller coins to make at least 1 * MIN_CHANGE change (0.5+0.6+0.7 < 1.0+1.0), // we need to try finding an exact subset anyway // sometimes it will fail, and so we use the next biggest coin: empty_wallet(); - add_coin(0.5 * CENT); - add_coin(0.6 * CENT); - add_coin(0.7 * CENT); - add_coin(1111 * CENT); - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1111 * CENT); // we get the bigger coin + add_coin(0.5 * MIN_CHANGE); + add_coin(0.6 * MIN_CHANGE); + add_coin(0.7 * MIN_CHANGE); + add_coin(1111 * MIN_CHANGE); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1111 * MIN_CHANGE); // we get the bigger coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); // but sometimes it's possible, and we use an exact subset (0.4 + 0.6 = 1.0) empty_wallet(); - add_coin(0.4 * CENT); - add_coin(0.6 * CENT); - add_coin(0.8 * CENT); - add_coin(1111 * CENT); - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount + add_coin(0.4 * MIN_CHANGE); + add_coin(0.6 * MIN_CHANGE); + add_coin(0.8 * MIN_CHANGE); + add_coin(1111 * MIN_CHANGE); + BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE); // we should get the exact amount BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // in two coins 0.4+0.6 - // test avoiding sub-cent change + // test avoiding small change empty_wallet(); - add_coin(0.0005 * COIN); - add_coin(0.01 * COIN); - add_coin(1 * COIN); + add_coin(0.05 * MIN_CHANGE); + add_coin(1 * MIN_CHANGE); + add_coin(100 * MIN_CHANGE); - // trying to make 1.0001 from these three coins - BOOST_CHECK( wallet.SelectCoinsMinConf(1.0001 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1.0105 * COIN); // we should get all coins + // trying to make 100.01 from these three coins + BOOST_CHECK( wallet.SelectCoinsMinConf(100.01 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 101.05 * MIN_CHANGE); // we should get all coins BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); - // but if we try to make 0.999, we should take the bigger of the two small coins to avoid sub-cent change - BOOST_CHECK( wallet.SelectCoinsMinConf(0.999 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1.01 * COIN); // we should get 1 + 0.01 + // but if we try to make 99.9, we should take the bigger of the two small coins to avoid small change + BOOST_CHECK( wallet.SelectCoinsMinConf(99.9 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 101 * MIN_CHANGE); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); + // test with many inputs + for (CAmount amt=1500; amt < COIN; amt*=10) { + empty_wallet(); + // Create 676 inputs (= MAX_STANDARD_TX_SIZE / 148 bytes per input) + for (uint16_t j = 0; j < 676; j++) + add_coin(amt); + BOOST_CHECK(wallet.SelectCoinsMinConf(2000, 1, 1, vCoins, setCoinsRet, nValueRet)); + if (amt - 2000 < MIN_CHANGE) { + // needs more than one input: + uint16_t returnSize = std::ceil((2000.0 + MIN_CHANGE)/amt); + CAmount returnValue = amt * returnSize; + BOOST_CHECK_EQUAL(nValueRet, returnValue); + BOOST_CHECK_EQUAL(setCoinsRet.size(), returnSize); + } else { + // one input is sufficient: + BOOST_CHECK_EQUAL(nValueRet, amt); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); + } + } + // test randomness { empty_wallet(); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 3f2d5a05f6..93c7c7f247 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -47,7 +47,7 @@ bool fPayAtLeastCustomFee = true; * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) * Override with -mintxfee */ -CFeeRate CWallet::minTxFee = CFeeRate(1000); +CFeeRate CWallet::minTxFee = CFeeRate(DEFAULT_TRANSACTION_MINFEE); /** @defgroup mapWallet * @@ -1497,9 +1497,6 @@ CAmount CWallet::GetImmatureWatchOnlyBalance() const return nTotal; } -/** - * populate vCoins with vector of available COutputs. - */ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, bool fIncludeZeroValue) const { vCoins.clear(); @@ -1619,7 +1616,7 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nValueRet += coin.first; return true; } - else if (n < nTargetValue + CENT) + else if (n < nTargetValue + MIN_CHANGE) { vValue.push_back(coin); nTotalLower += n; @@ -1654,14 +1651,14 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int vector<char> vfBest; CAmount nBest; - ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000); - if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT) - ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000); + ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest); + if (nBest != nTargetValue && nTotalLower >= nTargetValue + MIN_CHANGE) + ApproximateBestSubset(vValue, nTotalLower, nTargetValue + MIN_CHANGE, vfBest, nBest); // If we have a bigger coin and (either the stochastic approximation didn't find a good solution, // or the next bigger coin is closer), return the bigger coin if (coinLowestLarger.second.first && - ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest)) + ((nBest != nTargetValue && nBest < nTargetValue + MIN_CHANGE) || coinLowestLarger.first <= nBest)) { setCoinsRet.insert(coinLowestLarger.second); nValueRet += coinLowestLarger.first; @@ -1844,6 +1841,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt LOCK2(cs_main, cs_wallet); { nFeeRet = 0; + // Start with no fee and loop until there is enough fee while (true) { txNew.vin.clear(); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 34e98cfb81..7e8dcc2914 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -41,8 +41,12 @@ extern bool fPayAtLeastCustomFee; static const CAmount DEFAULT_TRANSACTION_FEE = 0; //! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB static const CAmount nHighTransactionFeeWarning = 0.01 * COIN; +//! -mintxfee default +static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000; //! -maxtxfee default static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN; +//! minimum change amount +static const CAmount MIN_CHANGE = CENT; //! -txconfirmtarget default static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2; //! -maxtxfee will warn if called with a higher fee than this amount (in satoshis) @@ -442,6 +446,11 @@ public: class CWallet : public CCryptoKeyStore, public CValidationInterface { private: + /** + * Select a set of coins such that nValueRet >= nTargetValue and at least + * all coins from coinControl are selected; Never select unconfirmed coins + * if they are not ours + */ bool SelectCoins(const CAmount& nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL) const; CWalletDB *pwalletdbEncryption; @@ -539,7 +548,17 @@ public: //! check whether we are allowed to upgrade (or already support) to the named feature bool CanSupportFeature(enum WalletFeature wf) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; } + /** + * populate vCoins with vector of available COutputs. + */ void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL, bool fIncludeZeroValue=false) const; + + /** + * Shuffle and select coins until nTargetValue is reached while avoiding + * small change; This method is stochastic for some inputs and upon + * completion the coin set and corresponding actual target value is + * assembled + */ bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const; bool IsSpent(const uint256& hash, unsigned int n) const; @@ -622,7 +641,17 @@ public: CAmount GetWatchOnlyBalance() const; CAmount GetUnconfirmedWatchOnlyBalance() const; CAmount GetImmatureWatchOnlyBalance() const; + + /** + * Insert additional inputs into the transaction by + * calling CreateTransaction(); + */ bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching); + + /** + * Create a new transaction paying the recipients with a set of coins + * selected by SelectCoins(); Also create the change output, when needed + */ bool CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index 388b86707b..09fe3aeb4c 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -21,8 +21,7 @@ CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(NULL) CZMQNotificationInterface::~CZMQNotificationInterface() { - // ensure Shutdown if Initialize is called - assert(!pcontext); + Shutdown(); for (std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin(); i!=notifiers.end(); ++i) { @@ -59,6 +58,12 @@ CZMQNotificationInterface* CZMQNotificationInterface::CreateWithArguments(const { notificationInterface = new CZMQNotificationInterface(); notificationInterface->notifiers = notifiers; + + if (!notificationInterface->Initialize()) + { + delete notificationInterface; + notificationInterface = NULL; + } } return notificationInterface; @@ -99,7 +104,7 @@ bool CZMQNotificationInterface::Initialize() return false; } - return false; + return true; } // Called during shutdown sequence diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h index 8eea15c068..3ccfaf341d 100644 --- a/src/zmq/zmqnotificationinterface.h +++ b/src/zmq/zmqnotificationinterface.h @@ -19,10 +19,11 @@ public: static CZMQNotificationInterface* CreateWithArguments(const std::map<std::string, std::string> &args); +protected: bool Initialize(); void Shutdown(); -protected: // CValidationInterface + // CValidationInterface void SyncTransaction(const CTransaction &tx, const CBlock *pblock); void UpdatedBlockTip(const CBlockIndex *pindex); |