Here is a change against master that could replace the first commit in this PR. It solves the same problem - when NextInvToInbounds() decides to wait more than the test timeout. In addition, by using mocktime, the diff below eliminates the waits in a few places of the test due to the NextInvToInbounds() delays. As a result the test passes in about 1 second instead of the current random few seconds to few tens of seconds.
--- i/test/functional/p2p_leak_tx.py
+++ w/test/functional/p2p_leak_tx.py
@@ -24,31 +24,34 @@ class P2PLeakTxTest(BitcoinTestFramework):
self.num_nodes = 1
def run_test(self):
self.gen_node = self.nodes[0] # The block and tx generating node
self.miniwallet = MiniWallet(self.gen_node)
+ self.mocktime = int(time.time())
+
self.test_tx_in_block()
self.test_notfound_on_replaced_tx()
self.test_notfound_on_unannounced_tx()
def test_tx_in_block(self):
self.log.info("Check that a transaction in the last block is uploaded (beneficial for compact block relay)")
+ self.gen_node.setmocktime(self.mocktime)
inbound_peer = self.gen_node.add_p2p_connection(P2PNode())
self.log.debug("Generate transaction and block")
inbound_peer.last_message.pop("inv", None)
- self.gen_node.setmocktime(int(time.time())) # pause time based activities
wtxid = self.miniwallet.send_self_transfer(from_node=self.gen_node)["wtxid"]
rawmp = self.gen_node.getrawmempool(False, True)
pi = self.gen_node.getpeerinfo()[0]
assert_equal(rawmp["mempool_sequence"], 2) # our tx cause mempool activity
assert_equal(pi["last_inv_sequence"], 1) # that is after the last inv
assert_equal(pi["inv_to_send"], 1) # and our tx has been queued
- self.gen_node.setmocktime(0)
+ self.mocktime += 120
+ self.gen_node.setmocktime(self.mocktime)
inbound_peer.wait_until(lambda: "inv" in inbound_peer.last_message and inbound_peer.last_message.get("inv").inv[0].hash == int(wtxid, 16))
rawmp = self.gen_node.getrawmempool(False, True)
pi = self.gen_node.getpeerinfo()[0]
assert_equal(rawmp["mempool_sequence"], 2) # no mempool update
@@ -62,21 +65,26 @@ class P2PLeakTxTest(BitcoinTestFramework):
inbound_peer.last_message.pop("tx", None)
inbound_peer.send_and_ping(want_tx)
assert_equal(inbound_peer.last_message.get("tx").tx.wtxid_hex, wtxid)
def test_notfound_on_replaced_tx(self):
self.gen_node.disconnect_p2ps()
+ self.gen_node.setmocktime(self.mocktime)
inbound_peer = self.gen_node.add_p2p_connection(P2PTxInvStore())
self.log.info("Transaction tx_a is broadcast")
tx_a = self.miniwallet.send_self_transfer(from_node=self.gen_node)
- inbound_peer.wait_for_broadcast(txns=[tx_a["wtxid"]])
+ self.mocktime += 120
+ self.gen_node.setmocktime(self.mocktime)
+ inbound_peer.wait_until(lambda: "inv" in inbound_peer.last_message and inbound_peer.last_message.get("inv").inv[0].hash == int(tx_a['wtxid'], 16))
tx_b = tx_a["tx"]
tx_b.vout[0].nValue -= 9000
self.gen_node.sendrawtransaction(tx_b.serialize().hex())
+ self.mocktime += 120
+ self.gen_node.setmocktime(self.mocktime)
inbound_peer.wait_until(lambda: "tx" in inbound_peer.last_message and inbound_peer.last_message.get("tx").tx.wtxid_hex == tx_b.wtxid_hex)
self.log.info("Re-request of tx_a after replacement is answered with notfound")
req_vec = [
CInv(t=MSG_TX, h=int(tx_a["txid"], 16)),
CInv(t=MSG_WTX, h=int(tx_a["wtxid"], 16)),