Skip to content

Commit 651f1d8

Browse files
committed
[test] wait for inital broadcast before comparing mempool entries
- mempool entry 'unbroadcast' field changes when tx passes initial broadcast (receive getdata), so anytime you compare mempool entries as a whole, you must wait for all broadcasts to complete ('unbroadcast' = False) otherwise the state may change in between calls - update P2PTxInvStore to send msg_getdata for invs and add functionality to wait for a list of txids to complete initial broadcast - make mempool_packages.py wait because it compares entries using getrawmempool and getmempoolentry
1 parent 9d3f7eb commit 651f1d8

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

test/functional/mempool_packages.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from decimal import Decimal
88

99
from test_framework.messages import COIN
10+
from test_framework.mininode import P2PTxInvStore
1011
from test_framework.test_framework import BitcoinTestFramework
1112
from test_framework.util import (
1213
assert_equal,
@@ -58,6 +59,7 @@ def chain_transaction(self, node, parent_txid, vout, value, fee, num_outputs):
5859

5960
def run_test(self):
6061
# Mine some blocks and have them mature.
62+
self.nodes[0].add_p2p_connection(P2PTxInvStore()) # keep track of invs
6163
self.nodes[0].generate(101)
6264
utxo = self.nodes[0].listunspent(10)
6365
txid = utxo[0]['txid']
@@ -72,6 +74,10 @@ def run_test(self):
7274
value = sent_value
7375
chain.append(txid)
7476

77+
# Wait until mempool transactions have passed initial broadcast (sent inv and received getdata)
78+
# Otherwise, getrawmempool may be inconsistent with getmempoolentry if unbroadcast changes in between
79+
self.nodes[0].p2p.wait_for_broadcast(chain)
80+
7581
# Check mempool has MAX_ANCESTORS transactions in it, and descendant and ancestor
7682
# count and fees should look correct
7783
mempool = self.nodes[0].getrawmempool(True)

test/functional/test_framework/mininode.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,7 @@ def __init__(self):
645645
self.tx_invs_received = defaultdict(int)
646646

647647
def on_inv(self, message):
648+
super().on_inv(message) # Send getdata in response.
648649
# Store how many times invs have been received for each tx.
649650
for i in message.inv:
650651
if i.type == MSG_TX:
@@ -654,3 +655,12 @@ def on_inv(self, message):
654655
def get_invs(self):
655656
with mininode_lock:
656657
return list(self.tx_invs_received.keys())
658+
659+
def wait_for_broadcast(self, txns, timeout=60):
660+
"""Waits for the txns (list of txids) to complete initial broadcast.
661+
The mempool should mark unbroadcast=False for these transactions.
662+
"""
663+
# Wait until invs have been received (and getdatas sent) for each txid.
664+
self.wait_until(lambda: set(self.get_invs()) == set([int(tx, 16) for tx in txns]), timeout)
665+
# Flush messages and wait for the getdatas to be processed
666+
self.sync_with_ping()

0 commit comments

Comments
 (0)