Fix potential race conditions in p2p testing framework
Previously, each NodeConnCB had its own lock to synchronize data structures
used by the testing thread and the networking thread, and NodeConn provided a
separate additional lock for synchronizing access to each send buffer. This
commit replaces those locks with a single global lock (mininode_lock) that we
use to synchronize access to all data structures shared by the two threads.
Updates comptool and maxblocksinflight to use the new synchronization
semantics, eliminating previous race conditions within comptool, and re-enables
invalidblockrequest.py in travis.
@ -25,6 +25,8 @@ generator that returns TestInstance objects. See below for definition.
@@ -25,6 +25,8 @@ generator that returns TestInstance objects. See below for definition.
# on_getheaders: provide headers via BlockStore
# on_getdata: provide blocks via BlockStore
globalmininode_lock
classTestNode(NodeConnCB):
def__init__(self,block_store,tx_store):
@ -148,10 +150,11 @@ class TestManager(object):
@@ -148,10 +150,11 @@ class TestManager(object):
max_tries=10/sleep_time# Wait at most 10 seconds
whilemax_tries>0:
done=True
forcinself.connections:
ifc.cb.verack_receivedisFalse:
done=False
break
withmininode_lock:
forcinself.connections:
ifc.cb.verack_receivedisFalse:
done=False
break
ifdone:
break
time.sleep(sleep_time)
@ -161,10 +164,11 @@ class TestManager(object):
@@ -161,10 +164,11 @@ class TestManager(object):
whilereceived_pongsisnotTrue:
time.sleep(0.05)
received_pongs=True
forcinself.connections:
ifc.cb.received_ping_response(counter)isnotTrue:
received_pongs=False
break
withmininode_lock:
forcinself.connections:
ifc.cb.received_ping_response(counter)isnotTrue:
received_pongs=False
break
# sync_blocks: Wait for all connections to request the blockhash given
# then send get_headers to find out the tip of each node, and synchronize
@ -173,8 +177,9 @@ class TestManager(object):
@@ -173,8 +177,9 @@ class TestManager(object):
# Wait for nodes to request block (50ms sleep * 20 tries * num_blocks)