Merge #19208: test: move sync_blocks and sync_mempool functions to test_framework.py
cc84460c16
test: move sync_blocks and sync_mempool functions to test_framework.py (Roy Shao) Pull request description: This PR moves `sync_blocks` and `sync_mempool` out from `test_framework/util.py` to `test_framework/test_framework.py` so they can take contextual information of test framework into account. * Change all reference callers to call functions from `test_framework.py` * Remove `**kwargs` which is not used * Take into account of `timeout_factor` when respecting timeout in function implementations. * Pass all tests by running `./test/functional/test_runner.py` fixes #18930 ACKs for top commit: MarcoFalke: ACKcc84460c16
, reviewed with --color-moved=dimmed-zebra --color-moved-ws=ignore-all-space 💫 Tree-SHA512: a79b2a3fa842fc26a7aacb834bb2aea88b3049916c0b754e60002a77ce94bb5954e0ea3b436bf268e9295efb62d721dfef263a09339a55c684ac3fda388c275e
This commit is contained in:
commit
4b5c9191e3
5 changed files with 54 additions and 64 deletions
|
@ -27,8 +27,6 @@ from test_framework.descriptors import descsum_create
|
||||||
|
|
||||||
from test_framework.util import (
|
from test_framework.util import (
|
||||||
assert_equal,
|
assert_equal,
|
||||||
sync_blocks,
|
|
||||||
sync_mempools,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,7 +63,7 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
|
||||||
def run_test(self):
|
def run_test(self):
|
||||||
self.nodes[0].generatetoaddress(101, self.nodes[0].getnewaddress())
|
self.nodes[0].generatetoaddress(101, self.nodes[0].getnewaddress())
|
||||||
|
|
||||||
sync_blocks(self.nodes)
|
self.sync_blocks()
|
||||||
|
|
||||||
# Sanity check the test framework:
|
# Sanity check the test framework:
|
||||||
res = self.nodes[self.num_nodes - 1].getblockchaininfo()
|
res = self.nodes[self.num_nodes - 1].getblockchaininfo()
|
||||||
|
@ -90,17 +88,17 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
|
||||||
# Create a confirmed transaction, receiving coins
|
# Create a confirmed transaction, receiving coins
|
||||||
address = wallet.getnewaddress()
|
address = wallet.getnewaddress()
|
||||||
self.nodes[0].sendtoaddress(address, 10)
|
self.nodes[0].sendtoaddress(address, 10)
|
||||||
sync_mempools(self.nodes)
|
self.sync_mempools()
|
||||||
self.nodes[0].generate(1)
|
self.nodes[0].generate(1)
|
||||||
sync_blocks(self.nodes)
|
self.sync_blocks()
|
||||||
# Create a conflicting transaction using RBF
|
# Create a conflicting transaction using RBF
|
||||||
return_address = self.nodes[0].getnewaddress()
|
return_address = self.nodes[0].getnewaddress()
|
||||||
tx1_id = self.nodes[1].sendtoaddress(return_address, 1)
|
tx1_id = self.nodes[1].sendtoaddress(return_address, 1)
|
||||||
tx2_id = self.nodes[1].bumpfee(tx1_id)["txid"]
|
tx2_id = self.nodes[1].bumpfee(tx1_id)["txid"]
|
||||||
# Confirm the transaction
|
# Confirm the transaction
|
||||||
sync_mempools(self.nodes)
|
self.sync_mempools()
|
||||||
self.nodes[0].generate(1)
|
self.nodes[0].generate(1)
|
||||||
sync_blocks(self.nodes)
|
self.sync_blocks()
|
||||||
# Create another conflicting transaction using RBF
|
# Create another conflicting transaction using RBF
|
||||||
tx3_id = self.nodes[1].sendtoaddress(return_address, 1)
|
tx3_id = self.nodes[1].sendtoaddress(return_address, 1)
|
||||||
tx4_id = self.nodes[1].bumpfee(tx3_id)["txid"]
|
tx4_id = self.nodes[1].bumpfee(tx3_id)["txid"]
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
from test_framework.test_framework import BitcoinTestFramework
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
from test_framework.util import (
|
from test_framework.util import (
|
||||||
assert_equal, assert_is_hex_string, assert_raises_rpc_error,
|
assert_equal, assert_is_hex_string, assert_raises_rpc_error,
|
||||||
connect_nodes, disconnect_nodes, sync_blocks
|
connect_nodes, disconnect_nodes
|
||||||
)
|
)
|
||||||
|
|
||||||
FILTER_TYPES = ["basic"]
|
FILTER_TYPES = ["basic"]
|
||||||
|
@ -30,7 +30,7 @@ class GetBlockFilterTest(BitcoinTestFramework):
|
||||||
|
|
||||||
# Reorg node 0 to a new chain
|
# Reorg node 0 to a new chain
|
||||||
connect_nodes(self.nodes[0], 1)
|
connect_nodes(self.nodes[0], 1)
|
||||||
sync_blocks(self.nodes)
|
self.sync_blocks()
|
||||||
|
|
||||||
assert_equal(self.nodes[0].getblockcount(), 4)
|
assert_equal(self.nodes[0].getblockcount(), 4)
|
||||||
chain1_hashes = [self.nodes[0].getblockhash(block_height) for block_height in range(4)]
|
chain1_hashes = [self.nodes[0].getblockhash(block_height) for block_height in range(4)]
|
||||||
|
|
|
@ -31,8 +31,6 @@ from .util import (
|
||||||
disconnect_nodes,
|
disconnect_nodes,
|
||||||
get_datadir_path,
|
get_datadir_path,
|
||||||
initialize_datadir,
|
initialize_datadir,
|
||||||
sync_blocks,
|
|
||||||
sync_mempools,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -549,15 +547,54 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
|
||||||
connect_nodes(self.nodes[1], 2)
|
connect_nodes(self.nodes[1], 2)
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
|
|
||||||
def sync_blocks(self, nodes=None, **kwargs):
|
def sync_blocks(self, nodes=None, wait=1, timeout=60):
|
||||||
sync_blocks(nodes or self.nodes, **kwargs)
|
"""
|
||||||
|
Wait until everybody has the same tip.
|
||||||
|
sync_blocks needs to be called with an rpc_connections set that has least
|
||||||
|
one node already synced to the latest, stable tip, otherwise there's a
|
||||||
|
chance it might return before all nodes are stably synced.
|
||||||
|
"""
|
||||||
|
rpc_connections = nodes or self.nodes
|
||||||
|
timeout = int(timeout * self.options.timeout_factor)
|
||||||
|
stop_time = time.time() + timeout
|
||||||
|
while time.time() <= stop_time:
|
||||||
|
best_hash = [x.getbestblockhash() for x in rpc_connections]
|
||||||
|
if best_hash.count(best_hash[0]) == len(rpc_connections):
|
||||||
|
return
|
||||||
|
# Check that each peer has at least one connection
|
||||||
|
assert (all([len(x.getpeerinfo()) for x in rpc_connections]))
|
||||||
|
time.sleep(wait)
|
||||||
|
raise AssertionError("Block sync timed out after {}s:{}".format(
|
||||||
|
timeout,
|
||||||
|
"".join("\n {!r}".format(b) for b in best_hash),
|
||||||
|
))
|
||||||
|
|
||||||
def sync_mempools(self, nodes=None, **kwargs):
|
def sync_mempools(self, nodes=None, wait=1, timeout=60, flush_scheduler=True):
|
||||||
sync_mempools(nodes or self.nodes, **kwargs)
|
"""
|
||||||
|
Wait until everybody has the same transactions in their memory
|
||||||
|
pools
|
||||||
|
"""
|
||||||
|
rpc_connections = nodes or self.nodes
|
||||||
|
timeout = int(timeout * self.options.timeout_factor)
|
||||||
|
stop_time = time.time() + timeout
|
||||||
|
while time.time() <= stop_time:
|
||||||
|
pool = [set(r.getrawmempool()) for r in rpc_connections]
|
||||||
|
if pool.count(pool[0]) == len(rpc_connections):
|
||||||
|
if flush_scheduler:
|
||||||
|
for r in rpc_connections:
|
||||||
|
r.syncwithvalidationinterfacequeue()
|
||||||
|
return
|
||||||
|
# Check that each peer has at least one connection
|
||||||
|
assert (all([len(x.getpeerinfo()) for x in rpc_connections]))
|
||||||
|
time.sleep(wait)
|
||||||
|
raise AssertionError("Mempool sync timed out after {}s:{}".format(
|
||||||
|
timeout,
|
||||||
|
"".join("\n {!r}".format(m) for m in pool),
|
||||||
|
))
|
||||||
|
|
||||||
def sync_all(self, nodes=None, **kwargs):
|
def sync_all(self, nodes=None):
|
||||||
self.sync_blocks(nodes, **kwargs)
|
self.sync_blocks(nodes)
|
||||||
self.sync_mempools(nodes, **kwargs)
|
self.sync_mempools(nodes)
|
||||||
|
|
||||||
# Private helper methods. These should not be accessed by the subclass test scripts.
|
# Private helper methods. These should not be accessed by the subclass test scripts.
|
||||||
|
|
||||||
|
|
|
@ -444,50 +444,6 @@ def connect_nodes(from_connection, node_num):
|
||||||
wait_until(lambda: all(peer['bytesrecv_per_msg'].pop('verack', 0) == 24 for peer in from_connection.getpeerinfo()))
|
wait_until(lambda: all(peer['bytesrecv_per_msg'].pop('verack', 0) == 24 for peer in from_connection.getpeerinfo()))
|
||||||
|
|
||||||
|
|
||||||
def sync_blocks(rpc_connections, *, wait=1, timeout=60):
|
|
||||||
"""
|
|
||||||
Wait until everybody has the same tip.
|
|
||||||
|
|
||||||
sync_blocks needs to be called with an rpc_connections set that has least
|
|
||||||
one node already synced to the latest, stable tip, otherwise there's a
|
|
||||||
chance it might return before all nodes are stably synced.
|
|
||||||
"""
|
|
||||||
stop_time = time.time() + timeout
|
|
||||||
while time.time() <= stop_time:
|
|
||||||
best_hash = [x.getbestblockhash() for x in rpc_connections]
|
|
||||||
if best_hash.count(best_hash[0]) == len(rpc_connections):
|
|
||||||
return
|
|
||||||
# Check that each peer has at least one connection
|
|
||||||
assert (all([len(x.getpeerinfo()) for x in rpc_connections]))
|
|
||||||
time.sleep(wait)
|
|
||||||
raise AssertionError("Block sync timed out after {}s:{}".format(
|
|
||||||
timeout,
|
|
||||||
"".join("\n {!r}".format(b) for b in best_hash),
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
def sync_mempools(rpc_connections, *, wait=1, timeout=60, flush_scheduler=True):
|
|
||||||
"""
|
|
||||||
Wait until everybody has the same transactions in their memory
|
|
||||||
pools
|
|
||||||
"""
|
|
||||||
stop_time = time.time() + timeout
|
|
||||||
while time.time() <= stop_time:
|
|
||||||
pool = [set(r.getrawmempool()) for r in rpc_connections]
|
|
||||||
if pool.count(pool[0]) == len(rpc_connections):
|
|
||||||
if flush_scheduler:
|
|
||||||
for r in rpc_connections:
|
|
||||||
r.syncwithvalidationinterfacequeue()
|
|
||||||
return
|
|
||||||
# Check that each peer has at least one connection
|
|
||||||
assert (all([len(x.getpeerinfo()) for x in rpc_connections]))
|
|
||||||
time.sleep(wait)
|
|
||||||
raise AssertionError("Mempool sync timed out after {}s:{}".format(
|
|
||||||
timeout,
|
|
||||||
"".join("\n {!r}".format(m) for m in pool),
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
# Transaction/Block functions
|
# Transaction/Block functions
|
||||||
#############################
|
#############################
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ from test_framework.util import (
|
||||||
assert_equal,
|
assert_equal,
|
||||||
assert_raises_rpc_error,
|
assert_raises_rpc_error,
|
||||||
connect_nodes,
|
connect_nodes,
|
||||||
sync_blocks,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -264,7 +263,7 @@ class WalletTest(BitcoinTestFramework):
|
||||||
# Now confirm tx_orig
|
# Now confirm tx_orig
|
||||||
self.restart_node(1, ['-persistmempool=0'])
|
self.restart_node(1, ['-persistmempool=0'])
|
||||||
connect_nodes(self.nodes[0], 1)
|
connect_nodes(self.nodes[0], 1)
|
||||||
sync_blocks(self.nodes)
|
self.sync_blocks()
|
||||||
self.nodes[1].sendrawtransaction(tx_orig)
|
self.nodes[1].sendrawtransaction(tx_orig)
|
||||||
self.nodes[1].generatetoaddress(1, ADDRESS_WATCHONLY)
|
self.nodes[1].generatetoaddress(1, ADDRESS_WATCHONLY)
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
|
|
Loading…
Reference in a new issue