aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgzhao408 <gzhao408@berkeley.edu>2020-05-09 13:42:15 -0700
committergzhao408 <gzhao408@berkeley.edu>2020-05-19 14:24:27 -0700
commit651f1d816f054cb9c637f8a99c9360bba381ef58 (patch)
tree9f3432f5c419b57cefe4c09c708808bf9fd50929
parent9d3f7eb9860254eb787ebe2734fd6a26bcf365c1 (diff)
downloadbitcoin-651f1d816f054cb9c637f8a99c9360bba381ef58.tar.xz
[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
-rwxr-xr-xtest/functional/mempool_packages.py6
-rwxr-xr-xtest/functional/test_framework/mininode.py10
2 files changed, 16 insertions, 0 deletions
diff --git a/test/functional/mempool_packages.py b/test/functional/mempool_packages.py
index edd1e14725..5b7216b253 100755
--- a/test/functional/mempool_packages.py
+++ b/test/functional/mempool_packages.py
@@ -7,6 +7,7 @@
from decimal import Decimal
from test_framework.messages import COIN
+from test_framework.mininode import P2PTxInvStore
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
@@ -58,6 +59,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
def run_test(self):
# Mine some blocks and have them mature.
+ self.nodes[0].add_p2p_connection(P2PTxInvStore()) # keep track of invs
self.nodes[0].generate(101)
utxo = self.nodes[0].listunspent(10)
txid = utxo[0]['txid']
@@ -72,6 +74,10 @@ class MempoolPackagesTest(BitcoinTestFramework):
value = sent_value
chain.append(txid)
+ # 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
+ self.nodes[0].p2p.wait_for_broadcast(chain)
+
# Check mempool has MAX_ANCESTORS transactions in it, and descendant and ancestor
# count and fees should look correct
mempool = self.nodes[0].getrawmempool(True)
diff --git a/test/functional/test_framework/mininode.py b/test/functional/test_framework/mininode.py
index ba0391625e..28c6c175db 100755
--- a/test/functional/test_framework/mininode.py
+++ b/test/functional/test_framework/mininode.py
@@ -645,6 +645,7 @@ class P2PTxInvStore(P2PInterface):
self.tx_invs_received = defaultdict(int)
def on_inv(self, message):
+ super().on_inv(message) # Send getdata in response.
# Store how many times invs have been received for each tx.
for i in message.inv:
if i.type == MSG_TX:
@@ -654,3 +655,12 @@ class P2PTxInvStore(P2PInterface):
def get_invs(self):
with mininode_lock:
return list(self.tx_invs_received.keys())
+
+ def wait_for_broadcast(self, txns, timeout=60):
+ """Waits for the txns (list of txids) to complete initial broadcast.
+ The mempool should mark unbroadcast=False for these transactions.
+ """
+ # Wait until invs have been received (and getdatas sent) for each txid.
+ self.wait_until(lambda: set(self.get_invs()) == set([int(tx, 16) for tx in txns]), timeout)
+ # Flush messages and wait for the getdatas to be processed
+ self.sync_with_ping()