aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml3
-rw-r--r--CONTRIBUTING.md6
-rwxr-xr-xcontrib/testgen/gen_base58_test_vectors.py2
-rw-r--r--src/Makefile.am4
-rw-r--r--src/core_write.cpp4
-rw-r--r--src/init.cpp6
-rw-r--r--src/miner.cpp13
-rw-r--r--src/qt/rpcconsole.cpp7
-rw-r--r--src/rpc/server.h2
-rw-r--r--src/txmempool.cpp2
-rw-r--r--src/txmempool.h8
-rw-r--r--src/validation.h2
-rw-r--r--src/validationinterface.h7
-rw-r--r--src/zmq/zmqpublishnotifier.cpp3
-rwxr-xr-xtest/functional/assumevalid.py102
-rwxr-xr-xtest/functional/bip68-sequence.py4
-rwxr-xr-xtest/functional/bumpfee.py110
-rwxr-xr-xtest/functional/fundrawtransaction.py37
-rwxr-xr-xtest/functional/import-rescan.py1
-rwxr-xr-xtest/functional/multi_rpc.py2
-rwxr-xr-xtest/functional/rawtransactions.py1
-rwxr-xr-xtest/functional/rpcbind_test.py18
-rwxr-xr-xtest/functional/segwit.py5
-rwxr-xr-xtest/functional/smartfees.py3
-rw-r--r--test/functional/test_framework/socks5.py1
-rwxr-xr-xtest/functional/test_framework/test_framework.py10
-rwxr-xr-xtest/functional/test_runner.py36
-rwxr-xr-xtest/functional/zmq_test.py1
28 files changed, 208 insertions, 192 deletions
diff --git a/.travis.yml b/.travis.yml
index f57a19c4ca..503172f2a9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -70,7 +70,8 @@ script:
- make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false )
- export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib
- if [ "$RUN_TESTS" = "true" ]; then make $MAKEJOBS check VERBOSE=1; fi
- - if [ "$RUN_TESTS" = "true" ]; then test/functional/test_runner.py --coverage; fi
+ - if [ "$TRAVIS_EVENT_TYPE" = "cron" ]; then extended="--extended --exclude pruning"; fi
+ - if [ "$RUN_TESTS" = "true" ]; then test/functional/test_runner.py --coverage ${extended}; fi
after_script:
- echo $TRAVIS_COMMIT_RANGE
- echo $TRAVIS_COMMIT_LOG
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index fc8d58d97d..0766d89f55 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -130,7 +130,7 @@ pull requests which attempt to do too much, are overly large, or overly complex
as this makes review difficult.
-###Features
+### Features
When adding a new feature, thought must be given to the long term technical debt
and maintenance that feature may require after inclusion. Before proposing a new
@@ -139,7 +139,7 @@ maintain it (including bug fixing). If features get orphaned with no maintainer
in the future, they may be removed by the Repository Maintainer.
-###Refactoring
+### Refactoring
Refactoring is a necessary part of any software project's evolution. The
following guidelines cover refactoring pull requests for the project.
@@ -187,7 +187,7 @@ other kinds of patches because of increased peer review and consensus building
requirements.
-###Peer Review
+### Peer Review
Anyone may participate in peer review which is expressed by comments in the pull
request. Typically reviewers will review the code for obvious errors, as well as
diff --git a/contrib/testgen/gen_base58_test_vectors.py b/contrib/testgen/gen_base58_test_vectors.py
index ac0701e6be..86366eb8e3 100755
--- a/contrib/testgen/gen_base58_test_vectors.py
+++ b/contrib/testgen/gen_base58_test_vectors.py
@@ -13,7 +13,7 @@ Usage:
# Released under MIT License
import os
from itertools import islice
-from base58 import b58encode, b58decode, b58encode_chk, b58decode_chk, b58chars
+from base58 import b58encode_chk, b58decode_chk, b58chars
import random
from binascii import b2a_hex
diff --git a/src/Makefile.am b/src/Makefile.am
index e8d22313dc..8a32156884 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -167,8 +167,8 @@ BITCOIN_CORE_H = \
obj/build.h: FORCE
@$(MKDIR_P) $(builddir)/obj
- @$(top_srcdir)/share/genbuild.sh $(abs_top_builddir)/src/obj/build.h \
- $(abs_top_srcdir)
+ @$(top_srcdir)/share/genbuild.sh "$(abs_top_builddir)/src/obj/build.h" \
+ "$(abs_top_srcdir)"
libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h
# server: shared between bitcoind and bitcoin-qt
diff --git a/src/core_write.cpp b/src/core_write.cpp
index b0993a131f..a3ca87c8b5 100644
--- a/src/core_write.cpp
+++ b/src/core_write.cpp
@@ -114,9 +114,9 @@ std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDeco
return str;
}
-std::string EncodeHexTx(const CTransaction& tx, const int serialFlags)
+std::string EncodeHexTx(const CTransaction& tx, const int serializeFlags)
{
- CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | serialFlags);
+ CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | serializeFlags);
ssTx << tx;
return HexStr(ssTx.begin(), ssTx.end());
}
diff --git a/src/init.cpp b/src/init.cpp
index 81a12d431e..a78224d5d7 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -373,13 +373,13 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-banscore=<n>", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), DEFAULT_BANSCORE_THRESHOLD));
strUsage += HelpMessageOpt("-bantime=<n>", strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), DEFAULT_MISBEHAVING_BANTIME));
strUsage += HelpMessageOpt("-bind=<addr>", _("Bind to given address and always listen on it. Use [host]:port notation for IPv6"));
- strUsage += HelpMessageOpt("-connect=<ip>", _("Connect only to the specified node(s); -noconnect or -connect=0 alone to disable automatic connections"));
+ strUsage += HelpMessageOpt("-connect=<ip>", _("Connect only to the specified node(s); -connect=0 disables automatic connections"));
strUsage += HelpMessageOpt("-discover", _("Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)"));
strUsage += HelpMessageOpt("-dns", _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + strprintf(_("(default: %u)"), DEFAULT_NAME_LOOKUP));
- strUsage += HelpMessageOpt("-dnsseed", _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect/-noconnect)"));
+ strUsage += HelpMessageOpt("-dnsseed", _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect used)"));
strUsage += HelpMessageOpt("-externalip=<ip>", _("Specify your own public address"));
strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), DEFAULT_FORCEDNSSEED));
- strUsage += HelpMessageOpt("-listen", _("Accept connections from outside (default: 1 if no -proxy or -connect/-noconnect)"));
+ strUsage += HelpMessageOpt("-listen", _("Accept connections from outside (default: 1 if no -proxy or -connect)"));
strUsage += HelpMessageOpt("-listenonion", strprintf(_("Automatically create Tor hidden service (default: %d)"), DEFAULT_LISTEN_ONION));
strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf(_("Maintain at most <n> connections to peers (default: %u)"), DEFAULT_MAX_PEER_CONNECTIONS));
strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), DEFAULT_MAXRECEIVEBUFFER));
diff --git a/src/miner.cpp b/src/miner.cpp
index ff28a5680e..4fd99c5282 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -26,8 +26,6 @@
#include "validationinterface.h"
#include <algorithm>
-#include <boost/thread.hpp>
-#include <boost/tuple/tuple.hpp>
#include <queue>
#include <utility>
@@ -46,17 +44,6 @@ uint64_t nLastBlockTx = 0;
uint64_t nLastBlockSize = 0;
uint64_t nLastBlockWeight = 0;
-class ScoreCompare
-{
-public:
- ScoreCompare() {}
-
- bool operator()(const CTxMemPool::txiter a, const CTxMemPool::txiter b)
- {
- return CompareTxMemPoolEntryByScore()(*b,*a); // Convert to less than
- }
-};
-
int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
{
int64_t nOldTime = pblock->nTime;
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 60406c2059..5167232d6a 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -175,6 +175,10 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
nDepthInsideSensitive = 1;
filter_begin_pos = chpos;
}
+ // Make sure stack is not empty before adding something
+ if (stack.empty()) {
+ stack.push_back(std::vector<std::string>());
+ }
stack.back().push_back(strArg);
};
@@ -626,9 +630,12 @@ void RPCConsole::setClientModel(ClientModel *model)
for (size_t i = 0; i < commandList.size(); ++i)
{
wordList << commandList[i].c_str();
+ wordList << ("help " + commandList[i]).c_str();
}
+ wordList.sort();
autoCompleter = new QCompleter(wordList, this);
+ autoCompleter->setModelSorting(QCompleter::CaseSensitivelySortedModel);
ui->lineEdit->setCompleter(autoCompleter);
autoCompleter->popup()->installEventFilter(this);
// Start thread to execute RPC commands.
diff --git a/src/rpc/server.h b/src/rpc/server.h
index ad064e5690..de14c7ed3e 100644
--- a/src/rpc/server.h
+++ b/src/rpc/server.h
@@ -68,7 +68,7 @@ void SetRPCWarmupStatus(const std::string& newStatus);
void SetRPCWarmupFinished();
/* returns the current warmup state. */
-bool RPCIsInWarmup(std::string *statusOut);
+bool RPCIsInWarmup(std::string *outStatus);
/**
* Type-check arguments; throws JSONRPCError if wrong type given. Does not check that
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index fb58208774..6e1d7a42b5 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -108,7 +108,7 @@ void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendan
// vHashesToUpdate is the set of transaction hashes from a disconnected block
// which has been re-added to the mempool.
-// for each entry, look for descendants that are outside hashesToUpdate, and
+// for each entry, look for descendants that are outside vHashesToUpdate, and
// add fee/size information for such descendants to the parent.
// for each such descendant, also update the ancestor state to include the parent.
void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256> &vHashesToUpdate)
diff --git a/src/txmempool.h b/src/txmempool.h
index f9a9d088d0..4222789510 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -552,12 +552,12 @@ public:
* new mempool entries may have children in the mempool (which is generally
* not the case when otherwise adding transactions).
* UpdateTransactionsFromBlock() will find child transactions and update the
- * descendant state for each transaction in hashesToUpdate (excluding any
- * child transactions present in hashesToUpdate, which are already accounted
- * for). Note: hashesToUpdate should be the set of transactions from the
+ * descendant state for each transaction in vHashesToUpdate (excluding any
+ * child transactions present in vHashesToUpdate, which are already accounted
+ * for). Note: vHashesToUpdate should be the set of transactions from the
* disconnected block that have been accepted back into the mempool.
*/
- void UpdateTransactionsFromBlock(const std::vector<uint256> &hashesToUpdate);
+ void UpdateTransactionsFromBlock(const std::vector<uint256> &vHashesToUpdate);
/** Try to calculate all in-mempool ancestors of entry.
* (these are all calculated including the tx itself)
diff --git a/src/validation.h b/src/validation.h
index 43f0dbae34..5f8e9a689c 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -314,7 +314,7 @@ void FlushStateToDisk();
/** Prune block files and flush state to disk. */
void PruneAndFlush();
/** Prune block files up to a given height */
-void PruneBlockFilesManual(int nPruneUpToHeight);
+void PruneBlockFilesManual(int nManualPruneHeight);
/** (try to) add transaction to memory pool
* plTxnReplaced will be appended to with all transactions replaced from mempool **/
diff --git a/src/validationinterface.h b/src/validationinterface.h
index a494eb6990..7f13a29d23 100644
--- a/src/validationinterface.h
+++ b/src/validationinterface.h
@@ -69,7 +69,12 @@ struct CMainSignals {
boost::signals2::signal<void (const uint256 &)> Inventory;
/** Tells listeners to broadcast their data. */
boost::signals2::signal<void (int64_t nBestBlockTime, CConnman* connman)> Broadcast;
- /** Notifies listeners of a block validation result */
+ /**
+ * Notifies listeners of a block validation result.
+ * If the provided CValidationState IsValid, the provided block
+ * is guaranteed to be the current best block at the time the
+ * callback was generated (not necessarily now)
+ */
boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
/** Notifies listeners that a key for mining is required (coinbase) */
boost::signals2::signal<void (boost::shared_ptr<CReserveScript>&)> ScriptForMining;
diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp
index caca1248a1..4e13cbcaf4 100644
--- a/src/zmq/zmqpublishnotifier.cpp
+++ b/src/zmq/zmqpublishnotifier.cpp
@@ -30,6 +30,7 @@ static int zmq_send_multipart(void *sock, const void* data, size_t size, ...)
if (rc != 0)
{
zmqError("Unable to initialize ZMQ msg");
+ va_end(args);
return -1;
}
@@ -43,6 +44,7 @@ static int zmq_send_multipart(void *sock, const void* data, size_t size, ...)
{
zmqError("Unable to send ZMQ msg");
zmq_msg_close(&msg);
+ va_end(args);
return -1;
}
@@ -53,6 +55,7 @@ static int zmq_send_multipart(void *sock, const void* data, size_t size, ...)
size = va_arg(args, size_t);
}
+ va_end(args);
return 0;
}
diff --git a/test/functional/assumevalid.py b/test/functional/assumevalid.py
index c60c8e6d1a..da680a5d24 100755
--- a/test/functional/assumevalid.py
+++ b/test/functional/assumevalid.py
@@ -15,7 +15,7 @@ transactions:
2-101: bury that block with 100 blocks so the coinbase transaction
output can be spent
102: a block containing a transaction spending the coinbase
- transaction output. The transaction has an invalid signature.
+ transaction output. The transaction has an invalid signature.
103-2202: bury the bad block with just over two weeks' worth of blocks
(2100 blocks)
@@ -29,40 +29,34 @@ Start three nodes:
block 200. node2 will reject block 102 since it's assumed valid, but it
isn't buried by at least two weeks' work.
"""
+import time
-from test_framework.mininode import *
-from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import *
-from test_framework.blocktools import create_block, create_coinbase
+from test_framework.blocktools import (create_block, create_coinbase)
from test_framework.key import CECKey
-from test_framework.script import *
+from test_framework.mininode import (CBlockHeader,
+ COutPoint,
+ CTransaction,
+ CTxIn,
+ CTxOut,
+ NetworkThread,
+ NodeConn,
+ SingleNodeConnCB,
+ msg_block,
+ msg_headers)
+from test_framework.script import (CScript, OP_TRUE)
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import (start_node, p2p_port, assert_equal)
class BaseNode(SingleNodeConnCB):
def __init__(self):
- SingleNodeConnCB.__init__(self)
- self.last_inv = None
- self.last_headers = None
- self.last_block = None
- self.last_getdata = None
- self.block_announced = False
- self.last_getheaders = None
- self.disconnected = False
- self.last_blockhash_announced = None
-
- def on_close(self, conn):
- self.disconnected = True
-
- def wait_for_disconnect(self, timeout=60):
- test_function = lambda: self.disconnected
- assert(wait_until(test_function, timeout=timeout))
- return
+ super().__init__()
def send_header_for_blocks(self, new_blocks):
headers_message = msg_headers()
- headers_message.headers = [ CBlockHeader(b) for b in new_blocks ]
+ headers_message.headers = [CBlockHeader(b) for b in new_blocks]
self.send_message(headers_message)
-class SendHeadersTest(BitcoinTestFramework):
+class AssumeValidTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
@@ -72,8 +66,34 @@ class SendHeadersTest(BitcoinTestFramework):
# Start node0. We don't start the other nodes yet since
# we need to pre-mine a block with an invalid transaction
# signature so we can pass in the block hash as assumevalid.
- self.nodes = []
- self.nodes.append(start_node(0, self.options.tmpdir))
+ self.nodes = [start_node(0, self.options.tmpdir)]
+
+ def send_blocks_until_disconnected(self, node):
+ """Keep sending blocks to the node until we're disconnected."""
+ for i in range(len(self.blocks)):
+ try:
+ node.send_message(msg_block(self.blocks[i]))
+ except IOError as e:
+ assert str(e) == 'Not connected, no pushbuf'
+ break
+
+ def assert_blockchain_height(self, node, height):
+ """Wait until the blockchain is no longer advancing and verify it's reached the expected height."""
+ last_height = node.getblock(node.getbestblockhash())['height']
+ timeout = 10
+ while True:
+ time.sleep(0.25)
+ current_height = node.getblock(node.getbestblockhash())['height']
+ if current_height != last_height:
+ last_height = current_height
+ if timeout < 0:
+ assert False, "blockchain too short after timeout: %d" % current_height
+ timeout - 0.25
+ continue
+ elif current_height > height:
+ assert False, "blockchain too long: %d" % current_height
+ elif current_height == height:
+ break
def run_test(self):
@@ -83,7 +103,7 @@ class SendHeadersTest(BitcoinTestFramework):
connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], node0))
node0.add_connection(connections[0])
- NetworkThread().start() # Start up network handling in another thread
+ NetworkThread().start() # Start up network handling in another thread
node0.wait_for_verack()
# Build the blockchain
@@ -120,7 +140,7 @@ class SendHeadersTest(BitcoinTestFramework):
# Create a transaction spending the coinbase output with an invalid (null) signature
tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(self.block1.vtx[0].sha256, 0), scriptSig=b""))
- tx.vout.append(CTxOut(49*100000000, CScript([OP_TRUE])))
+ tx.vout.append(CTxOut(49 * 100000000, CScript([OP_TRUE])))
tx.calc_sha256()
block102 = create_block(self.tip, create_coinbase(height), self.block_time)
@@ -166,25 +186,19 @@ class SendHeadersTest(BitcoinTestFramework):
node1.send_header_for_blocks(self.blocks[2000:])
node2.send_header_for_blocks(self.blocks[0:200])
- # Send 102 blocks to node0. Block 102 will be rejected.
- for i in range(101):
- node0.send_message(msg_block(self.blocks[i]))
- node0.sync_with_ping() # make sure the most recent block is synced
- node0.send_message(msg_block(self.blocks[101]))
- assert_equal(self.nodes[0].getblock(self.nodes[0].getbestblockhash())['height'], 101)
+ # Send blocks to node0. Block 102 will be rejected.
+ self.send_blocks_until_disconnected(node0)
+ self.assert_blockchain_height(self.nodes[0], 101)
- # Send 3102 blocks to node1. All blocks will be accepted.
+ # Send all blocks to node1. All blocks will be accepted.
for i in range(2202):
node1.send_message(msg_block(self.blocks[i]))
- node1.sync_with_ping() # make sure the most recent block is synced
+ node1.sync_with_ping() # make sure the most recent block is synced
assert_equal(self.nodes[1].getblock(self.nodes[1].getbestblockhash())['height'], 2202)
- # Send 102 blocks to node2. Block 102 will be rejected.
- for i in range(101):
- node2.send_message(msg_block(self.blocks[i]))
- node2.sync_with_ping() # make sure the most recent block is synced
- node2.send_message(msg_block(self.blocks[101]))
- assert_equal(self.nodes[2].getblock(self.nodes[2].getbestblockhash())['height'], 101)
+ # Send blocks to node2. Block 102 will be rejected.
+ self.send_blocks_until_disconnected(node2)
+ self.assert_blockchain_height(self.nodes[2], 101)
if __name__ == '__main__':
- SendHeadersTest().main()
+ AssumeValidTest().main()
diff --git a/test/functional/bip68-sequence.py b/test/functional/bip68-sequence.py
index 3ed6ebe044..89d42a710c 100755
--- a/test/functional/bip68-sequence.py
+++ b/test/functional/bip68-sequence.py
@@ -378,8 +378,8 @@ class BIP68Test(BitcoinTestFramework):
# activation should happen at block height 432 (3 periods)
min_activation_height = 432
height = self.nodes[0].getblockcount()
- assert(height < 432)
- self.nodes[0].generate(432-height)
+ assert(height < min_activation_height)
+ self.nodes[0].generate(min_activation_height-height)
assert(get_bip9_status(self.nodes[0], 'csv')['status'] == 'active')
sync_blocks(self.nodes)
diff --git a/test/functional/bumpfee.py b/test/functional/bumpfee.py
index 8f75e9ed4d..172e414188 100755
--- a/test/functional/bumpfee.py
+++ b/test/functional/bumpfee.py
@@ -2,7 +2,17 @@
# Copyright (c) 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.
-"""Test the bumpfee RPC."""
+"""Test the bumpfee RPC.
+
+Verifies that the bumpfee RPC creates replacement transactions successfully when
+its preconditions are met, and returns appropriate errors in other cases.
+
+This module consists of around a dozen individual test cases implemented in the
+top-level functions named as test_<test_case_description>. The test functions
+can be disabled or reordered if needed for debugging. If new test cases are
+added in the the future, they should try to follow the same convention and not
+make assumptions about execution order.
+"""
from segwit import send_to_witness
from test_framework.test_framework import BitcoinTestFramework
@@ -57,13 +67,13 @@ class BumpFeeTest(BitcoinTestFramework):
self.log.info("Running tests")
dest_address = peer_node.getnewaddress()
- test_small_output_fails(rbf_node, dest_address)
- test_dust_to_fee(rbf_node, dest_address)
test_simple_bumpfee_succeeds(rbf_node, peer_node, dest_address)
test_segwit_bumpfee_succeeds(rbf_node, dest_address)
test_nonrbf_bumpfee_fails(peer_node, dest_address)
test_notmine_bumpfee_fails(rbf_node, peer_node, dest_address)
test_bumpfee_with_descendant_fails(rbf_node, rbf_node_address, dest_address)
+ test_small_output_fails(rbf_node, dest_address)
+ test_dust_to_fee(rbf_node, dest_address)
test_settxfee(rbf_node, dest_address)
test_rebumping(rbf_node, dest_address)
test_rebumping_not_replaceable(rbf_node, dest_address)
@@ -74,7 +84,7 @@ class BumpFeeTest(BitcoinTestFramework):
def test_simple_bumpfee_succeeds(rbf_node, peer_node, dest_address):
- rbfid = create_fund_sign_send(rbf_node, {dest_address: 0.00090000})
+ rbfid = spend_one_input(rbf_node, dest_address)
rbftx = rbf_node.gettransaction(rbfid)
sync_mempools((rbf_node, peer_node))
assert rbfid in rbf_node.getrawmempool() and rbfid in peer_node.getrawmempool()
@@ -115,7 +125,7 @@ def test_segwit_bumpfee_succeeds(rbf_node, dest_address):
'vout': 0,
"sequence": BIP125_SEQUENCE_NUMBER
}], {dest_address: Decimal("0.0005"),
- get_change_address(rbf_node): Decimal("0.0003")})
+ rbf_node.getrawchangeaddress(): Decimal("0.0003")})
rbfsigned = rbf_node.signrawtransaction(rbfraw)
rbfid = rbf_node.sendrawtransaction(rbfsigned["hex"])
assert rbfid in rbf_node.getrawmempool()
@@ -127,7 +137,7 @@ def test_segwit_bumpfee_succeeds(rbf_node, dest_address):
def test_nonrbf_bumpfee_fails(peer_node, dest_address):
# cannot replace a non RBF transaction (from node which did not enable RBF)
- not_rbfid = create_fund_sign_send(peer_node, {dest_address: 0.00090000})
+ not_rbfid = peer_node.sendtoaddress(dest_address, Decimal("0.00090000"))
assert_raises_jsonrpc(-4, "not BIP 125 replaceable", peer_node.bumpfee, not_rbfid)
@@ -155,7 +165,7 @@ def test_notmine_bumpfee_fails(rbf_node, peer_node, dest_address):
def test_bumpfee_with_descendant_fails(rbf_node, rbf_node_address, dest_address):
# cannot bump fee if the transaction has a descendant
# parent is send-to-self, so we don't have to check which output is change when creating the child tx
- parent_id = create_fund_sign_send(rbf_node, {rbf_node_address: 0.00050000})
+ parent_id = spend_one_input(rbf_node, rbf_node_address)
tx = rbf_node.createrawtransaction([{"txid": parent_id, "vout": 0}], {dest_address: 0.00020000})
tx = rbf_node.signrawtransaction(tx)
txid = rbf_node.sendrawtransaction(tx["hex"])
@@ -164,58 +174,50 @@ def test_bumpfee_with_descendant_fails(rbf_node, rbf_node_address, dest_address)
def test_small_output_fails(rbf_node, dest_address):
# cannot bump fee with a too-small output
- rbfid = spend_one_input(rbf_node,
- Decimal("0.00100000"),
- {dest_address: 0.00080000,
- get_change_address(rbf_node): Decimal("0.00010000")})
- rbf_node.bumpfee(rbfid, {"totalFee": 20000})
+ rbfid = spend_one_input(rbf_node, dest_address)
+ rbf_node.bumpfee(rbfid, {"totalFee": 50000})
- rbfid = spend_one_input(rbf_node,
- Decimal("0.00100000"),
- {dest_address: 0.00080000,
- get_change_address(rbf_node): Decimal("0.00010000")})
- assert_raises_jsonrpc(-4, "Change output is too small", rbf_node.bumpfee, rbfid, {"totalFee": 20001})
+ rbfid = spend_one_input(rbf_node, dest_address)
+ assert_raises_jsonrpc(-4, "Change output is too small", rbf_node.bumpfee, rbfid, {"totalFee": 50001})
def test_dust_to_fee(rbf_node, dest_address):
# check that if output is reduced to dust, it will be converted to fee
- # the bumped tx sets fee=9900, but it converts to 10,000
- rbfid = spend_one_input(rbf_node,
- Decimal("0.00100000"),
- {dest_address: 0.00080000,
- get_change_address(rbf_node): Decimal("0.00010000")})
+ # the bumped tx sets fee=49,900, but it converts to 50,000
+ rbfid = spend_one_input(rbf_node, dest_address)
fulltx = rbf_node.getrawtransaction(rbfid, 1)
- bumped_tx = rbf_node.bumpfee(rbfid, {"totalFee": 19900})
+ bumped_tx = rbf_node.bumpfee(rbfid, {"totalFee": 49900})
full_bumped_tx = rbf_node.getrawtransaction(bumped_tx["txid"], 1)
- assert_equal(bumped_tx["fee"], Decimal("0.00020000"))
+ assert_equal(bumped_tx["fee"], Decimal("0.00050000"))
assert_equal(len(fulltx["vout"]), 2)
assert_equal(len(full_bumped_tx["vout"]), 1) #change output is eliminated
def test_settxfee(rbf_node, dest_address):
# check that bumpfee reacts correctly to the use of settxfee (paytxfee)
- # increase feerate by 2.5x, test that fee increased at least 2x
- rbf_node.settxfee(Decimal("0.00001000"))
- rbfid = create_fund_sign_send(rbf_node, {dest_address: 0.00090000})
+ rbfid = spend_one_input(rbf_node, dest_address)
rbftx = rbf_node.gettransaction(rbfid)
- rbf_node.settxfee(Decimal("0.00002500"))
+ requested_feerate = Decimal("0.00025000")
+ rbf_node.settxfee(requested_feerate)
bumped_tx = rbf_node.bumpfee(rbfid)
- assert bumped_tx["fee"] > 2 * abs(rbftx["fee"])
+ actual_feerate = bumped_tx["fee"] * 1000 / rbf_node.getrawtransaction(bumped_tx["txid"], True)["size"]
+ # Assert that the difference between the requested feerate and the actual
+ # feerate of the bumped transaction is small.
+ assert_greater_than(Decimal("0.00001000"), abs(requested_feerate - actual_feerate))
rbf_node.settxfee(Decimal("0.00000000")) # unset paytxfee
def test_rebumping(rbf_node, dest_address):
# check that re-bumping the original tx fails, but bumping the bumper succeeds
- rbf_node.settxfee(Decimal("0.00001000"))
- rbfid = create_fund_sign_send(rbf_node, {dest_address: 0.00090000})
- bumped = rbf_node.bumpfee(rbfid, {"totalFee": 1000})
- assert_raises_jsonrpc(-4, "already bumped", rbf_node.bumpfee, rbfid, {"totalFee": 2000})
- rbf_node.bumpfee(bumped["txid"], {"totalFee": 2000})
+ rbfid = spend_one_input(rbf_node, dest_address)
+ bumped = rbf_node.bumpfee(rbfid, {"totalFee": 2000})
+ assert_raises_jsonrpc(-4, "already bumped", rbf_node.bumpfee, rbfid, {"totalFee": 3000})
+ rbf_node.bumpfee(bumped["txid"], {"totalFee": 3000})
def test_rebumping_not_replaceable(rbf_node, dest_address):
# check that re-bumping a non-replaceable bump tx fails
- rbfid = create_fund_sign_send(rbf_node, {dest_address: 0.00090000})
+ rbfid = spend_one_input(rbf_node, dest_address)
bumped = rbf_node.bumpfee(rbfid, {"totalFee": 10000, "replaceable": False})
assert_raises_jsonrpc(-4, "Transaction is not BIP 125 replaceable", rbf_node.bumpfee, bumped["txid"],
{"totalFee": 20000})
@@ -223,7 +225,7 @@ def test_rebumping_not_replaceable(rbf_node, dest_address):
def test_unconfirmed_not_spendable(rbf_node, rbf_node_address):
# check that unconfirmed outputs from bumped transactions are not spendable
- rbfid = create_fund_sign_send(rbf_node, {rbf_node_address: 0.00090000})
+ rbfid = spend_one_input(rbf_node, rbf_node_address)
rbftx = rbf_node.gettransaction(rbfid)["hex"]
assert rbfid in rbf_node.getrawmempool()
bumpid = rbf_node.bumpfee(rbfid)["txid"]
@@ -258,7 +260,7 @@ def test_unconfirmed_not_spendable(rbf_node, rbf_node_address):
def test_bumpfee_metadata(rbf_node, dest_address):
- rbfid = rbf_node.sendtoaddress(dest_address, 0.00090000, "comment value", "to value")
+ rbfid = rbf_node.sendtoaddress(dest_address, Decimal("0.00100000"), "comment value", "to value")
bumped_tx = rbf_node.bumpfee(rbfid)
bumped_wtx = rbf_node.gettransaction(bumped_tx["txid"])
assert_equal(bumped_wtx["comment"], "comment value")
@@ -266,43 +268,23 @@ def test_bumpfee_metadata(rbf_node, dest_address):
def test_locked_wallet_fails(rbf_node, dest_address):
- rbfid = create_fund_sign_send(rbf_node, {dest_address: 0.00090000})
+ rbfid = spend_one_input(rbf_node, dest_address)
rbf_node.walletlock()
assert_raises_jsonrpc(-13, "Please enter the wallet passphrase with walletpassphrase first.",
rbf_node.bumpfee, rbfid)
-def create_fund_sign_send(node, outputs):
- rawtx = node.createrawtransaction([], outputs)
- fundtx = node.fundrawtransaction(rawtx)
- signedtx = node.signrawtransaction(fundtx["hex"])
- txid = node.sendrawtransaction(signedtx["hex"])
- return txid
-
-
-def spend_one_input(node, input_amount, outputs):
- input = dict(sequence=BIP125_SEQUENCE_NUMBER, **next(u for u in node.listunspent() if u["amount"] == input_amount))
- rawtx = node.createrawtransaction([input], outputs)
+def spend_one_input(node, dest_address):
+ tx_input = dict(
+ sequence=BIP125_SEQUENCE_NUMBER, **next(u for u in node.listunspent() if u["amount"] == Decimal("0.00100000")))
+ rawtx = node.createrawtransaction(
+ [tx_input], {dest_address: Decimal("0.00050000"),
+ node.getrawchangeaddress(): Decimal("0.00049000")})
signedtx = node.signrawtransaction(rawtx)
txid = node.sendrawtransaction(signedtx["hex"])
return txid
-def get_change_address(node):
- """Get a wallet change address.
-
- There is no wallet RPC to access unused change addresses, so this creates a
- dummy transaction, calls fundrawtransaction to give add an input and change
- output, then returns the change address."""
- dest_address = node.getnewaddress()
- dest_amount = Decimal("0.00012345")
- rawtx = node.createrawtransaction([], {dest_address: dest_amount})
- fundtx = node.fundrawtransaction(rawtx)
- info = node.decoderawtransaction(fundtx["hex"])
- return next(address for out in info["vout"]
- if out["value"] != dest_amount for address in out["scriptPubKey"]["addresses"])
-
-
def submit_block_with_tx(node, tx):
ctx = CTransaction()
ctx.deserialize(io.BytesIO(hex_str_to_bytes(tx)))
diff --git a/test/functional/fundrawtransaction.py b/test/functional/fundrawtransaction.py
index fd330ef277..3bfc05d37b 100755
--- a/test/functional/fundrawtransaction.py
+++ b/test/functional/fundrawtransaction.py
@@ -322,8 +322,8 @@ class RawTransactionsTest(BitcoinTestFramework):
#compare fee of a standard pubkeyhash transaction
inputs = []
outputs = {self.nodes[1].getnewaddress():1.1}
- rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
- fundedTx = self.nodes[0].fundrawtransaction(rawTx)
+ rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
+ fundedTx = self.nodes[0].fundrawtransaction(rawtx)
#create same transaction over sendtoaddress
txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1.1)
@@ -338,8 +338,8 @@ class RawTransactionsTest(BitcoinTestFramework):
#compare fee of a standard pubkeyhash transaction with multiple outputs
inputs = []
outputs = {self.nodes[1].getnewaddress():1.1,self.nodes[1].getnewaddress():1.2,self.nodes[1].getnewaddress():0.1,self.nodes[1].getnewaddress():1.3,self.nodes[1].getnewaddress():0.2,self.nodes[1].getnewaddress():0.3}
- rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
- fundedTx = self.nodes[0].fundrawtransaction(rawTx)
+ rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
+ fundedTx = self.nodes[0].fundrawtransaction(rawtx)
#create same transaction over sendtoaddress
txId = self.nodes[0].sendmany("", outputs)
signedFee = self.nodes[0].getrawmempool(True)[txId]['fee']
@@ -364,8 +364,8 @@ class RawTransactionsTest(BitcoinTestFramework):
inputs = []
outputs = {mSigObj:1.1}
- rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
- fundedTx = self.nodes[0].fundrawtransaction(rawTx)
+ rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
+ fundedTx = self.nodes[0].fundrawtransaction(rawtx)
#create same transaction over sendtoaddress
txId = self.nodes[0].sendtoaddress(mSigObj, 1.1)
@@ -397,8 +397,8 @@ class RawTransactionsTest(BitcoinTestFramework):
inputs = []
outputs = {mSigObj:1.1}
- rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
- fundedTx = self.nodes[0].fundrawtransaction(rawTx)
+ rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
+ fundedTx = self.nodes[0].fundrawtransaction(rawtx)
#create same transaction over sendtoaddress
txId = self.nodes[0].sendtoaddress(mSigObj, 1.1)
@@ -432,8 +432,8 @@ class RawTransactionsTest(BitcoinTestFramework):
oldBalance = self.nodes[1].getbalance()
inputs = []
outputs = {self.nodes[1].getnewaddress():1.1}
- rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
- fundedTx = self.nodes[2].fundrawtransaction(rawTx)
+ rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
+ fundedTx = self.nodes[2].fundrawtransaction(rawtx)
signedTx = self.nodes[2].signrawtransaction(fundedTx['hex'])
txId = self.nodes[2].sendrawtransaction(signedTx['hex'])
@@ -469,10 +469,10 @@ class RawTransactionsTest(BitcoinTestFramework):
self.nodes[1].getnewaddress()
inputs = []
outputs = {self.nodes[0].getnewaddress():1.1}
- rawTx = self.nodes[1].createrawtransaction(inputs, outputs)
+ rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
# fund a transaction that requires a new key for the change output
# creating the key must be impossible because the wallet is locked
- assert_raises_jsonrpc(-4, "Insufficient funds", self.nodes[1].fundrawtransaction, rawtx)
+ assert_raises_jsonrpc(-4, "Keypool ran out, please call keypoolrefill first", self.nodes[1].fundrawtransaction, rawtx)
#refill the keypool
self.nodes[1].walletpassphrase("test", 100)
@@ -484,8 +484,8 @@ class RawTransactionsTest(BitcoinTestFramework):
inputs = []
outputs = {self.nodes[0].getnewaddress():1.1}
- rawTx = self.nodes[1].createrawtransaction(inputs, outputs)
- fundedTx = self.nodes[1].fundrawtransaction(rawTx)
+ rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
+ fundedTx = self.nodes[1].fundrawtransaction(rawtx)
#now we need to unlock
self.nodes[1].walletpassphrase("test", 600)
@@ -516,8 +516,8 @@ class RawTransactionsTest(BitcoinTestFramework):
#fund a tx with ~20 small inputs
inputs = []
outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04}
- rawTx = self.nodes[1].createrawtransaction(inputs, outputs)
- fundedTx = self.nodes[1].fundrawtransaction(rawTx)
+ rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
+ fundedTx = self.nodes[1].fundrawtransaction(rawtx)
#create same transaction over sendtoaddress
txId = self.nodes[1].sendmany("", outputs)
@@ -548,8 +548,8 @@ class RawTransactionsTest(BitcoinTestFramework):
inputs = []
outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04}
- rawTx = self.nodes[1].createrawtransaction(inputs, outputs)
- fundedTx = self.nodes[1].fundrawtransaction(rawTx)
+ rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
+ fundedTx = self.nodes[1].fundrawtransaction(rawtx)
fundedAndSignedTx = self.nodes[1].signrawtransaction(fundedTx['hex'])
txId = self.nodes[1].sendrawtransaction(fundedAndSignedTx['hex'])
self.sync_all()
@@ -691,7 +691,6 @@ class RawTransactionsTest(BitcoinTestFramework):
inputs = []
outputs = {self.nodes[2].getnewaddress(): value for value in (1.0, 1.1, 1.2, 1.3)}
- keys = list(outputs.keys())
rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
result = [self.nodes[3].fundrawtransaction(rawtx),
diff --git a/test/functional/import-rescan.py b/test/functional/import-rescan.py
index 0218a46168..5be095e62d 100755
--- a/test/functional/import-rescan.py
+++ b/test/functional/import-rescan.py
@@ -22,7 +22,6 @@ happened previously.
from test_framework.authproxy import JSONRPCException
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (start_nodes, connect_nodes, sync_blocks, assert_equal, set_node_times)
-from decimal import Decimal
import collections
import enum
diff --git a/test/functional/multi_rpc.py b/test/functional/multi_rpc.py
index 3b74bf1c46..a9701c548b 100755
--- a/test/functional/multi_rpc.py
+++ b/test/functional/multi_rpc.py
@@ -41,11 +41,9 @@ class HTTPBasicsTest (BitcoinTestFramework):
authpair = url.username + ':' + url.password
#New authpair generated via share/rpcuser tool
- rpcauth = "rpcauth=rt:93648e835a54c573682c2eb19f882535$7681e9c5b74bdd85e78166031d2058e1069b3ed7ed967c93fc63abba06f31144"
password = "cA773lm788buwYe4g4WT+05pKyNruVKjQ25x3n0DQcM="
#Second authpair with different username
- rpcauth2 = "rpcauth=rt2:f8607b1a88861fac29dfccf9b52ff9f$ff36a0c23c8c62b4846112e50fa888416e94c17bfd4c42f88fd8f55ec6a3137e"
password2 = "8/F3uMDw4KSEbw96U3CA1C4X05dkHDN2BPFjTgZW4KI="
authpairnew = "rt:"+password
diff --git a/test/functional/rawtransactions.py b/test/functional/rawtransactions.py
index 0374d8984a..d4c684136c 100755
--- a/test/functional/rawtransactions.py
+++ b/test/functional/rawtransactions.py
@@ -104,7 +104,6 @@ class RawTransactionsTest(BitcoinTestFramework):
txId = self.nodes[0].sendtoaddress(mSigObj, 2.2)
decTx = self.nodes[0].gettransaction(txId)
rawTx = self.nodes[0].decoderawtransaction(decTx['hex'])
- sPK = rawTx['vout'][0]['scriptPubKey']['hex']
self.sync_all()
self.nodes[0].generate(1)
self.sync_all()
diff --git a/test/functional/rpcbind_test.py b/test/functional/rpcbind_test.py
index 8720a345ce..efc36481d1 100755
--- a/test/functional/rpcbind_test.py
+++ b/test/functional/rpcbind_test.py
@@ -4,6 +4,9 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test running bitcoind with the -rpcbind and -rpcallowip options."""
+import socket
+import sys
+
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from test_framework.netutil import *
@@ -52,7 +55,9 @@ class RPCBindTest(BitcoinTestFramework):
def run_test(self):
# due to OS-specific network stats queries, this test works only on Linux
- assert(sys.platform.startswith('linux'))
+ if not sys.platform.startswith('linux'):
+ self.log.warning("This test can only be run on linux. Skipping test.")
+ sys.exit(self.TEST_EXIT_SKIPPED)
# find the first non-loopback interface for testing
non_loopback_ip = None
for name,ip in all_interfaces():
@@ -60,7 +65,16 @@ class RPCBindTest(BitcoinTestFramework):
non_loopback_ip = ip
break
if non_loopback_ip is None:
- assert(not 'This test requires at least one non-loopback IPv4 interface')
+ self.log.warning("This test requires at least one non-loopback IPv4 interface. Skipping test.")
+ sys.exit(self.TEST_EXIT_SKIPPED)
+ try:
+ s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
+ s.connect(("::1",1))
+ s.close
+ except OSError:
+ self.log.warning("This test requires IPv6 support. Skipping test.")
+ sys.exit(self.TEST_EXIT_SKIPPED)
+
self.log.info("Using interface %s for testing" % non_loopback_ip)
defaultport = rpc_port(0)
diff --git a/test/functional/segwit.py b/test/functional/segwit.py
index 5b1fba8eec..a1fffcb81a 100755
--- a/test/functional/segwit.py
+++ b/test/functional/segwit.py
@@ -6,11 +6,10 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
-from test_framework.mininode import sha256, ripemd160, CTransaction, CTxIn, COutPoint, CTxOut, COIN
+from test_framework.mininode import sha256, CTransaction, CTxIn, COutPoint, CTxOut, COIN, ToHex, FromHex
from test_framework.address import script_to_p2sh, key_to_p2pkh
-from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG, hash160, OP_TRUE
+from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG, OP_TRUE
from io import BytesIO
-from test_framework.mininode import ToHex, FromHex, COIN
NODE_0 = 0
NODE_1 = 1
diff --git a/test/functional/smartfees.py b/test/functional/smartfees.py
index 49f2df5c37..b7f4b86e7b 100755
--- a/test/functional/smartfees.py
+++ b/test/functional/smartfees.py
@@ -4,11 +4,10 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test fee estimation code."""
-from collections import OrderedDict
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from test_framework.script import CScript, OP_1, OP_DROP, OP_2, OP_HASH160, OP_EQUAL, hash160, OP_TRUE
-from test_framework.mininode import CTransaction, CTxIn, CTxOut, COutPoint, ToHex, FromHex, COIN
+from test_framework.mininode import CTransaction, CTxIn, CTxOut, COutPoint, ToHex, COIN
# Construct 2 trivial P2SH's and the ScriptSigs that spend them
# So we can create many many transactions without needing to spend
diff --git a/test/functional/test_framework/socks5.py b/test/functional/test_framework/socks5.py
index dd7624d454..a08b03ed24 100644
--- a/test/functional/test_framework/socks5.py
+++ b/test/functional/test_framework/socks5.py
@@ -5,7 +5,6 @@
"""Dummy Socks5 server for testing."""
import socket, threading, queue
-import traceback, sys
import logging
logger = logging.getLogger("TestFramework.socks5")
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
index fd2e803541..26a8aacb41 100755
--- a/test/functional/test_framework/test_framework.py
+++ b/test/functional/test_framework/test_framework.py
@@ -11,7 +11,6 @@ import sys
import shutil
import tempfile
import time
-import traceback
from .util import (
initialize_chain,
@@ -28,9 +27,12 @@ from .util import (
)
from .authproxy import JSONRPCException
-
class BitcoinTestFramework(object):
+ TEST_EXIT_PASSED = 0
+ TEST_EXIT_FAILED = 1
+ TEST_EXIT_SKIPPED = 77
+
def __init__(self):
self.num_nodes = 4
self.setup_clean_chain = False
@@ -183,11 +185,11 @@ class BitcoinTestFramework(object):
print("".join(deque(open(f), MAX_LINES_TO_PRINT)))
if success:
self.log.info("Tests successful")
- sys.exit(0)
+ sys.exit(self.TEST_EXIT_PASSED)
else:
self.log.error("Test failed. Test logging available at %s/test_framework.log", self.options.tmpdir)
logging.shutdown()
- sys.exit(1)
+ sys.exit(self.TEST_EXIT_FAILED)
def _start_logging(self):
# Add logger and logging handlers
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 12eb92028f..e8d8908b13 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -24,6 +24,9 @@ import subprocess
import tempfile
import re
+TEST_EXIT_PASSED = 0
+TEST_EXIT_SKIPPED = 77
+
BASE_SCRIPTS= [
# Scripts that are run by the travis build process.
# Longest test should go first, to favor running tests in parallel
@@ -87,7 +90,7 @@ BASE_SCRIPTS= [
ZMQ_SCRIPTS = [
# ZMQ test can only be run if bitcoin was built with zmq-enabled.
# call test_runner.py with -nozmq to explicitly exclude these tests.
- "zmq_test.py"]
+ 'zmq_test.py']
EXTENDED_SCRIPTS = [
# These tests are not run by the travis build process.
@@ -107,6 +110,7 @@ EXTENDED_SCRIPTS = [
'p2p-feefilter.py',
'rpcbind_test.py',
# vv Tests less than 30s vv
+ 'assumevalid.py',
'bip65-cltv.py',
'bip65-cltv-p2p.py',
'bipdersig-p2p.py',
@@ -203,9 +207,9 @@ def main():
sys.exit(0)
if args.help:
- # Print help for test_runner.py, then print help of the first script and exit.
+ # Print help for test_runner.py, then print help of the first script (with args removed) and exit.
parser.print_help()
- subprocess.check_call((config["environment"]["SRCDIR"] + '/test/functional/' + test_list[0]).split() + ['-h'])
+ subprocess.check_call([(config["environment"]["SRCDIR"] + '/test/functional/' + test_list[0].split()[0])] + ['-h'])
sys.exit(0)
run_tests(test_list, config["environment"]["SRCDIR"], config["environment"]["BUILDDIR"], config["environment"]["EXEEXT"], args.jobs, args.coverage, passon_args)
@@ -245,20 +249,20 @@ def run_tests(test_list, src_dir, build_dir, exeext, jobs=1, enable_coverage=Fal
job_queue = TestHandler(jobs, tests_dir, test_list, flags)
max_len_name = len(max(test_list, key=len))
- results = BOLD[1] + "%s | %s | %s\n\n" % ("TEST".ljust(max_len_name), "PASSED", "DURATION") + BOLD[0]
+ results = BOLD[1] + "%s | %s | %s\n\n" % ("TEST".ljust(max_len_name), "STATUS ", "DURATION") + BOLD[0]
for _ in range(len(test_list)):
- (name, stdout, stderr, passed, duration) = job_queue.get_next()
- all_passed = all_passed and passed
+ (name, stdout, stderr, status, duration) = job_queue.get_next()
+ all_passed = all_passed and status != "Failed"
time_sum += duration
print('\n' + BOLD[1] + name + BOLD[0] + ":")
- print('' if passed else stdout + '\n', end='')
+ print('' if status == "Passed" else stdout + '\n', end='')
print('' if stderr == '' else 'stderr:\n' + stderr + '\n', end='')
- print("Pass: %s%s%s, Duration: %s s\n" % (BOLD[1], passed, BOLD[0], duration))
+ print("Status: %s%s%s, Duration: %s s\n" % (BOLD[1], status, BOLD[0], duration))
- results += "%s | %s | %s s\n" % (name.ljust(max_len_name), str(passed).ljust(6), duration)
+ results += "%s | %s | %s s\n" % (name.ljust(max_len_name), status.ljust(7), duration)
- results += BOLD[1] + "\n%s | %s | %s s (accumulated)" % ("ALL".ljust(max_len_name), str(all_passed).ljust(6), time_sum) + BOLD[0]
+ results += BOLD[1] + "\n%s | %s | %s s (accumulated)" % ("ALL".ljust(max_len_name), str(all_passed).ljust(7), time_sum) + BOLD[0]
print(results)
print("\nRuntime: %s s" % (int(time.time() - time0)))
@@ -296,9 +300,10 @@ class TestHandler:
port_seed = ["--portseed={}".format(len(self.test_list) + self.portseed_offset)]
log_stdout = tempfile.SpooledTemporaryFile(max_size=2**16)
log_stderr = tempfile.SpooledTemporaryFile(max_size=2**16)
+ test_argv = t.split()
self.jobs.append((t,
time.time(),
- subprocess.Popen((self.tests_dir + t).split() + self.flags + port_seed,
+ subprocess.Popen([self.tests_dir + test_argv[0]] + test_argv[1:] + self.flags + port_seed,
universal_newlines=True,
stdout=log_stdout,
stderr=log_stderr),
@@ -315,10 +320,15 @@ class TestHandler:
log_out.seek(0), log_err.seek(0)
[stdout, stderr] = [l.read().decode('utf-8') for l in (log_out, log_err)]
log_out.close(), log_err.close()
- passed = stderr == "" and proc.returncode == 0
+ if proc.returncode == TEST_EXIT_PASSED and stderr == "":
+ status = "Passed"
+ elif proc.returncode == TEST_EXIT_SKIPPED:
+ status = "Skipped"
+ else:
+ status = "Failed"
self.num_running -= 1
self.jobs.remove(j)
- return name, stdout, stderr, passed, int(time.time() - time0)
+ return name, stdout, stderr, status, int(time.time() - time0)
print('.', end='', flush=True)
diff --git a/test/functional/zmq_test.py b/test/functional/zmq_test.py
index e6f18b0b93..9e27b46381 100755
--- a/test/functional/zmq_test.py
+++ b/test/functional/zmq_test.py
@@ -41,7 +41,6 @@ class ZMQTest (BitcoinTestFramework):
topic = msg[0]
assert_equal(topic, b"hashtx")
body = msg[1]
- nseq = msg[2]
msgSequence = struct.unpack('<I', msg[-1])[-1]
assert_equal(msgSequence, 0) #must be sequence 0 on hashtx