aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/README.md2
-rwxr-xr-xtest/functional/feature_addrman.py63
-rwxr-xr-xtest/functional/feature_asmap.py29
-rwxr-xr-xtest/functional/feature_coinstatsindex.py12
-rwxr-xr-xtest/functional/feature_rbf.py73
-rwxr-xr-xtest/functional/interface_bitcoin_cli.py11
-rwxr-xr-xtest/functional/mempool_packages.py20
-rwxr-xr-xtest/functional/mempool_reorg.py2
-rwxr-xr-xtest/functional/mempool_spend_coinbase.py8
-rwxr-xr-xtest/functional/p2p_addr_relay.py14
-rwxr-xr-xtest/functional/p2p_addrfetch.py13
-rwxr-xr-xtest/functional/p2p_addrv2_relay.py9
-rwxr-xr-xtest/functional/p2p_segwit.py13
-rwxr-xr-xtest/functional/rpc_blockchain.py2
-rwxr-xr-xtest/functional/rpc_net.py47
-rwxr-xr-xtest/functional/test_framework/p2p.py4
-rw-r--r--test/functional/test_framework/wallet.py11
-rwxr-xr-xtest/get_previous_releases.py1
-rw-r--r--test/sanitizer_suppressions/ubsan2
19 files changed, 226 insertions, 110 deletions
diff --git a/test/functional/README.md b/test/functional/README.md
index d830ba0334..926810cf03 100644
--- a/test/functional/README.md
+++ b/test/functional/README.md
@@ -188,5 +188,5 @@ perf report -i /path/to/datadir/send-big-msgs.perf.data.xxxx --stdio | c++filt |
#### See also:
- [Installing perf](https://askubuntu.com/q/50145)
-- [Perf examples](http://www.brendangregg.com/perf.html)
+- [Perf examples](https://www.brendangregg.com/perf.html)
- [Hotspot](https://github.com/KDAB/hotspot): a GUI for perf output analysis
diff --git a/test/functional/feature_addrman.py b/test/functional/feature_addrman.py
index ee421c89b5..55d3e48c64 100755
--- a/test/functional/feature_addrman.py
+++ b/test/functional/feature_addrman.py
@@ -14,22 +14,31 @@ from test_framework.test_node import ErrorMatch
from test_framework.util import assert_equal
-def serialize_addrman(*, format=1, lowest_compatible=3):
+def serialize_addrman(
+ *,
+ format=1,
+ lowest_compatible=3,
+ net_magic="regtest",
+ bucket_key=1,
+ len_new=None,
+ len_tried=None,
+ mock_checksum=None,
+):
new = []
tried = []
INCOMPATIBILITY_BASE = 32
- r = MAGIC_BYTES["regtest"]
+ r = MAGIC_BYTES[net_magic]
r += struct.pack("B", format)
r += struct.pack("B", INCOMPATIBILITY_BASE + lowest_compatible)
- r += ser_uint256(1)
- r += struct.pack("i", len(new))
- r += struct.pack("i", len(tried))
+ r += ser_uint256(bucket_key)
+ r += struct.pack("i", len_new or len(new))
+ r += struct.pack("i", len_tried or len(tried))
ADDRMAN_NEW_BUCKET_COUNT = 1 << 10
r += struct.pack("i", ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30))
for _ in range(ADDRMAN_NEW_BUCKET_COUNT):
r += struct.pack("i", 0)
checksum = hash256(r)
- r += checksum
+ r += mock_checksum or checksum
return r
@@ -70,7 +79,7 @@ class AddrmanTest(BitcoinTestFramework):
match=ErrorMatch.FULL_REGEX,
)
- self.log.info("Check that corrupt addrman cannot be read")
+ self.log.info("Check that corrupt addrman cannot be read (EOF)")
self.stop_node(0)
with open(peers_dat, "wb") as f:
f.write(serialize_addrman()[:-1])
@@ -79,6 +88,46 @@ class AddrmanTest(BitcoinTestFramework):
match=ErrorMatch.FULL_REGEX,
)
+ self.log.info("Check that corrupt addrman cannot be read (magic)")
+ self.stop_node(0)
+ write_addrman(peers_dat, net_magic="signet")
+ self.nodes[0].assert_start_raises_init_error(
+ expected_msg=init_error("Invalid network magic number"),
+ match=ErrorMatch.FULL_REGEX,
+ )
+
+ self.log.info("Check that corrupt addrman cannot be read (checksum)")
+ self.stop_node(0)
+ write_addrman(peers_dat, mock_checksum=b"ab" * 32)
+ self.nodes[0].assert_start_raises_init_error(
+ expected_msg=init_error("Checksum mismatch, data corrupted"),
+ match=ErrorMatch.FULL_REGEX,
+ )
+
+ self.log.info("Check that corrupt addrman cannot be read (len_tried)")
+ self.stop_node(0)
+ write_addrman(peers_dat, len_tried=-1)
+ self.nodes[0].assert_start_raises_init_error(
+ expected_msg=init_error("Corrupt CAddrMan serialization: nTried=-1, should be in \\[0, 16384\\]:.*"),
+ match=ErrorMatch.FULL_REGEX,
+ )
+
+ self.log.info("Check that corrupt addrman cannot be read (len_new)")
+ self.stop_node(0)
+ write_addrman(peers_dat, len_new=-1)
+ self.nodes[0].assert_start_raises_init_error(
+ expected_msg=init_error("Corrupt CAddrMan serialization: nNew=-1, should be in \\[0, 65536\\]:.*"),
+ match=ErrorMatch.FULL_REGEX,
+ )
+
+ self.log.info("Check that corrupt addrman cannot be read (failed check)")
+ self.stop_node(0)
+ write_addrman(peers_dat, bucket_key=0)
+ self.nodes[0].assert_start_raises_init_error(
+ expected_msg=init_error("Corrupt data. Consistency check failed with code -16: .*"),
+ match=ErrorMatch.FULL_REGEX,
+ )
+
self.log.info("Check that missing addrman is recreated")
self.stop_node(0)
os.remove(peers_dat)
diff --git a/test/functional/feature_asmap.py b/test/functional/feature_asmap.py
index 704dd6126b..2dc1e3a7cb 100755
--- a/test/functional/feature_asmap.py
+++ b/test/functional/feature_asmap.py
@@ -14,9 +14,11 @@ Verify node behaviour and debug log when launching bitcoind in these cases:
4. `bitcoind -asmap/-asmap=` with no file specified, using the default asmap
-5. `bitcoind -asmap` with no file specified and a missing default asmap file
+5. `bitcoind -asmap` restart with an addrman containing new and tried entries
-6. `bitcoind -asmap` with an empty (unparsable) default asmap file
+6. `bitcoind -asmap` with no file specified and a missing default asmap file
+
+7. `bitcoind -asmap` with an empty (unparsable) default asmap file
The tests are order-independent.
@@ -37,6 +39,12 @@ def expected_messages(filename):
class AsmapTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
+ self.extra_args = [["-checkaddrman=1"]] # Do addrman checks on all operations.
+
+ def fill_addrman(self, node_id):
+ """Add 2 tried addresses to the addrman, followed by 2 new addresses."""
+ for addr, tried in [[0, True], [1, True], [2, False], [3, False]]:
+ self.nodes[node_id].addpeeraddress(address=f"101.{addr}.0.0", tried=tried, port=8333)
def test_without_asmap_arg(self):
self.log.info('Test bitcoind with no -asmap arg passed')
@@ -72,6 +80,22 @@ class AsmapTest(BitcoinTestFramework):
self.start_node(0, [arg])
os.remove(self.default_asmap)
+ def test_asmap_interaction_with_addrman_containing_entries(self):
+ self.log.info("Test bitcoind -asmap restart with addrman containing new and tried entries")
+ self.stop_node(0)
+ shutil.copyfile(self.asmap_raw, self.default_asmap)
+ self.start_node(0, ["-asmap", "-checkaddrman=1"])
+ self.fill_addrman(node_id=0)
+ self.restart_node(0, ["-asmap", "-checkaddrman=1"])
+ with self.node.assert_debug_log(
+ expected_msgs=[
+ "Addrman checks started: new 2, tried 2, total 4",
+ "Addrman checks completed successfully",
+ ]
+ ):
+ self.node.getnodeaddresses() # getnodeaddresses re-runs the addrman checks
+ os.remove(self.default_asmap)
+
def test_default_asmap_with_missing_file(self):
self.log.info('Test bitcoind -asmap with missing default map file')
self.stop_node(0)
@@ -97,6 +121,7 @@ class AsmapTest(BitcoinTestFramework):
self.test_asmap_with_absolute_path()
self.test_asmap_with_relative_path()
self.test_default_asmap()
+ self.test_asmap_interaction_with_addrman_containing_entries()
self.test_default_asmap_with_missing_file()
self.test_empty_asmap()
diff --git a/test/functional/feature_coinstatsindex.py b/test/functional/feature_coinstatsindex.py
index 146e776b07..c592d7bd69 100755
--- a/test/functional/feature_coinstatsindex.py
+++ b/test/functional/feature_coinstatsindex.py
@@ -164,7 +164,7 @@ class CoinStatsIndexTest(BitcoinTestFramework):
# Generate and send another tx with an OP_RETURN output (which is unspendable)
tx2 = CTransaction()
tx2.vin.append(CTxIn(COutPoint(int(tx1_txid, 16), n), b''))
- tx2.vout.append(CTxOut(int(20.99 * COIN), CScript([OP_RETURN] + [OP_FALSE]*30)))
+ tx2.vout.append(CTxOut(int(Decimal('20.99') * COIN), CScript([OP_RETURN] + [OP_FALSE]*30)))
tx2_hex = self.nodes[0].signrawtransactionwithwallet(tx2.serialize().hex())['hex']
self.nodes[0].sendrawtransaction(tx2_hex)
@@ -175,16 +175,16 @@ class CoinStatsIndexTest(BitcoinTestFramework):
for hash_option in index_hash_options:
# Check all amounts were registered correctly
res6 = index_node.gettxoutsetinfo(hash_option, 108)
- assert_equal(res6['total_unspendable_amount'], Decimal('70.98999999'))
+ assert_equal(res6['total_unspendable_amount'], Decimal('70.99000000'))
assert_equal(res6['block_info'], {
- 'unspendable': Decimal('20.98999999'),
+ 'unspendable': Decimal('20.99000000'),
'prevout_spent': 111,
'new_outputs_ex_coinbase': Decimal('89.99993620'),
- 'coinbase': Decimal('50.01006381'),
+ 'coinbase': Decimal('50.01006380'),
'unspendables': {
'genesis_block': 0,
'bip30': 0,
- 'scripts': Decimal('20.98999999'),
+ 'scripts': Decimal('20.99000000'),
'unclaimed_rewards': 0
}
})
@@ -206,7 +206,7 @@ class CoinStatsIndexTest(BitcoinTestFramework):
for hash_option in index_hash_options:
res7 = index_node.gettxoutsetinfo(hash_option, 109)
- assert_equal(res7['total_unspendable_amount'], Decimal('80.98999999'))
+ assert_equal(res7['total_unspendable_amount'], Decimal('80.99000000'))
assert_equal(res7['block_info'], {
'unspendable': 10,
'prevout_spent': 0,
diff --git a/test/functional/feature_rbf.py b/test/functional/feature_rbf.py
index cb7556feb4..a6e9cd2ed1 100755
--- a/test/functional/feature_rbf.py
+++ b/test/functional/feature_rbf.py
@@ -7,7 +7,6 @@
from copy import deepcopy
from decimal import Decimal
-from test_framework.blocktools import COINBASE_MATURITY
from test_framework.messages import (
BIP125_SEQUENCE_NUMBER,
COIN,
@@ -18,10 +17,18 @@ from test_framework.messages import (
)
from test_framework.script import CScript, OP_DROP
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import assert_equal, assert_raises_rpc_error, satoshi_round
-from test_framework.script_util import DUMMY_P2WPKH_SCRIPT, DUMMY_2_P2WPKH_SCRIPT
+from test_framework.util import (
+ assert_equal,
+ assert_greater_than,
+ assert_raises_rpc_error,
+)
+from test_framework.script_util import (
+ DUMMY_P2WPKH_SCRIPT,
+ DUMMY_2_P2WPKH_SCRIPT,
+)
from test_framework.wallet import MiniWallet
+
MAX_REPLACEMENT_LIMIT = 100
class ReplaceByFeeTest(BitcoinTestFramework):
def set_test_params(self):
@@ -46,7 +53,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# the pre-mined test framework chain contains coinbase outputs to the
# MiniWallet's default address ADDRESS_BCRT1_P2WSH_OP_TRUE in blocks
# 76-100 (see method BitcoinTestFramework._initialize_chain())
- self.wallet.scan_blocks(start=76, num=2)
+ self.wallet.rescan_utxos()
self.log.info("Running test simple doublespend...")
self.test_simple_doublespend()
@@ -89,29 +96,23 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def make_utxo(self, node, amount, confirmed=True, scriptPubKey=DUMMY_P2WPKH_SCRIPT):
"""Create a txout with a given amount and scriptPubKey
- Mines coins as needed.
+ Assumes that MiniWallet has enough funds to cover the amount and the fixed fee
+ (from it's internal utxos, the one with the largest value is taken).
confirmed - txouts created will be confirmed in the blockchain;
unconfirmed otherwise.
"""
- fee = 1 * COIN
- while node.getbalance() < satoshi_round((amount + fee) / COIN):
- self.generate(node, COINBASE_MATURITY)
-
- new_addr = node.getnewaddress()
- txid = node.sendtoaddress(new_addr, satoshi_round((amount + fee) / COIN))
- tx1 = node.getrawtransaction(txid, 1)
- txid = int(txid, 16)
- i, _ = next(filter(lambda vout: new_addr == vout[1]['scriptPubKey']['address'], enumerate(tx1['vout'])))
-
- tx2 = CTransaction()
- tx2.vin = [CTxIn(COutPoint(txid, i))]
- tx2.vout = [CTxOut(amount, scriptPubKey)]
- tx2.rehash()
-
- signed_tx = node.signrawtransactionwithwallet(tx2.serialize().hex())
-
- txid = node.sendrawtransaction(signed_tx['hex'], 0)
+ # MiniWallet only supports sweeping utxos to its own internal scriptPubKey, so in
+ # order to create an output with arbitrary amount/scriptPubKey, we have to add it
+ # manually after calling the create_self_transfer method. The MiniWallet output's
+ # nValue has to be adapted accordingly (amount and fee deduction). To keep things
+ # simple, we use a fixed fee of 1000 Satoshis here.
+ fee = 1000
+ tx = self.wallet.create_self_transfer(from_node=node, fee_rate=0, mempool_valid=False)['tx']
+ assert_greater_than(tx.vout[0].nValue, amount + fee)
+ tx.vout[0].nValue -= (amount + fee) # change output -> MiniWallet
+ tx.vout.append(CTxOut(amount, scriptPubKey)) # desired output -> to be returned
+ txid = self.wallet.sendrawtransaction(from_node=node, tx_hex=tx.serialize().hex())
# If requested, ensure txouts are confirmed.
if confirmed:
@@ -124,7 +125,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
assert new_size < mempool_size
mempool_size = new_size
- return COutPoint(int(txid, 16), 0)
+ return COutPoint(int(txid, 16), 1)
def test_simple_doublespend(self):
"""Simple doublespend"""
@@ -161,14 +162,14 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def test_doublespend_chain(self):
"""Doublespend of a long chain"""
- initial_nValue = 50 * COIN
+ initial_nValue = 5 * COIN
tx0_outpoint = self.make_utxo(self.nodes[0], initial_nValue)
prevout = tx0_outpoint
remaining_value = initial_nValue
chain_txids = []
- while remaining_value > 10 * COIN:
- remaining_value -= 1 * COIN
+ while remaining_value > 1 * COIN:
+ remaining_value -= int(0.1 * COIN)
tx = CTransaction()
tx.vin = [CTxIn(prevout, nSequence=0)]
tx.vout = [CTxOut(remaining_value, CScript([1, OP_DROP] * 15 + [1]))]
@@ -178,10 +179,10 @@ class ReplaceByFeeTest(BitcoinTestFramework):
prevout = COutPoint(int(txid, 16), 0)
# Whether the double-spend is allowed is evaluated by including all
- # child fees - 40 BTC - so this attempt is rejected.
+ # child fees - 4 BTC - so this attempt is rejected.
dbl_tx = CTransaction()
dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)]
- dbl_tx.vout = [CTxOut(initial_nValue - 30 * COIN, DUMMY_P2WPKH_SCRIPT)]
+ dbl_tx.vout = [CTxOut(initial_nValue - 3 * COIN, DUMMY_P2WPKH_SCRIPT)]
dbl_tx_hex = dbl_tx.serialize().hex()
# This will raise an exception due to insufficient fee
@@ -190,7 +191,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Accepted with sufficient fee
dbl_tx = CTransaction()
dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)]
- dbl_tx.vout = [CTxOut(1 * COIN, DUMMY_P2WPKH_SCRIPT)]
+ dbl_tx.vout = [CTxOut(int(0.1 * COIN), DUMMY_P2WPKH_SCRIPT)]
dbl_tx_hex = dbl_tx.serialize().hex()
self.nodes[0].sendrawtransaction(dbl_tx_hex, 0)
@@ -201,10 +202,10 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def test_doublespend_tree(self):
"""Doublespend of a big tree of transactions"""
- initial_nValue = 50 * COIN
+ initial_nValue = 5 * COIN
tx0_outpoint = self.make_utxo(self.nodes[0], initial_nValue)
- def branch(prevout, initial_value, max_txs, tree_width=5, fee=0.0001 * COIN, _total_txs=None):
+ def branch(prevout, initial_value, max_txs, tree_width=5, fee=0.00001 * COIN, _total_txs=None):
if _total_txs is None:
_total_txs = [0]
if _total_txs[0] >= max_txs:
@@ -235,7 +236,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
_total_txs=_total_txs):
yield x
- fee = int(0.0001 * COIN)
+ fee = int(0.00001 * COIN)
n = MAX_REPLACEMENT_LIMIT
tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee))
assert_equal(len(tree_txs), n)
@@ -248,10 +249,10 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# This will raise an exception due to insufficient fee
assert_raises_rpc_error(-26, "insufficient fee", self.nodes[0].sendrawtransaction, dbl_tx_hex, 0)
- # 1 BTC fee is enough
+ # 0.1 BTC fee is enough
dbl_tx = CTransaction()
dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)]
- dbl_tx.vout = [CTxOut(initial_nValue - fee * n - 1 * COIN, DUMMY_P2WPKH_SCRIPT)]
+ dbl_tx.vout = [CTxOut(initial_nValue - fee * n - int(0.1 * COIN), DUMMY_P2WPKH_SCRIPT)]
dbl_tx_hex = dbl_tx.serialize().hex()
self.nodes[0].sendrawtransaction(dbl_tx_hex, 0)
@@ -264,7 +265,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Try again, but with more total transactions than the "max txs
# double-spent at once" anti-DoS limit.
for n in (MAX_REPLACEMENT_LIMIT + 1, MAX_REPLACEMENT_LIMIT * 2):
- fee = int(0.0001 * COIN)
+ fee = int(0.00001 * COIN)
tx0_outpoint = self.make_utxo(self.nodes[0], initial_nValue)
tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee))
assert_equal(len(tree_txs), n)
diff --git a/test/functional/interface_bitcoin_cli.py b/test/functional/interface_bitcoin_cli.py
index 89503adda3..c28186cde7 100755
--- a/test/functional/interface_bitcoin_cli.py
+++ b/test/functional/interface_bitcoin_cli.py
@@ -57,7 +57,7 @@ def cli_get_info_string_to_dict(cli_get_info_string):
if key == 'Wallet' and value == '""':
# Set default wallet("") to empty string
value = ''
- if key == "Proxy" and value == "N/A":
+ if key == "Proxies" and value == "n/a":
# Set N/A to empty string to represent no proxy
value = ''
cli_get_info[key.strip()] = value.strip()
@@ -127,10 +127,17 @@ class TestBitcoinCli(BitcoinTestFramework):
assert_equal(int(cli_get_info['Time offset (s)']), network_info['timeoffset'])
expected_network_info = f"in {network_info['connections_in']}, out {network_info['connections_out']}, total {network_info['connections']}"
assert_equal(cli_get_info["Network"], expected_network_info)
- assert_equal(cli_get_info['Proxy'], network_info['networks'][0]['proxy'])
+ assert_equal(cli_get_info['Proxies'], network_info['networks'][0]['proxy'])
assert_equal(Decimal(cli_get_info['Difficulty']), blockchain_info['difficulty'])
assert_equal(cli_get_info['Chain'], blockchain_info['chain'])
+ self.log.info("Test -getinfo and bitcoin-cli return all proxies")
+ self.restart_node(0, extra_args=["-proxy=127.0.0.1:9050", "-i2psam=127.0.0.1:7656"])
+ network_info = self.nodes[0].getnetworkinfo()
+ cli_get_info_string = self.nodes[0].cli('-getinfo').send_cli()
+ cli_get_info = cli_get_info_string_to_dict(cli_get_info_string)
+ assert_equal(cli_get_info["Proxies"], "127.0.0.1:9050 (ipv4, ipv6, onion), 127.0.0.1:7656 (i2p)")
+
if self.is_wallet_compiled():
self.log.info("Test -getinfo and bitcoin-cli getwalletinfo return expected wallet info")
assert_equal(Decimal(cli_get_info['Balance']), BALANCE)
diff --git a/test/functional/mempool_packages.py b/test/functional/mempool_packages.py
index b9344ad6da..c042961937 100755
--- a/test/functional/mempool_packages.py
+++ b/test/functional/mempool_packages.py
@@ -51,12 +51,17 @@ class MempoolPackagesTest(BitcoinTestFramework):
txid = utxo[0]['txid']
vout = utxo[0]['vout']
value = utxo[0]['amount']
+ assert 'ancestorcount' not in utxo[0]
+ assert 'ancestorsize' not in utxo[0]
+ assert 'ancestorfees' not in utxo[0]
fee = Decimal("0.0001")
# MAX_ANCESTORS transactions off a confirmed tx should be fine
chain = []
witness_chain = []
- for _ in range(MAX_ANCESTORS):
+ ancestor_vsize = 0
+ ancestor_fees = Decimal(0)
+ for i in range(MAX_ANCESTORS):
(txid, sent_value) = chain_transaction(self.nodes[0], [txid], [0], value, fee, 1)
value = sent_value
chain.append(txid)
@@ -65,6 +70,15 @@ class MempoolPackagesTest(BitcoinTestFramework):
witnesstx = self.nodes[0].decoderawtransaction(fulltx, True)
witness_chain.append(witnesstx['hash'])
+ # Check that listunspent ancestor{count, size, fees} yield the correct results
+ wallet_unspent = self.nodes[0].listunspent(minconf=0)
+ this_unspent = next(utxo_info for utxo_info in wallet_unspent if utxo_info['txid'] == txid)
+ assert_equal(this_unspent['ancestorcount'], i + 1)
+ ancestor_vsize += self.nodes[0].getrawtransaction(txid=txid, verbose=True)['vsize']
+ assert_equal(this_unspent['ancestorsize'], ancestor_vsize)
+ ancestor_fees -= self.nodes[0].gettransaction(txid=txid)['fee']
+ assert_equal(this_unspent['ancestorfees'], ancestor_fees * COIN)
+
# Wait until mempool transactions have passed initial broadcast (sent inv and received getdata)
# Otherwise, getrawmempool may be inconsistent with getmempoolentry if unbroadcast changes in between
peer_inv_store.wait_for_broadcast(witness_chain)
@@ -77,9 +91,9 @@ class MempoolPackagesTest(BitcoinTestFramework):
descendant_fees = 0
descendant_vsize = 0
- ancestor_vsize = sum([mempool[tx]['vsize'] for tx in mempool])
+ assert_equal(ancestor_vsize, sum([mempool[tx]['vsize'] for tx in mempool]))
ancestor_count = MAX_ANCESTORS
- ancestor_fees = sum([mempool[tx]['fee'] for tx in mempool])
+ assert_equal(ancestor_fees, sum([mempool[tx]['fee'] for tx in mempool]))
descendants = []
ancestors = list(chain)
diff --git a/test/functional/mempool_reorg.py b/test/functional/mempool_reorg.py
index 0ee6af62f6..260b41ef12 100755
--- a/test/functional/mempool_reorg.py
+++ b/test/functional/mempool_reorg.py
@@ -31,7 +31,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
self.log.info("Add 4 coinbase utxos to the miniwallet")
# Block 76 contains the first spendable coinbase txs.
first_block = 76
- wallet.scan_blocks(start=first_block, num=4)
+ wallet.rescan_utxos()
# Three scenarios for re-orging coinbase spends in the memory pool:
# 1. Direct coinbase spend : spend_1
diff --git a/test/functional/mempool_spend_coinbase.py b/test/functional/mempool_spend_coinbase.py
index e97595ed86..4e1dd80ba7 100755
--- a/test/functional/mempool_spend_coinbase.py
+++ b/test/functional/mempool_spend_coinbase.py
@@ -28,14 +28,14 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework):
chain_height = 198
self.nodes[0].invalidateblock(self.nodes[0].getblockhash(chain_height + 1))
assert_equal(chain_height, self.nodes[0].getblockcount())
+ wallet.rescan_utxos()
# Coinbase at height chain_height-100+1 ok in mempool, should
# get mined. Coinbase at height chain_height-100+2 is
# too immature to spend.
- wallet.scan_blocks(start=chain_height - 100 + 1, num=1)
- utxo_mature = wallet.get_utxo()
- wallet.scan_blocks(start=chain_height - 100 + 2, num=1)
- utxo_immature = wallet.get_utxo()
+ coinbase_txid = lambda h: self.nodes[0].getblock(self.nodes[0].getblockhash(h))['tx'][0]
+ utxo_mature = wallet.get_utxo(txid=coinbase_txid(chain_height - 100 + 1))
+ utxo_immature = wallet.get_utxo(txid=coinbase_txid(chain_height - 100 + 2))
spend_mature_id = wallet.send_self_transfer(from_node=self.nodes[0], utxo_to_spend=utxo_mature)["txid"]
diff --git a/test/functional/p2p_addr_relay.py b/test/functional/p2p_addr_relay.py
index e93698b08e..15b90fa61f 100755
--- a/test/functional/p2p_addr_relay.py
+++ b/test/functional/p2p_addr_relay.py
@@ -6,22 +6,22 @@
Test addr relay
"""
+import random
+import time
+
from test_framework.messages import (
CAddress,
- NODE_NETWORK,
- NODE_WITNESS,
msg_addr,
msg_getaddr,
- msg_verack
+ msg_verack,
)
from test_framework.p2p import (
P2PInterface,
p2p_lock,
+ P2P_SERVICES,
)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, assert_greater_than
-import random
-import time
class AddrReceiver(P2PInterface):
@@ -96,7 +96,7 @@ class AddrTest(BitcoinTestFramework):
for i in range(num):
addr = CAddress()
addr.time = self.mocktime + i
- addr.nServices = NODE_NETWORK | NODE_WITNESS
+ addr.nServices = P2P_SERVICES
addr.ip = f"123.123.123.{self.counter % 256}"
addr.port = 8333 + i
addrs.append(addr)
@@ -111,7 +111,7 @@ class AddrTest(BitcoinTestFramework):
for i in range(num):
addr = CAddress()
addr.time = self.mocktime + i
- addr.nServices = NODE_NETWORK | NODE_WITNESS
+ addr.nServices = P2P_SERVICES
addr.ip = f"{random.randrange(128,169)}.{random.randrange(1,255)}.{random.randrange(1,255)}.{random.randrange(1,255)}"
addr.port = 8333
addrs.append(addr)
diff --git a/test/functional/p2p_addrfetch.py b/test/functional/p2p_addrfetch.py
index 2a0f6432a9..25efd50040 100755
--- a/test/functional/p2p_addrfetch.py
+++ b/test/functional/p2p_addrfetch.py
@@ -8,14 +8,21 @@ Test p2p addr-fetch connections
import time
-from test_framework.messages import msg_addr, CAddress, NODE_NETWORK, NODE_WITNESS
-from test_framework.p2p import P2PInterface, p2p_lock
+from test_framework.messages import (
+ CAddress,
+ msg_addr,
+)
+from test_framework.p2p import (
+ P2PInterface,
+ p2p_lock,
+ P2P_SERVICES,
+)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
ADDR = CAddress()
ADDR.time = int(time.time())
-ADDR.nServices = NODE_NETWORK | NODE_WITNESS
+ADDR.nServices = P2P_SERVICES
ADDR.ip = "192.0.0.8"
ADDR.port = 18444
diff --git a/test/functional/p2p_addrv2_relay.py b/test/functional/p2p_addrv2_relay.py
index 32c1d42b1c..3833c58680 100755
--- a/test/functional/p2p_addrv2_relay.py
+++ b/test/functional/p2p_addrv2_relay.py
@@ -11,10 +11,11 @@ import time
from test_framework.messages import (
CAddress,
msg_addrv2,
- NODE_NETWORK,
- NODE_WITNESS,
)
-from test_framework.p2p import P2PInterface
+from test_framework.p2p import (
+ P2PInterface,
+ P2P_SERVICES,
+)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
@@ -24,7 +25,7 @@ ADDRS = []
for i in range(10):
addr = CAddress()
addr.time = int(time.time()) + i
- addr.nServices = NODE_NETWORK | NODE_WITNESS
+ addr.nServices = P2P_SERVICES
# Add one I2P address at an arbitrary position.
if i == 5:
addr.net = addr.NET_I2P
diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py
index 3c33b89535..aa3b95fc4f 100755
--- a/test/functional/p2p_segwit.py
+++ b/test/functional/p2p_segwit.py
@@ -43,6 +43,7 @@ from test_framework.messages import (
from test_framework.p2p import (
P2PInterface,
p2p_lock,
+ P2P_SERVICES,
)
from test_framework.script import (
CScript,
@@ -220,14 +221,14 @@ class SegWitTest(BitcoinTestFramework):
def run_test(self):
# Setup the p2p connections
- # self.test_node sets NODE_WITNESS|NODE_NETWORK
- self.test_node = self.nodes[0].add_p2p_connection(TestP2PConn(), services=NODE_NETWORK | NODE_WITNESS)
+ # self.test_node sets P2P_SERVICES, i.e. NODE_WITNESS | NODE_NETWORK
+ self.test_node = self.nodes[0].add_p2p_connection(TestP2PConn(), services=P2P_SERVICES)
# self.old_node sets only NODE_NETWORK
self.old_node = self.nodes[0].add_p2p_connection(TestP2PConn(), services=NODE_NETWORK)
# self.std_node is for testing node1 (fRequireStandard=true)
- self.std_node = self.nodes[1].add_p2p_connection(TestP2PConn(), services=NODE_NETWORK | NODE_WITNESS)
+ self.std_node = self.nodes[1].add_p2p_connection(TestP2PConn(), services=P2P_SERVICES)
# self.std_wtx_node is for testing node1 with wtxid relay
- self.std_wtx_node = self.nodes[1].add_p2p_connection(TestP2PConn(wtxidrelay=True), services=NODE_NETWORK | NODE_WITNESS)
+ self.std_wtx_node = self.nodes[1].add_p2p_connection(TestP2PConn(wtxidrelay=True), services=P2P_SERVICES)
assert self.test_node.nServices & NODE_WITNESS != 0
@@ -2007,8 +2008,8 @@ class SegWitTest(BitcoinTestFramework):
@subtest # type: ignore
def test_wtxid_relay(self):
# Use brand new nodes to avoid contamination from earlier tests
- self.wtx_node = self.nodes[0].add_p2p_connection(TestP2PConn(wtxidrelay=True), services=NODE_NETWORK | NODE_WITNESS)
- self.tx_node = self.nodes[0].add_p2p_connection(TestP2PConn(wtxidrelay=False), services=NODE_NETWORK | NODE_WITNESS)
+ self.wtx_node = self.nodes[0].add_p2p_connection(TestP2PConn(wtxidrelay=True), services=P2P_SERVICES)
+ self.tx_node = self.nodes[0].add_p2p_connection(TestP2PConn(wtxidrelay=False), services=P2P_SERVICES)
# Check wtxidrelay feature negotiation message through connecting a new peer
def received_wtxidrelay():
diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py
index 0eba74e469..b8b5c5a519 100755
--- a/test/functional/rpc_blockchain.py
+++ b/test/functional/rpc_blockchain.py
@@ -404,7 +404,7 @@ class BlockchainTest(BitcoinTestFramework):
node = self.nodes[0]
miniwallet = MiniWallet(node)
- miniwallet.scan_blocks(num=5)
+ miniwallet.rescan_utxos()
fee_per_byte = Decimal('0.00000010')
fee_per_kb = 1000 * fee_per_byte
diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py
index aa53e354a3..0f3bbce54c 100755
--- a/test/functional/rpc_net.py
+++ b/test/functional/rpc_net.py
@@ -12,11 +12,10 @@ from itertools import product
import time
from test_framework.blocktools import COINBASE_MATURITY
-from test_framework.p2p import P2PInterface
import test_framework.messages
-from test_framework.messages import (
- NODE_NETWORK,
- NODE_WITNESS,
+from test_framework.p2p import (
+ P2PInterface,
+ P2P_SERVICES,
)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
@@ -189,7 +188,6 @@ class NetTest(BitcoinTestFramework):
def test_getnodeaddresses(self):
self.log.info("Test getnodeaddresses")
self.nodes[0].add_p2p_connection(P2PInterface())
- services = NODE_NETWORK | NODE_WITNESS
# Add an IPv6 address to the address manager.
ipv6_addr = "1233:3432:2434:2343:3234:2345:6546:4534"
@@ -217,7 +215,7 @@ class NetTest(BitcoinTestFramework):
assert_greater_than(10000, len(node_addresses))
for a in node_addresses:
assert_greater_than(a["time"], 1527811200) # 1st June 2018
- assert_equal(a["services"], services)
+ assert_equal(a["services"], P2P_SERVICES)
assert a["address"] in imported_addrs
assert_equal(a["port"], 8333)
assert_equal(a["network"], "ipv4")
@@ -228,7 +226,7 @@ class NetTest(BitcoinTestFramework):
assert_equal(res[0]["address"], ipv6_addr)
assert_equal(res[0]["network"], "ipv6")
assert_equal(res[0]["port"], 8333)
- assert_equal(res[0]["services"], services)
+ assert_equal(res[0]["services"], P2P_SERVICES)
# Test for the absence of onion and I2P addresses.
for network in ["onion", "i2p"]:
@@ -239,7 +237,16 @@ class NetTest(BitcoinTestFramework):
assert_raises_rpc_error(-8, "Network not recognized: Foo", self.nodes[0].getnodeaddresses, 1, "Foo")
def test_addpeeraddress(self):
+ """RPC addpeeraddress sets the source address equal to the destination address.
+ If an address with the same /16 as an existing new entry is passed, it will be
+ placed in the same new bucket and have a 1/64 chance of the bucket positions
+ colliding (depending on the value of nKey in the addrman), in which case the
+ new address won't be added. The probability of collision can be reduced to
+ 1/2^16 = 1/65536 by using an address from a different /16. We avoid this here
+ by first testing adding a tried table entry before testing adding a new table one.
+ """
self.log.info("Test addpeeraddress")
+ self.restart_node(1, ["-checkaddrman=1"])
node = self.nodes[1]
self.log.debug("Test that addpeerinfo is a hidden RPC")
@@ -251,17 +258,25 @@ class NetTest(BitcoinTestFramework):
assert_equal(node.addpeeraddress(address="", port=8333), {"success": False})
assert_equal(node.getnodeaddresses(count=0), [])
- self.log.debug("Test that adding a valid address succeeds")
- assert_equal(node.addpeeraddress(address="1.2.3.4", port=8333), {"success": True})
- addrs = node.getnodeaddresses(count=0)
- assert_equal(len(addrs), 1)
- assert_equal(addrs[0]["address"], "1.2.3.4")
- assert_equal(addrs[0]["port"], 8333)
-
- self.log.debug("Test that adding the same address again when already present fails")
- assert_equal(node.addpeeraddress(address="1.2.3.4", port=8333), {"success": False})
+ self.log.debug("Test that adding a valid address to the tried table succeeds")
+ assert_equal(node.addpeeraddress(address="1.2.3.4", tried=True, port=8333), {"success": True})
+ with node.assert_debug_log(expected_msgs=["Addrman checks started: new 0, tried 1, total 1"]):
+ addrs = node.getnodeaddresses(count=0) # getnodeaddresses re-runs the addrman checks
+ assert_equal(len(addrs), 1)
+ assert_equal(addrs[0]["address"], "1.2.3.4")
+ assert_equal(addrs[0]["port"], 8333)
+
+ self.log.debug("Test that adding an already-present tried address to the new and tried tables fails")
+ for value in [True, False]:
+ assert_equal(node.addpeeraddress(address="1.2.3.4", tried=value, port=8333), {"success": False})
assert_equal(len(node.getnodeaddresses(count=0)), 1)
+ self.log.debug("Test that adding a second address, this time to the new table, succeeds")
+ assert_equal(node.addpeeraddress(address="2.0.0.0", port=8333), {"success": True})
+ with node.assert_debug_log(expected_msgs=["Addrman checks started: new 1, tried 1, total 2"]):
+ addrs = node.getnodeaddresses(count=0) # getnodeaddresses re-runs the addrman checks
+ assert_equal(len(addrs), 2)
+
if __name__ == '__main__':
NetTest().main()
diff --git a/test/functional/test_framework/p2p.py b/test/functional/test_framework/p2p.py
index b7d5bd8fab..78c63b57a1 100755
--- a/test/functional/test_framework/p2p.py
+++ b/test/functional/test_framework/p2p.py
@@ -356,7 +356,7 @@ class P2PInterface(P2PConnection):
return create_conn
- def peer_accept_connection(self, *args, services=NODE_NETWORK | NODE_WITNESS, **kwargs):
+ def peer_accept_connection(self, *args, services=P2P_SERVICES, **kwargs):
create_conn = super().peer_accept_connection(*args, **kwargs)
self.peer_connect_send_version(services)
@@ -577,6 +577,8 @@ class NetworkThread(threading.Thread):
NetworkThread.listeners = {}
NetworkThread.protos = {}
+ if sys.platform == 'win32':
+ asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
NetworkThread.network_event_loop = asyncio.new_event_loop()
def run(self):
diff --git a/test/functional/test_framework/wallet.py b/test/functional/test_framework/wallet.py
index 08086bc0b9..2ffeb2d115 100644
--- a/test/functional/test_framework/wallet.py
+++ b/test/functional/test_framework/wallet.py
@@ -87,13 +87,6 @@ class MiniWallet:
for utxo in res['unspents']:
self._utxos.append({'txid': utxo['txid'], 'vout': utxo['vout'], 'value': utxo['amount']})
- def scan_blocks(self, *, start=1, num):
- """Scan the blocks for self._address outputs and add them to self._utxos"""
- for i in range(start, start + num):
- block = self._test_node.getblock(blockhash=self._test_node.getblockhash(i), verbosity=2)
- for tx in block['tx']:
- self.scan_tx(tx)
-
def scan_tx(self, tx):
"""Scan the tx for self._scriptPubKey outputs and add them to self._utxos"""
for out in tx['vout']:
@@ -187,8 +180,10 @@ class MiniWallet:
return {'txid': tx_info['txid'], 'wtxid': tx_info['wtxid'], 'hex': tx_hex, 'tx': tx}
def sendrawtransaction(self, *, from_node, tx_hex):
- from_node.sendrawtransaction(tx_hex)
+ txid = from_node.sendrawtransaction(tx_hex)
self.scan_tx(from_node.decoderawtransaction(tx_hex))
+ return txid
+
def make_chain(node, address, privkeys, parent_txid, parent_value, n=0, parent_locking_script=None, fee=DEFAULT_FEE):
"""Build a transaction that spends parent_txid.vout[n] and produces one output with
diff --git a/test/get_previous_releases.py b/test/get_previous_releases.py
index e92bb402b5..62fcad04b3 100755
--- a/test/get_previous_releases.py
+++ b/test/get_previous_releases.py
@@ -190,6 +190,7 @@ def check_host(args) -> int:
'aarch64-*-linux*': 'aarch64-linux-gnu',
'x86_64-*-linux*': 'x86_64-linux-gnu',
'x86_64-apple-darwin*': 'osx64',
+ 'aarch64-apple-darwin*': 'osx64',
}
args.platform = ''
for pattern, target in platforms.items():
diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan
index 63e7c57ddb..b52e105a33 100644
--- a/test/sanitizer_suppressions/ubsan
+++ b/test/sanitizer_suppressions/ubsan
@@ -5,8 +5,6 @@
# names can be used.
# See https://github.com/google/sanitizers/issues/1364
signed-integer-overflow:txmempool.cpp
-# nLastSuccess read from peers.dat might cause an overflow in IsTerrible
-signed-integer-overflow:addrman.cpp
# https://github.com/bitcoin/bitcoin/pull/21798#issuecomment-829180719
signed-integer-overflow:policy/feerate.cpp