aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac3
-rwxr-xr-xcontrib/devtools/symbol-check.py2
-rw-r--r--src/Makefile.am1
-rw-r--r--src/Makefile.bench.include1
-rw-r--r--src/bench/bech32.cpp38
-rw-r--r--src/compat/glibc_compat.cpp45
-rw-r--r--src/interfaces/wallet.cpp1
-rw-r--r--src/interfaces/wallet.h1
-rw-r--r--src/keystore.h21
-rw-r--r--src/net.cpp2
-rw-r--r--src/net_processing.cpp6
-rw-r--r--src/qt/guiconstants.h2
-rw-r--r--src/qt/transactiondesc.cpp10
-rw-r--r--src/qt/transactionrecord.cpp8
-rw-r--r--src/qt/transactionrecord.h4
-rw-r--r--src/qt/transactiontablemodel.cpp9
-rw-r--r--src/test/dbwrapper_tests.cpp14
-rw-r--r--src/test/test_bitcoin.cpp37
-rw-r--r--src/test/test_bitcoin.h6
-rw-r--r--src/test/util_tests.cpp8
-rw-r--r--src/validationinterface.cpp10
-rw-r--r--src/validationinterface.h7
-rw-r--r--src/wallet/crypter.h6
-rw-r--r--src/wallet/test/wallet_tests.cpp6
-rw-r--r--src/wallet/wallet.cpp55
-rw-r--r--src/wallet/wallet.h16
-rwxr-xr-xtest/functional/interface_zmq.py19
-rwxr-xr-xtest/functional/rpc_zmq.py5
-rwxr-xr-xtest/functional/test_framework/test_framework.py17
29 files changed, 182 insertions, 178 deletions
diff --git a/configure.ac b/configure.ac
index 490b638ee1..bf0f3f8f52 100644
--- a/configure.ac
+++ b/configure.ac
@@ -651,6 +651,8 @@ if test x$use_glibc_compat != xno; then
[ fdelt_type="long int"])
AC_MSG_RESULT($fdelt_type)
AC_DEFINE_UNQUOTED(FDELT_TYPE, $fdelt_type,[parameter and return value type for __fdelt_chk])
+ AX_CHECK_LINK_FLAG([[-Wl,--wrap=__divmoddi4]], [COMPAT_LDFLAGS="$COMPAT_LDFLAGS -Wl,--wrap=__divmoddi4"])
+ AX_CHECK_LINK_FLAG([[-Wl,--wrap=log2f]], [COMPAT_LDFLAGS="$COMPAT_LDFLAGS -Wl,--wrap=log2f"])
else
AC_SEARCH_LIBS([clock_gettime],[rt])
fi
@@ -1351,6 +1353,7 @@ AC_SUBST(DEBUG_CPPFLAGS)
AC_SUBST(WARN_CXXFLAGS)
AC_SUBST(NOWARN_CXXFLAGS)
AC_SUBST(DEBUG_CXXFLAGS)
+AC_SUBST(COMPAT_LDFLAGS)
AC_SUBST(ERROR_CXXFLAGS)
AC_SUBST(GPROF_CXXFLAGS)
AC_SUBST(GPROF_LDFLAGS)
diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py
index 3a67319eaa..6808e77da7 100755
--- a/contrib/devtools/symbol-check.py
+++ b/contrib/devtools/symbol-check.py
@@ -46,7 +46,7 @@ MAX_VERSIONS = {
# Ignore symbols that are exported as part of every executable
IGNORE_EXPORTS = {
-'_edata', '_end', '_init', '__bss_start', '_fini', '_IO_stdin_used'
+'_edata', '_end', '_init', '__bss_start', '_fini', '_IO_stdin_used', 'stdin', 'stdout', 'stderr'
}
READELF_CMD = os.getenv('READELF', '/usr/bin/readelf')
CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt')
diff --git a/src/Makefile.am b/src/Makefile.am
index 458721293e..5d7eafb3f1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -418,6 +418,7 @@ libbitcoin_util_a_SOURCES = \
if GLIBC_BACK_COMPAT
libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp
+AM_LDFLAGS += $(COMPAT_LDFLAGS)
endif
# cli: shared between bitcoin-cli and bitcoin-qt
diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include
index 7b32b72bd1..f5293585a0 100644
--- a/src/Makefile.bench.include
+++ b/src/Makefile.bench.include
@@ -26,6 +26,7 @@ bench_bench_bitcoin_SOURCES = \
bench/mempool_eviction.cpp \
bench/verify_script.cpp \
bench/base58.cpp \
+ bench/bech32.cpp \
bench/lockedpool.cpp \
bench/prevector.cpp
diff --git a/src/bench/bech32.cpp b/src/bench/bech32.cpp
new file mode 100644
index 0000000000..ff655bded0
--- /dev/null
+++ b/src/bench/bech32.cpp
@@ -0,0 +1,38 @@
+// Copyright (c) 2018 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 <bench/bench.h>
+
+#include <validation.h>
+#include <bech32.h>
+#include <utilstrencodings.h>
+
+#include <vector>
+#include <string>
+
+
+static void Bech32Encode(benchmark::State& state)
+{
+ std::vector<uint8_t> v = ParseHex("c97f5a67ec381b760aeaf67573bc164845ff39a3bb26a1cee401ac67243b48db");
+ std::vector<unsigned char> tmp = {0};
+ tmp.reserve(1 + 32 * 8 / 5);
+ ConvertBits<8, 5, true>([&](unsigned char c) { tmp.push_back(c); }, v.begin(), v.end());
+ while (state.KeepRunning()) {
+ bech32::Encode("bc", tmp);
+ }
+}
+
+
+static void Bech32Decode(benchmark::State& state)
+{
+ std::string addr = "bc1qkallence7tjawwvy0dwt4twc62qjgaw8f4vlhyd006d99f09";
+ std::vector<unsigned char> vch;
+ while (state.KeepRunning()) {
+ bech32::Decode(addr);
+ }
+}
+
+
+BENCHMARK(Bech32Encode, 800 * 1000);
+BENCHMARK(Bech32Decode, 800 * 1000);
diff --git a/src/compat/glibc_compat.cpp b/src/compat/glibc_compat.cpp
index 55da5ef63f..b1cbe9f72a 100644
--- a/src/compat/glibc_compat.cpp
+++ b/src/compat/glibc_compat.cpp
@@ -7,6 +7,7 @@
#endif
#include <cstddef>
+#include <cstdint>
#if defined(HAVE_SYS_SELECT_H)
#include <sys/select.h>
@@ -27,3 +28,47 @@ extern "C" FDELT_TYPE __fdelt_warn(FDELT_TYPE a)
return a / __NFDBITS;
}
extern "C" FDELT_TYPE __fdelt_chk(FDELT_TYPE) __attribute__((weak, alias("__fdelt_warn")));
+
+#if defined(__i386__) || defined(__arm__)
+
+extern "C" int64_t __udivmoddi4(uint64_t u, uint64_t v, uint64_t* rp);
+
+extern "C" int64_t __wrap___divmoddi4(int64_t u, int64_t v, int64_t* rp)
+{
+ int32_t c1 = 0, c2 = 0;
+ int64_t uu = u, vv = v;
+ int64_t w;
+ int64_t r;
+
+ if (uu < 0) {
+ c1 = ~c1, c2 = ~c2, uu = -uu;
+ }
+ if (vv < 0) {
+ c1 = ~c1, vv = -vv;
+ }
+
+ w = __udivmoddi4(uu, vv, (uint64_t*)&r);
+ if (c1)
+ w = -w;
+ if (c2)
+ r = -r;
+
+ *rp = r;
+ return w;
+}
+#endif
+
+extern "C" float log2f_old(float x);
+#ifdef __i386__
+__asm(".symver log2f_old,log2f@GLIBC_2.1");
+#elif defined(__amd64__)
+__asm(".symver log2f_old,log2f@GLIBC_2.2.5");
+#elif defined(__arm__)
+__asm(".symver log2f_old,log2f@GLIBC_2.4");
+#elif defined(__aarch64__)
+__asm(".symver log2f_old,log2f@GLIBC_2.17");
+#endif
+extern "C" float __wrap_log2f(float x)
+{
+ return log2f_old(x);
+}
diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp
index e98acba0df..aade4b2df3 100644
--- a/src/interfaces/wallet.cpp
+++ b/src/interfaces/wallet.cpp
@@ -93,7 +93,6 @@ WalletTxStatus MakeWalletTxStatus(const CWalletTx& wtx)
result.block_height = (block ? block->nHeight : std::numeric_limits<int>::max()),
result.blocks_to_maturity = wtx.GetBlocksToMaturity();
result.depth_in_main_chain = wtx.GetDepthInMainChain();
- result.request_count = wtx.GetRequestCount();
result.time_received = wtx.nTimeReceived;
result.lock_time = wtx.tx->nLockTime;
result.is_final = CheckFinalTx(*wtx.tx);
diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h
index ce42e14eea..96e742eaca 100644
--- a/src/interfaces/wallet.h
+++ b/src/interfaces/wallet.h
@@ -346,7 +346,6 @@ struct WalletTxStatus
int block_height;
int blocks_to_maturity;
int depth_in_main_chain;
- int request_count;
unsigned int time_received;
uint32_t lock_time;
bool is_final;
diff --git a/src/keystore.h b/src/keystore.h
index cd5ded9203..f64024c7e7 100644
--- a/src/keystore.h
+++ b/src/keystore.h
@@ -38,21 +38,21 @@ public:
virtual bool HaveWatchOnly() const =0;
};
-typedef std::map<CKeyID, CKey> KeyMap;
-typedef std::map<CKeyID, CPubKey> WatchKeyMap;
-typedef std::map<CScriptID, CScript > ScriptMap;
-typedef std::set<CScript> WatchOnlySet;
-
/** Basic key store, that keeps keys in an address->secret map */
class CBasicKeyStore : public CKeyStore
{
protected:
mutable CCriticalSection cs_KeyStore;
- KeyMap mapKeys;
- WatchKeyMap mapWatchKeys;
- ScriptMap mapScripts;
- WatchOnlySet setWatchOnly;
+ using KeyMap = std::map<CKeyID, CKey>;
+ using WatchKeyMap = std::map<CKeyID, CPubKey>;
+ using ScriptMap = std::map<CScriptID, CScript>;
+ using WatchOnlySet = std::set<CScript>;
+
+ KeyMap mapKeys GUARDED_BY(cs_KeyStore);
+ WatchKeyMap mapWatchKeys GUARDED_BY(cs_KeyStore);
+ ScriptMap mapScripts GUARDED_BY(cs_KeyStore);
+ WatchOnlySet setWatchOnly GUARDED_BY(cs_KeyStore);
void ImplicitlyLearnRelatedKeyScripts(const CPubKey& pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
@@ -74,9 +74,6 @@ public:
bool HaveWatchOnly() const override;
};
-typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
-typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
-
/** Return the CKeyID of the key involved in a script (if there is a unique one). */
CKeyID GetKeyForDestination(const CKeyStore& store, const CTxDestination& dest);
diff --git a/src/net.cpp b/src/net.cpp
index b24ceb67d6..d806059ece 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -2254,7 +2254,7 @@ bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<C
if (binds.empty() && whiteBinds.empty()) {
struct in_addr inaddr_any;
inaddr_any.s_addr = INADDR_ANY;
- fBound |= Bind(CService(in6addr_any, GetListenPort()), BF_NONE);
+ fBound |= Bind(CService((in6_addr)IN6ADDR_ANY_INIT, GetListenPort()), BF_NONE);
fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE);
}
return fBound;
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 458e9c2e9f..2f3a604064 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -1264,9 +1264,6 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
if (!push) {
vNotFound.push_back(inv);
}
-
- // Track requests for our stuff.
- GetMainSignals().Inventory(inv.hash);
}
} // release cs_main
@@ -1965,9 +1962,6 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
pfrom->AskFor(inv);
}
}
-
- // Track requests for our stuff
- GetMainSignals().Inventory(inv.hash);
}
}
diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h
index 1d21d8c766..ff47653fb7 100644
--- a/src/qt/guiconstants.h
+++ b/src/qt/guiconstants.h
@@ -27,8 +27,6 @@ static const bool DEFAULT_SPLASHSCREEN = true;
#define COLOR_BAREADDRESS QColor(140, 140, 140)
/* Transaction list -- TX status decoration - open until date */
#define COLOR_TX_STATUS_OPENUNTILDATE QColor(64, 64, 255)
-/* Transaction list -- TX status decoration - offline */
-#define COLOR_TX_STATUS_OFFLINE QColor(192, 192, 192)
/* Transaction list -- TX status decoration - danger, tx needs attention */
#define COLOR_TX_STATUS_DANGER QColor(200, 100, 100)
/* Transaction list -- TX status decoration - default color */
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp
index 2cb446c459..8297f75799 100644
--- a/src/qt/transactiondesc.cpp
+++ b/src/qt/transactiondesc.cpp
@@ -37,8 +37,6 @@ QString TransactionDesc::FormatTxStatus(const interfaces::WalletTx& wtx, const i
int nDepth = status.depth_in_main_chain;
if (nDepth < 0)
return tr("conflicted with a transaction with %1 confirmations").arg(-nDepth);
- else if (adjustedTime - status.time_received > 2 * 60 && status.request_count == 0)
- return tr("%1/offline").arg(nDepth);
else if (nDepth == 0)
return tr("0/unconfirmed, %1").arg((inMempool ? tr("in memory pool") : tr("not in memory pool"))) + (status.is_abandoned ? ", "+tr("abandoned") : "");
else if (nDepth < 6)
@@ -68,14 +66,6 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall
CAmount nNet = nCredit - nDebit;
strHTML += "<b>" + tr("Status") + ":</b> " + FormatTxStatus(wtx, status, inMempool, numBlocks, adjustedTime);
- int nRequests = status.request_count;
- if (nRequests != -1)
- {
- if (nRequests == 0)
- strHTML += tr(", has not been successfully broadcast yet");
- else if (nRequests > 0)
- strHTML += tr(", broadcast through %n node(s)", "", nRequests);
- }
strHTML += "<br>";
strHTML += "<b>" + tr("Date") + ":</b> " + (nTime ? GUIUtil::dateTimeStr(nTime) : "") + "<br>";
diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp
index b6ed66ad96..65f5e87d15 100644
--- a/src/qt/transactionrecord.cpp
+++ b/src/qt/transactionrecord.cpp
@@ -195,10 +195,6 @@ void TransactionRecord::updateStatus(const interfaces::WalletTxStatus& wtx, int
if (wtx.is_in_main_chain)
{
status.matures_in = wtx.blocks_to_maturity;
-
- // Check if the block was requested by anyone
- if (adjustedTime - wtx.time_received > 2 * 60 && wtx.request_count == 0)
- status.status = TransactionStatus::MaturesWarning;
}
else
{
@@ -216,10 +212,6 @@ void TransactionRecord::updateStatus(const interfaces::WalletTxStatus& wtx, int
{
status.status = TransactionStatus::Conflicted;
}
- else if (adjustedTime - wtx.time_received > 2 * 60 && wtx.request_count == 0)
- {
- status.status = TransactionStatus::Offline;
- }
else if (status.depth == 0)
{
status.status = TransactionStatus::Unconfirmed;
diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h
index 62961434ed..a6424e74fa 100644
--- a/src/qt/transactionrecord.h
+++ b/src/qt/transactionrecord.h
@@ -25,7 +25,7 @@ class TransactionStatus
public:
TransactionStatus():
countsForBalance(false), sortKey(""),
- matures_in(0), status(Offline), depth(0), open_for(0), cur_num_blocks(-1)
+ matures_in(0), status(Unconfirmed), depth(0), open_for(0), cur_num_blocks(-1)
{ }
enum Status {
@@ -33,14 +33,12 @@ public:
/// Normal (sent/received) transactions
OpenUntilDate, /**< Transaction not yet final, waiting for date */
OpenUntilBlock, /**< Transaction not yet final, waiting for block */
- Offline, /**< Not sent to any other nodes **/
Unconfirmed, /**< Not yet mined into a block **/
Confirming, /**< Confirmed, but waiting for the recommended number of confirmations **/
Conflicted, /**< Conflicts with other transaction or mempool **/
Abandoned, /**< Abandoned from the wallet **/
/// Generated (mined) transactions
Immature, /**< Mined but waiting for maturity */
- MaturesWarning, /**< Transaction will likely not mature because no nodes have confirmed */
NotAccepted /**< Mined but not accepted */
};
diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
index 46169a91d1..63a4afe191 100644
--- a/src/qt/transactiontablemodel.cpp
+++ b/src/qt/transactiontablemodel.cpp
@@ -286,9 +286,6 @@ QString TransactionTableModel::formatTxStatus(const TransactionRecord *wtx) cons
case TransactionStatus::OpenUntilDate:
status = tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx->status.open_for));
break;
- case TransactionStatus::Offline:
- status = tr("Offline");
- break;
case TransactionStatus::Unconfirmed:
status = tr("Unconfirmed");
break;
@@ -307,9 +304,6 @@ QString TransactionTableModel::formatTxStatus(const TransactionRecord *wtx) cons
case TransactionStatus::Immature:
status = tr("Immature (%1 confirmations, will be available after %2)").arg(wtx->status.depth).arg(wtx->status.depth + wtx->status.matures_in);
break;
- case TransactionStatus::MaturesWarning:
- status = tr("This block was not received by any other nodes and will probably not be accepted!");
- break;
case TransactionStatus::NotAccepted:
status = tr("Generated but not accepted");
break;
@@ -447,8 +441,6 @@ QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx)
case TransactionStatus::OpenUntilBlock:
case TransactionStatus::OpenUntilDate:
return COLOR_TX_STATUS_OPENUNTILDATE;
- case TransactionStatus::Offline:
- return COLOR_TX_STATUS_OFFLINE;
case TransactionStatus::Unconfirmed:
return QIcon(":/icons/transaction_0");
case TransactionStatus::Abandoned:
@@ -471,7 +463,6 @@ QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx)
int part = (wtx->status.depth * 4 / total) + 1;
return QIcon(QString(":/icons/transaction_%1").arg(part));
}
- case TransactionStatus::MaturesWarning:
case TransactionStatus::NotAccepted:
return QIcon(":/icons/transaction_0");
default:
diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp
index 6df5aec9c9..fac7418cba 100644
--- a/src/test/dbwrapper_tests.cpp
+++ b/src/test/dbwrapper_tests.cpp
@@ -27,7 +27,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper)
{
// Perform tests both obfuscated and non-obfuscated.
for (bool obfuscate : {false, true}) {
- fs::path ph = fs::temp_directory_path() / fs::unique_path();
+ fs::path ph = SetDataDir(std::string("dbwrapper").append(obfuscate ? "_true" : "_false"));
CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate);
char key = 'k';
uint256 in = InsecureRand256();
@@ -47,7 +47,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_batch)
{
// Perform tests both obfuscated and non-obfuscated.
for (bool obfuscate : {false, true}) {
- fs::path ph = fs::temp_directory_path() / fs::unique_path();
+ fs::path ph = SetDataDir(std::string("dbwrapper_batch").append(obfuscate ? "_true" : "_false"));
CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate);
char key = 'i';
@@ -83,7 +83,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_iterator)
{
// Perform tests both obfuscated and non-obfuscated.
for (bool obfuscate : {false, true}) {
- fs::path ph = fs::temp_directory_path() / fs::unique_path();
+ fs::path ph = SetDataDir(std::string("dbwrapper_iterator").append(obfuscate ? "_true" : "_false"));
CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate);
// The two keys are intentionally chosen for ordering
@@ -123,7 +123,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_iterator)
BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate)
{
// We're going to share this fs::path between two wrappers
- fs::path ph = fs::temp_directory_path() / fs::unique_path();
+ fs::path ph = SetDataDir("existing_data_no_obfuscate");
create_directories(ph);
// Set up a non-obfuscated wrapper to write some initial data.
@@ -164,7 +164,7 @@ BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate)
BOOST_AUTO_TEST_CASE(existing_data_reindex)
{
// We're going to share this fs::path between two wrappers
- fs::path ph = fs::temp_directory_path() / fs::unique_path();
+ fs::path ph = SetDataDir("existing_data_reindex");
create_directories(ph);
// Set up a non-obfuscated wrapper to write some initial data.
@@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex)
BOOST_AUTO_TEST_CASE(iterator_ordering)
{
- fs::path ph = fs::temp_directory_path() / fs::unique_path();
+ fs::path ph = SetDataDir("iterator_ordering");
CDBWrapper dbw(ph, (1 << 20), true, false, false);
for (int x=0x00; x<256; ++x) {
uint8_t key = x;
@@ -277,7 +277,7 @@ BOOST_AUTO_TEST_CASE(iterator_string_ordering)
{
char buf[10];
- fs::path ph = fs::temp_directory_path() / fs::unique_path();
+ fs::path ph = SetDataDir("iterator_string_ordering");
CDBWrapper dbw(ph, (1 << 20), true, false, false);
for (int x=0x00; x<10; ++x) {
for (int y = 0; y < 10; y++) {
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index e9814edc23..6ede65c23a 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -46,35 +46,43 @@ std::ostream& operator<<(std::ostream& os, const uint256& num)
}
BasicTestingSetup::BasicTestingSetup(const std::string& chainName)
+ : m_path_root(fs::temp_directory_path() / "test_bitcoin" / strprintf("%lu_%i", (unsigned long)GetTime(), (int)(InsecureRandRange(1 << 30))))
{
- SHA256AutoDetect();
- RandomInit();
- ECC_Start();
- SetupEnvironment();
- SetupNetworking();
- InitSignatureCache();
- InitScriptExecutionCache();
- fCheckBlockIndex = true;
- SelectParams(chainName);
- noui_connect();
+ SHA256AutoDetect();
+ RandomInit();
+ ECC_Start();
+ SetupEnvironment();
+ SetupNetworking();
+ InitSignatureCache();
+ InitScriptExecutionCache();
+ fCheckBlockIndex = true;
+ SelectParams(chainName);
+ noui_connect();
}
BasicTestingSetup::~BasicTestingSetup()
{
- ECC_Stop();
+ fs::remove_all(m_path_root);
+ ECC_Stop();
+}
+
+fs::path BasicTestingSetup::SetDataDir(const std::string& name)
+{
+ fs::path ret = m_path_root / name;
+ fs::create_directories(ret);
+ gArgs.ForceSetArg("-datadir", ret.string());
+ return ret;
}
TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(chainName)
{
+ SetDataDir("tempdir");
const CChainParams& chainparams = Params();
// Ideally we'd move all the RPC tests to the functional testing framework
// instead of unit tests, but for now we need these here.
RegisterAllCoreRPCCommands(tableRPC);
ClearDatadirCache();
- pathTemp = fs::temp_directory_path() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(InsecureRandRange(1 << 30)));
- fs::create_directories(pathTemp);
- gArgs.ForceSetArg("-datadir", pathTemp.string());
// We have to run a scheduler thread to prevent ActivateBestChain
// from blocking due to queue overrun.
@@ -114,7 +122,6 @@ TestingSetup::~TestingSetup()
pcoinsTip.reset();
pcoinsdbview.reset();
pblocktree.reset();
- fs::remove_all(pathTemp);
}
TestChain100Setup::TestChain100Setup() : TestingSetup(CBaseChainParams::REGTEST)
diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h
index d013613de2..88b2d37e87 100644
--- a/src/test/test_bitcoin.h
+++ b/src/test/test_bitcoin.h
@@ -45,6 +45,11 @@ struct BasicTestingSetup {
explicit BasicTestingSetup(const std::string& chainName = CBaseChainParams::MAIN);
~BasicTestingSetup();
+
+ fs::path SetDataDir(const std::string& name);
+
+private:
+ const fs::path m_path_root;
};
/** Testing setup that configures a complete environment.
@@ -59,7 +64,6 @@ struct CConnmanTest {
class PeerLogicValidation;
struct TestingSetup: public BasicTestingSetup {
- fs::path pathTemp;
boost::thread_group threadGroup;
CConnman* connman;
CScheduler scheduler;
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index 611ccc9b77..d535f74e91 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -1100,7 +1100,7 @@ static void TestOtherProcess(fs::path dirname, std::string lockname, int fd)
BOOST_AUTO_TEST_CASE(test_LockDirectory)
{
- fs::path dirname = fs::temp_directory_path() / fs::unique_path();
+ fs::path dirname = SetDataDir("test_LockDirectory") / fs::unique_path();
const std::string lockname = ".lock";
#ifndef WIN32
// Revert SIGCHLD to default, otherwise boost.test will catch and fail on
@@ -1188,12 +1188,12 @@ BOOST_AUTO_TEST_CASE(test_LockDirectory)
BOOST_AUTO_TEST_CASE(test_DirIsWritable)
{
- // Should be able to write to the system tmp dir.
- fs::path tmpdirname = fs::temp_directory_path();
+ // Should be able to write to the data dir.
+ fs::path tmpdirname = SetDataDir("test_DirIsWritable");
BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), true);
// Should not be able to write to a non-existent dir.
- tmpdirname = fs::temp_directory_path() / fs::unique_path();
+ tmpdirname = tmpdirname / fs::unique_path();
BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), false);
fs::create_directory(tmpdirname);
diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp
index 55aa5c2cdf..aff4c44cea 100644
--- a/src/validationinterface.cpp
+++ b/src/validationinterface.cpp
@@ -25,7 +25,6 @@ struct MainSignalsInstance {
boost::signals2::signal<void (const std::shared_ptr<const CBlock> &)> BlockDisconnected;
boost::signals2::signal<void (const CTransactionRef &)> TransactionRemovedFromMempool;
boost::signals2::signal<void (const CBlockLocator &)> ChainStateFlushed;
- boost::signals2::signal<void (const uint256 &)> Inventory;
boost::signals2::signal<void (int64_t nBestBlockTime, CConnman* connman)> Broadcast;
boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
boost::signals2::signal<void (const CBlockIndex *, const std::shared_ptr<const CBlock>&)> NewPoWValidBlock;
@@ -80,7 +79,6 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) {
g_signals.m_internals->BlockDisconnected.connect(boost::bind(&CValidationInterface::BlockDisconnected, pwalletIn, _1));
g_signals.m_internals->TransactionRemovedFromMempool.connect(boost::bind(&CValidationInterface::TransactionRemovedFromMempool, pwalletIn, _1));
g_signals.m_internals->ChainStateFlushed.connect(boost::bind(&CValidationInterface::ChainStateFlushed, pwalletIn, _1));
- g_signals.m_internals->Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
g_signals.m_internals->Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2));
g_signals.m_internals->BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
g_signals.m_internals->NewPoWValidBlock.connect(boost::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2));
@@ -89,7 +87,6 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) {
void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
g_signals.m_internals->BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
g_signals.m_internals->Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2));
- g_signals.m_internals->Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
g_signals.m_internals->ChainStateFlushed.disconnect(boost::bind(&CValidationInterface::ChainStateFlushed, pwalletIn, _1));
g_signals.m_internals->TransactionAddedToMempool.disconnect(boost::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1));
g_signals.m_internals->BlockConnected.disconnect(boost::bind(&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3));
@@ -105,7 +102,6 @@ void UnregisterAllValidationInterfaces() {
}
g_signals.m_internals->BlockChecked.disconnect_all_slots();
g_signals.m_internals->Broadcast.disconnect_all_slots();
- g_signals.m_internals->Inventory.disconnect_all_slots();
g_signals.m_internals->ChainStateFlushed.disconnect_all_slots();
g_signals.m_internals->TransactionAddedToMempool.disconnect_all_slots();
g_signals.m_internals->BlockConnected.disconnect_all_slots();
@@ -171,12 +167,6 @@ void CMainSignals::ChainStateFlushed(const CBlockLocator &locator) {
});
}
-void CMainSignals::Inventory(const uint256 &hash) {
- m_internals->m_schedulerClient.AddToProcessQueue([hash, this] {
- m_internals->Inventory(hash);
- });
-}
-
void CMainSignals::Broadcast(int64_t nBestBlockTime, CConnman* connman) {
m_internals->Broadcast(nBestBlockTime, connman);
}
diff --git a/src/validationinterface.h b/src/validationinterface.h
index 0ca82235da..42cc2e9a20 100644
--- a/src/validationinterface.h
+++ b/src/validationinterface.h
@@ -117,12 +117,6 @@ protected:
* Called on a background thread.
*/
virtual void ChainStateFlushed(const CBlockLocator &locator) {}
- /**
- * Notifies listeners about an inventory item being seen on the network.
- *
- * Called on a background thread.
- */
- virtual void Inventory(const uint256 &hash) {}
/** Tells listeners to broadcast their data. */
virtual void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman) {}
/**
@@ -173,7 +167,6 @@ public:
void BlockConnected(const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::shared_ptr<const std::vector<CTransactionRef>> &);
void BlockDisconnected(const std::shared_ptr<const CBlock> &);
void ChainStateFlushed(const CBlockLocator &);
- void Inventory(const uint256 &);
void Broadcast(int64_t nBestBlockTime, CConnman* connman);
void BlockChecked(const CBlock&, const CValidationState&);
void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr<const CBlock>&);
diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h
index 4c0c8ff5ec..52842cd978 100644
--- a/src/wallet/crypter.h
+++ b/src/wallet/crypter.h
@@ -116,7 +116,7 @@ class CCryptoKeyStore : public CBasicKeyStore
{
private:
- CKeyingMaterial vMasterKey;
+ CKeyingMaterial vMasterKey GUARDED_BY(cs_KeyStore);
//! if fUseCrypto is true, mapKeys must be empty
//! if fUseCrypto is false, vMasterKey must be empty
@@ -126,13 +126,15 @@ private:
bool fDecryptionThoroughlyChecked;
protected:
+ using CryptedKeyMap = std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char>>>;
+
bool SetCrypted();
//! will encrypt previously unencrypted keys
bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
bool Unlock(const CKeyingMaterial& vMasterKeyIn);
- CryptedKeyMap mapCryptedKeys;
+ CryptedKeyMap mapCryptedKeys GUARDED_BY(cs_KeyStore);
public:
CCryptoKeyStore() : fUseCrypto(false), fDecryptionThoroughlyChecked(false)
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index 03754154fc..a946b565f1 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -130,6 +130,8 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
LOCK(cs_main);
+ std::string backup_file = (SetDataDir("importwallet_rescan") / "wallet.backup").string();
+
// Import key into wallet and call dumpwallet to create backup file.
{
std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>("dummy", WalletDatabase::CreateDummy());
@@ -139,7 +141,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
JSONRPCRequest request;
request.params.setArray();
- request.params.push_back((pathTemp / "wallet.backup").string());
+ request.params.push_back(backup_file);
AddWallet(wallet);
::dumpwallet(request);
RemoveWallet(wallet);
@@ -152,7 +154,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
JSONRPCRequest request;
request.params.setArray();
- request.params.push_back((pathTemp / "wallet.backup").string());
+ request.params.push_back(backup_file);
AddWallet(wallet);
::importwallet(request);
RemoveWallet(wallet);
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index adc48a8650..244d5d65e9 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -1227,10 +1227,10 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx)
}
}
-void CWallet::SyncTransaction(const CTransactionRef& ptx, const CBlockIndex *pindex, int posInBlock) {
+void CWallet::SyncTransaction(const CTransactionRef& ptx, const CBlockIndex *pindex, int posInBlock, bool update_tx) {
const CTransaction& tx = *ptx;
- if (!AddToWalletIfInvolvingMe(ptx, pindex, posInBlock, true))
+ if (!AddToWalletIfInvolvingMe(ptx, pindex, posInBlock, update_tx))
return; // Not one of ours
// If a transaction changes 'conflicted' state, that changes the balance
@@ -1532,45 +1532,6 @@ int64_t CWalletTx::GetTxTime() const
return n ? n : nTimeReceived;
}
-int CWalletTx::GetRequestCount() const
-{
- // Returns -1 if it wasn't being tracked
- int nRequests = -1;
- {
- LOCK(pwallet->cs_wallet);
- if (IsCoinBase())
- {
- // Generated block
- if (!hashUnset())
- {
- std::map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
- if (mi != pwallet->mapRequestCount.end())
- nRequests = (*mi).second;
- }
- }
- else
- {
- // Did anyone request this transaction?
- std::map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
- if (mi != pwallet->mapRequestCount.end())
- {
- nRequests = (*mi).second;
-
- // How about the block it's in?
- if (nRequests == 0 && !hashUnset())
- {
- std::map<uint256, int>::const_iterator _mi = pwallet->mapRequestCount.find(hashBlock);
- if (_mi != pwallet->mapRequestCount.end())
- nRequests = (*_mi).second;
- else
- nRequests = 1; // If it's in someone else's block it must have got out
- }
- }
- }
- }
- return nRequests;
-}
-
// Helper for producing a max-sized low-S signature (eg 72 bytes)
bool CWallet::DummySignInput(CTxIn &tx_in, const CTxOut &txout) const
{
@@ -1797,7 +1758,7 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock
break;
}
for (size_t posInBlock = 0; posInBlock < block.vtx.size(); ++posInBlock) {
- AddToWalletIfInvolvingMe(block.vtx[posInBlock], pindex, posInBlock, fUpdate);
+ SyncTransaction(block.vtx[posInBlock], pindex, posInBlock, fUpdate);
}
} else {
ret = pindex;
@@ -3145,9 +3106,6 @@ bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
}
}
- // Track how many getdata requests our transaction gets
- mapRequestCount[wtxNew.GetHash()] = 0;
-
// Get the inserted-CWalletTx from mapWallet so that the
// fInMempool flag is cached properly
CWalletTx& wtx = mapWallet.at(wtxNew.GetHash());
@@ -3210,8 +3168,11 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
}
}
- // This wallet is in its first run if all of these are empty
- fFirstRunRet = mapKeys.empty() && mapCryptedKeys.empty() && mapWatchKeys.empty() && setWatchOnly.empty() && mapScripts.empty();
+ {
+ LOCK(cs_KeyStore);
+ // This wallet is in its first run if all of these are empty
+ fFirstRunRet = mapKeys.empty() && mapCryptedKeys.empty() && mapWatchKeys.empty() && setWatchOnly.empty() && mapScripts.empty();
+ }
if (nLoadWalletRet != DBErrors::LOAD_OK)
return nLoadWalletRet;
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index b829394847..0118ced687 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -486,7 +486,6 @@ public:
bool IsTrusted() const;
int64_t GetTxTime() const;
- int GetRequestCount() const;
// RelayWalletTransaction may only be called if fBroadcastTransactions!
bool RelayWalletTransaction(CConnman* connman);
@@ -709,9 +708,9 @@ private:
void SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator>);
- /* Used by TransactionAddedToMemorypool/BlockConnected/Disconnected.
+ /* Used by TransactionAddedToMemorypool/BlockConnected/Disconnected/ScanForWalletTransactions.
* Should be called with pindexBlock and posInBlock if this is for a transaction that is included in a block. */
- void SyncTransaction(const CTransactionRef& tx, const CBlockIndex *pindex = nullptr, int posInBlock = 0) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ void SyncTransaction(const CTransactionRef& tx, const CBlockIndex *pindex = nullptr, int posInBlock = 0, bool update_tx = true) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/* the HD chain data model (external chain counters) */
CHDChain hdChain;
@@ -820,7 +819,6 @@ public:
int64_t nOrderPosNext = 0;
uint64_t nAccountingEntryNumber = 0;
- std::map<uint256, int> mapRequestCount;
std::map<CTxDestination, CAddressBookData> mapAddressBook;
@@ -1064,16 +1062,6 @@ public:
const std::string& GetLabelName(const CScript& scriptPubKey) const;
- void Inventory(const uint256 &hash) override
- {
- {
- LOCK(cs_wallet);
- std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
- if (mi != mapRequestCount.end())
- (*mi).second++;
- }
- }
-
void GetScriptForMining(std::shared_ptr<CReserveScript> &script);
unsigned int GetKeyPoolSize() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
diff --git a/test/functional/interface_zmq.py b/test/functional/interface_zmq.py
index af2e752b7a..def71c5f0f 100755
--- a/test/functional/interface_zmq.py
+++ b/test/functional/interface_zmq.py
@@ -3,10 +3,10 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the ZMQ notification interface."""
-import configparser
import struct
-from test_framework.test_framework import BitcoinTestFramework, SkipTest
+from test_framework.test_framework import (
+ BitcoinTestFramework, skip_if_no_bitcoind_zmq, skip_if_no_py3_zmq)
from test_framework.mininode import CTransaction
from test_framework.util import (assert_equal,
bytes_to_hex_str,
@@ -38,18 +38,9 @@ class ZMQTest (BitcoinTestFramework):
self.num_nodes = 2
def setup_nodes(self):
- # Try to import python3-zmq. Skip this test if the import fails.
- try:
- import zmq
- except ImportError:
- raise SkipTest("python3-zmq module not available.")
-
- # Check that bitcoin has been built with ZMQ enabled.
- config = configparser.ConfigParser()
- config.read_file(open(self.options.configfile))
-
- if not config["components"].getboolean("ENABLE_ZMQ"):
- raise SkipTest("bitcoind has not been built with zmq enabled.")
+ skip_if_no_py3_zmq()
+ skip_if_no_bitcoind_zmq(self)
+ import zmq
# Initialize ZMQ context and socket.
# All messages are received in the same socket which means
diff --git a/test/functional/rpc_zmq.py b/test/functional/rpc_zmq.py
index eb789face2..6dbc726d5e 100755
--- a/test/functional/rpc_zmq.py
+++ b/test/functional/rpc_zmq.py
@@ -4,7 +4,8 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test for the ZMQ RPC methods."""
-from test_framework.test_framework import BitcoinTestFramework
+from test_framework.test_framework import (
+ BitcoinTestFramework, skip_if_no_py3_zmq, skip_if_no_bitcoind_zmq)
from test_framework.util import assert_equal
@@ -17,6 +18,8 @@ class RPCZMQTest(BitcoinTestFramework):
self.setup_clean_chain = True
def run_test(self):
+ skip_if_no_py3_zmq()
+ skip_if_no_bitcoind_zmq(self)
self._test_getzmqnotifications()
def _test_getzmqnotifications(self):
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
index abe8d12e59..c2fb2077ac 100755
--- a/test/functional/test_framework/test_framework.py
+++ b/test/functional/test_framework/test_framework.py
@@ -475,3 +475,20 @@ class SkipTest(Exception):
"""This exception is raised to skip a test"""
def __init__(self, message):
self.message = message
+
+
+def skip_if_no_py3_zmq():
+ """Attempt to import the zmq package and skip the test if the import fails."""
+ try:
+ import zmq # noqa
+ except ImportError:
+ raise SkipTest("python3-zmq module not available.")
+
+
+def skip_if_no_bitcoind_zmq(test_instance):
+ """Skip the running test if bitcoind has not been compiled with zmq support."""
+ config = configparser.ConfigParser()
+ config.read_file(open(test_instance.options.configfile))
+
+ if not config["components"].getboolean("ENABLE_ZMQ"):
+ raise SkipTest("bitcoind has not been built with zmq enabled.")