aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/init.cpp18
-rw-r--r--src/node/coinstats.cpp77
-rw-r--r--src/node/coinstats.h33
-rw-r--r--src/qt/forms/debugwindow.ui19
-rw-r--r--src/qt/overviewpage.cpp5
-rw-r--r--src/qt/paymentserver.cpp6
-rw-r--r--src/qt/rpcconsole.cpp17
-rw-r--r--src/qt/rpcconsole.h3
-rw-r--r--src/qt/sendcoinsdialog.cpp3
-rw-r--r--src/rpc/blockchain.cpp72
-rw-r--r--src/serialize.h13
-rw-r--r--src/test/README.md4
-rw-r--r--src/test/serialize_tests.cpp8
14 files changed, 193 insertions, 87 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 477b1300bc..8fc7f61d4b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -156,6 +156,7 @@ BITCOIN_CORE_H = \
netbase.h \
netmessagemaker.h \
node/coin.h \
+ node/coinstats.h \
node/psbt.h \
node/transaction.h \
noui.h \
@@ -278,6 +279,7 @@ libbitcoin_server_a_SOURCES = \
net.cpp \
net_processing.cpp \
node/coin.cpp \
+ node/coinstats.cpp \
node/psbt.cpp \
node/transaction.cpp \
noui.cpp \
diff --git a/src/init.cpp b/src/init.cpp
index dd43ef71c9..042335b8e7 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -438,9 +438,17 @@ void SetupServerArgs()
#else
hidden_args.emplace_back("-upnp");
#endif
- gArgs.AddArg("-whitebind=<addr>", "Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
- gArgs.AddArg("-whitelist=<IP address or network>", "Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or CIDR notated network (e.g. 1.2.3.0/24). Can be specified multiple times."
- " Whitelisted peers cannot be DoS banned", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
+ gArgs.AddArg("-whitebind=<[permissions@]addr>", "Bind to given address and whitelist peers connecting to it. "
+ "Use [host]:port notation for IPv6. Allowed permissions are bloomfilter (allow requesting BIP37 filtered blocks and transactions), "
+ "noban (do not ban for misbehavior), "
+ "forcerelay (relay even non-standard transactions), "
+ "relay (relay even in -blocksonly mode), "
+ "and mempool (allow requesting BIP35 mempool contents). "
+ "Specify multiple permissions separated by commas (default: noban,mempool,relay). Can be specified multiple times.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
+
+ gArgs.AddArg("-whitelist=<[permissions@]IP address or network>", "Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or "
+ "CIDR notated network(e.g. 1.2.3.0/24). Uses same permissions as "
+ "-whitebind. Can be specified multiple times." , ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
g_wallet_init_interface.AddWalletOptions();
@@ -510,8 +518,8 @@ void SetupServerArgs()
gArgs.AddArg("-datacarriersize", strprintf("Maximum size of data in data carrier transactions we relay and mine (default: %u)", MAX_OP_RETURN_RELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
gArgs.AddArg("-minrelaytxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)",
CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
- gArgs.AddArg("-whitelistforcerelay", strprintf("Force relay of transactions from whitelisted inbound peers even if the transactions were already in the mempool or violate local relay policy (default: %d)", DEFAULT_WHITELISTFORCERELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
- gArgs.AddArg("-whitelistrelay", strprintf("Accept relayed transactions received from whitelisted inbound peers even when not relaying transactions (default: %d)", DEFAULT_WHITELISTRELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
+ gArgs.AddArg("-whitelistforcerelay", strprintf("Add 'forcerelay' permission to whitelisted inbound peers with default permissions. This will relay transactions even if the transactions were already in the mempool or violate local relay policy. (default: %d)", DEFAULT_WHITELISTFORCERELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
+ gArgs.AddArg("-whitelistrelay", strprintf("Add 'relay' permission to whitelisted inbound peers with default permissions. The will accept relayed transactions even when not relaying transactions (default: %d)", DEFAULT_WHITELISTRELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
gArgs.AddArg("-blockmaxweight=<n>", strprintf("Set maximum BIP141 block weight (default: %d)", DEFAULT_BLOCK_MAX_WEIGHT), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
diff --git a/src/node/coinstats.cpp b/src/node/coinstats.cpp
new file mode 100644
index 0000000000..e1891b9898
--- /dev/null
+++ b/src/node/coinstats.cpp
@@ -0,0 +1,77 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2019 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <node/coinstats.h>
+
+#include <amount.h>
+#include <coins.h>
+#include <chain.h>
+#include <hash.h>
+#include <serialize.h>
+#include <validation.h>
+#include <uint256.h>
+#include <util/system.h>
+
+#include <map>
+
+#include <boost/thread.hpp>
+
+
+static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash, const std::map<uint32_t, Coin>& outputs)
+{
+ assert(!outputs.empty());
+ ss << hash;
+ ss << VARINT(outputs.begin()->second.nHeight * 2 + outputs.begin()->second.fCoinBase ? 1u : 0u);
+ stats.nTransactions++;
+ for (const auto& output : outputs) {
+ ss << VARINT(output.first + 1);
+ ss << output.second.out.scriptPubKey;
+ ss << VARINT(output.second.out.nValue, VarIntMode::NONNEGATIVE_SIGNED);
+ stats.nTransactionOutputs++;
+ stats.nTotalAmount += output.second.out.nValue;
+ stats.nBogoSize += 32 /* txid */ + 4 /* vout index */ + 4 /* height + coinbase */ + 8 /* amount */ +
+ 2 /* scriptPubKey len */ + output.second.out.scriptPubKey.size() /* scriptPubKey */;
+ }
+ ss << VARINT(0u);
+}
+
+//! Calculate statistics about the unspent transaction output set
+bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
+{
+ std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
+ assert(pcursor);
+
+ CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
+ stats.hashBlock = pcursor->GetBestBlock();
+ {
+ LOCK(cs_main);
+ stats.nHeight = LookupBlockIndex(stats.hashBlock)->nHeight;
+ }
+ ss << stats.hashBlock;
+ uint256 prevkey;
+ std::map<uint32_t, Coin> outputs;
+ while (pcursor->Valid()) {
+ boost::this_thread::interruption_point();
+ COutPoint key;
+ Coin coin;
+ if (pcursor->GetKey(key) && pcursor->GetValue(coin)) {
+ if (!outputs.empty() && key.hash != prevkey) {
+ ApplyStats(stats, ss, prevkey, outputs);
+ outputs.clear();
+ }
+ prevkey = key.hash;
+ outputs[key.n] = std::move(coin);
+ } else {
+ return error("%s: unable to read value", __func__);
+ }
+ pcursor->Next();
+ }
+ if (!outputs.empty()) {
+ ApplyStats(stats, ss, prevkey, outputs);
+ }
+ stats.hashSerialized = ss.GetHash();
+ stats.nDiskSize = view->EstimateSize();
+ return true;
+}
diff --git a/src/node/coinstats.h b/src/node/coinstats.h
new file mode 100644
index 0000000000..7c11aab8bd
--- /dev/null
+++ b/src/node/coinstats.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2019 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_NODE_COINSTATS_H
+#define BITCOIN_NODE_COINSTATS_H
+
+#include <amount.h>
+#include <uint256.h>
+
+#include <cstdint>
+
+class CCoinsView;
+
+struct CCoinsStats
+{
+ int nHeight;
+ uint256 hashBlock;
+ uint64_t nTransactions;
+ uint64_t nTransactionOutputs;
+ uint64_t nBogoSize;
+ uint256 hashSerialized;
+ uint64_t nDiskSize;
+ CAmount nTotalAmount;
+
+ CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nBogoSize(0), nDiskSize(0), nTotalAmount(0) {}
+};
+
+//! Calculate statistics about the unspent transaction output set
+bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats);
+
+#endif // BITCOIN_NODE_COINSTATS_H
diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui
index 6e52c5e477..be807b20c0 100644
--- a/src/qt/forms/debugwindow.ui
+++ b/src/qt/forms/debugwindow.ui
@@ -15,6 +15,25 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
+ <widget class="QLabel" name="label_alerts">
+ <property name="visible">
+ <bool>false</bool>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">QLabel { background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #F0D0A0, stop:1 #F8D488); color:#000000; }</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="margin">
+ <number>3</number>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp
index d8e48f350a..07ffff0126 100644
--- a/src/qt/overviewpage.cpp
+++ b/src/qt/overviewpage.cpp
@@ -204,9 +204,8 @@ void OverviewPage::updateWatchOnlyLabels(bool showWatchOnly)
void OverviewPage::setClientModel(ClientModel *model)
{
this->clientModel = model;
- if(model)
- {
- // Show warning if this is a prerelease version
+ if (model) {
+ // Show warning, for example if this is a prerelease version
connect(model, &ClientModel::alertsChanged, this, &OverviewPage::updateAlerts);
updateAlerts(model->getStatusBarWarnings());
}
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index f3f5d28af9..0bb87742e9 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -41,8 +41,8 @@
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QSslCertificate>
+#include <QSslConfiguration>
#include <QSslError>
-#include <QSslSocket>
#include <QStringList>
#include <QTextDocument>
#include <QUrlQuery>
@@ -448,9 +448,9 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store)
certList = QSslCertificate::fromPath(certFile);
// Use those certificates when fetching payment requests, too:
- QSslSocket::setDefaultCaCertificates(certList);
+ QSslConfiguration::defaultConfiguration().setCaCertificates(certList);
} else
- certList = QSslSocket::systemCaCertificates();
+ certList = QSslConfiguration::systemCaCertificates();
int nRootCerts = 0;
const QDateTime currentTime = QDateTime::currentDateTime();
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 8922ab6270..8a3671dc54 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -558,6 +558,17 @@ bool RPCConsole::eventFilter(QObject* obj, QEvent *event)
void RPCConsole::setClientModel(ClientModel *model)
{
clientModel = model;
+
+ bool wallet_enabled{false};
+#ifdef ENABLE_WALLET
+ wallet_enabled = WalletModel::isWalletEnabled();
+#endif // ENABLE_WALLET
+ if (model && !wallet_enabled) {
+ // Show warning, for example if this is a prerelease version
+ connect(model, &ClientModel::alertsChanged, this, &RPCConsole::updateAlerts);
+ updateAlerts(model->getStatusBarWarnings());
+ }
+
ui->trafficGraph->setClientModel(model);
if (model && clientModel->getPeerTableModel() && clientModel->getBanTableModel()) {
// Keep up to date with client
@@ -1274,3 +1285,9 @@ QString RPCConsole::tabTitle(TabTypes tab_type) const
{
return ui->tabWidget->tabText(tab_type);
}
+
+void RPCConsole::updateAlerts(const QString& warnings)
+{
+ this->ui->label_alerts->setVisible(!warnings.isEmpty());
+ this->ui->label_alerts->setText(warnings);
+}
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index 38015e38fd..3f7a74ba03 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -167,6 +167,9 @@ private:
/** Update UI with latest network info from model. */
void updateNetworkState();
+
+private Q_SLOTS:
+ void updateAlerts(const QString& warnings);
};
#endif // BITCOIN_QT_RPCCONSOLE_H
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index f8c415cf52..f23c47736f 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -230,8 +230,9 @@ void SendCoinsDialog::on_sendButton_clicked()
{
recipients.append(entry->getValue());
}
- else
+ else if (valid)
{
+ ui->scrollArea->ensureWidgetVisible(entry);
valid = false;
}
}
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index a74003149d..7161c39ffd 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -10,6 +10,7 @@
#include <chain.h>
#include <chainparams.h>
#include <coins.h>
+#include <node/coinstats.h>
#include <consensus/validation.h>
#include <core_io.h>
#include <hash.h>
@@ -909,77 +910,6 @@ static UniValue getblock(const JSONRPCRequest& request)
return blockToJSON(block, tip, pblockindex, verbosity >= 2);
}
-struct CCoinsStats
-{
- int nHeight;
- uint256 hashBlock;
- uint64_t nTransactions;
- uint64_t nTransactionOutputs;
- uint64_t nBogoSize;
- uint256 hashSerialized;
- uint64_t nDiskSize;
- CAmount nTotalAmount;
-
- CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nBogoSize(0), nDiskSize(0), nTotalAmount(0) {}
-};
-
-static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash, const std::map<uint32_t, Coin>& outputs)
-{
- assert(!outputs.empty());
- ss << hash;
- ss << VARINT(outputs.begin()->second.nHeight * 2 + outputs.begin()->second.fCoinBase ? 1u : 0u);
- stats.nTransactions++;
- for (const auto& output : outputs) {
- ss << VARINT(output.first + 1);
- ss << output.second.out.scriptPubKey;
- ss << VARINT(output.second.out.nValue, VarIntMode::NONNEGATIVE_SIGNED);
- stats.nTransactionOutputs++;
- stats.nTotalAmount += output.second.out.nValue;
- stats.nBogoSize += 32 /* txid */ + 4 /* vout index */ + 4 /* height + coinbase */ + 8 /* amount */ +
- 2 /* scriptPubKey len */ + output.second.out.scriptPubKey.size() /* scriptPubKey */;
- }
- ss << VARINT(0u);
-}
-
-//! Calculate statistics about the unspent transaction output set
-static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
-{
- std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
- assert(pcursor);
-
- CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
- stats.hashBlock = pcursor->GetBestBlock();
- {
- LOCK(cs_main);
- stats.nHeight = LookupBlockIndex(stats.hashBlock)->nHeight;
- }
- ss << stats.hashBlock;
- uint256 prevkey;
- std::map<uint32_t, Coin> outputs;
- while (pcursor->Valid()) {
- boost::this_thread::interruption_point();
- COutPoint key;
- Coin coin;
- if (pcursor->GetKey(key) && pcursor->GetValue(coin)) {
- if (!outputs.empty() && key.hash != prevkey) {
- ApplyStats(stats, ss, prevkey, outputs);
- outputs.clear();
- }
- prevkey = key.hash;
- outputs[key.n] = std::move(coin);
- } else {
- return error("%s: unable to read value", __func__);
- }
- pcursor->Next();
- }
- if (!outputs.empty()) {
- ApplyStats(stats, ss, prevkey, outputs);
- }
- stats.hashSerialized = ss.GetHash();
- stats.nDiskSize = view->EstimateSize();
- return true;
-}
-
static UniValue pruneblockchain(const JSONRPCRequest& request)
{
RPCHelpMan{"pruneblockchain", "",
diff --git a/src/serialize.h b/src/serialize.h
index 1dc27d84eb..a38d76fc18 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -555,6 +555,7 @@ template<typename Stream, unsigned int N, typename T> inline void Unserialize(St
* vectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
*/
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&);
+template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const bool&);
template<typename Stream, typename T, typename A, typename V> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const V&);
template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v);
template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&);
@@ -713,6 +714,18 @@ void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&
os.write((char*)v.data(), v.size() * sizeof(T));
}
+template<typename Stream, typename T, typename A>
+void Serialize_impl(Stream& os, const std::vector<T, A>& v, const bool&)
+{
+ // A special case for std::vector<bool>, as dereferencing
+ // std::vector<bool>::const_iterator does not result in a const bool&
+ // due to std::vector's special casing for bool arguments.
+ WriteCompactSize(os, v.size());
+ for (bool elem : v) {
+ ::Serialize(os, elem);
+ }
+}
+
template<typename Stream, typename T, typename A, typename V>
void Serialize_impl(Stream& os, const std::vector<T, A>& v, const V&)
{
diff --git a/src/test/README.md b/src/test/README.md
index 0017e3de26..8901fae7bd 100644
--- a/src/test/README.md
+++ b/src/test/README.md
@@ -49,7 +49,3 @@ unit tests. The file naming convention is `<source_filename>_tests.cpp`
and such files should wrap their tests in a test suite
called `<source_filename>_tests`. For an example of this pattern,
examine `uint256_tests.cpp`.
-
-For further reading, I found the following website to be helpful in
-explaining how the boost unit test framework works:
-[http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/](http://archive.is/dRBGf).
diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp
index 8a8620938e..b90be15fba 100644
--- a/src/test/serialize_tests.cpp
+++ b/src/test/serialize_tests.cpp
@@ -258,6 +258,14 @@ static bool isCanonicalException(const std::ios_base::failure& ex)
return strcmp(expectedException.what(), ex.what()) == 0;
}
+BOOST_AUTO_TEST_CASE(vector_bool)
+{
+ std::vector<uint8_t> vec1{1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1};
+ std::vector<bool> vec2{1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1};
+
+ BOOST_CHECK(vec1 == std::vector<uint8_t>(vec2.begin(), vec2.end()));
+ BOOST_CHECK(SerializeHash(vec1) == SerializeHash(vec2));
+}
BOOST_AUTO_TEST_CASE(noncanonical)
{