0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-02 09:46:52 -05:00

Merge #19804: test/refactor: reference p2p objects explicitly and remove confusing Test_Node.p2p property

10d61505fe [test] remove confusing p2p property (gzhao408)
549d30faf0 scripted-diff: replace p2p with p2ps[0] in p2p_invalid_tx (gzhao408)
7a0de46aea [doc] sample code for test framework p2p objects (gzhao408)
784f757994 [refactor] clarify tests by referencing p2p objects directly (gzhao408)

Pull request description:

  The `TestNode` has a `p2p` property which is an alias for `p2ps[0]`.

  I think this should be removed because it can be confusing and misleading (to both the test writer and reviewer), especially if a TestNode has multiple p2ps connected (which is the case for many tests).
  Another example is when a test has multiple subtests that connect 1 p2p and use the `p2p` property to reference it. If the subtests don't completely clean up after themselves, the subtests may affect one another.

  The best way to refer to a connected p2p is use the object returned by `add_p2p_connection` like this:
  ```py
  p2p_conn = node.add_p2p_connection(P2PInterface())
  ```
  A good example is [p2p_invalid_locator.py](https://github.com/bitcoin/bitcoin/blob/master/test/functional/p2p_invalid_locator.py), which cleans up after itself (waits in both `wait_for_disconnect` and in `disconnect_p2ps`) but wouldn't need so much complexity if it just referenced the connections directly.

  If there is only one connected, it's not really that tedious to just use `node.p2ps[0]` instead of `node.p2p` (and it can always be aliased inside the test itself).

ACKs for top commit:
  robot-dreams:
    utACK 10d61505fe
  jnewbery:
    utACK 10d61505fe
  guggero:
    Concept ACK 10d61505.

Tree-SHA512: 5965548929794ec660dae03467640cb2156d7d826cefd26d3a126472cbc2494b855c1d26bbb7b412281fbdc92b9798b9765a85c27bc1a97f7798f27f64db6f13
This commit is contained in:
MarcoFalke 2020-09-25 14:18:21 +02:00
commit 78f912c901
No known key found for this signature in database
GPG key ID: D2EA4850E7528B25
20 changed files with 99 additions and 92 deletions

View file

@ -87,7 +87,9 @@ P2P messages. These can be found in the following source files:
#### Using the P2P interface #### Using the P2P interface
- [messages.py](test_framework/messages.py) contains all the definitions for objects that pass - `P2P`s can be used to test specific P2P protocol behavior.
[p2p.py](test_framework/p2p.py) contains test framework p2p objects and
[messages.py](test_framework/messages.py) contains all the definitions for objects passed
over the network (`CBlock`, `CTransaction`, etc, along with the network-level over the network (`CBlock`, `CTransaction`, etc, along with the network-level
wrappers for them, `msg_block`, `msg_tx`, etc). wrappers for them, `msg_block`, `msg_tx`, etc).
@ -100,8 +102,22 @@ contains the higher level logic for processing P2P payloads and connecting to
the Bitcoin Core node application logic. For custom behaviour, subclass the the Bitcoin Core node application logic. For custom behaviour, subclass the
P2PInterface object and override the callback methods. P2PInterface object and override the callback methods.
- Can be used to write tests where specific P2P protocol behavior is tested. `P2PConnection`s can be used as such:
Examples tests are [p2p_unrequested_blocks.py](p2p_unrequested_blocks.py),
```python
p2p_conn = node.add_p2p_connection(P2PInterface())
p2p_conn.send_and_ping(msg)
```
They can also be referenced by indexing into a `TestNode`'s `p2ps` list, which
contains the list of test framework `p2p` objects connected to itself
(it does not include any `TestNode`s):
```python
node.p2ps[0].sync_with_ping()
```
More examples can be found in [p2p_unrequested_blocks.py](p2p_unrequested_blocks.py),
[p2p_compactblocks.py](p2p_compactblocks.py). [p2p_compactblocks.py](p2p_compactblocks.py).
#### Prototyping tests #### Prototyping tests
@ -157,7 +173,7 @@ way is the use the `profile_with_perf` context manager, e.g.
with node.profile_with_perf("send-big-msgs"): with node.profile_with_perf("send-big-msgs"):
# Perform activity on the node you're interested in profiling, e.g.: # Perform activity on the node you're interested in profiling, e.g.:
for _ in range(10000): for _ in range(10000):
node.p2p.send_message(some_large_message) node.p2ps[0].send_message(some_large_message)
``` ```
To see useful textual output, run To see useful textual output, run

View file

@ -136,7 +136,7 @@ class ExampleTest(BitcoinTestFramework):
"""Main test logic""" """Main test logic"""
# Create P2P connections will wait for a verack to make sure the connection is fully up # Create P2P connections will wait for a verack to make sure the connection is fully up
self.nodes[0].add_p2p_connection(BaseNode()) peer_messaging = self.nodes[0].add_p2p_connection(BaseNode())
# Generating a block on one of the nodes will get us out of IBD # Generating a block on one of the nodes will get us out of IBD
blocks = [int(self.nodes[0].generate(nblocks=1)[0], 16)] blocks = [int(self.nodes[0].generate(nblocks=1)[0], 16)]
@ -173,7 +173,7 @@ class ExampleTest(BitcoinTestFramework):
block.solve() block.solve()
block_message = msg_block(block) block_message = msg_block(block)
# Send message is used to send a P2P message to the node over our P2PInterface # Send message is used to send a P2P message to the node over our P2PInterface
self.nodes[0].p2p.send_message(block_message) peer_messaging.send_message(block_message)
self.tip = block.sha256 self.tip = block.sha256
blocks.append(self.tip) blocks.append(self.tip)
self.block_time += 1 self.block_time += 1
@ -191,25 +191,25 @@ class ExampleTest(BitcoinTestFramework):
self.log.info("Add P2P connection to node2") self.log.info("Add P2P connection to node2")
self.nodes[0].disconnect_p2ps() self.nodes[0].disconnect_p2ps()
self.nodes[2].add_p2p_connection(BaseNode()) peer_receiving = self.nodes[2].add_p2p_connection(BaseNode())
self.log.info("Test that node2 propagates all the blocks to us") self.log.info("Test that node2 propagates all the blocks to us")
getdata_request = msg_getdata() getdata_request = msg_getdata()
for block in blocks: for block in blocks:
getdata_request.inv.append(CInv(MSG_BLOCK, block)) getdata_request.inv.append(CInv(MSG_BLOCK, block))
self.nodes[2].p2p.send_message(getdata_request) peer_receiving.send_message(getdata_request)
# wait_until() will loop until a predicate condition is met. Use it to test properties of the # wait_until() will loop until a predicate condition is met. Use it to test properties of the
# P2PInterface objects. # P2PInterface objects.
self.nodes[2].p2p.wait_until(lambda: sorted(blocks) == sorted(list(self.nodes[2].p2p.block_receive_map.keys())), timeout=5) peer_receiving.wait_until(lambda: sorted(blocks) == sorted(list(peer_receiving.block_receive_map.keys())), timeout=5)
self.log.info("Check that each block was received only once") self.log.info("Check that each block was received only once")
# The network thread uses a global lock on data access to the P2PConnection objects when sending and receiving # The network thread uses a global lock on data access to the P2PConnection objects when sending and receiving
# messages. The test thread should acquire the global lock before accessing any P2PConnection data to avoid locking # messages. The test thread should acquire the global lock before accessing any P2PConnection data to avoid locking
# and synchronization issues. Note p2p.wait_until() acquires this global lock internally when testing the predicate. # and synchronization issues. Note p2p.wait_until() acquires this global lock internally when testing the predicate.
with p2p_lock: with p2p_lock:
for block in self.nodes[2].p2p.block_receive_map.values(): for block in peer_receiving.block_receive_map.values():
assert_equal(block, 1) assert_equal(block, 1)

View file

@ -1386,14 +1386,14 @@ class FullBlockTest(BitcoinTestFramework):
"""Add a P2P connection to the node. """Add a P2P connection to the node.
Helper to connect and wait for version handshake.""" Helper to connect and wait for version handshake."""
self.nodes[0].add_p2p_connection(P2PDataStore()) self.helper_peer = self.nodes[0].add_p2p_connection(P2PDataStore())
# We need to wait for the initial getheaders from the peer before we # We need to wait for the initial getheaders from the peer before we
# start populating our blockstore. If we don't, then we may run ahead # start populating our blockstore. If we don't, then we may run ahead
# to the next subtest before we receive the getheaders. We'd then send # to the next subtest before we receive the getheaders. We'd then send
# an INV for the next block and receive two getheaders - one for the # an INV for the next block and receive two getheaders - one for the
# IBD and one for the INV. We'd respond to both and could get # IBD and one for the INV. We'd respond to both and could get
# unexpectedly disconnected if the DoS score for that error is 50. # unexpectedly disconnected if the DoS score for that error is 50.
self.nodes[0].p2p.wait_for_getheaders(timeout=timeout) self.helper_peer.wait_for_getheaders(timeout=timeout)
def reconnect_p2p(self, timeout=60): def reconnect_p2p(self, timeout=60):
"""Tear down and bootstrap the P2P connection to the node. """Tear down and bootstrap the P2P connection to the node.
@ -1407,7 +1407,7 @@ class FullBlockTest(BitcoinTestFramework):
"""Sends blocks to test node. Syncs and verifies that tip has advanced to most recent block. """Sends blocks to test node. Syncs and verifies that tip has advanced to most recent block.
Call with success = False if the tip shouldn't advance to the most recent block.""" Call with success = False if the tip shouldn't advance to the most recent block."""
self.nodes[0].p2p.send_blocks_and_test(blocks, self.nodes[0], success=success, reject_reason=reject_reason, force_send=force_send, timeout=timeout, expect_disconnect=reconnect) self.helper_peer.send_blocks_and_test(blocks, self.nodes[0], success=success, reject_reason=reject_reason, force_send=force_send, timeout=timeout, expect_disconnect=reconnect)
if reconnect: if reconnect:
self.reconnect_p2p(timeout=timeout) self.reconnect_p2p(timeout=timeout)

View file

@ -75,7 +75,7 @@ class BIP65Test(BitcoinTestFramework):
) )
def run_test(self): def run_test(self):
self.nodes[0].add_p2p_connection(P2PInterface()) peer = self.nodes[0].add_p2p_connection(P2PInterface())
self.test_cltv_info(is_active=False) self.test_cltv_info(is_active=False)
@ -99,7 +99,7 @@ class BIP65Test(BitcoinTestFramework):
block.solve() block.solve()
self.test_cltv_info(is_active=False) # Not active as of current tip and next block does not need to obey rules self.test_cltv_info(is_active=False) # Not active as of current tip and next block does not need to obey rules
self.nodes[0].p2p.send_and_ping(msg_block(block)) peer.send_and_ping(msg_block(block))
self.test_cltv_info(is_active=True) # Not active as of current tip, but next block must obey rules self.test_cltv_info(is_active=True) # Not active as of current tip, but next block must obey rules
assert_equal(self.nodes[0].getbestblockhash(), block.hash) assert_equal(self.nodes[0].getbestblockhash(), block.hash)
@ -111,9 +111,9 @@ class BIP65Test(BitcoinTestFramework):
block.solve() block.solve()
with self.nodes[0].assert_debug_log(expected_msgs=['{}, bad-version(0x00000003)'.format(block.hash)]): with self.nodes[0].assert_debug_log(expected_msgs=['{}, bad-version(0x00000003)'.format(block.hash)]):
self.nodes[0].p2p.send_and_ping(msg_block(block)) peer.send_and_ping(msg_block(block))
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
self.nodes[0].p2p.sync_with_ping() peer.sync_with_ping()
self.log.info("Test that invalid-according-to-cltv transactions cannot appear in a block") self.log.info("Test that invalid-according-to-cltv transactions cannot appear in a block")
block.nVersion = 4 block.nVersion = 4
@ -136,9 +136,9 @@ class BIP65Test(BitcoinTestFramework):
block.solve() block.solve()
with self.nodes[0].assert_debug_log(expected_msgs=['CheckInputScripts on {} failed with non-mandatory-script-verify-flag (Negative locktime)'.format(block.vtx[-1].hash)]): with self.nodes[0].assert_debug_log(expected_msgs=['CheckInputScripts on {} failed with non-mandatory-script-verify-flag (Negative locktime)'.format(block.vtx[-1].hash)]):
self.nodes[0].p2p.send_and_ping(msg_block(block)) peer.send_and_ping(msg_block(block))
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
self.nodes[0].p2p.sync_with_ping() peer.sync_with_ping()
self.log.info("Test that a version 4 block with a valid-according-to-CLTV transaction is accepted") self.log.info("Test that a version 4 block with a valid-according-to-CLTV transaction is accepted")
spendtx = cltv_validate(self.nodes[0], spendtx, CLTV_HEIGHT - 1) spendtx = cltv_validate(self.nodes[0], spendtx, CLTV_HEIGHT - 1)
@ -150,7 +150,7 @@ class BIP65Test(BitcoinTestFramework):
block.solve() block.solve()
self.test_cltv_info(is_active=True) # Not active as of current tip, but next block must obey rules self.test_cltv_info(is_active=True) # Not active as of current tip, but next block must obey rules
self.nodes[0].p2p.send_and_ping(msg_block(block)) peer.send_and_ping(msg_block(block))
self.test_cltv_info(is_active=True) # Active as of current tip self.test_cltv_info(is_active=True) # Active as of current tip
assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256)

View file

@ -182,10 +182,10 @@ class BIP68_112_113Test(BitcoinTestFramework):
"""Sends blocks to test node. Syncs and verifies that tip has advanced to most recent block. """Sends blocks to test node. Syncs and verifies that tip has advanced to most recent block.
Call with success = False if the tip shouldn't advance to the most recent block.""" Call with success = False if the tip shouldn't advance to the most recent block."""
self.nodes[0].p2p.send_blocks_and_test(blocks, self.nodes[0], success=success, reject_reason=reject_reason) self.helper_peer.send_blocks_and_test(blocks, self.nodes[0], success=success, reject_reason=reject_reason)
def run_test(self): def run_test(self):
self.nodes[0].add_p2p_connection(P2PDataStore()) self.helper_peer = self.nodes[0].add_p2p_connection(P2PDataStore())
self.log.info("Generate blocks in the past for coinbase outputs.") self.log.info("Generate blocks in the past for coinbase outputs.")
long_past_time = int(time.time()) - 600 * 1000 # enough to build up to 1000 blocks 10 minutes apart without worrying about getting into the future long_past_time = int(time.time()) - 600 * 1000 # enough to build up to 1000 blocks 10 minutes apart without worrying about getting into the future

View file

@ -59,7 +59,7 @@ class BIP66Test(BitcoinTestFramework):
) )
def run_test(self): def run_test(self):
self.nodes[0].add_p2p_connection(P2PInterface()) peer = self.nodes[0].add_p2p_connection(P2PInterface())
self.test_dersig_info(is_active=False) self.test_dersig_info(is_active=False)
@ -84,7 +84,7 @@ class BIP66Test(BitcoinTestFramework):
block.solve() block.solve()
self.test_dersig_info(is_active=False) # Not active as of current tip and next block does not need to obey rules self.test_dersig_info(is_active=False) # Not active as of current tip and next block does not need to obey rules
self.nodes[0].p2p.send_and_ping(msg_block(block)) peer.send_and_ping(msg_block(block))
self.test_dersig_info(is_active=True) # Not active as of current tip, but next block must obey rules self.test_dersig_info(is_active=True) # Not active as of current tip, but next block must obey rules
assert_equal(self.nodes[0].getbestblockhash(), block.hash) assert_equal(self.nodes[0].getbestblockhash(), block.hash)
@ -97,9 +97,9 @@ class BIP66Test(BitcoinTestFramework):
block.solve() block.solve()
with self.nodes[0].assert_debug_log(expected_msgs=['{}, bad-version(0x00000002)'.format(block.hash)]): with self.nodes[0].assert_debug_log(expected_msgs=['{}, bad-version(0x00000002)'.format(block.hash)]):
self.nodes[0].p2p.send_and_ping(msg_block(block)) peer.send_and_ping(msg_block(block))
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
self.nodes[0].p2p.sync_with_ping() peer.sync_with_ping()
self.log.info("Test that transactions with non-DER signatures cannot appear in a block") self.log.info("Test that transactions with non-DER signatures cannot appear in a block")
block.nVersion = 3 block.nVersion = 3
@ -123,9 +123,9 @@ class BIP66Test(BitcoinTestFramework):
block.solve() block.solve()
with self.nodes[0].assert_debug_log(expected_msgs=['CheckInputScripts on {} failed with non-mandatory-script-verify-flag (Non-canonical DER signature)'.format(block.vtx[-1].hash)]): with self.nodes[0].assert_debug_log(expected_msgs=['CheckInputScripts on {} failed with non-mandatory-script-verify-flag (Non-canonical DER signature)'.format(block.vtx[-1].hash)]):
self.nodes[0].p2p.send_and_ping(msg_block(block)) peer.send_and_ping(msg_block(block))
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
self.nodes[0].p2p.sync_with_ping() peer.sync_with_ping()
self.log.info("Test that a version 3 block with a DERSIG-compliant transaction is accepted") self.log.info("Test that a version 3 block with a DERSIG-compliant transaction is accepted")
block.vtx[1] = create_transaction(self.nodes[0], self.coinbase_txids[1], self.nodeaddress, amount=1.0) block.vtx[1] = create_transaction(self.nodes[0], self.coinbase_txids[1], self.nodeaddress, amount=1.0)
@ -134,7 +134,7 @@ class BIP66Test(BitcoinTestFramework):
block.solve() block.solve()
self.test_dersig_info(is_active=True) # Not active as of current tip, but next block must obey rules self.test_dersig_info(is_active=True) # Not active as of current tip, but next block must obey rules
self.nodes[0].p2p.send_and_ping(msg_block(block)) peer.send_and_ping(msg_block(block))
self.test_dersig_info(is_active=True) # Active as of current tip self.test_dersig_info(is_active=True) # Active as of current tip
assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256)

View file

@ -145,16 +145,16 @@ class MaxUploadTest(BitcoinTestFramework):
self.restart_node(0, ["-whitelist=download@127.0.0.1", "-maxuploadtarget=1"]) self.restart_node(0, ["-whitelist=download@127.0.0.1", "-maxuploadtarget=1"])
# Reconnect to self.nodes[0] # Reconnect to self.nodes[0]
self.nodes[0].add_p2p_connection(TestP2PConn()) peer = self.nodes[0].add_p2p_connection(TestP2PConn())
#retrieve 20 blocks which should be enough to break the 1MB limit #retrieve 20 blocks which should be enough to break the 1MB limit
getdata_request.inv = [CInv(MSG_BLOCK, big_new_block)] getdata_request.inv = [CInv(MSG_BLOCK, big_new_block)]
for i in range(20): for i in range(20):
self.nodes[0].p2p.send_and_ping(getdata_request) peer.send_and_ping(getdata_request)
assert_equal(self.nodes[0].p2p.block_receive_map[big_new_block], i+1) assert_equal(peer.block_receive_map[big_new_block], i+1)
getdata_request.inv = [CInv(MSG_BLOCK, big_old_block)] getdata_request.inv = [CInv(MSG_BLOCK, big_old_block)]
self.nodes[0].p2p.send_and_ping(getdata_request) peer.send_and_ping(getdata_request)
self.log.info("Peer still connected after trying to download old block (download permission)") self.log.info("Peer still connected after trying to download old block (download permission)")
peer_info = self.nodes[0].getpeerinfo() peer_info = self.nodes[0].getpeerinfo()

View file

@ -61,7 +61,7 @@ class VersionBitsWarningTest(BitcoinTestFramework):
def run_test(self): def run_test(self):
node = self.nodes[0] node = self.nodes[0]
node.add_p2p_connection(P2PInterface()) peer = node.add_p2p_connection(P2PInterface())
node_deterministic_address = node.get_deterministic_priv_key().address node_deterministic_address = node.get_deterministic_priv_key().address
# Mine one period worth of blocks # Mine one period worth of blocks
@ -69,7 +69,7 @@ class VersionBitsWarningTest(BitcoinTestFramework):
self.log.info("Check that there is no warning if previous VB_BLOCKS have <VB_THRESHOLD blocks with unknown versionbits version.") self.log.info("Check that there is no warning if previous VB_BLOCKS have <VB_THRESHOLD blocks with unknown versionbits version.")
# Build one period of blocks with < VB_THRESHOLD blocks signaling some unknown bit # Build one period of blocks with < VB_THRESHOLD blocks signaling some unknown bit
self.send_blocks_with_version(node.p2p, VB_THRESHOLD - 1, VB_UNKNOWN_VERSION) self.send_blocks_with_version(peer, VB_THRESHOLD - 1, VB_UNKNOWN_VERSION)
node.generatetoaddress(VB_PERIOD - VB_THRESHOLD + 1, node_deterministic_address) node.generatetoaddress(VB_PERIOD - VB_THRESHOLD + 1, node_deterministic_address)
# Check that we're not getting any versionbit-related errors in get*info() # Check that we're not getting any versionbit-related errors in get*info()
@ -77,7 +77,7 @@ class VersionBitsWarningTest(BitcoinTestFramework):
assert not VB_PATTERN.match(node.getnetworkinfo()["warnings"]) assert not VB_PATTERN.match(node.getnetworkinfo()["warnings"])
# Build one period of blocks with VB_THRESHOLD blocks signaling some unknown bit # Build one period of blocks with VB_THRESHOLD blocks signaling some unknown bit
self.send_blocks_with_version(node.p2p, VB_THRESHOLD, VB_UNKNOWN_VERSION) self.send_blocks_with_version(peer, VB_THRESHOLD, VB_UNKNOWN_VERSION)
node.generatetoaddress(VB_PERIOD - VB_THRESHOLD, node_deterministic_address) node.generatetoaddress(VB_PERIOD - VB_THRESHOLD, node_deterministic_address)
self.log.info("Check that there is a warning if previous VB_BLOCKS have >=VB_THRESHOLD blocks with unknown versionbits version.") self.log.info("Check that there is a warning if previous VB_BLOCKS have >=VB_THRESHOLD blocks with unknown versionbits version.")

View file

@ -58,7 +58,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
def run_test(self): def run_test(self):
# Mine some blocks and have them mature. # Mine some blocks and have them mature.
self.nodes[0].add_p2p_connection(P2PTxInvStore()) # keep track of invs peer_inv_store = self.nodes[0].add_p2p_connection(P2PTxInvStore()) # keep track of invs
self.nodes[0].generate(101) self.nodes[0].generate(101)
utxo = self.nodes[0].listunspent(10) utxo = self.nodes[0].listunspent(10)
txid = utxo[0]['txid'] txid = utxo[0]['txid']
@ -80,7 +80,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
# Wait until mempool transactions have passed initial broadcast (sent inv and received getdata) # 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 # Otherwise, getrawmempool may be inconsistent with getmempoolentry if unbroadcast changes in between
self.nodes[0].p2p.wait_for_broadcast(witness_chain) peer_inv_store.wait_for_broadcast(witness_chain)
# Check mempool has MAX_ANCESTORS transactions in it, and descendant and ancestor # Check mempool has MAX_ANCESTORS transactions in it, and descendant and ancestor
# count and fees should look correct # count and fees should look correct

View file

@ -234,9 +234,9 @@ class MiningTest(BitcoinTestFramework):
assert_raises_rpc_error(-25, 'time-too-old', lambda: node.submitheader(hexdata=CBlockHeader(bad_block_time).serialize().hex())) assert_raises_rpc_error(-25, 'time-too-old', lambda: node.submitheader(hexdata=CBlockHeader(bad_block_time).serialize().hex()))
# Should ask for the block from a p2p node, if they announce the header as well: # Should ask for the block from a p2p node, if they announce the header as well:
node.add_p2p_connection(P2PDataStore()) peer = node.add_p2p_connection(P2PDataStore())
node.p2p.wait_for_getheaders(timeout=5) # Drop the first getheaders peer.wait_for_getheaders(timeout=5) # Drop the first getheaders
node.p2p.send_blocks_and_test(blocks=[block], node=node) peer.send_blocks_and_test(blocks=[block], node=node)
# Must be active now: # Must be active now:
assert chain_tip(block.hash, status='active', branchlen=0) in node.getchaintips() assert chain_tip(block.hash, status='active', branchlen=0) in node.getchaintips()

View file

@ -17,7 +17,7 @@ class P2PBlocksOnly(BitcoinTestFramework):
self.extra_args = [["-blocksonly"]] self.extra_args = [["-blocksonly"]]
def run_test(self): def run_test(self):
self.nodes[0].add_p2p_connection(P2PInterface()) block_relay_peer = self.nodes[0].add_p2p_connection(P2PInterface())
self.log.info('Check that txs from p2p are rejected and result in disconnect') self.log.info('Check that txs from p2p are rejected and result in disconnect')
prevtx = self.nodes[0].getblock(self.nodes[0].getblockhash(1), 2)['tx'][0] prevtx = self.nodes[0].getblock(self.nodes[0].getblockhash(1), 2)['tx'][0]
@ -41,20 +41,20 @@ class P2PBlocksOnly(BitcoinTestFramework):
)['hex'] )['hex']
assert_equal(self.nodes[0].getnetworkinfo()['localrelay'], False) assert_equal(self.nodes[0].getnetworkinfo()['localrelay'], False)
with self.nodes[0].assert_debug_log(['transaction sent in violation of protocol peer=0']): with self.nodes[0].assert_debug_log(['transaction sent in violation of protocol peer=0']):
self.nodes[0].p2p.send_message(msg_tx(FromHex(CTransaction(), sigtx))) block_relay_peer.send_message(msg_tx(FromHex(CTransaction(), sigtx)))
self.nodes[0].p2p.wait_for_disconnect() block_relay_peer.wait_for_disconnect()
assert_equal(self.nodes[0].getmempoolinfo()['size'], 0) assert_equal(self.nodes[0].getmempoolinfo()['size'], 0)
# Remove the disconnected peer and add a new one. # Remove the disconnected peer and add a new one.
del self.nodes[0].p2ps[0] del self.nodes[0].p2ps[0]
self.nodes[0].add_p2p_connection(P2PInterface()) tx_relay_peer = self.nodes[0].add_p2p_connection(P2PInterface())
self.log.info('Check that txs from rpc are not rejected and relayed to other peers') self.log.info('Check that txs from rpc are not rejected and relayed to other peers')
assert_equal(self.nodes[0].getpeerinfo()[0]['relaytxes'], True) assert_equal(self.nodes[0].getpeerinfo()[0]['relaytxes'], True)
txid = self.nodes[0].testmempoolaccept([sigtx])[0]['txid'] txid = self.nodes[0].testmempoolaccept([sigtx])[0]['txid']
with self.nodes[0].assert_debug_log(['received getdata for: wtx {} peer=1'.format(txid)]): with self.nodes[0].assert_debug_log(['received getdata for: wtx {} peer=1'.format(txid)]):
self.nodes[0].sendrawtransaction(sigtx) self.nodes[0].sendrawtransaction(sigtx)
self.nodes[0].p2p.wait_for_tx(txid) tx_relay_peer.wait_for_tx(txid)
assert_equal(self.nodes[0].getmempoolinfo()['size'], 1) assert_equal(self.nodes[0].getmempoolinfo()['size'], 1)
self.log.info('Check that txs from peers with relay-permission are not rejected and relayed to others') self.log.info('Check that txs from peers with relay-permission are not rejected and relayed to others')

View file

@ -46,8 +46,8 @@ class RejectLowDifficultyHeadersTest(BitcoinTestFramework):
self.headers_fork = [FromHex(CBlockHeader(), h) for h in self.headers_fork] self.headers_fork = [FromHex(CBlockHeader(), h) for h in self.headers_fork]
self.log.info("Feed all non-fork headers, including and up to the first checkpoint") self.log.info("Feed all non-fork headers, including and up to the first checkpoint")
self.nodes[0].add_p2p_connection(P2PInterface()) peer_checkpoint = self.nodes[0].add_p2p_connection(P2PInterface())
self.nodes[0].p2p.send_and_ping(msg_headers(self.headers)) peer_checkpoint.send_and_ping(msg_headers(self.headers))
assert { assert {
'height': 546, 'height': 546,
'hash': '000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70', 'hash': '000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70',
@ -57,14 +57,14 @@ class RejectLowDifficultyHeadersTest(BitcoinTestFramework):
self.log.info("Feed all fork headers (fails due to checkpoint)") self.log.info("Feed all fork headers (fails due to checkpoint)")
with self.nodes[0].assert_debug_log(['bad-fork-prior-to-checkpoint']): with self.nodes[0].assert_debug_log(['bad-fork-prior-to-checkpoint']):
self.nodes[0].p2p.send_message(msg_headers(self.headers_fork)) peer_checkpoint.send_message(msg_headers(self.headers_fork))
self.nodes[0].p2p.wait_for_disconnect() peer_checkpoint.wait_for_disconnect()
self.log.info("Feed all fork headers (succeeds without checkpoint)") self.log.info("Feed all fork headers (succeeds without checkpoint)")
# On node 0 it succeeds because checkpoints are disabled # On node 0 it succeeds because checkpoints are disabled
self.restart_node(0, extra_args=['-nocheckpoints']) self.restart_node(0, extra_args=['-nocheckpoints'])
self.nodes[0].add_p2p_connection(P2PInterface()) peer_no_checkpoint = self.nodes[0].add_p2p_connection(P2PInterface())
self.nodes[0].p2p.send_and_ping(msg_headers(self.headers_fork)) peer_no_checkpoint.send_and_ping(msg_headers(self.headers_fork))
assert { assert {
"height": 2, "height": 2,
"hash": "00000000b0494bd6c3d5ff79c497cfce40831871cbf39b1bc28bd1dac817dc39", "hash": "00000000b0494bd6c3d5ff79c497cfce40831871cbf39b1bc28bd1dac817dc39",
@ -73,8 +73,8 @@ class RejectLowDifficultyHeadersTest(BitcoinTestFramework):
} in self.nodes[0].getchaintips() } in self.nodes[0].getchaintips()
# On node 1 it succeeds because no checkpoint has been reached yet by a chain tip # On node 1 it succeeds because no checkpoint has been reached yet by a chain tip
self.nodes[1].add_p2p_connection(P2PInterface()) peer_before_checkpoint = self.nodes[1].add_p2p_connection(P2PInterface())
self.nodes[1].p2p.send_and_ping(msg_headers(self.headers_fork)) peer_before_checkpoint.send_and_ping(msg_headers(self.headers_fork))
assert { assert {
"height": 2, "height": 2,
"hash": "00000000b0494bd6c3d5ff79c497cfce40831871cbf39b1bc28bd1dac817dc39", "hash": "00000000b0494bd6c3d5ff79c497cfce40831871cbf39b1bc28bd1dac817dc39",

View file

@ -131,7 +131,7 @@ class FilterTest(BitcoinTestFramework):
self.log.debug("Send a mempool msg after connecting and check that the tx is received") self.log.debug("Send a mempool msg after connecting and check that the tx is received")
self.nodes[0].add_p2p_connection(filter_peer) self.nodes[0].add_p2p_connection(filter_peer)
filter_peer.send_and_ping(filter_peer.watch_filter_init) filter_peer.send_and_ping(filter_peer.watch_filter_init)
self.nodes[0].p2p.send_message(msg_mempool()) filter_peer.send_message(msg_mempool())
filter_peer.wait_for_tx(txid) filter_peer.wait_for_tx(txid)
def test_frelay_false(self, filter_peer): def test_frelay_false(self, filter_peer):

View file

@ -27,7 +27,7 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
def run_test(self): def run_test(self):
# Add p2p connection to node0 # Add p2p connection to node0
node = self.nodes[0] # convenience reference to the node node = self.nodes[0] # convenience reference to the node
node.add_p2p_connection(P2PDataStore()) peer = node.add_p2p_connection(P2PDataStore())
best_block = node.getblock(node.getbestblockhash()) best_block = node.getblock(node.getbestblockhash())
tip = int(node.getbestblockhash(), 16) tip = int(node.getbestblockhash(), 16)
@ -42,7 +42,7 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
# Save the coinbase for later # Save the coinbase for later
block1 = block block1 = block
tip = block.sha256 tip = block.sha256
node.p2p.send_blocks_and_test([block1], node, success=True) peer.send_blocks_and_test([block1], node, success=True)
self.log.info("Mature the block.") self.log.info("Mature the block.")
node.generatetoaddress(100, node.get_deterministic_priv_key().address) node.generatetoaddress(100, node.get_deterministic_priv_key().address)
@ -80,7 +80,7 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
assert_equal(orig_hash, block2.rehash()) assert_equal(orig_hash, block2.rehash())
assert block2_orig.vtx != block2.vtx assert block2_orig.vtx != block2.vtx
node.p2p.send_blocks_and_test([block2], node, success=False, reject_reason='bad-txns-duplicate') peer.send_blocks_and_test([block2], node, success=False, reject_reason='bad-txns-duplicate')
# Check transactions for duplicate inputs (CVE-2018-17144) # Check transactions for duplicate inputs (CVE-2018-17144)
self.log.info("Test duplicate input block.") self.log.info("Test duplicate input block.")
@ -91,7 +91,7 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
block2_dup.hashMerkleRoot = block2_dup.calc_merkle_root() block2_dup.hashMerkleRoot = block2_dup.calc_merkle_root()
block2_dup.rehash() block2_dup.rehash()
block2_dup.solve() block2_dup.solve()
node.p2p.send_blocks_and_test([block2_dup], node, success=False, reject_reason='bad-txns-inputs-duplicate') peer.send_blocks_and_test([block2_dup], node, success=False, reject_reason='bad-txns-inputs-duplicate')
self.log.info("Test very broken block.") self.log.info("Test very broken block.")
@ -104,14 +104,14 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
block3.rehash() block3.rehash()
block3.solve() block3.solve()
node.p2p.send_blocks_and_test([block3], node, success=False, reject_reason='bad-cb-amount') peer.send_blocks_and_test([block3], node, success=False, reject_reason='bad-cb-amount')
# Complete testing of CVE-2012-2459 by sending the original block. # Complete testing of CVE-2012-2459 by sending the original block.
# It should be accepted even though it has the same hash as the mutated one. # It should be accepted even though it has the same hash as the mutated one.
self.log.info("Test accepting original block after rejecting its mutated version.") self.log.info("Test accepting original block after rejecting its mutated version.")
node.p2p.send_blocks_and_test([block2_orig], node, success=True, timeout=5) peer.send_blocks_and_test([block2_orig], node, success=True, timeout=5)
# Update tip info # Update tip info
height += 1 height += 1
@ -131,7 +131,7 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
block4.rehash() block4.rehash()
block4.solve() block4.solve()
self.log.info("Test inflation by duplicating input") self.log.info("Test inflation by duplicating input")
node.p2p.send_blocks_and_test([block4], node, success=False, reject_reason='bad-txns-inputs-duplicate') peer.send_blocks_and_test([block4], node, success=False, reject_reason='bad-txns-inputs-duplicate')
if __name__ == '__main__': if __name__ == '__main__':
InvalidBlockRequestTest().main() InvalidBlockRequestTest().main()

View file

@ -23,20 +23,20 @@ class InvalidLocatorTest(BitcoinTestFramework):
block_count = node.getblockcount() block_count = node.getblockcount()
for msg in [msg_getheaders(), msg_getblocks()]: for msg in [msg_getheaders(), msg_getblocks()]:
self.log.info('Wait for disconnect when sending {} hashes in locator'.format(MAX_LOCATOR_SZ + 1)) self.log.info('Wait for disconnect when sending {} hashes in locator'.format(MAX_LOCATOR_SZ + 1))
node.add_p2p_connection(P2PInterface()) exceed_max_peer = node.add_p2p_connection(P2PInterface())
msg.locator.vHave = [int(node.getblockhash(i - 1), 16) for i in range(block_count, block_count - (MAX_LOCATOR_SZ + 1), -1)] msg.locator.vHave = [int(node.getblockhash(i - 1), 16) for i in range(block_count, block_count - (MAX_LOCATOR_SZ + 1), -1)]
node.p2p.send_message(msg) exceed_max_peer.send_message(msg)
node.p2p.wait_for_disconnect() exceed_max_peer.wait_for_disconnect()
node.disconnect_p2ps() node.disconnect_p2ps()
self.log.info('Wait for response when sending {} hashes in locator'.format(MAX_LOCATOR_SZ)) self.log.info('Wait for response when sending {} hashes in locator'.format(MAX_LOCATOR_SZ))
node.add_p2p_connection(P2PInterface()) within_max_peer = node.add_p2p_connection(P2PInterface())
msg.locator.vHave = [int(node.getblockhash(i - 1), 16) for i in range(block_count, block_count - (MAX_LOCATOR_SZ), -1)] msg.locator.vHave = [int(node.getblockhash(i - 1), 16) for i in range(block_count, block_count - (MAX_LOCATOR_SZ), -1)]
node.p2p.send_message(msg) within_max_peer.send_message(msg)
if type(msg) == msg_getheaders: if type(msg) == msg_getheaders:
node.p2p.wait_for_header(node.getbestblockhash()) within_max_peer.wait_for_header(node.getbestblockhash())
else: else:
node.p2p.wait_for_block(int(node.getbestblockhash(), 16)) within_max_peer.wait_for_block(int(node.getbestblockhash(), 16))
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -61,7 +61,7 @@ class InvalidTxRequestTest(BitcoinTestFramework):
# Save the coinbase for later # Save the coinbase for later
block1 = block block1 = block
tip = block.sha256 tip = block.sha256
node.p2p.send_blocks_and_test([block], node, success=True) node.p2ps[0].send_blocks_and_test([block], node, success=True)
self.log.info("Mature the block.") self.log.info("Mature the block.")
self.nodes[0].generatetoaddress(100, self.nodes[0].get_deterministic_priv_key().address) self.nodes[0].generatetoaddress(100, self.nodes[0].get_deterministic_priv_key().address)
@ -72,7 +72,7 @@ class InvalidTxRequestTest(BitcoinTestFramework):
self.log.info("Testing invalid transaction: %s", BadTxTemplate.__name__) self.log.info("Testing invalid transaction: %s", BadTxTemplate.__name__)
template = BadTxTemplate(spend_block=block1) template = BadTxTemplate(spend_block=block1)
tx = template.get_tx() tx = template.get_tx()
node.p2p.send_txs_and_test( node.p2ps[0].send_txs_and_test(
[tx], node, success=False, [tx], node, success=False,
expect_disconnect=template.expect_disconnect, expect_disconnect=template.expect_disconnect,
reject_reason=template.reject_reason, reject_reason=template.reject_reason,
@ -121,7 +121,7 @@ class InvalidTxRequestTest(BitcoinTestFramework):
self.log.info('Send the orphans ... ') self.log.info('Send the orphans ... ')
# Send valid orphan txs from p2ps[0] # Send valid orphan txs from p2ps[0]
node.p2p.send_txs_and_test([tx_orphan_1, tx_orphan_2_no_fee, tx_orphan_2_valid], node, success=False) node.p2ps[0].send_txs_and_test([tx_orphan_1, tx_orphan_2_no_fee, tx_orphan_2_valid], node, success=False)
# Send invalid tx from p2ps[1] # Send invalid tx from p2ps[1]
node.p2ps[1].send_txs_and_test([tx_orphan_2_invalid], node, success=False) node.p2ps[1].send_txs_and_test([tx_orphan_2_invalid], node, success=False)
@ -130,7 +130,7 @@ class InvalidTxRequestTest(BitcoinTestFramework):
self.log.info('Send the withhold tx ... ') self.log.info('Send the withhold tx ... ')
with node.assert_debug_log(expected_msgs=["bad-txns-in-belowout"]): with node.assert_debug_log(expected_msgs=["bad-txns-in-belowout"]):
node.p2p.send_txs_and_test([tx_withhold], node, success=True) node.p2ps[0].send_txs_and_test([tx_withhold], node, success=True)
# Transactions that should end up in the mempool # Transactions that should end up in the mempool
expected_mempool = { expected_mempool = {
@ -155,14 +155,14 @@ class InvalidTxRequestTest(BitcoinTestFramework):
orphan_tx_pool[i].vout.append(CTxOut(nValue=11 * COIN, scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE)) orphan_tx_pool[i].vout.append(CTxOut(nValue=11 * COIN, scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE))
with node.assert_debug_log(['mapOrphan overflow, removed 1 tx']): with node.assert_debug_log(['mapOrphan overflow, removed 1 tx']):
node.p2p.send_txs_and_test(orphan_tx_pool, node, success=False) node.p2ps[0].send_txs_and_test(orphan_tx_pool, node, success=False)
rejected_parent = CTransaction() rejected_parent = CTransaction()
rejected_parent.vin.append(CTxIn(outpoint=COutPoint(tx_orphan_2_invalid.sha256, 0))) rejected_parent.vin.append(CTxIn(outpoint=COutPoint(tx_orphan_2_invalid.sha256, 0)))
rejected_parent.vout.append(CTxOut(nValue=11 * COIN, scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE)) rejected_parent.vout.append(CTxOut(nValue=11 * COIN, scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE))
rejected_parent.rehash() rejected_parent.rehash()
with node.assert_debug_log(['not keeping orphan with rejected parents {}'.format(rejected_parent.hash)]): with node.assert_debug_log(['not keeping orphan with rejected parents {}'.format(rejected_parent.hash)]):
node.p2p.send_txs_and_test([rejected_parent], node, success=False) node.p2ps[0].send_txs_and_test([rejected_parent], node, success=False)
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -2097,14 +2097,14 @@ class SegWitTest(BitcoinTestFramework):
tx = FromHex(CTransaction(), raw) tx = FromHex(CTransaction(), raw)
assert_raises_rpc_error(-22, "TX decode failed", self.nodes[0].decoderawtransaction, serialize_with_bogus_witness(tx).hex()) assert_raises_rpc_error(-22, "TX decode failed", self.nodes[0].decoderawtransaction, serialize_with_bogus_witness(tx).hex())
with self.nodes[0].assert_debug_log(['Superfluous witness record']): with self.nodes[0].assert_debug_log(['Superfluous witness record']):
self.nodes[0].p2p.send_and_ping(msg_bogus_tx(tx)) self.test_node.send_and_ping(msg_bogus_tx(tx))
raw = self.nodes[0].signrawtransactionwithwallet(raw) raw = self.nodes[0].signrawtransactionwithwallet(raw)
assert raw['complete'] assert raw['complete']
raw = raw['hex'] raw = raw['hex']
tx = FromHex(CTransaction(), raw) tx = FromHex(CTransaction(), raw)
assert_raises_rpc_error(-22, "TX decode failed", self.nodes[0].decoderawtransaction, serialize_with_bogus_witness(tx).hex()) assert_raises_rpc_error(-22, "TX decode failed", self.nodes[0].decoderawtransaction, serialize_with_bogus_witness(tx).hex())
with self.nodes[0].assert_debug_log(['Unknown transaction optional data']): with self.nodes[0].assert_debug_log(['Unknown transaction optional data']):
self.nodes[0].p2p.send_and_ping(msg_bogus_tx(tx)) self.test_node.send_and_ping(msg_bogus_tx(tx))
@subtest # type: ignore @subtest # type: ignore
def test_wtxid_relay(self): def test_wtxid_relay(self):

View file

@ -317,7 +317,7 @@ class BlockchainTest(BitcoinTestFramework):
def _test_waitforblockheight(self): def _test_waitforblockheight(self):
self.log.info("Test waitforblockheight") self.log.info("Test waitforblockheight")
node = self.nodes[0] node = self.nodes[0]
node.add_p2p_connection(P2PInterface()) peer = node.add_p2p_connection(P2PInterface())
current_height = node.getblock(node.getbestblockhash())['height'] current_height = node.getblock(node.getbestblockhash())['height']
@ -334,7 +334,7 @@ class BlockchainTest(BitcoinTestFramework):
def solve_and_send_block(prevhash, height, time): def solve_and_send_block(prevhash, height, time):
b = create_block(prevhash, create_coinbase(height), time) b = create_block(prevhash, create_coinbase(height), time)
b.solve() b.solve()
node.p2p.send_and_ping(msg_block(b)) peer.send_and_ping(msg_block(b))
return b return b
b21f = solve_and_send_block(int(b20hash, 16), 21, b20['time'] + 1) b21f = solve_and_send_block(int(b20hash, 16), 21, b20['time'] + 1)

View file

@ -542,15 +542,6 @@ class TestNode():
return p2p_conn return p2p_conn
@property
def p2p(self):
"""Return the first p2p connection
Convenience property - most tests only use a single p2p connection to each
node, so this saves having to write node.p2ps[0] many times."""
assert self.p2ps, self._node_msg("No p2p connection")
return self.p2ps[0]
def num_test_p2p_connections(self): def num_test_p2p_connections(self):
"""Return number of test framework p2p connections to the node.""" """Return number of test framework p2p connections to the node."""
return len([peer for peer in self.getpeerinfo() if peer['subver'] == MY_SUBVERSION]) return len([peer for peer in self.getpeerinfo() if peer['subver'] == MY_SUBVERSION])

View file

@ -21,7 +21,7 @@ class ResendWalletTransactionsTest(BitcoinTestFramework):
def run_test(self): def run_test(self):
node = self.nodes[0] # alias node = self.nodes[0] # alias
node.add_p2p_connection(P2PTxInvStore()) peer_first = node.add_p2p_connection(P2PTxInvStore())
self.log.info("Create a new transaction and wait until it's broadcast") self.log.info("Create a new transaction and wait until it's broadcast")
txid = node.sendtoaddress(node.getnewaddress(), 1) txid = node.sendtoaddress(node.getnewaddress(), 1)
@ -33,10 +33,10 @@ class ResendWalletTransactionsTest(BitcoinTestFramework):
time.sleep(1.1) time.sleep(1.1)
# Can take a few seconds due to transaction trickling # Can take a few seconds due to transaction trickling
node.p2p.wait_for_broadcast([txid]) peer_first.wait_for_broadcast([txid])
# Add a second peer since txs aren't rebroadcast to the same peer (see filterInventoryKnown) # Add a second peer since txs aren't rebroadcast to the same peer (see filterInventoryKnown)
node.add_p2p_connection(P2PTxInvStore()) peer_second = node.add_p2p_connection(P2PTxInvStore())
self.log.info("Create a block") self.log.info("Create a block")
# Create and submit a block without the transaction. # Create and submit a block without the transaction.
@ -64,7 +64,7 @@ class ResendWalletTransactionsTest(BitcoinTestFramework):
# Transaction should be rebroadcast approximately 24 hours in the future, # Transaction should be rebroadcast approximately 24 hours in the future,
# but can range from 12-36. So bump 36 hours to be sure. # but can range from 12-36. So bump 36 hours to be sure.
node.setmocktime(now + 36 * 60 * 60) node.setmocktime(now + 36 * 60 * 60)
node.p2p.wait_for_broadcast([txid]) peer_second.wait_for_broadcast([txid])
if __name__ == '__main__': if __name__ == '__main__':