async def test_proxy_peer_requests(request, event_bus, other_event_bus, event_loop, chaindb_fresh, chaindb_20): server_event_bus = event_bus client_event_bus = other_event_bus client_peer, server_peer = await get_directly_linked_peers( request, event_loop, alice_headerdb=FakeAsyncChainDB(chaindb_fresh.db), bob_headerdb=FakeAsyncChainDB(chaindb_20.db), ) client_peer_pool = MockPeerPoolWithConnectedPeers( [client_peer], event_bus=client_event_bus) server_peer_pool = MockPeerPoolWithConnectedPeers( [server_peer], event_bus=server_event_bus) async with run_peer_pool_event_server( client_event_bus, client_peer_pool, handler_type=ETHPeerPoolEventServer), run_peer_pool_event_server( server_event_bus, server_peer_pool, handler_type=ETHPeerPoolEventServer), run_request_server( server_event_bus, FakeAsyncChainDB(chaindb_20.db)), run_proxy_peer_pool( client_event_bus ) as client_proxy_peer_pool, run_proxy_peer_pool( server_event_bus): proxy_peer = await client_proxy_peer_pool.ensure_proxy_peer( client_peer.remote) headers = await proxy_peer.requests.get_block_headers(0, 1, 0, False) assert len(headers) == 1 block_header = headers[0] assert block_header.block_number == 0 receipts = await proxy_peer.requests.get_receipts(headers) assert len(receipts) == 1 receipt = receipts[0] assert receipt[1][0] == block_header.receipt_root block_bundles = await proxy_peer.requests.get_block_bodies(headers) assert len(block_bundles) == 1 first_bundle = block_bundles[0] assert first_bundle[1][0] == block_header.transaction_root node_data = await proxy_peer.requests.get_node_data( (block_header.state_root, )) assert node_data[0][0] == block_header.state_root
async def test_requests_when_peer_in_client_vanishs(request, event_bus, other_event_bus, event_loop, chaindb_fresh, chaindb_20): server_event_bus = event_bus client_event_bus = other_event_bus client_peer, server_peer = await get_directly_linked_peers( request, event_loop, alice_headerdb=FakeAsyncChainDB(chaindb_fresh.db), bob_headerdb=FakeAsyncChainDB(chaindb_20.db), ) client_peer_pool = MockPeerPoolWithConnectedPeers( [client_peer], event_bus=client_event_bus) server_peer_pool = MockPeerPoolWithConnectedPeers( [server_peer], event_bus=server_event_bus) async with run_peer_pool_event_server( client_event_bus, client_peer_pool, handler_type=ETHPeerPoolEventServer), run_peer_pool_event_server( server_event_bus, server_peer_pool, handler_type=ETHPeerPoolEventServer), run_request_server( server_event_bus, FakeAsyncChainDB(chaindb_20.db)), run_proxy_peer_pool( client_event_bus ) as client_proxy_peer_pool, run_proxy_peer_pool( server_event_bus): proxy_peer = await client_proxy_peer_pool.ensure_proxy_peer( client_peer.remote) # We remove the peer from the client and assume to see PeerConnectionLost exceptions raised client_peer_pool.connected_nodes.pop(client_peer.remote) with pytest.raises(PeerConnectionLost): await proxy_peer.requests.get_block_headers(0, 1, 0, False) with pytest.raises(PeerConnectionLost): await proxy_peer.requests.get_receipts(()) with pytest.raises(PeerConnectionLost): await proxy_peer.requests.get_block_bodies(()) with pytest.raises(PeerConnectionLost): await proxy_peer.requests.get_node_data(())
async def test_proxy_peer_requests(request, event_bus, other_event_bus, event_loop, chaindb_20, client_and_server): server_event_bus = event_bus client_event_bus = other_event_bus client_peer, server_peer = client_and_server client_peer_pool = MockPeerPoolWithConnectedPeers( [client_peer], event_bus=client_event_bus) server_peer_pool = MockPeerPoolWithConnectedPeers( [server_peer], event_bus=server_event_bus) async with run_peer_pool_event_server( client_event_bus, client_peer_pool, handler_type=ETHPeerPoolEventServer), run_peer_pool_event_server( server_event_bus, server_peer_pool, handler_type=ETHPeerPoolEventServer ), background_asyncio_service( ETHRequestServer( server_event_bus, TO_NETWORKING_BROADCAST_CONFIG, AsyncChainDB(chaindb_20.db))), run_proxy_peer_pool( client_event_bus ) as client_proxy_peer_pool, run_proxy_peer_pool( server_event_bus): proxy_peer = await client_proxy_peer_pool.ensure_proxy_peer( client_peer.session) headers = await proxy_peer.eth_api.get_block_headers(0, 1, 0, False) assert len(headers) == 1 block_header = headers[0] assert block_header.block_number == 0 receipts = await proxy_peer.eth_api.get_receipts(headers) assert len(receipts) == 1 receipt = receipts[0] assert receipt[1][0] == block_header.receipt_root block_bundles = await proxy_peer.eth_api.get_block_bodies(headers) assert len(block_bundles) == 1 first_bundle = block_bundles[0] assert first_bundle[1][0] == block_header.transaction_root node_data = await proxy_peer.eth_api.get_node_data( (block_header.state_root, )) assert node_data[0][0] == block_header.state_root
async def test_does_not_propagate_invalid_tx(event_bus, chain_with_block_validation, tx_validator): initial_two_peers = TEST_NODES[:2] node_one = initial_two_peers[0] node_two = initial_two_peers[1] async with run_proxy_peer_pool(event_bus) as peer_pool: outgoing_tx = observe_outgoing_transactions(event_bus) tx_pool = TxPool(event_bus, peer_pool, tx_validator) asyncio.ensure_future(tx_pool.run()) run_mock_request_response(GetConnectedPeersRequest, GetConnectedPeersResponse(initial_two_peers), event_bus) await asyncio.sleep(0.01) txs_broadcasted_by_peer1 = [ create_random_tx(chain_with_block_validation, is_valid=False), create_random_tx(chain_with_block_validation) ] # Peer1 sends some txs await event_bus.broadcast( TransactionsEvent(remote=node_one, msg=txs_broadcasted_by_peer1, cmd=Transactions)) await asyncio.sleep(0.01) # Check that Peer2 received only the second tx which is valid assert outgoing_tx == [ (node_two, [txs_broadcasted_by_peer1[1]]), ]
async def test_does_not_propagate_invalid_tx(event_bus, funded_address_private_key, chain_with_block_validation, tx_validator): initial_two_peers = TEST_NODES[:2] node_one = initial_two_peers[0] node_two = initial_two_peers[1] async with run_proxy_peer_pool(event_bus) as peer_pool: tx_pool = TxPool(event_bus, peer_pool, tx_validator) async with run_service(tx_pool): run_mock_request_response( GetConnectedPeersRequest, GetConnectedPeersResponse(initial_two_peers), event_bus) await asyncio.sleep(0.01) txs_broadcasted_by_peer1 = [ create_random_tx(chain_with_block_validation, funded_address_private_key, is_valid=False), # noqa: E501 create_random_tx(chain_with_block_validation, funded_address_private_key) ] outgoing_tx, got_txns = observe_outgoing_transactions(event_bus) # Peer1 sends some txs await event_bus.broadcast( TransactionsEvent(session=node_one, command=Transactions(txs_broadcasted_by_peer1)) ) await asyncio.wait_for(got_txns.wait(), timeout=0.1) # Check that Peer2 received only the second tx which is valid assert outgoing_tx == [ (node_two, (txs_broadcasted_by_peer1[1],)), ]
async def test_get_peers(event_bus, response, expected_count): run_mock_request_response(GetConnectedPeersRequest, response, event_bus) async with run_proxy_peer_pool(event_bus) as proxy_peer_pool: peers = await proxy_peer_pool.get_peers() assert len(peers) == expected_count
async def test_proxy_peer_requests_with_timeouts(request, event_bus, other_event_bus, event_loop, chaindb_fresh, chaindb_20): server_event_bus = event_bus client_event_bus = other_event_bus client_peer, server_peer = await get_directly_linked_peers( request, event_loop, alice_headerdb=FakeAsyncChainDB(chaindb_fresh.db), bob_headerdb=FakeAsyncChainDB(chaindb_20.db), ) client_peer_pool = MockPeerPoolWithConnectedPeers( [client_peer], event_bus=client_event_bus) server_peer_pool = MockPeerPoolWithConnectedPeers( [server_peer], event_bus=server_event_bus) async with run_peer_pool_event_server( client_event_bus, client_peer_pool, handler_type=ETHPeerPoolEventServer), run_peer_pool_event_server( server_event_bus, server_peer_pool, handler_type=ETHPeerPoolEventServer), run_proxy_peer_pool( client_event_bus ) as client_proxy_peer_pool, run_proxy_peer_pool( server_event_bus): proxy_peer = await client_proxy_peer_pool.ensure_proxy_peer( client_peer.remote) with pytest.raises(TimeoutError): await proxy_peer.requests.get_block_headers(0, 1, 0, False, timeout=0.01) with pytest.raises(TimeoutError): await proxy_peer.requests.get_receipts((), timeout=0.01) with pytest.raises(TimeoutError): await proxy_peer.requests.get_block_bodies((), timeout=0.01) with pytest.raises(TimeoutError): await proxy_peer.requests.get_node_data((), timeout=0.01)
async def test_requests_when_peer_in_client_vanishs(request, event_bus, other_event_bus, event_loop, chaindb_20, client_and_server): server_event_bus = event_bus client_event_bus = other_event_bus client_peer, server_peer = client_and_server client_peer_pool = MockPeerPoolWithConnectedPeers( [client_peer], event_bus=client_event_bus) server_peer_pool = MockPeerPoolWithConnectedPeers( [server_peer], event_bus=server_event_bus) async with run_peer_pool_event_server( client_event_bus, client_peer_pool, handler_type=ETHPeerPoolEventServer), run_peer_pool_event_server( server_event_bus, server_peer_pool, handler_type=ETHPeerPoolEventServer ), background_asyncio_service( ETHRequestServer( server_event_bus, TO_NETWORKING_BROADCAST_CONFIG, AsyncChainDB(chaindb_20.db))), run_proxy_peer_pool( client_event_bus ) as client_proxy_peer_pool, run_proxy_peer_pool( server_event_bus): proxy_peer = await client_proxy_peer_pool.ensure_proxy_peer( client_peer.session) # We remove the peer from the client and assume to see PeerConnectionLost exceptions raised client_peer_pool.connected_nodes.pop(client_peer.session) with pytest.raises(PeerConnectionLost): await proxy_peer.eth_api.get_block_headers(0, 1, 0, False) with pytest.raises(PeerConnectionLost): await proxy_peer.eth_api.get_receipts(()) with pytest.raises(PeerConnectionLost): await proxy_peer.eth_api.get_block_bodies(()) with pytest.raises(PeerConnectionLost): await proxy_peer.eth_api.get_node_data(())
async def test_proxy_peer_requests_with_timeouts(request, event_bus, other_event_bus, event_loop, client_and_server): server_event_bus = event_bus client_event_bus = other_event_bus client_peer, server_peer = client_and_server client_peer_pool = MockPeerPoolWithConnectedPeers( [client_peer], event_bus=client_event_bus) server_peer_pool = MockPeerPoolWithConnectedPeers( [server_peer], event_bus=server_event_bus) async with run_peer_pool_event_server( client_event_bus, client_peer_pool, handler_type=ETHPeerPoolEventServer), run_peer_pool_event_server( server_event_bus, server_peer_pool, handler_type=ETHPeerPoolEventServer), run_proxy_peer_pool( client_event_bus ) as client_proxy_peer_pool, run_proxy_peer_pool( server_event_bus): proxy_peer = await client_proxy_peer_pool.ensure_proxy_peer( client_peer.session) with pytest.raises(asyncio.TimeoutError): await proxy_peer.requests.get_block_headers(0, 1, 0, False, timeout=0.01) with pytest.raises(asyncio.TimeoutError): await proxy_peer.requests.get_receipts((), timeout=0.01) with pytest.raises(asyncio.TimeoutError): await proxy_peer.requests.get_block_bodies((), timeout=0.01) with pytest.raises(asyncio.TimeoutError): await proxy_peer.requests.get_node_data((), timeout=0.01)
async def test_adds_new_peers(event_bus): async with run_proxy_peer_pool(event_bus) as proxy_peer_pool: run_mock_request_response(GetConnectedPeersRequest, GetConnectedPeersResponse((TEST_NODES[0], )), event_bus) assert len(await proxy_peer_pool.get_peers()) == 1 await event_bus.broadcast(PeerJoinedEvent(TEST_NODES[1])) # Give the peer a moment to pickup the peer await asyncio.sleep(0.01) assert len(await proxy_peer_pool.get_peers()) == 2
async def test_removes_peers(event_bus): async with run_proxy_peer_pool(event_bus) as proxy_peer_pool: run_mock_request_response(GetConnectedPeersRequest, GetConnectedPeersResponse(TEST_NODES[:2]), event_bus) assert len(await proxy_peer_pool.get_peers()) == 2 await event_bus.broadcast(PeerLeftEvent(TEST_NODES[0])) # Give the peer a moment to remove the peer await asyncio.sleep(0.01) peers = await proxy_peer_pool.get_peers() assert len(peers) == 1 assert peers[0].remote is TEST_NODES[1]
async def test_tx_propagation(event_bus, chain_with_block_validation, tx_validator): initial_two_peers = TEST_NODES[:2] node_one = initial_two_peers[0] node_two = initial_two_peers[1] async with run_proxy_peer_pool(event_bus) as peer_pool: outgoing_tx = observe_outgoing_transactions(event_bus) tx_pool = TxPool(event_bus, peer_pool, tx_validator) asyncio.ensure_future(tx_pool.run()) run_mock_request_response(GetConnectedPeersRequest, GetConnectedPeersResponse(initial_two_peers), event_bus) await asyncio.sleep(0.01) txs_broadcasted_by_peer1 = [ create_random_tx(chain_with_block_validation) ] # Peer1 sends some txs await event_bus.broadcast( TransactionsEvent(remote=node_one, msg=txs_broadcasted_by_peer1, cmd=Transactions)) await asyncio.sleep(0.01) assert outgoing_tx == [ (node_two, txs_broadcasted_by_peer1), ] # Clear the recording, we asserted all we want and would like to have a fresh start outgoing_tx.clear() # Peer1 sends same txs again await event_bus.broadcast( TransactionsEvent(remote=node_one, msg=txs_broadcasted_by_peer1, cmd=Transactions)) await asyncio.sleep(0.01) # Check that Peer2 doesn't receive them again assert len(outgoing_tx) == 0 # Peer2 sends exact same txs back await event_bus.broadcast( TransactionsEvent(remote=node_two, msg=txs_broadcasted_by_peer1, cmd=Transactions)) await asyncio.sleep(0.01) # Check that Peer1 won't get them as that is where they originally came from assert len(outgoing_tx) == 0 txs_broadcasted_by_peer2 = [ create_random_tx(chain_with_block_validation), txs_broadcasted_by_peer1[0] ] # Peer2 sends old + new tx await event_bus.broadcast( TransactionsEvent(remote=node_two, msg=txs_broadcasted_by_peer2, cmd=Transactions)) await asyncio.sleep(0.01) # Check that Peer1 receives only the one tx that it didn't know about assert outgoing_tx == [ (node_one, [txs_broadcasted_by_peer2[0]]), ]
async def test_tx_propagation(event_bus, funded_address_private_key, chain_with_block_validation, tx_validator): initial_two_peers = TEST_NODES[:2] node_one = initial_two_peers[0] node_two = initial_two_peers[1] async with run_proxy_peer_pool(event_bus) as peer_pool: tx_pool = TxPool(event_bus, peer_pool, tx_validator) async with run_service(tx_pool): run_mock_request_response( GetConnectedPeersRequest, GetConnectedPeersResponse(initial_two_peers), event_bus) await asyncio.sleep(0.01) txs_broadcasted_by_peer1 = [ create_random_tx(chain_with_block_validation, funded_address_private_key) ] # this needs to go here to ensure that the subscription is *after* # the one installed by the transaction pool so that the got_txns # event will get set after the other handlers have been called. outgoing_tx, got_txns = observe_outgoing_transactions(event_bus) # Peer1 sends some txs await event_bus.broadcast( TransactionsEvent(session=node_one, command=Transactions(txs_broadcasted_by_peer1)) ) await asyncio.wait_for(got_txns.wait(), timeout=0.1) assert outgoing_tx == [ (node_two, tuple(txs_broadcasted_by_peer1)), ] # Clear the recording, we asserted all we want and would like to have a fresh start outgoing_tx.clear() # Peer1 sends same txs again await event_bus.broadcast( TransactionsEvent(session=node_one, command=Transactions(txs_broadcasted_by_peer1)) ) await asyncio.wait_for(got_txns.wait(), timeout=0.1) # Check that Peer2 doesn't receive them again assert len(outgoing_tx) == 0 # Peer2 sends exact same txs back await event_bus.broadcast( TransactionsEvent(session=node_two, command=Transactions(txs_broadcasted_by_peer1)) ) await asyncio.wait_for(got_txns.wait(), timeout=0.1) # Check that Peer1 won't get them as that is where they originally came from assert len(outgoing_tx) == 0 txs_broadcasted_by_peer2 = [ create_random_tx(chain_with_block_validation, funded_address_private_key), txs_broadcasted_by_peer1[0] ] # Peer2 sends old + new tx await event_bus.broadcast( TransactionsEvent(session=node_two, command=Transactions(txs_broadcasted_by_peer2)) ) await asyncio.wait_for(got_txns.wait(), timeout=0.1) # Not sure why this sleep is needed.... await asyncio.sleep(0.01) # Check that Peer1 receives only the one tx that it didn't know about assert outgoing_tx == [ (node_one, (txs_broadcasted_by_peer2[0],)), ]
async def test_can_instantiate_proxy_pool(event_bus): async with run_proxy_peer_pool(event_bus) as proxy_peer_pool: assert proxy_peer_pool is not None