aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rwxr-xr-xtest/functional/feature_fee_estimation.py6
-rwxr-xr-xtest/functional/feature_taproot.py6
-rwxr-xr-xtest/functional/p2p_addr_relay.py37
-rwxr-xr-xtest/functional/p2p_compactblocks.py31
-rwxr-xr-xtest/functional/p2p_fingerprint.py5
-rwxr-xr-xtest/functional/p2p_invalid_messages.py9
-rwxr-xr-xtest/functional/p2p_leak.py19
-rwxr-xr-xtest/functional/p2p_timeouts.py6
-rwxr-xr-xtest/functional/rpc_estimatefee.py2
-rwxr-xr-xtest/functional/rpc_fundrawtransaction.py4
-rwxr-xr-xtest/functional/rpc_psbt.py4
-rwxr-xr-xtest/functional/rpc_rawtransaction.py7
-rwxr-xr-xtest/functional/rpc_signrawtransaction.py14
-rwxr-xr-xtest/functional/rpc_txoutproof.py2
-rwxr-xr-xtest/functional/rpc_users.py11
-rwxr-xr-xtest/functional/test_framework/messages.py1
-rwxr-xr-xtest/functional/test_framework/p2p.py2
-rw-r--r--test/functional/test_framework/script.py24
-rwxr-xr-xtest/functional/test_framework/test_node.py19
-rwxr-xr-xtest/functional/wallet_balance.py2
-rwxr-xr-xtest/functional/wallet_basic.py29
-rwxr-xr-xtest/functional/wallet_bumpfee.py2
-rwxr-xr-xtest/functional/wallet_importmulti.py2
-rwxr-xr-xtest/functional/wallet_multiwallet.py2
-rwxr-xr-xtest/functional/wallet_resendwallettransactions.py1
-rwxr-xr-xtest/functional/wallet_send.py4
-rwxr-xr-xtest/fuzz/test_runner.py65
-rw-r--r--test/lint/README.md15
-rwxr-xr-xtest/lint/extended-lint-cppcheck.sh11
-rwxr-xr-xtest/lint/git-subtree-check.sh57
-rwxr-xr-xtest/lint/lint-circular-dependencies.sh1
-rw-r--r--test/sanitizer_suppressions/tsan1
32 files changed, 292 insertions, 109 deletions
diff --git a/test/functional/feature_fee_estimation.py b/test/functional/feature_fee_estimation.py
index 8a8a0c7614..8f522aee66 100755
--- a/test/functional/feature_fee_estimation.py
+++ b/test/functional/feature_fee_estimation.py
@@ -13,6 +13,7 @@ from test_framework.util import (
assert_equal,
assert_greater_than,
assert_greater_than_or_equal,
+ assert_raises_rpc_error,
satoshi_round,
)
@@ -262,6 +263,11 @@ class EstimateFeeTest(BitcoinTestFramework):
self.log.info("Final estimates after emptying mempools")
check_estimates(self.nodes[1], self.fees_per_kb)
+ self.log.info("Testing that fee estimation is disabled in blocksonly.")
+ self.restart_node(0, ["-blocksonly"])
+ assert_raises_rpc_error(-32603, "Fee estimation disabled",
+ self.nodes[0].estimatesmartfee, 2)
+
if __name__ == '__main__':
EstimateFeeTest().main()
diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py
index 0f0fe8a34a..6ee2b72c11 100755
--- a/test/functional/feature_taproot.py
+++ b/test/functional/feature_taproot.py
@@ -444,6 +444,8 @@ def make_spender(comment, *, tap=None, witv0=False, script=None, pkh=None, p2sh=
* standard: whether the (valid version of) spending is expected to be standard
* err_msg: a string with an expected error message for failure (or None, if not cared about)
* sigops_weight: the pre-taproot sigops weight consumed by a successful spend
+ * need_vin_vout_mismatch: whether this test requires being tested in a transaction input that has no corresponding
+ transaction output.
"""
conf = dict()
@@ -1442,6 +1444,10 @@ class TaprootTest(BitcoinTestFramework):
self.nodes[1].generate(101)
self.test_spenders(self.nodes[1], spenders_taproot_active(), input_counts=[1, 2, 2, 2, 2, 3])
+ # Re-connect nodes in case they have been disconnected
+ self.disconnect_nodes(0, 1)
+ self.connect_nodes(0, 1)
+
# Transfer value of the largest 500 coins to pre-taproot node.
addr = self.nodes[0].getnewaddress()
diff --git a/test/functional/p2p_addr_relay.py b/test/functional/p2p_addr_relay.py
index 80f262d0d3..91fbd722cf 100755
--- a/test/functional/p2p_addr_relay.py
+++ b/test/functional/p2p_addr_relay.py
@@ -19,8 +19,11 @@ from test_framework.util import (
)
import time
+# Keep this with length <= 10. Addresses from larger messages are not relayed.
ADDRS = []
-for i in range(10):
+num_ipv4_addrs = 10
+
+for i in range(num_ipv4_addrs):
addr = CAddress()
addr.time = int(time.time()) + i
addr.nServices = NODE_NETWORK | NODE_WITNESS
@@ -30,11 +33,15 @@ for i in range(10):
class AddrReceiver(P2PInterface):
+ num_ipv4_received = 0
+
def on_addr(self, message):
for addr in message.addrs:
assert_equal(addr.nServices, 9)
+ if not 8333 <= addr.port < 8343:
+ raise AssertionError("Invalid addr.port of {} (8333-8342 expected)".format(addr.port))
assert addr.ip.startswith('123.123.123.')
- assert (8333 <= addr.port < 8343)
+ self.num_ipv4_received += 1
class AddrTest(BitcoinTestFramework):
@@ -48,21 +55,33 @@ class AddrTest(BitcoinTestFramework):
msg = msg_addr()
self.log.info('Send too-large addr message')
- msg.addrs = ADDRS * 101
+ msg.addrs = ADDRS * 101 # more than 1000 addresses in one message
with self.nodes[0].assert_debug_log(['addr message size = 1010']):
addr_source.send_and_ping(msg)
self.log.info('Check that addr message content is relayed and added to addrman')
- addr_receiver = self.nodes[0].add_p2p_connection(AddrReceiver())
+ num_receivers = 7
+ receivers = []
+ for _ in range(num_receivers):
+ receivers.append(self.nodes[0].add_p2p_connection(AddrReceiver()))
msg.addrs = ADDRS
- with self.nodes[0].assert_debug_log([
- 'Added 10 addresses from 127.0.0.1: 0 tried',
+ with self.nodes[0].assert_debug_log(
+ [
+ 'Added {} addresses from 127.0.0.1: 0 tried'.format(num_ipv4_addrs),
'received: addr (301 bytes) peer=0',
- 'sending addr (301 bytes) peer=1',
- ]):
+ ]
+ ):
addr_source.send_and_ping(msg)
self.nodes[0].setmocktime(int(time.time()) + 30 * 60)
- addr_receiver.sync_with_ping()
+ for receiver in receivers:
+ receiver.sync_with_ping()
+
+ total_ipv4_received = sum(r.num_ipv4_received for r in receivers)
+
+ # Every IPv4 address must be relayed to two peers, other than the
+ # originating node (addr_source).
+ ipv4_branching_factor = 2
+ assert_equal(total_ipv4_received, num_ipv4_addrs * ipv4_branching_factor)
if __name__ == '__main__':
diff --git a/test/functional/p2p_compactblocks.py b/test/functional/p2p_compactblocks.py
index 611bffb25f..9a9df73049 100755
--- a/test/functional/p2p_compactblocks.py
+++ b/test/functional/p2p_compactblocks.py
@@ -764,6 +764,34 @@ class CompactBlocksTest(BitcoinTestFramework):
stalling_peer.send_and_ping(msg)
assert_equal(int(node.getbestblockhash(), 16), block.sha256)
+ def test_highbandwidth_mode_states_via_getpeerinfo(self):
+ # create new p2p connection for a fresh state w/o any prior sendcmpct messages sent
+ hb_test_node = self.nodes[0].add_p2p_connection(TestP2PConn(cmpct_version=2))
+
+ # assert the RPC getpeerinfo boolean fields `bip152_hb_{to, from}`
+ # match the given parameters for the last peer of a given node
+ def assert_highbandwidth_states(node, hb_to, hb_from):
+ peerinfo = node.getpeerinfo()[-1]
+ assert_equal(peerinfo['bip152_hb_to'], hb_to)
+ assert_equal(peerinfo['bip152_hb_from'], hb_from)
+
+ # initially, neither node has selected the other peer as high-bandwidth yet
+ assert_highbandwidth_states(self.nodes[0], hb_to=False, hb_from=False)
+
+ # peer requests high-bandwidth mode by sending sendcmpct(1)
+ hb_test_node.send_and_ping(msg_sendcmpct(announce=True, version=2))
+ assert_highbandwidth_states(self.nodes[0], hb_to=False, hb_from=True)
+
+ # peer generates a block and sends it to node, which should
+ # select the peer as high-bandwidth (up to 3 peers according to BIP 152)
+ block = self.build_block_on_tip(self.nodes[0])
+ hb_test_node.send_and_ping(msg_block(block))
+ assert_highbandwidth_states(self.nodes[0], hb_to=True, hb_from=True)
+
+ # peer requests low-bandwidth mode by sending sendcmpct(0)
+ hb_test_node.send_and_ping(msg_sendcmpct(announce=False, version=2))
+ assert_highbandwidth_states(self.nodes[0], hb_to=True, hb_from=False)
+
def run_test(self):
# Get the nodes out of IBD
self.nodes[0].generate(1)
@@ -822,6 +850,9 @@ class CompactBlocksTest(BitcoinTestFramework):
self.log.info("Testing invalid index in cmpctblock message...")
self.test_invalid_cmpctblock_message()
+ self.log.info("Testing high-bandwidth mode states via getpeerinfo...")
+ self.test_highbandwidth_mode_states_via_getpeerinfo()
+
if __name__ == '__main__':
CompactBlocksTest().main()
diff --git a/test/functional/p2p_fingerprint.py b/test/functional/p2p_fingerprint.py
index f60eba2dbf..9614ab6872 100755
--- a/test/functional/p2p_fingerprint.py
+++ b/test/functional/p2p_fingerprint.py
@@ -98,9 +98,9 @@ class P2PFingerprintTest(BitcoinTestFramework):
# Longest chain is extended so stale is much older than chain tip
self.nodes[0].setmocktime(0)
- self.nodes[0].generatetoaddress(1, self.nodes[0].get_deterministic_priv_key().address)
+ block_hash = int(self.nodes[0].generatetoaddress(1, self.nodes[0].get_deterministic_priv_key().address)[-1], 16)
assert_equal(self.nodes[0].getblockcount(), 14)
- node0.sync_with_ping()
+ node0.wait_for_block(block_hash, timeout=3)
# Request for very old stale block should now fail
with p2p_lock:
@@ -128,5 +128,6 @@ class P2PFingerprintTest(BitcoinTestFramework):
self.send_header_request(block_hash, node0)
node0.wait_for_header(hex(block_hash), timeout=3)
+
if __name__ == '__main__':
P2PFingerprintTest().main()
diff --git a/test/functional/p2p_invalid_messages.py b/test/functional/p2p_invalid_messages.py
index db72a361d9..c0b3c2cb12 100755
--- a/test/functional/p2p_invalid_messages.py
+++ b/test/functional/p2p_invalid_messages.py
@@ -18,6 +18,7 @@ from test_framework.messages import (
msg_inv,
msg_ping,
MSG_TX,
+ msg_version,
ser_string,
)
from test_framework.p2p import (
@@ -60,6 +61,7 @@ class InvalidMessagesTest(BitcoinTestFramework):
def run_test(self):
self.test_buffer()
+ self.test_duplicate_version_msg()
self.test_magic_bytes()
self.test_checksum()
self.test_size()
@@ -92,6 +94,13 @@ class InvalidMessagesTest(BitcoinTestFramework):
conn.sync_with_ping(timeout=1)
self.nodes[0].disconnect_p2ps()
+ def test_duplicate_version_msg(self):
+ self.log.info("Test duplicate version message is ignored")
+ conn = self.nodes[0].add_p2p_connection(P2PDataStore())
+ with self.nodes[0].assert_debug_log(['redundant version message from peer']):
+ conn.send_and_ping(msg_version())
+ self.nodes[0].disconnect_p2ps()
+
def test_magic_bytes(self):
self.log.info("Test message with invalid magic bytes disconnects peer")
conn = self.nodes[0].add_p2p_connection(P2PDataStore())
diff --git a/test/functional/p2p_leak.py b/test/functional/p2p_leak.py
index 4b32d60db0..ca8bf908a9 100755
--- a/test/functional/p2p_leak.py
+++ b/test/functional/p2p_leak.py
@@ -24,8 +24,6 @@ from test_framework.util import (
assert_greater_than_or_equal,
)
-DISCOURAGEMENT_THRESHOLD = 100
-
class LazyPeer(P2PInterface):
def __init__(self):
@@ -93,27 +91,16 @@ class P2PLeakTest(BitcoinTestFramework):
self.num_nodes = 1
def run_test(self):
- # Peer that never sends a version. We will send a bunch of messages
- # from this peer anyway and verify eventual disconnection.
- no_version_disconnect_peer = self.nodes[0].add_p2p_connection(
- LazyPeer(), send_version=False, wait_for_verack=False)
-
# Another peer that never sends a version, nor any other messages. It shouldn't receive anything from the node.
no_version_idle_peer = self.nodes[0].add_p2p_connection(LazyPeer(), send_version=False, wait_for_verack=False)
# Peer that sends a version but not a verack.
no_verack_idle_peer = self.nodes[0].add_p2p_connection(NoVerackIdlePeer(), wait_for_verack=False)
- # Send enough ping messages (any non-version message will do) prior to sending
- # version to reach the peer discouragement threshold. This should get us disconnected.
- for _ in range(DISCOURAGEMENT_THRESHOLD):
- no_version_disconnect_peer.send_message(msg_ping())
-
# Wait until we got the verack in response to the version. Though, don't wait for the node to receive the
# verack, since we never sent one
no_verack_idle_peer.wait_for_verack()
- no_version_disconnect_peer.wait_until(lambda: no_version_disconnect_peer.ever_connected, check_connected=False)
no_version_idle_peer.wait_until(lambda: no_version_idle_peer.ever_connected)
no_verack_idle_peer.wait_until(lambda: no_verack_idle_peer.version_received)
@@ -123,13 +110,9 @@ class P2PLeakTest(BitcoinTestFramework):
#Give the node enough time to possibly leak out a message
time.sleep(5)
- # Expect this peer to be disconnected for misbehavior
- assert not no_version_disconnect_peer.is_connected
-
self.nodes[0].disconnect_p2ps()
# Make sure no unexpected messages came in
- assert no_version_disconnect_peer.unexpected_msg == False
assert no_version_idle_peer.unexpected_msg == False
assert no_verack_idle_peer.unexpected_msg == False
@@ -148,7 +131,7 @@ class P2PLeakTest(BitcoinTestFramework):
p2p_old_peer = self.nodes[0].add_p2p_connection(P2PInterface(), send_version=False, wait_for_verack=False)
old_version_msg = msg_version()
old_version_msg.nVersion = 31799
- with self.nodes[0].assert_debug_log(['peer=4 using obsolete version 31799; disconnecting']):
+ with self.nodes[0].assert_debug_log(['peer=3 using obsolete version 31799; disconnecting']):
p2p_old_peer.send_message(old_version_msg)
p2p_old_peer.wait_for_disconnect()
diff --git a/test/functional/p2p_timeouts.py b/test/functional/p2p_timeouts.py
index ce12ce26ce..47832b04bf 100755
--- a/test/functional/p2p_timeouts.py
+++ b/test/functional/p2p_timeouts.py
@@ -57,8 +57,10 @@ class TimeoutsTest(BitcoinTestFramework):
assert no_version_node.is_connected
assert no_send_node.is_connected
- no_verack_node.send_message(msg_ping())
- no_version_node.send_message(msg_ping())
+ with self.nodes[0].assert_debug_log(['Unsupported message "ping" prior to verack from peer=0']):
+ no_verack_node.send_message(msg_ping())
+ with self.nodes[0].assert_debug_log(['non-version message before version handshake. Message "ping" from peer=1']):
+ no_version_node.send_message(msg_ping())
sleep(1)
diff --git a/test/functional/rpc_estimatefee.py b/test/functional/rpc_estimatefee.py
index 3b76c7dd1e..81862ac69e 100755
--- a/test/functional/rpc_estimatefee.py
+++ b/test/functional/rpc_estimatefee.py
@@ -41,6 +41,8 @@ class EstimateFeeTest(BitcoinTestFramework):
self.nodes[0].estimatesmartfee(1)
# self.nodes[0].estimatesmartfee(1, None)
self.nodes[0].estimatesmartfee(1, 'ECONOMICAL')
+ self.nodes[0].estimatesmartfee(1, 'unset')
+ self.nodes[0].estimatesmartfee(1, 'conservative')
self.nodes[0].estimaterawfee(1)
self.nodes[0].estimaterawfee(1, None)
diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py
index 8ee0ecab0a..569471dc87 100755
--- a/test/functional/rpc_fundrawtransaction.py
+++ b/test/functional/rpc_fundrawtransaction.py
@@ -717,10 +717,10 @@ class RawTransactionsTest(BitcoinTestFramework):
result = node.fundrawtransaction(rawtx) # uses self.min_relay_tx_fee (set by settxfee)
btc_kvb_to_sat_vb = 100000 # (1e5)
- result1 = node.fundrawtransaction(rawtx, {"fee_rate": 2 * btc_kvb_to_sat_vb * self.min_relay_tx_fee})
+ result1 = node.fundrawtransaction(rawtx, {"fee_rate": str(2 * btc_kvb_to_sat_vb * self.min_relay_tx_fee)})
result2 = node.fundrawtransaction(rawtx, {"feeRate": 2 * self.min_relay_tx_fee})
result3 = node.fundrawtransaction(rawtx, {"fee_rate": 10 * btc_kvb_to_sat_vb * self.min_relay_tx_fee})
- result4 = node.fundrawtransaction(rawtx, {"feeRate": 10 * self.min_relay_tx_fee})
+ result4 = node.fundrawtransaction(rawtx, {"feeRate": str(10 * self.min_relay_tx_fee)})
# Test that funding non-standard "zero-fee" transactions is valid.
result5 = self.nodes[3].fundrawtransaction(rawtx, {"fee_rate": 0})
result6 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 0})
diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py
index 5840801b00..b364077a9a 100755
--- a/test/functional/rpc_psbt.py
+++ b/test/functional/rpc_psbt.py
@@ -190,11 +190,11 @@ class PSBTTest(BitcoinTestFramework):
self.log.info("Test walletcreatefundedpsbt fee rate of 10000 sat/vB and 0.1 BTC/kvB produces a total fee at or slightly below -maxtxfee (~0.05290000)")
res1 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"fee_rate": 10000, "add_inputs": True})
assert_approx(res1["fee"], 0.055, 0.005)
- res2 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": 0.1, "add_inputs": True})
+ res2 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": "0.1", "add_inputs": True})
assert_approx(res2["fee"], 0.055, 0.005)
self.log.info("Test min fee rate checks with walletcreatefundedpsbt are bypassed, e.g. a fee_rate under 1 sat/vB is allowed")
- res3 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"fee_rate": 0.99999999, "add_inputs": True})
+ res3 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"fee_rate": "0.99999999", "add_inputs": True})
assert_approx(res3["fee"], 0.00000381, 0.0000001)
res4 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": 0.00000999, "add_inputs": True})
assert_approx(res4["fee"], 0.00000381, 0.0000001)
diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py
index 554c30c0d2..60e66a27c9 100755
--- a/test/functional/rpc_rawtransaction.py
+++ b/test/functional/rpc_rawtransaction.py
@@ -372,6 +372,13 @@ class RawTransactionsTest(BitcoinTestFramework):
encrawtx = "01000000010000000000000072c1a6a246ae63f74f931e8365e15a089c68d61900000000000000000000ffffffff0100e1f505000000000000000000"
decrawtx = self.nodes[0].decoderawtransaction(encrawtx, False) # decode as non-witness transaction
assert_equal(decrawtx['vout'][0]['value'], Decimal('1.00000000'))
+ # known ambiguous transaction in the chain (see https://github.com/bitcoin/bitcoin/issues/20579)
+ encrawtx = "020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff4b03c68708046ff8415c622f4254432e434f4d2ffabe6d6de1965d02c68f928e5b244ab1965115a36f56eb997633c7f690124bbf43644e23080000000ca3d3af6d005a65ff0200fd00000000ffffffff03f4c1fb4b0000000016001497cfc76442fe717f2a3f0cc9c175f7561b6619970000000000000000266a24aa21a9ed957d1036a80343e0d1b659497e1b48a38ebe876a056d45965fac4a85cda84e1900000000000000002952534b424c4f434b3a8e092581ab01986cbadc84f4b43f4fa4bb9e7a2e2a0caf9b7cf64d939028e22c0120000000000000000000000000000000000000000000000000000000000000000000000000"
+ decrawtx = self.nodes[0].decoderawtransaction(encrawtx)
+ decrawtx_wit = self.nodes[0].decoderawtransaction(encrawtx, True)
+ assert_raises_rpc_error(-22, 'TX decode failed', self.nodes[0].decoderawtransaction, encrawtx, False) # fails to decode as non-witness transaction
+ assert_equal(decrawtx, decrawtx_wit) # the witness interpretation should be chosen
+ assert_equal(decrawtx['vin'][0]['coinbase'], "03c68708046ff8415c622f4254432e434f4d2ffabe6d6de1965d02c68f928e5b244ab1965115a36f56eb997633c7f690124bbf43644e23080000000ca3d3af6d005a65ff0200fd00000000")
# Basic signrawtransaction test
addr = self.nodes[1].getnewaddress()
diff --git a/test/functional/rpc_signrawtransaction.py b/test/functional/rpc_signrawtransaction.py
index b962e1c3a5..2fbbdbbdf0 100755
--- a/test/functional/rpc_signrawtransaction.py
+++ b/test/functional/rpc_signrawtransaction.py
@@ -151,6 +151,19 @@ class SignRawTransactionsTest(BitcoinTestFramework):
assert_equal(rawTxSigned['errors'][1]['witness'], ["304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee01", "025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357"])
assert not rawTxSigned['errors'][0]['witness']
+ def test_fully_signed_tx(self):
+ self.log.info("Test signing a fully signed transaction does nothing")
+ self.nodes[0].walletpassphrase("password", 9999)
+ self.nodes[0].generate(101)
+ rawtx = self.nodes[0].createrawtransaction([], [{self.nodes[0].getnewaddress(): 10}])
+ fundedtx = self.nodes[0].fundrawtransaction(rawtx)
+ signedtx = self.nodes[0].signrawtransactionwithwallet(fundedtx["hex"])
+ assert_equal(signedtx["complete"], True)
+ signedtx2 = self.nodes[0].signrawtransactionwithwallet(signedtx["hex"])
+ assert_equal(signedtx2["complete"], True)
+ assert_equal(signedtx["hex"], signedtx2["hex"])
+ self.nodes[0].walletlock()
+
def witness_script_test(self):
self.log.info("Test signing transaction to P2SH-P2WSH addresses without wallet")
# Create a new P2SH-P2WSH 1-of-1 multisig address:
@@ -231,6 +244,7 @@ class SignRawTransactionsTest(BitcoinTestFramework):
self.witness_script_test()
self.OP_1NEGATE_test()
self.test_with_lock_outputs()
+ self.test_fully_signed_tx()
if __name__ == '__main__':
diff --git a/test/functional/rpc_txoutproof.py b/test/functional/rpc_txoutproof.py
index 93fb62c5d6..2d6ce77613 100755
--- a/test/functional/rpc_txoutproof.py
+++ b/test/functional/rpc_txoutproof.py
@@ -78,7 +78,7 @@ class MerkleBlockTest(BitcoinTestFramework):
# We can't get a proof if we specify transactions from different blocks
assert_raises_rpc_error(-5, "Not all transactions found in specified or retrieved block", self.nodes[0].gettxoutproof, [txid1, txid3])
# Test empty list
- assert_raises_rpc_error(-5, "Transaction not yet in block", self.nodes[0].gettxoutproof, [])
+ assert_raises_rpc_error(-8, "Parameter 'txids' cannot be empty", self.nodes[0].gettxoutproof, [])
# Test duplicate txid
assert_raises_rpc_error(-8, 'Invalid parameter, duplicated txid', self.nodes[0].gettxoutproof, [txid1, txid1])
diff --git a/test/functional/rpc_users.py b/test/functional/rpc_users.py
index daf02fc4f3..108af2cac8 100755
--- a/test/functional/rpc_users.py
+++ b/test/functional/rpc_users.py
@@ -99,11 +99,18 @@ class HTTPBasicsTest(BitcoinTestFramework):
self.test_auth(self.nodes[1], self.rpcuser, self.rpcpassword)
- self.log.info('Check that failure to write cookie file will abort the node gracefully')
+ init_error = 'Error: Unable to start HTTP server. See debug log for details.'
+
+ self.log.info('Check -rpcauth are validated')
+ # Empty -rpcauth= are ignored
+ self.restart_node(0, extra_args=['-rpcauth='])
self.stop_node(0)
+ self.nodes[0].assert_start_raises_init_error(expected_msg=init_error, extra_args=['-rpcauth=foo'])
+ self.nodes[0].assert_start_raises_init_error(expected_msg=init_error, extra_args=['-rpcauth=foo:bar'])
+
+ self.log.info('Check that failure to write cookie file will abort the node gracefully')
cookie_file = os.path.join(get_datadir_path(self.options.tmpdir, 0), self.chain, '.cookie.tmp')
os.mkdir(cookie_file)
- init_error = 'Error: Unable to start HTTP server. See debug log for details.'
self.nodes[0].assert_start_raises_init_error(expected_msg=init_error)
diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py
index ff7f73bdf4..bab4ad0008 100755
--- a/test/functional/test_framework/messages.py
+++ b/test/functional/test_framework/messages.py
@@ -51,7 +51,6 @@ MAX_HEADERS_RESULTS = 2000 # Number of headers sent in one getheaders result
MAX_INV_SIZE = 50000 # Maximum number of entries in an 'inv' protocol message
NODE_NETWORK = (1 << 0)
-NODE_GETUTXO = (1 << 1)
NODE_BLOOM = (1 << 2)
NODE_WITNESS = (1 << 3)
NODE_COMPACT_FILTERS = (1 << 6)
diff --git a/test/functional/test_framework/p2p.py b/test/functional/test_framework/p2p.py
index 6846d31221..8b79a4dc2f 100755
--- a/test/functional/test_framework/p2p.py
+++ b/test/functional/test_framework/p2p.py
@@ -396,9 +396,9 @@ class P2PInterface(P2PConnection):
assert message.nVersion >= MIN_VERSION_SUPPORTED, "Version {} received. Test framework only supports versions greater than {}".format(message.nVersion, MIN_VERSION_SUPPORTED)
if message.nVersion >= 70016:
self.send_message(msg_wtxidrelay())
- self.send_message(msg_verack())
if self.support_addrv2:
self.send_message(msg_sendaddrv2())
+ self.send_message(msg_verack())
self.nServices = message.nServices
# Connection helper methods
diff --git a/test/functional/test_framework/script.py b/test/functional/test_framework/script.py
index 8e5848d493..26ccab3039 100644
--- a/test/functional/test_framework/script.py
+++ b/test/functional/test_framework/script.py
@@ -824,21 +824,33 @@ def taproot_tree_helper(scripts):
h = TaggedHash("TapBranch", left_h + right_h)
return (left + right, h)
+# A TaprootInfo object has the following fields:
+# - scriptPubKey: the scriptPubKey (witness v1 CScript)
+# - inner_pubkey: the inner pubkey (32 bytes)
+# - negflag: whether the pubkey in the scriptPubKey was negated from inner_pubkey+tweak*G (bool).
+# - tweak: the tweak (32 bytes)
+# - leaves: a dict of name -> TaprootLeafInfo objects for all known leaves
TaprootInfo = namedtuple("TaprootInfo", "scriptPubKey,inner_pubkey,negflag,tweak,leaves")
+
+# A TaprootLeafInfo object has the following fields:
+# - script: the leaf script (CScript or bytes)
+# - version: the leaf version (0xc0 for BIP342 tapscript)
+# - merklebranch: the merkle branch to use for this leaf (32*N bytes)
TaprootLeafInfo = namedtuple("TaprootLeafInfo", "script,version,merklebranch")
def taproot_construct(pubkey, scripts=None):
"""Construct a tree of Taproot spending conditions
- pubkey: an ECPubKey object for the internal pubkey
+ pubkey: a 32-byte xonly pubkey for the internal pubkey (bytes)
scripts: a list of items; each item is either:
- - a (name, CScript) tuple
- - a (name, CScript, leaf version) tuple
+ - a (name, CScript or bytes, leaf version) tuple
+ - a (name, CScript or bytes) tuple (defaulting to leaf version 0xc0)
- another list of items (with the same structure)
- - a function, which specifies how to compute the hashing partner
- in function of the hash of whatever it is combined with
+ - a list of two items; the first of which is an item itself, and the
+ second is a function. The function takes as input the Merkle root of the
+ first item, and produces a (fictitious) partner to hash with.
- Returns: script (sPK or redeemScript), tweak, {name:(script, leaf version, negation flag, innerkey, merklepath), ...}
+ Returns: a TaprootInfo object
"""
if scripts is None:
scripts = []
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index 046efe730e..a618706a77 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -482,11 +482,8 @@ class TestNode():
tempfile.NamedTemporaryFile(dir=self.stdout_dir, delete=False) as log_stdout:
try:
self.start(extra_args, stdout=log_stdout, stderr=log_stderr, *args, **kwargs)
- self.wait_for_rpc_connection()
- self.stop_node()
- self.wait_until_stopped()
- except FailedToStartError as e:
- self.log.debug('bitcoind failed to start: %s', e)
+ ret = self.process.wait(timeout=self.rpc_timeout)
+ self.log.debug(self._node_msg(f'bitcoind exited with status {ret} during initialization'))
self.running = False
self.process = None
# Check stderr for expected message
@@ -505,11 +502,15 @@ class TestNode():
if expected_msg != stderr:
self._raise_assertion_error(
'Expected message "{}" does not fully match stderr:\n"{}"'.format(expected_msg, stderr))
- else:
+ except subprocess.TimeoutExpired:
+ self.process.kill()
+ self.running = False
+ self.process = None
+ assert_msg = f'bitcoind should have exited within {self.rpc_timeout}s '
if expected_msg is None:
- assert_msg = "bitcoind should have exited with an error"
+ assert_msg += "with an error"
else:
- assert_msg = "bitcoind should have exited with expected error " + expected_msg
+ assert_msg += "with expected error " + expected_msg
self._raise_assertion_error(assert_msg)
def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, **kwargs):
@@ -544,7 +545,7 @@ class TestNode():
def num_test_p2p_connections(self):
"""Return number of test framework p2p connections to the node."""
- return len([peer for peer in self.getpeerinfo() if peer['subver'] == MY_SUBVERSION])
+ return len([peer for peer in self.getpeerinfo() if peer['subver'] == MY_SUBVERSION.decode("utf-8")])
def disconnect_p2ps(self):
"""Close all p2p connections to the node."""
diff --git a/test/functional/wallet_balance.py b/test/functional/wallet_balance.py
index 0e786ca595..433b40faee 100755
--- a/test/functional/wallet_balance.py
+++ b/test/functional/wallet_balance.py
@@ -263,8 +263,6 @@ class WalletTest(BitcoinTestFramework):
self.log.info('Put txs back into mempool of node 1 (not node 0)')
self.nodes[0].invalidateblock(block_reorg)
self.nodes[1].invalidateblock(block_reorg)
- self.sync_blocks()
- self.nodes[0].syncwithvalidationinterfacequeue()
assert_equal(self.nodes[0].getbalance(minconf=0), 0) # wallet txs not in the mempool are untrusted
self.nodes[0].generatetoaddress(1, ADDRESS_WATCHONLY)
assert_equal(self.nodes[0].getbalance(minconf=0), 0) # wallet txs not in the mempool are untrusted
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index ac4a6e4948..3cbddaf6da 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -235,7 +235,8 @@ class WalletTest(BitcoinTestFramework):
fee_rate_btc_kvb = fee_rate_sat_vb * 1e3 / 1e8
explicit_fee_rate_btc_kvb = Decimal(fee_rate_btc_kvb) / 1000
- txid = self.nodes[2].sendmany(amounts={address: 10}, fee_rate=fee_rate_sat_vb)
+ # Test passing fee_rate as a string
+ txid = self.nodes[2].sendmany(amounts={address: 10}, fee_rate=str(fee_rate_sat_vb))
self.nodes[2].generate(1)
self.sync_all(self.nodes[0:3])
balance = self.nodes[2].getbalance()
@@ -244,6 +245,17 @@ class WalletTest(BitcoinTestFramework):
node_0_bal += Decimal('10')
assert_equal(self.nodes[0].getbalance(), node_0_bal)
+ # Test passing fee_rate as an integer
+ amount = Decimal("0.0001")
+ txid = self.nodes[2].sendmany(amounts={address: amount}, fee_rate=fee_rate_sat_vb)
+ self.nodes[2].generate(1)
+ self.sync_all(self.nodes[0:3])
+ balance = self.nodes[2].getbalance()
+ node_2_bal = self.check_fee_amount(balance, node_2_bal - amount, explicit_fee_rate_btc_kvb, self.get_vsize(self.nodes[2].gettransaction(txid)['hex']))
+ assert_equal(balance, node_2_bal)
+ node_0_bal += amount
+ assert_equal(self.nodes[0].getbalance(), node_0_bal)
+
for key in ["totalFee", "feeRate"]:
assert_raises_rpc_error(-8, "Unknown named parameter key", self.nodes[2].sendtoaddress, address=address, amount=1, fee_rate=1, key=1)
@@ -405,7 +417,7 @@ class WalletTest(BitcoinTestFramework):
amount = 3
fee_rate_sat_vb = 2
fee_rate_btc_kvb = fee_rate_sat_vb * 1e3 / 1e8
-
+ # Test passing fee_rate as an integer
txid = self.nodes[2].sendtoaddress(address=address, amount=amount, fee_rate=fee_rate_sat_vb)
tx_size = self.get_vsize(self.nodes[2].gettransaction(txid)['hex'])
self.nodes[0].generate(1)
@@ -414,6 +426,19 @@ class WalletTest(BitcoinTestFramework):
fee = prebalance - postbalance - Decimal(amount)
assert_fee_amount(fee, tx_size, Decimal(fee_rate_btc_kvb))
+ prebalance = self.nodes[2].getbalance()
+ amount = Decimal("0.001")
+ fee_rate_sat_vb = 1.23
+ fee_rate_btc_kvb = fee_rate_sat_vb * 1e3 / 1e8
+ # Test passing fee_rate as a string
+ txid = self.nodes[2].sendtoaddress(address=address, amount=amount, fee_rate=str(fee_rate_sat_vb))
+ tx_size = self.get_vsize(self.nodes[2].gettransaction(txid)['hex'])
+ self.nodes[0].generate(1)
+ self.sync_all(self.nodes[0:3])
+ postbalance = self.nodes[2].getbalance()
+ fee = prebalance - postbalance - amount
+ assert_fee_amount(fee, tx_size, Decimal(fee_rate_btc_kvb))
+
for key in ["totalFee", "feeRate"]:
assert_raises_rpc_error(-8, "Unknown named parameter key", self.nodes[2].sendtoaddress, address=address, amount=1, fee_rate=1, key=1)
diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py
index 99c9737258..c8c1f2e374 100755
--- a/test/functional/wallet_bumpfee.py
+++ b/test/functional/wallet_bumpfee.py
@@ -149,7 +149,7 @@ def test_simple_bumpfee_succeeds(self, mode, rbf_node, peer_node, dest_address):
self.sync_mempools((rbf_node, peer_node))
assert rbfid in rbf_node.getrawmempool() and rbfid in peer_node.getrawmempool()
if mode == "fee_rate":
- bumped_psbt = rbf_node.psbtbumpfee(rbfid, {"fee_rate": NORMAL})
+ bumped_psbt = rbf_node.psbtbumpfee(rbfid, {"fee_rate": str(NORMAL)})
bumped_tx = rbf_node.bumpfee(rbfid, {"fee_rate": NORMAL})
else:
bumped_psbt = rbf_node.psbtbumpfee(rbfid)
diff --git a/test/functional/wallet_importmulti.py b/test/functional/wallet_importmulti.py
index f7fdd6e908..30206349ae 100755
--- a/test/functional/wallet_importmulti.py
+++ b/test/functional/wallet_importmulti.py
@@ -64,7 +64,7 @@ class ImportMultiTest(BitcoinTestFramework):
self.nodes[0].generate(1)
self.nodes[1].generate(1)
timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
- self.nodes[1].syncwithvalidationinterfacequeue()
+ self.nodes[1].syncwithvalidationinterfacequeue() # Sync the timestamp to the wallet, so that importmulti works
node0_address1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py
index eeaa607db7..fb4532bcf6 100755
--- a/test/functional/wallet_multiwallet.py
+++ b/test/functional/wallet_multiwallet.py
@@ -127,7 +127,7 @@ class MultiWalletTest(BitcoinTestFramework):
os.mkdir(wallet_dir('no_access'))
os.chmod(wallet_dir('no_access'), 0)
try:
- with self.nodes[0].assert_debug_log(expected_msgs=['Too many levels of symbolic links', 'Error scanning']):
+ with self.nodes[0].assert_debug_log(expected_msgs=['Error scanning']):
walletlist = self.nodes[0].listwalletdir()['wallets']
finally:
# Need to ensure access is restored for cleanup
diff --git a/test/functional/wallet_resendwallettransactions.py b/test/functional/wallet_resendwallettransactions.py
index 353deefcc1..78d88f8aa5 100755
--- a/test/functional/wallet_resendwallettransactions.py
+++ b/test/functional/wallet_resendwallettransactions.py
@@ -50,6 +50,7 @@ class ResendWalletTransactionsTest(BitcoinTestFramework):
block.solve()
node.submitblock(ToHex(block))
+ # Set correct m_best_block_time, which is used in ResendWalletTransactions
node.syncwithvalidationinterfacequeue()
now = int(time.time())
diff --git a/test/functional/wallet_send.py b/test/functional/wallet_send.py
index 192e9065e6..9835c5a2af 100755
--- a/test/functional/wallet_send.py
+++ b/test/functional/wallet_send.py
@@ -256,8 +256,8 @@ class WalletSendTest(BitcoinTestFramework):
assert res["complete"]
self.log.info("Test setting explicit fee rate")
- res1 = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=1, add_to_wallet=False)
- res2 = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=1, add_to_wallet=False)
+ res1 = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate="1", add_to_wallet=False)
+ res2 = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate="1", add_to_wallet=False)
assert_equal(self.nodes[1].decodepsbt(res1["psbt"])["fee"], self.nodes[1].decodepsbt(res2["psbt"])["fee"])
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=7, add_to_wallet=False)
diff --git a/test/fuzz/test_runner.py b/test/fuzz/test_runner.py
index c7895edbcc..3a2cefbe2b 100755
--- a/test/fuzz/test_runner.py
+++ b/test/fuzz/test_runner.py
@@ -83,7 +83,7 @@ def main():
sys.exit(1)
# Build list of tests
- test_list_all = parse_test_list(makefile=os.path.join(config["environment"]["SRCDIR"], 'src', 'Makefile.test.include'))
+ test_list_all = parse_test_list(fuzz_bin=os.path.join(config["environment"]["BUILDDIR"], 'src', 'test', 'fuzz', 'fuzz'))
if not test_list_all:
logging.error("No fuzz targets found")
@@ -126,9 +126,12 @@ def main():
try:
help_output = subprocess.run(
args=[
- os.path.join(config["environment"]["BUILDDIR"], 'src', 'test', 'fuzz', test_list_selection[0]),
+ os.path.join(config["environment"]["BUILDDIR"], 'src', 'test', 'fuzz', 'fuzz'),
'-help=1',
],
+ env={
+ 'FUZZ': test_list_selection[0]
+ },
timeout=20,
check=True,
stderr=subprocess.PIPE,
@@ -177,24 +180,30 @@ def generate_corpus_seeds(*, fuzz_pool, build_dir, seed_dir, targets):
"""
logging.info("Generating corpus seeds to {}".format(seed_dir))
- def job(command):
+ def job(command, t):
logging.debug("Running '{}'\n".format(" ".join(command)))
logging.debug("Command '{}' output:\n'{}'\n".format(
' '.join(command),
- subprocess.run(command, check=True, stderr=subprocess.PIPE,
- universal_newlines=True).stderr
- ))
+ subprocess.run(
+ command,
+ env={
+ 'FUZZ': t
+ },
+ check=True,
+ stderr=subprocess.PIPE,
+ universal_newlines=True,
+ ).stderr))
futures = []
for target in targets:
target_seed_dir = os.path.join(seed_dir, target)
os.makedirs(target_seed_dir, exist_ok=True)
command = [
- os.path.join(build_dir, "src", "test", "fuzz", target),
+ os.path.join(build_dir, 'src', 'test', 'fuzz', 'fuzz'),
"-runs=100000",
target_seed_dir,
]
- futures.append(fuzz_pool.submit(job, command))
+ futures.append(fuzz_pool.submit(job, command, target))
for future in as_completed(futures):
future.result()
@@ -205,7 +214,7 @@ def merge_inputs(*, fuzz_pool, corpus, test_list, build_dir, merge_dir):
jobs = []
for t in test_list:
args = [
- os.path.join(build_dir, 'src', 'test', 'fuzz', t),
+ os.path.join(build_dir, 'src', 'test', 'fuzz', 'fuzz'),
'-merge=1',
'-use_value_profile=1', # Also done by oss-fuzz https://github.com/google/oss-fuzz/issues/1406#issuecomment-387790487
os.path.join(corpus, t),
@@ -216,7 +225,15 @@ def merge_inputs(*, fuzz_pool, corpus, test_list, build_dir, merge_dir):
def job(t, args):
output = 'Run {} with args {}\n'.format(t, " ".join(args))
- output += subprocess.run(args, check=True, stderr=subprocess.PIPE, universal_newlines=True).stderr
+ output += subprocess.run(
+ args,
+ env={
+ 'FUZZ': t
+ },
+ check=True,
+ stderr=subprocess.PIPE,
+ universal_newlines=True,
+ ).stderr
logging.debug(output)
jobs.append(fuzz_pool.submit(job, t, args))
@@ -231,7 +248,7 @@ def run_once(*, fuzz_pool, corpus, test_list, build_dir, use_valgrind):
corpus_path = os.path.join(corpus, t)
os.makedirs(corpus_path, exist_ok=True)
args = [
- os.path.join(build_dir, 'src', 'test', 'fuzz', t),
+ os.path.join(build_dir, 'src', 'test', 'fuzz', 'fuzz'),
'-runs=1',
corpus_path,
]
@@ -240,7 +257,7 @@ def run_once(*, fuzz_pool, corpus, test_list, build_dir, use_valgrind):
def job(t, args):
output = 'Run {} with args {}'.format(t, args)
- result = subprocess.run(args, stderr=subprocess.PIPE, universal_newlines=True)
+ result = subprocess.run(args, env={'FUZZ': t}, stderr=subprocess.PIPE, universal_newlines=True)
output += result.stderr
return output, result
@@ -260,20 +277,16 @@ def run_once(*, fuzz_pool, corpus, test_list, build_dir, use_valgrind):
sys.exit(1)
-def parse_test_list(makefile):
- with open(makefile, encoding='utf-8') as makefile_test:
- test_list_all = []
- read_targets = False
- for line in makefile_test.readlines():
- line = line.strip().replace('test/fuzz/', '').replace(' \\', '')
- if read_targets:
- if not line:
- break
- test_list_all.append(line)
- continue
-
- if line == 'FUZZ_TARGETS =':
- read_targets = True
+def parse_test_list(*, fuzz_bin):
+ test_list_all = subprocess.run(
+ fuzz_bin,
+ env={
+ 'PRINT_ALL_FUZZ_TARGETS_AND_ABORT': ''
+ },
+ stdout=subprocess.PIPE,
+ stderr=subprocess.DEVNULL,
+ universal_newlines=True,
+ ).stdout.splitlines()
return test_list_all
diff --git a/test/lint/README.md b/test/lint/README.md
index d15c061288..7e06308347 100644
--- a/test/lint/README.md
+++ b/test/lint/README.md
@@ -15,7 +15,16 @@ git-subtree-check.sh
Run this script from the root of the repository to verify that a subtree matches the contents of
the commit it claims to have been updated to.
-To use, make sure that you have fetched the upstream repository branch in which the subtree is
+```
+Usage: test/lint/git-subtree-check.sh [-r] DIR [COMMIT]
+ test/lint/git-subtree-check.sh -?
+```
+
+- `DIR` is the prefix within the repository to check.
+- `COMMIT` is the commit to check, if it is not provided, HEAD will be used.
+- `-r` checks that subtree commit is present in repository.
+
+To do a full check with `-r`, make sure that you have fetched the upstream repository branch in which the subtree is
maintained:
* for `src/secp256k1`: https://github.com/bitcoin-core/secp256k1.git (branch master)
* for `src/leveldb`: https://github.com/bitcoin-core/leveldb.git (branch bitcoin-fork)
@@ -29,10 +38,6 @@ To do so, add the upstream repository as remote:
git remote add --fetch secp256k1 https://github.com/bitcoin-core/secp256k1.git
```
-Usage: `git-subtree-check.sh DIR (COMMIT)`
-
-`COMMIT` may be omitted, in which case `HEAD` is used.
-
lint-all.sh
===========
Calls other scripts with the `lint-` prefix.
diff --git a/test/lint/extended-lint-cppcheck.sh b/test/lint/extended-lint-cppcheck.sh
index dfa49977de..b2ed811cda 100755
--- a/test/lint/extended-lint-cppcheck.sh
+++ b/test/lint/extended-lint-cppcheck.sh
@@ -30,6 +30,7 @@ IGNORED_WARNINGS=(
"src/protocol.h:.* Class 'CMessageHeader' has a constructor with 1 argument that is not explicit."
"src/qt/guiutil.h:.* Class 'ItemDelegate' has a constructor with 1 argument that is not explicit."
"src/rpc/util.h:.* Struct 'RPCResults' has a constructor with 1 argument that is not explicit."
+ "src/rpc/util.h:.* Struct 'UniValueType' has a constructor with 1 argument that is not explicit."
"src/rpc/util.h:.* style: Struct 'UniValueType' has a constructor with 1 argument that is not explicit."
"src/script/descriptor.cpp:.* Class 'AddressDescriptor' has a constructor with 1 argument that is not explicit."
"src/script/descriptor.cpp:.* Class 'ComboDescriptor' has a constructor with 1 argument that is not explicit."
@@ -42,6 +43,11 @@ IGNORED_WARNINGS=(
"src/script/descriptor.cpp:.* Class 'WSHDescriptor' has a constructor with 1 argument that is not explicit."
"src/script/script.h:.* Class 'CScript' has a constructor with 1 argument that is not explicit."
"src/script/standard.h:.* Class 'CScriptID' has a constructor with 1 argument that is not explicit."
+ "src/span.h:.* Class 'Span < const CRPCCommand >' has a constructor with 1 argument that is not explicit."
+ "src/span.h:.* Class 'Span < const char >' has a constructor with 1 argument that is not explicit."
+ "src/span.h:.* Class 'Span < const std :: vector <unsigned char > >' has a constructor with 1 argument that is not explicit."
+ "src/span.h:.* Class 'Span < const uint8_t >' has a constructor with 1 argument that is not explicit."
+ "src/span.h:.* Class 'Span' has a constructor with 1 argument that is not explicit."
"src/support/allocators/secure.h:.* Struct 'secure_allocator < char >' has a constructor with 1 argument that is not explicit."
"src/support/allocators/secure.h:.* Struct 'secure_allocator < RNGState >' has a constructor with 1 argument that is not explicit."
"src/support/allocators/secure.h:.* Struct 'secure_allocator < unsigned char >' has a constructor with 1 argument that is not explicit."
@@ -49,6 +55,9 @@ IGNORED_WARNINGS=(
"src/test/checkqueue_tests.cpp:.* Struct 'FailingCheck' has a constructor with 1 argument that is not explicit."
"src/test/checkqueue_tests.cpp:.* Struct 'MemoryCheck' has a constructor with 1 argument that is not explicit."
"src/test/checkqueue_tests.cpp:.* Struct 'UniqueCheck' has a constructor with 1 argument that is not explicit."
+ "src/test/fuzz/util.h:.* Class 'FuzzedFileProvider' has a constructor with 1 argument that is not explicit."
+ "src/test/fuzz/util.h:.* Class 'FuzzedAutoFileProvider' has a constructor with 1 argument that is not explicit."
+ "src/util/ref.h:.* Class 'Ref' has a constructor with 1 argument that is not explicit."
"src/wallet/db.h:.* Class 'BerkeleyEnvironment' has a constructor with 1 argument that is not explicit."
)
@@ -66,7 +75,7 @@ function join_array {
ENABLED_CHECKS_REGEXP=$(join_array "|" "${ENABLED_CHECKS[@]}")
IGNORED_WARNINGS_REGEXP=$(join_array "|" "${IGNORED_WARNINGS[@]}")
WARNINGS=$(git ls-files -- "*.cpp" "*.h" ":(exclude)src/leveldb/" ":(exclude)src/crc32c/" ":(exclude)src/secp256k1/" ":(exclude)src/univalue/" | \
- xargs cppcheck --enable=all -j "$(getconf _NPROCESSORS_ONLN)" --language=c++ --std=c++11 --template=gcc -D__cplusplus -DCLIENT_VERSION_BUILD -DCLIENT_VERSION_IS_RELEASE -DCLIENT_VERSION_MAJOR -DCLIENT_VERSION_MINOR -DCOPYRIGHT_YEAR -DDEBUG -I src/ -q 2>&1 | sort -u | \
+ xargs cppcheck --enable=all -j "$(getconf _NPROCESSORS_ONLN)" --language=c++ --std=c++17 --template=gcc -D__cplusplus -DCLIENT_VERSION_BUILD -DCLIENT_VERSION_IS_RELEASE -DCLIENT_VERSION_MAJOR -DCLIENT_VERSION_MINOR -DCOPYRIGHT_YEAR -DDEBUG -I src/ -q 2>&1 | sort -u | \
grep -E "${ENABLED_CHECKS_REGEXP}" | \
grep -vE "${IGNORED_WARNINGS_REGEXP}")
if [[ ${WARNINGS} != "" ]]; then
diff --git a/test/lint/git-subtree-check.sh b/test/lint/git-subtree-check.sh
index 5a0500df25..46aa6e7157 100755
--- a/test/lint/git-subtree-check.sh
+++ b/test/lint/git-subtree-check.sh
@@ -4,6 +4,39 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
export LC_ALL=C
+
+check_remote=0
+while getopts "?hr" opt; do
+ case $opt in
+ '?' | h)
+ echo "Usage: $0 [-r] DIR [COMMIT]"
+ echo " $0 -?"
+ echo ""
+ echo "Checks that a certain prefix is pure subtree, and optionally whether the"
+ echo "referenced commit is present in any fetched remote."
+ echo ""
+ echo "DIR is the prefix within the repository to check."
+ echo "COMMIT is the commit to check, if it is not provided, HEAD will be used."
+ echo ""
+ echo "-r Check that subtree commit is present in repository."
+ echo " To do this check, fetch the subtreed remote first. Example:"
+ echo ""
+ echo " git fetch https://github.com/bitcoin-core/secp256k1.git"
+ echo " test/lint/git-subtree-check.sh -r src/secp256k1"
+ exit 1
+ ;;
+ r)
+ check_remote=1
+ ;;
+ esac
+done
+shift $((OPTIND-1))
+
+if [ -z "$1" ]; then
+ echo "Need to provide a DIR, see $0 -?"
+ exit 1
+fi
+
# Strip trailing / from directory path (in case it was added by autocomplete)
DIR="${1%/}"
COMMIT="$2"
@@ -79,18 +112,20 @@ if [ "$tree_actual_tree" != "$tree_commit" ]; then
exit 1
fi
-# get the tree in the subtree commit referred to
-if [ "d$(git cat-file -t $rev 2>/dev/null)" != dcommit ]; then
- echo "subtree commit $rev unavailable: cannot compare. Did you add and fetch the remote?" >&2
- exit
-fi
-tree_subtree=$(git show -s --format="%T" $rev)
-echo "$DIR in $COMMIT was last updated to upstream commit $rev (tree $tree_subtree)"
+if [ "$check_remote" != "0" ]; then
+ # get the tree in the subtree commit referred to
+ if [ "d$(git cat-file -t $rev 2>/dev/null)" != dcommit ]; then
+ echo "subtree commit $rev unavailable: cannot compare. Did you add and fetch the remote?" >&2
+ exit 1
+ fi
+ tree_subtree=$(git show -s --format="%T" $rev)
+ echo "$DIR in $COMMIT was last updated to upstream commit $rev (tree $tree_subtree)"
-# ... and compare the actual tree with it
-if [ "$tree_actual_tree" != "$tree_subtree" ]; then
- echo "FAIL: subtree update commit differs from upstream tree!" >&2
- exit 1
+ # ... and compare the actual tree with it
+ if [ "$tree_actual_tree" != "$tree_subtree" ]; then
+ echo "FAIL: subtree update commit differs from upstream tree!" >&2
+ exit 1
+ fi
fi
echo "GOOD"
diff --git a/test/lint/lint-circular-dependencies.sh b/test/lint/lint-circular-dependencies.sh
index 6bd02d45ac..c4ad00e954 100755
--- a/test/lint/lint-circular-dependencies.sh
+++ b/test/lint/lint-circular-dependencies.sh
@@ -20,7 +20,6 @@ EXPECTED_CIRCULAR_DEPENDENCIES=(
"txmempool -> validation -> txmempool"
"wallet/fees -> wallet/wallet -> wallet/fees"
"wallet/wallet -> wallet/walletdb -> wallet/wallet"
- "policy/fees -> txmempool -> validation -> policy/fees"
)
EXIT_CODE=0
diff --git a/test/sanitizer_suppressions/tsan b/test/sanitizer_suppressions/tsan
index 48f81f3dbf..986e096056 100644
--- a/test/sanitizer_suppressions/tsan
+++ b/test/sanitizer_suppressions/tsan
@@ -32,7 +32,6 @@ deadlock:CConnman::ForNode
deadlock:CConnman::GetNodeStats
deadlock:CChainState::ConnectTip
deadlock:UpdateTip
-deadlock:wallet_tests::CreateWallet
# WalletBatch (unidentified deadlock)
deadlock:WalletBatch