aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rwxr-xr-xqa/rpc-tests/importmulti.py19
-rwxr-xr-xqa/rpc-tests/nulldummy.py4
-rwxr-xr-xqa/rpc-tests/proxy_test.py4
-rw-r--r--qa/rpc-tests/test_framework/socks5.py7
-rw-r--r--src/Makefile.qttest.include22
-rw-r--r--src/Makefile.test.include1
-rw-r--r--src/bitcoin-tx.cpp16
-rw-r--r--src/chainparams.cpp3
-rw-r--r--src/chainparams.h3
-rw-r--r--src/coins.h1
-rw-r--r--src/dbwrapper.cpp61
-rw-r--r--src/dbwrapper.h4
-rw-r--r--src/httpserver.cpp7
-rw-r--r--src/init.cpp2
-rw-r--r--src/key.h2
-rw-r--r--src/net.cpp5
-rw-r--r--src/net.h2
-rw-r--r--src/qt/forms/debugwindow.ui2
-rw-r--r--src/qt/forms/sendcoinsdialog.ui14
-rw-r--r--src/qt/sendcoinsdialog.cpp10
-rw-r--r--src/qt/test/rpcnestedtests.cpp4
-rw-r--r--src/qt/test/test_main.cpp40
-rw-r--r--src/qt/test/wallettests.cpp104
-rw-r--r--src/qt/test/wallettests.h15
-rw-r--r--src/qt/walletmodel.cpp5
-rw-r--r--src/qt/walletmodel.h2
-rw-r--r--src/rpc/server.h1
-rw-r--r--src/streams.h4
-rw-r--r--src/sync.cpp2
-rw-r--r--src/sync.h1
-rw-r--r--src/test/checkqueue_tests.cpp8
-rw-r--r--src/test/key_tests.cpp28
-rw-r--r--src/test/script_tests.cpp33
-rw-r--r--src/test/test_bitcoin.cpp28
-rw-r--r--src/test/test_bitcoin_main.cpp26
-rw-r--r--src/torcontrol.cpp24
-rw-r--r--src/wallet/coincontrol.h4
-rw-r--r--src/wallet/db.cpp8
-rw-r--r--src/wallet/rpcdump.cpp10
-rw-r--r--src/wallet/wallet.cpp3
41 files changed, 374 insertions, 169 deletions
diff --git a/.travis.yml b/.travis.yml
index 8d20a7e1bb..ba250ec83b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -32,7 +32,7 @@ env:
# bitcoind
- HOST=x86_64-unknown-linux-gnu PACKAGES="bc python3-zmq" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER"
# No wallet
- - HOST=x86_64-unknown-linux-gnu PACKAGES="python3" DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
+ - HOST=x86_64-unknown-linux-gnu PACKAGES="python3 xvfb" DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
# Cross-Mac
- HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" OSX_SDK=10.11 GOAL="deploy"
@@ -50,6 +50,8 @@ before_script:
- if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
- if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
- make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS
+ # Start xvfb if needed, as documented at https://docs.travis-ci.com/user/gui-and-headless-browsers/#Using-xvfb-to-Run-Tests-That-Require-a-GUI
+ - if [ "$RUN_TESTS" = "true" -a "${DEP_OPTS#*NO_QT=1}" = "$DEP_OPTS" ]; then export DISPLAY=:99.0; /sbin/start-stop-daemon --start --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac; fi
script:
- if [ "$CHECK_DOC" = 1 -a "$TRAVIS_REPO_SLUG" = "bitcoin/bitcoin" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then while read LINE; do travis_retry gpg --keyserver hkp://subset.pool.sks-keyservers.net --recv-keys $LINE; done < contrib/verify-commits/trusted-keys; fi
- if [ "$CHECK_DOC" = 1 -a "$TRAVIS_REPO_SLUG" = "bitcoin/bitcoin" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then git fetch --unshallow; fi
diff --git a/qa/rpc-tests/importmulti.py b/qa/rpc-tests/importmulti.py
index 298b6e9b86..aa03c6780a 100755
--- a/qa/rpc-tests/importmulti.py
+++ b/qa/rpc-tests/importmulti.py
@@ -314,6 +314,7 @@ class ImportMultiTest (BitcoinTestFramework):
self.nodes[1].generate(100)
transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
self.nodes[1].generate(1)
+ timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
transaction = self.nodes[1].gettransaction(transactionid)
self.log.info("Should import a p2sh with respective redeem script and private keys")
@@ -409,6 +410,24 @@ class ImportMultiTest (BitcoinTestFramework):
assert_equal(address_assert['ismine'], False)
assert_equal('timestamp' in address_assert, False)
+
+ # Importing existing watch only address with new timestamp should replace saved timestamp.
+ assert_greater_than(timestamp, watchonly_timestamp)
+ self.log.info("Should replace previously saved watch only timestamp.")
+ result = self.nodes[1].importmulti([{
+ "scriptPubKey": {
+ "address": watchonly_address,
+ },
+ "timestamp": "now",
+ }])
+ assert_equal(result[0]['success'], True)
+ address_assert = self.nodes[1].validateaddress(watchonly_address)
+ assert_equal(address_assert['iswatchonly'], True)
+ assert_equal(address_assert['ismine'], False)
+ assert_equal(address_assert['timestamp'], timestamp)
+ watchonly_timestamp = timestamp
+
+
# restart nodes to check for proper serialization/deserialization of watch only address
stop_nodes(self.nodes)
self.nodes = start_nodes(2, self.options.tmpdir)
diff --git a/qa/rpc-tests/nulldummy.py b/qa/rpc-tests/nulldummy.py
index 7b19fbfd82..369c593a90 100755
--- a/qa/rpc-tests/nulldummy.py
+++ b/qa/rpc-tests/nulldummy.py
@@ -81,14 +81,14 @@ class NULLDUMMYTest(BitcoinTestFramework):
self.log.info("Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [431]")
self.block_submit(self.nodes[0], [test2tx], False, True)
- self.log.info ("Test 4: Non-NULLDUMMY base multisig transaction is invalid after activation")
+ self.log.info("Test 4: Non-NULLDUMMY base multisig transaction is invalid after activation")
test4tx = self.create_transaction(self.nodes[0], test2tx.hash, self.address, 46)
test6txs=[CTransaction(test4tx)]
trueDummy(test4tx)
assert_raises_jsonrpc(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, bytes_to_hex_str(test4tx.serialize_with_witness()), True)
self.block_submit(self.nodes[0], [test4tx])
- print ("Test 5: Non-NULLDUMMY P2WSH multisig transaction invalid after activation")
+ self.log.info("Test 5: Non-NULLDUMMY P2WSH multisig transaction invalid after activation")
test5tx = self.create_transaction(self.nodes[0], txid3, self.wit_address, 48)
test6txs.append(CTransaction(test5tx))
test5tx.wit.vtxinwit[0].scriptWitness.stack[0] = b'\x01'
diff --git a/qa/rpc-tests/proxy_test.py b/qa/rpc-tests/proxy_test.py
index 6b2a8ed1c7..748e3e69f6 100755
--- a/qa/rpc-tests/proxy_test.py
+++ b/qa/rpc-tests/proxy_test.py
@@ -49,6 +49,7 @@ class ProxyTest(BitcoinTestFramework):
self.num_nodes = 4
self.setup_clean_chain = False
+ def setup_nodes(self):
self.have_ipv6 = test_ipv6_local()
# Create two proxies on different ports
# ... one unauthenticated
@@ -69,7 +70,7 @@ class ProxyTest(BitcoinTestFramework):
self.conf3.unauth = True
self.conf3.auth = True
else:
- print("Warning: testing without local IPv6 support")
+ self.log.warning("Testing without local IPv6 support")
self.serv1 = Socks5Server(self.conf1)
self.serv1.start()
@@ -79,7 +80,6 @@ class ProxyTest(BitcoinTestFramework):
self.serv3 = Socks5Server(self.conf3)
self.serv3.start()
- def setup_nodes(self):
# Note: proxies are not used to connect to local nodes
# this is because the proxy to use is based on CService.GetNetwork(), which return NET_UNROUTABLE for localhost
args = [
diff --git a/qa/rpc-tests/test_framework/socks5.py b/qa/rpc-tests/test_framework/socks5.py
index 450bf3775e..dd7624d454 100644
--- a/qa/rpc-tests/test_framework/socks5.py
+++ b/qa/rpc-tests/test_framework/socks5.py
@@ -6,6 +6,9 @@
import socket, threading, queue
import traceback, sys
+import logging
+
+logger = logging.getLogger("TestFramework.socks5")
### Protocol constants
class Command:
@@ -112,10 +115,10 @@ class Socks5Connection(object):
cmdin = Socks5Command(cmd, atyp, addr, port, username, password)
self.serv.queue.put(cmdin)
- print('Proxy: ', cmdin)
+ logger.info('Proxy: %s', cmdin)
# Fall through to disconnect
except Exception as e:
- traceback.print_exc(file=sys.stderr)
+ logger.exception("socks5 request handling failed.")
self.serv.queue.put(e)
finally:
self.conn.close()
diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include
index 039f8ac547..948e13a9e1 100644
--- a/src/Makefile.qttest.include
+++ b/src/Makefile.qttest.include
@@ -11,7 +11,9 @@ TEST_QT_MOC_CPP = \
qt/test/moc_uritests.cpp
if ENABLE_WALLET
-TEST_QT_MOC_CPP += qt/test/moc_paymentservertests.cpp
+TEST_QT_MOC_CPP += \
+ qt/test/moc_paymentservertests.cpp \
+ qt/test/moc_wallettests.cpp
endif
TEST_QT_H = \
@@ -19,7 +21,16 @@ TEST_QT_H = \
qt/test/rpcnestedtests.h \
qt/test/uritests.h \
qt/test/paymentrequestdata.h \
- qt/test/paymentservertests.h
+ qt/test/paymentservertests.h \
+ qt/test/wallettests.h
+
+TEST_BITCOIN_CPP = \
+ test/test_bitcoin.cpp \
+ test/testutil.cpp
+
+TEST_BITCOIN_H = \
+ test/test_bitcoin.h \
+ test/testutil.h
qt_test_test_bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
$(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS)
@@ -29,10 +40,13 @@ qt_test_test_bitcoin_qt_SOURCES = \
qt/test/rpcnestedtests.cpp \
qt/test/test_main.cpp \
qt/test/uritests.cpp \
- $(TEST_QT_H)
+ $(TEST_QT_H) \
+ $(TEST_BITCOIN_CPP) \
+ $(TEST_BITCOIN_H)
if ENABLE_WALLET
qt_test_test_bitcoin_qt_SOURCES += \
- qt/test/paymentservertests.cpp
+ qt/test/paymentservertests.cpp \
+ qt/test/wallettests.cpp
endif
nodist_qt_test_test_bitcoin_qt_SOURCES = $(TEST_QT_MOC_CPP)
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 5517132465..cfd08b8238 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -127,6 +127,7 @@ BITCOIN_TESTS =\
test/streams_tests.cpp \
test/test_bitcoin.cpp \
test/test_bitcoin.h \
+ test/test_bitcoin_main.cpp \
test/test_random.h \
test/testutil.cpp \
test/testutil.h \
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index 3c3646523a..61e0eb74e6 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -483,22 +483,6 @@ static bool findSighashFlags(int& flags, const std::string& flagStr)
return false;
}
-uint256 ParseHashUO(std::map<std::string,UniValue>& o, std::string strKey)
-{
- if (!o.count(strKey))
- return uint256();
- return ParseHashUV(o[strKey], strKey);
-}
-
-std::vector<unsigned char> ParseHexUO(std::map<std::string,UniValue>& o, std::string strKey)
-{
- if (!o.count(strKey)) {
- std::vector<unsigned char> emptyVec;
- return emptyVec;
- }
- return ParseHexUV(o[strKey], strKey);
-}
-
static CAmount AmountFromValue(const UniValue& value)
{
if (!value.isNum() && !value.isStr())
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 8c38558829..1dc29826af 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -135,7 +135,6 @@ public:
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));
- fMiningRequiresPeers = true;
fDefaultConsistencyChecks = false;
fRequireStandard = true;
fMineBlocksOnDemand = false;
@@ -235,7 +234,6 @@ public:
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test));
- fMiningRequiresPeers = true;
fDefaultConsistencyChecks = false;
fRequireStandard = false;
fMineBlocksOnDemand = false;
@@ -307,7 +305,6 @@ public:
vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds.
vSeeds.clear(); //!< Regtest mode doesn't have any DNS seeds.
- fMiningRequiresPeers = false;
fDefaultConsistencyChecks = true;
fRequireStandard = false;
fMineBlocksOnDemand = true;
diff --git a/src/chainparams.h b/src/chainparams.h
index db524e8f8e..4fe88c691c 100644
--- a/src/chainparams.h
+++ b/src/chainparams.h
@@ -61,8 +61,6 @@ public:
int GetDefaultPort() const { return nDefaultPort; }
const CBlock& GenesisBlock() const { return genesis; }
- /** Make miner wait to have peers to avoid wasting work */
- bool MiningRequiresPeers() const { return fMiningRequiresPeers; }
/** Default value for -checkmempool and -checkblockindex argument */
bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; }
/** Policy: Filter transactions that do not match well-defined patterns */
@@ -89,7 +87,6 @@ protected:
std::string strNetworkID;
CBlock genesis;
std::vector<SeedSpec6> vFixedSeeds;
- bool fMiningRequiresPeers;
bool fDefaultConsistencyChecks;
bool fRequireStandard;
bool fMineBlocksOnDemand;
diff --git a/src/coins.h b/src/coins.h
index d921f5c2a5..8ee49b33ae 100644
--- a/src/coins.h
+++ b/src/coins.h
@@ -290,7 +290,6 @@ public:
virtual bool GetKey(uint256 &key) const = 0;
virtual bool GetValue(CCoins &coins) const = 0;
- /* Don't care about GetKeySize here */
virtual unsigned int GetValueSize() const = 0;
virtual bool Valid() const = 0;
diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp
index 94ebedeb72..cd441add4b 100644
--- a/src/dbwrapper.cpp
+++ b/src/dbwrapper.cpp
@@ -14,6 +14,64 @@
#include <leveldb/filter_policy.h>
#include <memenv.h>
#include <stdint.h>
+#include <algorithm>
+
+class CBitcoinLevelDBLogger : public leveldb::Logger {
+public:
+ // This code is adapted from posix_logger.h, which is why it is using vsprintf.
+ // Please do not do this in normal code
+ virtual void Logv(const char * format, va_list ap) override {
+ if (!LogAcceptCategory("leveldb"))
+ return;
+ char buffer[500];
+ for (int iter = 0; iter < 2; iter++) {
+ char* base;
+ int bufsize;
+ if (iter == 0) {
+ bufsize = sizeof(buffer);
+ base = buffer;
+ }
+ else {
+ bufsize = 30000;
+ base = new char[bufsize];
+ }
+ char* p = base;
+ char* limit = base + bufsize;
+
+ // Print the message
+ if (p < limit) {
+ va_list backup_ap;
+ va_copy(backup_ap, ap);
+ // Do not use vsnprintf elsewhere in bitcoin source code, see above.
+ p += vsnprintf(p, limit - p, format, backup_ap);
+ va_end(backup_ap);
+ }
+
+ // Truncate to available space if necessary
+ if (p >= limit) {
+ if (iter == 0) {
+ continue; // Try again with larger buffer
+ }
+ else {
+ p = limit - 1;
+ }
+ }
+
+ // Add newline if necessary
+ if (p == base || p[-1] != '\n') {
+ *p++ = '\n';
+ }
+
+ assert(p <= limit);
+ base[std::min(bufsize - 1, (int)(p - base))] = '\0';
+ LogPrintStr(base);
+ if (base != buffer) {
+ delete[] base;
+ }
+ break;
+ }
+ }
+};
static leveldb::Options GetOptions(size_t nCacheSize)
{
@@ -23,6 +81,7 @@ static leveldb::Options GetOptions(size_t nCacheSize)
options.filter_policy = leveldb::NewBloomFilterPolicy(10);
options.compression = leveldb::kNoCompression;
options.max_open_files = 64;
+ options.info_log = new CBitcoinLevelDBLogger();
if (leveldb::kMajorVersion > 1 || (leveldb::kMajorVersion == 1 && leveldb::kMinorVersion >= 16)) {
// LevelDB versions before 1.16 consider short writes to be corruption. Only trigger error
// on corruption in later versions.
@@ -82,6 +141,8 @@ CDBWrapper::~CDBWrapper()
pdb = NULL;
delete options.filter_policy;
options.filter_policy = NULL;
+ delete options.info_log;
+ options.info_log = NULL;
delete options.block_cache;
options.block_cache = NULL;
delete penv;
diff --git a/src/dbwrapper.h b/src/dbwrapper.h
index dd59cc00ff..414df76a7c 100644
--- a/src/dbwrapper.h
+++ b/src/dbwrapper.h
@@ -132,10 +132,6 @@ public:
return true;
}
- unsigned int GetKeySize() {
- return piter->key().size();
- }
-
template<typename V> bool GetValue(V& value) {
leveldb::Slice slValue = piter->value();
try {
diff --git a/src/httpserver.cpp b/src/httpserver.cpp
index 5f240d3c49..799de1c2cb 100644
--- a/src/httpserver.cpp
+++ b/src/httpserver.cpp
@@ -146,13 +146,6 @@ public:
while (numThreads > 0)
cond.wait(lock);
}
-
- /** Return current depth of queue */
- size_t Depth()
- {
- std::unique_lock<std::mutex> lock(cs);
- return queue.size();
- }
};
struct HTTPPathHandler
diff --git a/src/init.cpp b/src/init.cpp
index 93131b4f94..246d5f340a 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -430,7 +430,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-limitdescendantsize=<n>", strprintf("Do not accept transactions if any ancestor would have more than <n> kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT));
strUsage += HelpMessageOpt("-bip9params=deployment:start:end", "Use given start/end times for specified BIP9 deployment (regtest-only)");
}
- std::string debugCategories = "addrman, alert, bench, cmpctblock, coindb, db, http, libevent, lock, mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, selectcoins, tor, zmq"; // Don't translate these and qt below
+ std::string debugCategories = "addrman, alert, bench, cmpctblock, coindb, db, http, leveldb, libevent, lock, mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, selectcoins, tor, zmq"; // Don't translate these and qt below
if (mode == HMM_BITCOIN_QT)
debugCategories += ", qt";
strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
diff --git a/src/key.h b/src/key.h
index 37c74e8732..925a8d186d 100644
--- a/src/key.h
+++ b/src/key.h
@@ -45,7 +45,7 @@ private:
//! The actual byte data
std::vector<unsigned char, secure_allocator<unsigned char> > keydata;
- //! Check whether the 32-byte array pointed to be vch is valid keydata.
+ //! Check whether the 32-byte array pointed to by vch is valid keydata.
bool static Check(const unsigned char* vch);
public:
diff --git a/src/net.cpp b/src/net.cpp
index 113823f0b4..4c5b04b785 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -2411,11 +2411,6 @@ void CConnman::MarkAddressGood(const CAddress& addr)
addrman.Good(addr);
}
-void CConnman::AddNewAddress(const CAddress& addr, const CAddress& addrFrom, int64_t nTimePenalty)
-{
- addrman.Add(addr, addrFrom, nTimePenalty);
-}
-
void CConnman::AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty)
{
addrman.Add(vAddr, addrFrom, nTimePenalty);
diff --git a/src/net.h b/src/net.h
index 29b6a44c88..3bbe386173 100644
--- a/src/net.h
+++ b/src/net.h
@@ -207,10 +207,8 @@ public:
size_t GetAddressCount() const;
void SetServices(const CService &addr, ServiceFlags nServices);
void MarkAddressGood(const CAddress& addr);
- void AddNewAddress(const CAddress& addr, const CAddress& addrFrom, int64_t nTimePenalty = 0);
void AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty = 0);
std::vector<CAddress> GetAddresses();
- void AddressCurrentlyConnected(const CService& addr);
// Denial-of-service detection/prevention
// The idea is to detect peers that are behaving
diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui
index 8be4a955b3..093e644bdc 100644
--- a/src/qt/forms/debugwindow.ui
+++ b/src/qt/forms/debugwindow.ui
@@ -645,7 +645,7 @@
<item>
<widget class="QPushButton" name="btnClearTrafficGraph">
<property name="text">
- <string>&amp;Clear</string>
+ <string>&amp;Reset</string>
</property>
<property name="autoDefault">
<bool>false</bool>
diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui
index f13b0d9cf9..cc183908d4 100644
--- a/src/qt/forms/sendcoinsdialog.ui
+++ b/src/qt/forms/sendcoinsdialog.ui
@@ -1180,6 +1180,16 @@
</item>
</layout>
</item>
+ <item>
+ <widget class="QCheckBox" name="optInRBF">
+ <property name="text">
+ <string>Request Replace-By-Fee</string>
+ </property>
+ <property name="toolTip">
+ <string>Indicates that the sender may wish to replace this transaction with a new one paying higher fees (prior to being confirmed).</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
@@ -1190,8 +1200,8 @@
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>800</width>
- <height>1</height>
+ <width>40</width>
+ <height>5</height>
</size>
</property>
</spacer>
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 65ca007552..ed7eab03f3 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -114,6 +114,7 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *_platformStyle, QWidget *p
ui->groupCustomFee->button((int)std::max(0, std::min(1, settings.value("nCustomFeeRadio").toInt())))->setChecked(true);
ui->customFee->setValue(settings.value("nTransactionFee").toLongLong());
ui->checkBoxMinimumFee->setChecked(settings.value("fPayOnlyMinFee").toBool());
+ ui->optInRBF->setCheckState(model->getDefaultWalletRbf() ? Qt::Checked : Qt::Unchecked);
minimizeFeeSection(settings.value("fFeeSectionMinimized").toBool());
}
@@ -247,6 +248,8 @@ void SendCoinsDialog::on_sendButton_clicked()
else
ctrl.nConfirmTarget = 0;
+ ctrl.signalRbf = ui->optInRBF->isChecked();
+
prepareStatus = model->prepareTransaction(currentTransaction, &ctrl);
// process prepareStatus and on error generate message shown to user
@@ -326,6 +329,13 @@ void SendCoinsDialog::on_sendButton_clicked()
questionString.append(QString("<span style='font-size:10pt;font-weight:normal;'><br />(=%2)</span>")
.arg(alternativeUnits.join(" " + tr("or") + "<br />")));
+ if (ui->optInRBF->isChecked())
+ {
+ questionString.append("<hr /><span>");
+ questionString.append(tr("This transaction signals replaceability (optin-RBF)."));
+ questionString.append("</span>");
+ }
+
SendConfirmationDialog confirmationDialog(tr("Confirm send coins"),
questionString.arg(formatted.join("<br />")), SEND_CONFIRM_DELAY, this);
confirmationDialog.exec();
diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp
index bd496f149c..a7b82117d8 100644
--- a/src/qt/test/rpcnestedtests.cpp
+++ b/src/qt/test/rpcnestedtests.cpp
@@ -148,9 +148,13 @@ void RPCNestedTests::rpcNestedTests()
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest(abc,,)"), std::runtime_error); //don't tollerate empty arguments when using ,
#endif
+ UnloadBlockIndex();
delete pcoinsTip;
+ pcoinsTip = nullptr;
delete pcoinsdbview;
+ pcoinsdbview = nullptr;
delete pblocktree;
+ pblocktree = nullptr;
boost::filesystem::remove_all(boost::filesystem::path(path));
}
diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp
index d44d711315..d8bcfedb7c 100644
--- a/src/qt/test/test_main.cpp
+++ b/src/qt/test/test_main.cpp
@@ -7,7 +7,6 @@
#endif
#include "chainparams.h"
-#include "key.h"
#include "rpcnestedtests.h"
#include "util.h"
#include "uritests.h"
@@ -15,20 +14,31 @@
#ifdef ENABLE_WALLET
#include "paymentservertests.h"
+#include "wallettests.h"
#endif
-#include <QCoreApplication>
+#include <QApplication>
#include <QObject>
#include <QTest>
#include <openssl/ssl.h>
-#if defined(QT_STATICPLUGIN) && QT_VERSION < 0x050000
+#if defined(QT_STATICPLUGIN)
#include <QtPlugin>
+#if QT_VERSION < 0x050000
Q_IMPORT_PLUGIN(qcncodecs)
Q_IMPORT_PLUGIN(qjpcodecs)
Q_IMPORT_PLUGIN(qtwcodecs)
Q_IMPORT_PLUGIN(qkrcodecs)
+#else
+#if defined(QT_QPA_PLATFORM_XCB)
+Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
+#elif defined(QT_QPA_PLATFORM_WINDOWS)
+Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
+#elif defined(QT_QPA_PLATFORM_COCOA)
+Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
+#endif
+#endif
#endif
extern void noui_connect();
@@ -36,7 +46,6 @@ extern void noui_connect();
// This is all you need to run all the tests
int main(int argc, char *argv[])
{
- ECC_Start();
SetupEnvironment();
SetupNetworking();
SelectParams(CBaseChainParams::MAIN);
@@ -45,27 +54,36 @@ int main(int argc, char *argv[])
bool fInvalid = false;
// Don't remove this, it's needed to access
- // QCoreApplication:: in the tests
- QCoreApplication app(argc, argv);
+ // QApplication:: and QCoreApplication:: in the tests
+ QApplication app(argc, argv);
app.setApplicationName("Bitcoin-Qt-test");
SSL_library_init();
URITests test1;
- if (QTest::qExec(&test1) != 0)
+ if (QTest::qExec(&test1) != 0) {
fInvalid = true;
+ }
#ifdef ENABLE_WALLET
PaymentServerTests test2;
- if (QTest::qExec(&test2) != 0)
+ if (QTest::qExec(&test2) != 0) {
fInvalid = true;
+ }
#endif
RPCNestedTests test3;
- if (QTest::qExec(&test3) != 0)
+ if (QTest::qExec(&test3) != 0) {
fInvalid = true;
+ }
CompatTests test4;
- if (QTest::qExec(&test4) != 0)
+ if (QTest::qExec(&test4) != 0) {
fInvalid = true;
+ }
+#ifdef ENABLE_WALLET
+ WalletTests test5;
+ if (QTest::qExec(&test5) != 0) {
+ fInvalid = true;
+ }
+#endif
- ECC_Stop();
return fInvalid;
}
diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp
new file mode 100644
index 0000000000..2bb7f01fdd
--- /dev/null
+++ b/src/qt/test/wallettests.cpp
@@ -0,0 +1,104 @@
+#include "wallettests.h"
+
+#include "qt/bitcoinamountfield.h"
+#include "qt/optionsmodel.h"
+#include "qt/platformstyle.h"
+#include "qt/qvalidatedlineedit.h"
+#include "qt/sendcoinsdialog.h"
+#include "qt/sendcoinsentry.h"
+#include "qt/transactiontablemodel.h"
+#include "qt/walletmodel.h"
+#include "test/test_bitcoin.h"
+#include "validation.h"
+#include "wallet/wallet.h"
+
+#include <QAbstractButton>
+#include <QApplication>
+#include <QTimer>
+#include <QVBoxLayout>
+
+namespace
+{
+//! Press "Yes" button in modal send confirmation dialog.
+void ConfirmSend()
+{
+ QTimer::singleShot(0, Qt::PreciseTimer, []() {
+ for (QWidget* widget : QApplication::topLevelWidgets()) {
+ if (widget->inherits("SendConfirmationDialog")) {
+ SendConfirmationDialog* dialog = qobject_cast<SendConfirmationDialog*>(widget);
+ QAbstractButton* button = dialog->button(QMessageBox::Yes);
+ button->setEnabled(true);
+ button->click();
+ }
+ }
+ });
+}
+
+//! Send coins to address and return txid.
+uint256 SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CBitcoinAddress& address, CAmount amount)
+{
+ QVBoxLayout* entries = sendCoinsDialog.findChild<QVBoxLayout*>("entries");
+ SendCoinsEntry* entry = qobject_cast<SendCoinsEntry*>(entries->itemAt(0)->widget());
+ entry->findChild<QValidatedLineEdit*>("payTo")->setText(QString::fromStdString(address.ToString()));
+ entry->findChild<BitcoinAmountField*>("payAmount")->setValue(amount);
+ uint256 txid;
+ boost::signals2::scoped_connection c = wallet.NotifyTransactionChanged.connect([&txid](CWallet*, const uint256& hash, ChangeType status) {
+ if (status == CT_NEW) txid = hash;
+ });
+ ConfirmSend();
+ QMetaObject::invokeMethod(&sendCoinsDialog, "on_sendButton_clicked");
+ return txid;
+}
+
+//! Find index of txid in transaction list.
+QModelIndex FindTx(const QAbstractItemModel& model, const uint256& txid)
+{
+ QString hash = QString::fromStdString(txid.ToString());
+ int rows = model.rowCount({});
+ for (int row = 0; row < rows; ++row) {
+ QModelIndex index = model.index(row, 0, {});
+ if (model.data(index, TransactionTableModel::TxHashRole) == hash) {
+ return index;
+ }
+ }
+ return {};
+}
+}
+
+//! Simple qt wallet tests.
+void WalletTests::walletTests()
+{
+ // Set up wallet and chain with 101 blocks (1 mature block for spending).
+ TestChain100Setup test;
+ test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey()));
+ bitdb.MakeMock();
+ CWallet wallet("wallet_test.dat");
+ bool firstRun;
+ wallet.LoadWallet(firstRun);
+ {
+ LOCK(wallet.cs_wallet);
+ wallet.SetAddressBook(test.coinbaseKey.GetPubKey().GetID(), "", "receive");
+ wallet.AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey());
+ }
+ wallet.ScanForWalletTransactions(chainActive.Genesis(), true);
+ wallet.SetBroadcastTransactions(true);
+
+ // Create widgets for sending coins and listing transactions.
+ std::unique_ptr<const PlatformStyle> platformStyle(PlatformStyle::instantiate("other"));
+ SendCoinsDialog sendCoinsDialog(platformStyle.get());
+ OptionsModel optionsModel;
+ WalletModel walletModel(platformStyle.get(), &wallet, &optionsModel);
+ sendCoinsDialog.setModel(&walletModel);
+
+ // Send two transactions, and verify they are added to transaction list.
+ TransactionTableModel* transactionTableModel = walletModel.getTransactionTableModel();
+ QCOMPARE(transactionTableModel->rowCount({}), 101);
+ uint256 txid1 = SendCoins(wallet, sendCoinsDialog, CBitcoinAddress(CKeyID()), 5 * COIN);
+ uint256 txid2 = SendCoins(wallet, sendCoinsDialog, CBitcoinAddress(CKeyID()), 10 * COIN);
+ QCOMPARE(transactionTableModel->rowCount({}), 103);
+ QVERIFY(FindTx(*transactionTableModel, txid1).isValid());
+ QVERIFY(FindTx(*transactionTableModel, txid2).isValid());
+
+ bitdb.Flush(true);
+ bitdb.Reset();
+}
diff --git a/src/qt/test/wallettests.h b/src/qt/test/wallettests.h
new file mode 100644
index 0000000000..342f7916c3
--- /dev/null
+++ b/src/qt/test/wallettests.h
@@ -0,0 +1,15 @@
+#ifndef BITCOIN_QT_TEST_WALLETTESTS_H
+#define BITCOIN_QT_TEST_WALLETTESTS_H
+
+#include <QObject>
+#include <QTest>
+
+class WalletTests : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void walletTests();
+};
+
+#endif // BITCOIN_QT_TEST_WALLETTESTS_H
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 878b7d58ae..ebcac53c25 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -706,3 +706,8 @@ int WalletModel::getDefaultConfirmTarget() const
{
return nTxConfirmTarget;
}
+
+bool WalletModel::getDefaultWalletRbf() const
+{
+ return fWalletRbf;
+}
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index cd7585635f..78e45dc369 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -213,6 +213,8 @@ public:
int getDefaultConfirmTarget() const;
+ bool getDefaultWalletRbf() const;
+
private:
CWallet *wallet;
bool fHaveWatchOnly;
diff --git a/src/rpc/server.h b/src/rpc/server.h
index 68d8a6ec96..ad064e5690 100644
--- a/src/rpc/server.h
+++ b/src/rpc/server.h
@@ -28,7 +28,6 @@ namespace RPCServer
void OnStarted(boost::function<void ()> slot);
void OnStopped(boost::function<void ()> slot);
void OnPreCommand(boost::function<void (const CRPCCommand&)> slot);
- void OnPostCommand(boost::function<void (const CRPCCommand&)> slot);
}
class CBlockIndex;
diff --git a/src/streams.h b/src/streams.h
index 3c24c2c373..1387b9cf54 100644
--- a/src/streams.h
+++ b/src/streams.h
@@ -404,8 +404,8 @@ public:
return (*this);
}
- void GetAndClear(CSerializeData &data) {
- data.insert(data.end(), begin(), end());
+ void GetAndClear(CSerializeData &d) {
+ d.insert(d.end(), begin(), end());
clear();
}
diff --git a/src/sync.cpp b/src/sync.cpp
index fce57f1df9..552682ab67 100644
--- a/src/sync.cpp
+++ b/src/sync.cpp
@@ -46,8 +46,6 @@ struct CLockLocation {
return mutexName + " " + sourceFile + ":" + itostr(sourceLine) + (fTry ? " (TRY)" : "");
}
- std::string MutexName() const { return mutexName; }
-
bool fTry;
private:
std::string mutexName;
diff --git a/src/sync.h b/src/sync.h
index 3b29050e0e..9274f50d8b 100644
--- a/src/sync.h
+++ b/src/sync.h
@@ -97,7 +97,6 @@ public:
}
};
-typedef CCriticalSection CDynamicCriticalSection;
/** Wrapped boost mutex: supports waiting but not recursive locking */
typedef AnnotatedMixin<boost::mutex> CWaitableCriticalSection;
diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp
index d89f9b770b..2f958c885c 100644
--- a/src/test/checkqueue_tests.cpp
+++ b/src/test/checkqueue_tests.cpp
@@ -46,7 +46,7 @@ struct FakeCheckCheckCompletion {
struct FailingCheck {
bool fails;
- FailingCheck(bool fails) : fails(fails){};
+ FailingCheck(bool _fails) : fails(_fails){};
FailingCheck() : fails(true){};
bool operator()()
{
@@ -411,15 +411,15 @@ BOOST_AUTO_TEST_CASE(test_CheckQueueControl_Locks)
std::unique_lock<std::mutex> l(m);
tg.create_thread([&]{
CCheckQueueControl<FakeCheck> control(queue.get());
- std::unique_lock<std::mutex> l(m);
+ std::unique_lock<std::mutex> ll(m);
has_lock = true;
cv.notify_one();
- cv.wait(l, [&]{return has_tried;});
+ cv.wait(ll, [&]{return has_tried;});
done = true;
cv.notify_one();
// Wait until the done is acknowledged
//
- cv.wait(l, [&]{return done_ack;});
+ cv.wait(ll, [&]{return done_ack;});
});
// Wait for thread to get the lock
cv.wait(l, [&](){return has_lock;});
diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp
index 40a7fdf11d..559b3caf1c 100644
--- a/src/test/key_tests.cpp
+++ b/src/test/key_tests.cpp
@@ -29,34 +29,6 @@ static const CBitcoinAddress addr2C("1CRj2HyM1CXWzHAXLQtiGLyggNT9WQqsDs");
static const std::string strAddressBad("1HV9Lc3sNHZxwj4Zk6fB38tEmBryq2cBiF");
-#ifdef KEY_TESTS_DUMPINFO
-void dumpKeyInfo(uint256 privkey)
-{
- CKey key;
- key.resize(32);
- memcpy(&secret[0], &privkey, 32);
- std::vector<unsigned char> sec;
- sec.resize(32);
- memcpy(&sec[0], &secret[0], 32);
- printf(" * secret (hex): %s\n", HexStr(sec).c_str());
-
- for (int nCompressed=0; nCompressed<2; nCompressed++)
- {
- bool fCompressed = nCompressed == 1;
- printf(" * %s:\n", fCompressed ? "compressed" : "uncompressed");
- CBitcoinSecret bsecret;
- bsecret.SetSecret(secret, fCompressed);
- printf(" * secret (base58): %s\n", bsecret.ToString().c_str());
- CKey key;
- key.SetSecret(secret, fCompressed);
- std::vector<unsigned char> vchPubKey = key.GetPubKey();
- printf(" * pubkey (hex): %s\n", HexStr(vchPubKey).c_str());
- printf(" * address (base58): %s\n", CBitcoinAddress(vchPubKey).ToString().c_str());
- }
-}
-#endif
-
-
BOOST_FIXTURE_TEST_SUITE(key_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(key_test1)
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 32184165f7..343c645cb1 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -32,7 +32,7 @@
// Uncomment if you want to output updated JSON tests.
// #define UPDATE_JSON_TESTS
-static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
+static const unsigned int gFlags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
unsigned int ParseScriptFlags(std::string strFlags);
std::string FormatScriptFlags(unsigned int flags);
@@ -455,11 +455,6 @@ public:
{
return comment;
}
-
- const CScript& GetScriptPubKey()
- {
- return creditTx->vout[0].scriptPubKey;
- }
};
std::string JSONPrettyPrint(const UniValue& univalue)
@@ -1070,18 +1065,18 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12)
CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom12);
CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12);
- BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
+ BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, NULL, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
txTo12.vout[0].nValue = 2;
- BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
+ BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, NULL, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12);
- BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
+ BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, NULL, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12);
- BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
+ BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, NULL, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
@@ -1103,54 +1098,54 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
std::vector<CKey> keys;
keys.push_back(key1); keys.push_back(key2);
CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear();
keys.push_back(key1); keys.push_back(key3);
CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear();
keys.push_back(key2); keys.push_back(key3);
CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear();
keys.push_back(key2); keys.push_back(key2); // Can't re-use sig
CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order
CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order
CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys
CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys
CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear(); // Must have signatures
CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, NULL, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
+ BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, NULL, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
}
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index 2297644c0b..abaec45cd7 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -2,8 +2,6 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#define BOOST_TEST_MODULE Bitcoin Test Suite
-
#include "test_bitcoin.h"
#include "chainparams.h"
@@ -27,10 +25,8 @@
#include <memory>
#include <boost/filesystem.hpp>
-#include <boost/test/unit_test.hpp>
#include <boost/thread.hpp>
-std::unique_ptr<CConnman> g_connman;
FastRandomContext insecure_rand_ctx(true);
extern bool fPrintToConsole;
@@ -69,11 +65,14 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
pblocktree = new CBlockTreeDB(1 << 20, true);
pcoinsdbview = new CCoinsViewDB(1 << 23, true);
pcoinsTip = new CCoinsViewCache(pcoinsdbview);
- BOOST_REQUIRE(InitBlockIndex(chainparams));
+ if (!InitBlockIndex(chainparams)) {
+ throw std::runtime_error("InitBlockIndex failed.");
+ }
{
CValidationState state;
- bool ok = ActivateBestChain(state, chainparams);
- BOOST_REQUIRE(ok);
+ if (!ActivateBestChain(state, chainparams)) {
+ throw std::runtime_error("ActivateBestChain failed.");
+ }
}
nScriptCheckThreads = 3;
for (int i=0; i < nScriptCheckThreads-1; i++)
@@ -150,18 +149,3 @@ CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransaction &txn) {
return CTxMemPoolEntry(MakeTransactionRef(txn), nFee, nTime, nHeight,
spendsCoinbase, sigOpCost, lp);
}
-
-void Shutdown(void* parg)
-{
- exit(EXIT_SUCCESS);
-}
-
-void StartShutdown()
-{
- exit(EXIT_SUCCESS);
-}
-
-bool ShutdownRequested()
-{
- return false;
-}
diff --git a/src/test/test_bitcoin_main.cpp b/src/test/test_bitcoin_main.cpp
new file mode 100644
index 0000000000..34beef5539
--- /dev/null
+++ b/src/test/test_bitcoin_main.cpp
@@ -0,0 +1,26 @@
+// Copyright (c) 2011-2016 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#define BOOST_TEST_MODULE Bitcoin Test Suite
+
+#include "net.h"
+
+#include <boost/test/unit_test.hpp>
+
+std::unique_ptr<CConnman> g_connman;
+
+void Shutdown(void* parg)
+{
+ exit(EXIT_SUCCESS);
+}
+
+void StartShutdown()
+{
+ exit(EXIT_SUCCESS);
+}
+
+bool ShutdownRequested()
+{
+ return false;
+}
diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp
index c49c5d9eb2..d24020e51f 100644
--- a/src/torcontrol.cpp
+++ b/src/torcontrol.cpp
@@ -662,26 +662,26 @@ void TorController::reconnect_cb(evutil_socket_t fd, short what, void *arg)
}
/****** Thread ********/
-struct event_base *base;
-boost::thread torControlThread;
+static struct event_base *gBase;
+static boost::thread torControlThread;
static void TorControlThread()
{
- TorController ctrl(base, GetArg("-torcontrol", DEFAULT_TOR_CONTROL));
+ TorController ctrl(gBase, GetArg("-torcontrol", DEFAULT_TOR_CONTROL));
- event_base_dispatch(base);
+ event_base_dispatch(gBase);
}
void StartTorControl(boost::thread_group& threadGroup, CScheduler& scheduler)
{
- assert(!base);
+ assert(!gBase);
#ifdef WIN32
evthread_use_windows_threads();
#else
evthread_use_pthreads();
#endif
- base = event_base_new();
- if (!base) {
+ gBase = event_base_new();
+ if (!gBase) {
LogPrintf("tor: Unable to create event_base\n");
return;
}
@@ -691,18 +691,18 @@ void StartTorControl(boost::thread_group& threadGroup, CScheduler& scheduler)
void InterruptTorControl()
{
- if (base) {
+ if (gBase) {
LogPrintf("tor: Thread interrupt\n");
- event_base_loopbreak(base);
+ event_base_loopbreak(gBase);
}
}
void StopTorControl()
{
- if (base) {
+ if (gBase) {
torControlThread.join();
- event_base_free(base);
- base = 0;
+ event_base_free(gBase);
+ gBase = 0;
}
}
diff --git a/src/wallet/coincontrol.h b/src/wallet/coincontrol.h
index eaf4ff8062..4e93e929be 100644
--- a/src/wallet/coincontrol.h
+++ b/src/wallet/coincontrol.h
@@ -6,6 +6,7 @@
#define BITCOIN_WALLET_COINCONTROL_H
#include "primitives/transaction.h"
+#include "wallet/wallet.h"
/** Coin Control Features. */
class CCoinControl
@@ -24,6 +25,8 @@ public:
CFeeRate nFeeRate;
//! Override the default confirmation target, 0 = use default
int nConfirmTarget;
+ //! Signal BIP-125 replace by fee.
+ bool signalRbf;
CCoinControl()
{
@@ -40,6 +43,7 @@ public:
nFeeRate = CFeeRate(0);
fOverrideFeeRate = false;
nConfirmTarget = 0;
+ signalRbf = fWalletRbf;
}
bool HasSelected() const
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index 80c42bd91b..0801bd7300 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -604,11 +604,11 @@ bool CDB::PeriodicFlush(std::string strFile)
{
// Don't do this if any databases are in use
int nRefCount = 0;
- std::map<std::string, int>::iterator mi = bitdb.mapFileUseCount.begin();
- while (mi != bitdb.mapFileUseCount.end())
+ std::map<std::string, int>::iterator mit = bitdb.mapFileUseCount.begin();
+ while (mit != bitdb.mapFileUseCount.end())
{
- nRefCount += (*mi).second;
- mi++;
+ nRefCount += (*mit).second;
+ mit++;
}
if (nRefCount == 0)
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index 9554f0541e..7ff9e7ae58 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -743,7 +743,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
pwallet->MarkDirty();
- if (!pwallet->HaveWatchOnly(redeemScript) && !pwallet->AddWatchOnly(redeemScript, timestamp)) {
+ if (!pwallet->AddWatchOnly(redeemScript, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
}
@@ -760,7 +760,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
pwallet->MarkDirty();
- if (!pwallet->HaveWatchOnly(redeemDestination) && !pwallet->AddWatchOnly(redeemDestination, timestamp)) {
+ if (!pwallet->AddWatchOnly(redeemDestination, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
}
@@ -853,7 +853,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
pwallet->MarkDirty();
- if (!pwallet->HaveWatchOnly(pubKeyScript) && !pwallet->AddWatchOnly(pubKeyScript, timestamp)) {
+ if (!pwallet->AddWatchOnly(pubKeyScript, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
}
@@ -871,7 +871,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
pwallet->MarkDirty();
- if (!pwallet->HaveWatchOnly(scriptRawPubKey) && !pwallet->AddWatchOnly(scriptRawPubKey, timestamp)) {
+ if (!pwallet->AddWatchOnly(scriptRawPubKey, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
}
@@ -945,7 +945,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
pwallet->MarkDirty();
- if (!pwallet->HaveWatchOnly(script) && !pwallet->AddWatchOnly(script, timestamp)) {
+ if (!pwallet->AddWatchOnly(script, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
}
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 9e3c8be3f2..445e40b043 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -2517,9 +2517,10 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
// to avoid conflicting with other possible uses of nSequence,
// and in the spirit of "smallest possible change from prior
// behavior."
+ bool rbf = coinControl ? coinControl->signalRbf : fWalletRbf;
for (const auto& coin : setCoins)
txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(),
- std::numeric_limits<unsigned int>::max() - (fWalletRbf ? 2 : 1)));
+ std::numeric_limits<unsigned int>::max() - (rbf ? 2 : 1)));
// Fill in dummy signatures for fee calculation.
if (!DummySignTx(txNew, setCoins)) {