aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/bech32.cpp8
-rw-r--r--src/outputtype.cpp6
-rw-r--r--src/qt/bitcoingui.cpp6
-rw-r--r--src/qt/forms/signverifymessagedialog.ui3
-rw-r--r--src/qt/modaloverlay.cpp6
-rw-r--r--src/qt/modaloverlay.h2
-rw-r--r--src/qt/winshutdownmonitor.cpp13
-rw-r--r--src/script/descriptor.cpp36
-rw-r--r--src/test/util_tests.cpp106
-rw-r--r--src/txdb.cpp3
-rw-r--r--src/util/vector.h51
12 files changed, 191 insertions, 50 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index eec84122ae..d50524a8ae 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -220,6 +220,7 @@ BITCOIN_CORE_H = \
util/translation.h \
util/url.h \
util/validation.h \
+ util/vector.h \
validation.h \
validationinterface.h \
versionbits.h \
diff --git a/src/bech32.cpp b/src/bech32.cpp
index 4c966350b4..1e0471f110 100644
--- a/src/bech32.cpp
+++ b/src/bech32.cpp
@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <bech32.h>
+#include <util/vector.h>
#include <assert.h>
@@ -26,13 +27,6 @@ const int8_t CHARSET_REV[128] = {
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1
};
-/** Concatenate two byte arrays. */
-data Cat(data x, const data& y)
-{
- x.insert(x.end(), y.begin(), y.end());
- return x;
-}
-
/** This function will compute what 6 5-bit values to XOR into the last 6 input values, in order to
* make the checksum 0. These 6 values are packed together in a single 30-bit integer. The higher
* bits correspond to earlier values. */
diff --git a/src/outputtype.cpp b/src/outputtype.cpp
index bcaa05f4b6..5cc43898a7 100644
--- a/src/outputtype.cpp
+++ b/src/outputtype.cpp
@@ -10,6 +10,7 @@
#include <script/sign.h>
#include <script/signingprovider.h>
#include <script/standard.h>
+#include <util/vector.h>
#include <assert.h>
#include <string>
@@ -65,12 +66,13 @@ CTxDestination GetDestinationForKey(const CPubKey& key, OutputType type)
std::vector<CTxDestination> GetAllDestinationsForKey(const CPubKey& key)
{
PKHash keyid(key);
+ CTxDestination p2pkh{keyid};
if (key.IsCompressed()) {
CTxDestination segwit = WitnessV0KeyHash(keyid);
CTxDestination p2sh = ScriptHash(GetScriptForDestination(segwit));
- return std::vector<CTxDestination>{std::move(keyid), std::move(p2sh), std::move(segwit)};
+ return Vector(std::move(p2pkh), std::move(p2sh), std::move(segwit));
} else {
- return std::vector<CTxDestination>{std::move(keyid)};
+ return Vector(std::move(p2pkh));
}
}
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 2cfcf346fa..b280a0c14f 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -199,12 +199,12 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty
openOptionsDialogWithTab(OptionsDialog::TAB_NETWORK);
});
- modalOverlay = new ModalOverlay(this->centralWidget());
+ modalOverlay = new ModalOverlay(enableWallet, this->centralWidget());
+ connect(labelBlocksIcon, &GUIUtil::ClickableLabel::clicked, this, &BitcoinGUI::showModalOverlay);
+ connect(progressBar, &GUIUtil::ClickableProgressBar::clicked, this, &BitcoinGUI::showModalOverlay);
#ifdef ENABLE_WALLET
if(enableWallet) {
connect(walletFrame, &WalletFrame::requestedSyncWarningInfo, this, &BitcoinGUI::showModalOverlay);
- connect(labelBlocksIcon, &GUIUtil::ClickableLabel::clicked, this, &BitcoinGUI::showModalOverlay);
- connect(progressBar, &GUIUtil::ClickableProgressBar::clicked, this, &BitcoinGUI::showModalOverlay);
}
#endif
diff --git a/src/qt/forms/signverifymessagedialog.ui b/src/qt/forms/signverifymessagedialog.ui
index 8a7bdfdbc6..202edf27d4 100644
--- a/src/qt/forms/signverifymessagedialog.ui
+++ b/src/qt/forms/signverifymessagedialog.ui
@@ -99,6 +99,9 @@
<property name="toolTip">
<string>Enter the message you want to sign here</string>
</property>
+ <property name="placeholderText">
+ <string>Enter the message you want to sign here</string>
+ </property>
</widget>
</item>
<item>
diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp
index 8ecc33da84..efdd494d9f 100644
--- a/src/qt/modaloverlay.cpp
+++ b/src/qt/modaloverlay.cpp
@@ -12,7 +12,7 @@
#include <QResizeEvent>
#include <QPropertyAnimation>
-ModalOverlay::ModalOverlay(QWidget *parent) :
+ModalOverlay::ModalOverlay(bool enable_wallet, QWidget *parent) :
QWidget(parent),
ui(new Ui::ModalOverlay),
bestHeaderHeight(0),
@@ -29,6 +29,10 @@ userClosed(false)
blockProcessTime.clear();
setVisible(false);
+ if (!enable_wallet) {
+ ui->infoText->setVisible(false);
+ ui->infoTextStrong->setText(tr("Bitcoin Core is currently syncing. It will download headers and blocks from peers and validate them until reaching the tip of the block chain."));
+ }
}
ModalOverlay::~ModalOverlay()
diff --git a/src/qt/modaloverlay.h b/src/qt/modaloverlay.h
index cf8b53f2b3..c075a89f94 100644
--- a/src/qt/modaloverlay.h
+++ b/src/qt/modaloverlay.h
@@ -21,7 +21,7 @@ class ModalOverlay : public QWidget
Q_OBJECT
public:
- explicit ModalOverlay(QWidget *parent);
+ explicit ModalOverlay(bool enable_wallet, QWidget *parent);
~ModalOverlay();
public Q_SLOTS:
diff --git a/src/qt/winshutdownmonitor.cpp b/src/qt/winshutdownmonitor.cpp
index b177b22b3f..c6eb133cbd 100644
--- a/src/qt/winshutdownmonitor.cpp
+++ b/src/qt/winshutdownmonitor.cpp
@@ -6,14 +6,11 @@
#if defined(Q_OS_WIN)
#include <shutdown.h>
-#include <util/system.h>
#include <windows.h>
#include <QDebug>
-#include <openssl/rand.h>
-
// If we don't want a message to be processed by Qt, return true and set result to
// the value that the window procedure should return. Otherwise return false.
bool WinShutdownMonitor::nativeEventFilter(const QByteArray &eventType, void *pMessage, long *pnResult)
@@ -22,16 +19,6 @@ bool WinShutdownMonitor::nativeEventFilter(const QByteArray &eventType, void *pM
MSG *pMsg = static_cast<MSG *>(pMessage);
- // Seed OpenSSL PRNG with Windows event data (e.g. mouse movements and other user interactions)
- if (RAND_event(pMsg->message, pMsg->wParam, pMsg->lParam) == 0) {
- // Warn only once as this is performance-critical
- static bool warned = false;
- if (!warned) {
- LogPrintf("%s: OpenSSL RAND_event() failed to seed OpenSSL PRNG with enough data.\n", __func__);
- warned = true;
- }
- }
-
switch(pMsg->message)
{
case WM_QUERYENDSESSION:
diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp
index ed1bd4cda9..536807e1d8 100644
--- a/src/script/descriptor.cpp
+++ b/src/script/descriptor.cpp
@@ -14,6 +14,7 @@
#include <util/spanparsing.h>
#include <util/system.h>
#include <util/strencodings.h>
+#include <util/vector.h>
#include <memory>
#include <string>
@@ -501,22 +502,13 @@ public:
}
};
-/** Construct a vector with one element, which is moved into it. */
-template<typename T>
-std::vector<T> Singleton(T elem)
-{
- std::vector<T> ret;
- ret.emplace_back(std::move(elem));
- return ret;
-}
-
/** A parsed addr(A) descriptor. */
class AddressDescriptor final : public DescriptorImpl
{
const CTxDestination m_destination;
protected:
std::string ToStringExtra() const override { return EncodeDestination(m_destination); }
- std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, const CScript*, FlatSigningProvider&) const override { return Singleton(GetScriptForDestination(m_destination)); }
+ std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, const CScript*, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(m_destination)); }
public:
AddressDescriptor(CTxDestination destination) : DescriptorImpl({}, {}, "addr"), m_destination(std::move(destination)) {}
bool IsSolvable() const final { return false; }
@@ -528,7 +520,7 @@ class RawDescriptor final : public DescriptorImpl
const CScript m_script;
protected:
std::string ToStringExtra() const override { return HexStr(m_script.begin(), m_script.end()); }
- std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, const CScript*, FlatSigningProvider&) const override { return Singleton(m_script); }
+ std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, const CScript*, FlatSigningProvider&) const override { return Vector(m_script); }
public:
RawDescriptor(CScript script) : DescriptorImpl({}, {}, "raw"), m_script(std::move(script)) {}
bool IsSolvable() const final { return false; }
@@ -538,9 +530,9 @@ public:
class PKDescriptor final : public DescriptorImpl
{
protected:
- std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, const CScript*, FlatSigningProvider&) const override { return Singleton(GetScriptForRawPubKey(keys[0])); }
+ std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, const CScript*, FlatSigningProvider&) const override { return Vector(GetScriptForRawPubKey(keys[0])); }
public:
- PKDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Singleton(std::move(prov)), {}, "pk") {}
+ PKDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), {}, "pk") {}
};
/** A parsed pkh(P) descriptor. */
@@ -551,10 +543,10 @@ protected:
{
CKeyID id = keys[0].GetID();
out.pubkeys.emplace(id, keys[0]);
- return Singleton(GetScriptForDestination(PKHash(id)));
+ return Vector(GetScriptForDestination(PKHash(id)));
}
public:
- PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Singleton(std::move(prov)), {}, "pkh") {}
+ PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), {}, "pkh") {}
};
/** A parsed wpkh(P) descriptor. */
@@ -565,10 +557,10 @@ protected:
{
CKeyID id = keys[0].GetID();
out.pubkeys.emplace(id, keys[0]);
- return Singleton(GetScriptForDestination(WitnessV0KeyHash(id)));
+ return Vector(GetScriptForDestination(WitnessV0KeyHash(id)));
}
public:
- WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Singleton(std::move(prov)), {}, "wpkh") {}
+ WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), {}, "wpkh") {}
};
/** A parsed combo(P) descriptor. */
@@ -591,7 +583,7 @@ protected:
return ret;
}
public:
- ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Singleton(std::move(prov)), {}, "combo") {}
+ ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), {}, "combo") {}
};
/** A parsed multi(...) or sortedmulti(...) descriptor */
@@ -605,9 +597,9 @@ protected:
if (m_sorted) {
std::vector<CPubKey> sorted_keys(keys);
std::sort(sorted_keys.begin(), sorted_keys.end());
- return Singleton(GetScriptForMultisig(m_threshold, sorted_keys));
+ return Vector(GetScriptForMultisig(m_threshold, sorted_keys));
}
- return Singleton(GetScriptForMultisig(m_threshold, keys));
+ return Vector(GetScriptForMultisig(m_threshold, keys));
}
public:
MultisigDescriptor(int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers, bool sorted = false) : DescriptorImpl(std::move(providers), {}, sorted ? "sortedmulti" : "multi"), m_threshold(threshold), m_sorted(sorted) {}
@@ -617,7 +609,7 @@ public:
class SHDescriptor final : public DescriptorImpl
{
protected:
- std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, const CScript* script, FlatSigningProvider&) const override { return Singleton(GetScriptForDestination(ScriptHash(*script))); }
+ std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, const CScript* script, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(ScriptHash(*script))); }
public:
SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "sh") {}
};
@@ -626,7 +618,7 @@ public:
class WSHDescriptor final : public DescriptorImpl
{
protected:
- std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, const CScript* script, FlatSigningProvider&) const override { return Singleton(GetScriptForDestination(WitnessV0ScriptHash(*script))); }
+ std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, const CScript* script, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(WitnessV0ScriptHash(*script))); }
public:
WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "wsh") {}
};
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index 3995a3c732..02303d0f65 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -13,6 +13,7 @@
#include <util/string.h>
#include <util/time.h>
#include <util/spanparsing.h>
+#include <util/vector.h>
#include <stdint.h>
#include <thread>
@@ -1714,4 +1715,109 @@ BOOST_AUTO_TEST_CASE(test_LogEscapeMessage)
BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage(NUL), R"(O\x00O)");
}
+namespace {
+
+struct Tracker
+{
+ //! Points to the original object (possibly itself) we moved/copied from
+ const Tracker* origin;
+ //! How many copies where involved between the original object and this one (moves are not counted)
+ int copies;
+
+ Tracker() noexcept : origin(this), copies(0) {}
+ Tracker(const Tracker& t) noexcept : origin(t.origin), copies(t.copies + 1) {}
+ Tracker(Tracker&& t) noexcept : origin(t.origin), copies(t.copies) {}
+ Tracker& operator=(const Tracker& t) noexcept
+ {
+ origin = t.origin;
+ copies = t.copies + 1;
+ return *this;
+ }
+ Tracker& operator=(Tracker&& t) noexcept
+ {
+ origin = t.origin;
+ copies = t.copies;
+ return *this;
+ }
+};
+
+}
+
+BOOST_AUTO_TEST_CASE(test_tracked_vector)
+{
+ Tracker t1;
+ Tracker t2;
+ Tracker t3;
+
+ BOOST_CHECK(t1.origin == &t1);
+ BOOST_CHECK(t2.origin == &t2);
+ BOOST_CHECK(t3.origin == &t3);
+
+ auto v1 = Vector(t1);
+ BOOST_CHECK_EQUAL(v1.size(), 1);
+ BOOST_CHECK(v1[0].origin == &t1);
+ BOOST_CHECK_EQUAL(v1[0].copies, 1);
+
+ auto v2 = Vector(std::move(t2));
+ BOOST_CHECK_EQUAL(v2.size(), 1);
+ BOOST_CHECK(v2[0].origin == &t2);
+ BOOST_CHECK_EQUAL(v2[0].copies, 0);
+
+ auto v3 = Vector(t1, std::move(t2));
+ BOOST_CHECK_EQUAL(v3.size(), 2);
+ BOOST_CHECK(v3[0].origin == &t1);
+ BOOST_CHECK(v3[1].origin == &t2);
+ BOOST_CHECK_EQUAL(v3[0].copies, 1);
+ BOOST_CHECK_EQUAL(v3[1].copies, 0);
+
+ auto v4 = Vector(std::move(v3[0]), v3[1], std::move(t3));
+ BOOST_CHECK_EQUAL(v4.size(), 3);
+ BOOST_CHECK(v4[0].origin == &t1);
+ BOOST_CHECK(v4[1].origin == &t2);
+ BOOST_CHECK(v4[2].origin == &t3);
+ BOOST_CHECK_EQUAL(v4[0].copies, 1);
+ BOOST_CHECK_EQUAL(v4[1].copies, 1);
+ BOOST_CHECK_EQUAL(v4[2].copies, 0);
+
+ auto v5 = Cat(v1, v4);
+ BOOST_CHECK_EQUAL(v5.size(), 4);
+ BOOST_CHECK(v5[0].origin == &t1);
+ BOOST_CHECK(v5[1].origin == &t1);
+ BOOST_CHECK(v5[2].origin == &t2);
+ BOOST_CHECK(v5[3].origin == &t3);
+ BOOST_CHECK_EQUAL(v5[0].copies, 2);
+ BOOST_CHECK_EQUAL(v5[1].copies, 2);
+ BOOST_CHECK_EQUAL(v5[2].copies, 2);
+ BOOST_CHECK_EQUAL(v5[3].copies, 1);
+
+ auto v6 = Cat(std::move(v1), v3);
+ BOOST_CHECK_EQUAL(v6.size(), 3);
+ BOOST_CHECK(v6[0].origin == &t1);
+ BOOST_CHECK(v6[1].origin == &t1);
+ BOOST_CHECK(v6[2].origin == &t2);
+ BOOST_CHECK_EQUAL(v6[0].copies, 1);
+ BOOST_CHECK_EQUAL(v6[1].copies, 2);
+ BOOST_CHECK_EQUAL(v6[2].copies, 1);
+
+ auto v7 = Cat(v2, std::move(v4));
+ BOOST_CHECK_EQUAL(v7.size(), 4);
+ BOOST_CHECK(v7[0].origin == &t2);
+ BOOST_CHECK(v7[1].origin == &t1);
+ BOOST_CHECK(v7[2].origin == &t2);
+ BOOST_CHECK(v7[3].origin == &t3);
+ BOOST_CHECK_EQUAL(v7[0].copies, 1);
+ BOOST_CHECK_EQUAL(v7[1].copies, 1);
+ BOOST_CHECK_EQUAL(v7[2].copies, 1);
+ BOOST_CHECK_EQUAL(v7[3].copies, 0);
+
+ auto v8 = Cat(std::move(v2), std::move(v3));
+ BOOST_CHECK_EQUAL(v8.size(), 3);
+ BOOST_CHECK(v8[0].origin == &t2);
+ BOOST_CHECK(v8[1].origin == &t1);
+ BOOST_CHECK(v8[2].origin == &t2);
+ BOOST_CHECK_EQUAL(v8[0].copies, 0);
+ BOOST_CHECK_EQUAL(v8[1].copies, 1);
+ BOOST_CHECK_EQUAL(v8[2].copies, 0);
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/txdb.cpp b/src/txdb.cpp
index 536bfee901..a7eb5f9f67 100644
--- a/src/txdb.cpp
+++ b/src/txdb.cpp
@@ -12,6 +12,7 @@
#include <uint256.h>
#include <util/system.h>
#include <util/translation.h>
+#include <util/vector.h>
#include <stdint.h>
@@ -102,7 +103,7 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) {
// A vector is used for future extensibility, as we may want to support
// interrupting after partial writes from multiple independent reorgs.
batch.Erase(DB_BEST_BLOCK);
- batch.Write(DB_HEAD_BLOCKS, std::vector<uint256>{hashBlock, old_tip});
+ batch.Write(DB_HEAD_BLOCKS, Vector(hashBlock, old_tip));
for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
if (it->second.flags & CCoinsCacheEntry::DIRTY) {
diff --git a/src/util/vector.h b/src/util/vector.h
new file mode 100644
index 0000000000..dab65ded2a
--- /dev/null
+++ b/src/util/vector.h
@@ -0,0 +1,51 @@
+// Copyright (c) 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_UTIL_VECTOR_H
+#define BITCOIN_UTIL_VECTOR_H
+
+#include <initializer_list>
+#include <type_traits>
+#include <vector>
+
+/** Construct a vector with the specified elements.
+ *
+ * This is preferable over the list initializing constructor of std::vector:
+ * - It automatically infers the element type from its arguments.
+ * - If any arguments are rvalue references, they will be moved into the vector
+ * (list initialization always copies).
+ */
+template<typename... Args>
+inline std::vector<typename std::common_type<Args...>::type> Vector(Args&&... args)
+{
+ std::vector<typename std::common_type<Args...>::type> ret;
+ ret.reserve(sizeof...(args));
+ // The line below uses the trick from https://www.experts-exchange.com/articles/32502/None-recursive-variadic-templates-with-std-initializer-list.html
+ (void)std::initializer_list<int>{(ret.emplace_back(std::forward<Args>(args)), 0)...};
+ return ret;
+}
+
+/** Concatenate two vectors, moving elements. */
+template<typename V>
+inline V Cat(V v1, V&& v2)
+{
+ v1.reserve(v1.size() + v2.size());
+ for (auto& arg : v2) {
+ v1.push_back(std::move(arg));
+ }
+ return v1;
+}
+
+/** Concatenate two vectors. */
+template<typename V>
+inline V Cat(V v1, const V& v2)
+{
+ v1.reserve(v1.size() + v2.size());
+ for (const auto& arg : v2) {
+ v1.push_back(arg);
+ }
+ return v1;
+}
+
+#endif // BITCOIN_UTIL_VECTOR_H