def test_peer_table_updated_on_join_command(self): # Network params issue w1 = Wallet() p1 = Network(wallet=w1, socket_base='tcp://127.0.0.1', ctx=self.ctx) w2 = Wallet() d = DiscoveryServer(wallet=w2, socket_id=_socket('tcp://127.0.0.1:19000'), pepper=PEPPER.encode(), ctx=self.ctx, linger=200) # 1. start network # 2. start discovery of other side # 3. send join request # 4. check to see if the data has been added join_message = ['join', (w2.verifying_key().hex(), 'tcp://127.0.0.1')] join_message = json.dumps(join_message).encode() tasks = asyncio.gather( p1.peer_service.serve(), d.serve(), services.get(_socket('tcp://127.0.0.1:10002'), msg=join_message, ctx=self.ctx, timeout=1000), stop_server(p1.peer_service, 0.3), stop_server(d, 0.3)) loop = asyncio.get_event_loop() loop.run_until_complete(tasks) self.assertEqual(p1.peer_service.table[w2.verifying_key().hex()], 'tcp://127.0.0.1')
def test_peer_server_returns_all_peers_if_doesnt_have_it_or_more_than_response_amount_ipc( self): w1 = Wallet() p1 = Network(wallet=w1, socket_base='ipc:///tmp', ctx=self.ctx) test_dict = {'test': 'value', 'another': 'one', 'something': 'else'} p1.peer_service.table = test_dict find_message = ['find', 'baloney'] find_message = json.dumps(find_message).encode() tasks = asyncio.gather( p1.peer_service.serve(), stop_server(p1.peer_service, 0.3), services.get(_socket('ipc:///tmp/peers'), msg=find_message, ctx=self.ctx, timeout=300)) loop = asyncio.get_event_loop() res = loop.run_until_complete(tasks) response = res[-1] response = response.decode() response = json.loads(response) self.assertDictEqual(test_dict, response)
def test_peer_server_returns_peer_when_asked_ipc(self): w1 = Wallet() p1 = Network(wallet=w1, socket_base='ipc:///tmp', ctx=self.ctx) w2 = Wallet() p1.peer_service.table[w2.verifying_key().hex()] = 'inproc://goodtimes' find_message = ['find', w2.verifying_key().hex()] find_message = json.dumps(find_message).encode() tasks = asyncio.gather( p1.peer_service.serve(), stop_server(p1.peer_service, 0.3), services.get(_socket('ipc:///tmp/peers'), msg=find_message, ctx=self.ctx, timeout=300)) loop = asyncio.get_event_loop() res = loop.run_until_complete(tasks) response = res[-1] response = response.decode() response = json.loads(response) self.assertEqual(response.get(w2.verifying_key().hex()), 'inproc://goodtimes')
def test_event_service_triggered_when_new_node_added_ipc(self): # Create Network service w1 = Wallet() p1 = Network(wallet=w1, ctx=self.ctx, socket_base='ipc:///tmp') n1 = '/tmp/n1' try: os.mkdir('/tmp/n1') except: pass # Create Discovery Server w2 = Wallet() d = DiscoveryServer(wallet=w2, socket_id=_socket('ipc:///tmp/n1/discovery'), pepper=PEPPER.encode(), ctx=self.ctx, poll_timeout=2000, linger=200) # Create raw subscriber subscriber = self.ctx.socket(zmq.SUB) subscriber.setsockopt(zmq.SUBSCRIBE, b'') subscriber.connect('ipc:///tmp/events') # TCP takes a bit longer to bind and is prone to dropping messages... sleep(0.3) # Construct the join RPC message join_message = ['join', (w2.verifying_key().hex(), 'ipc:///tmp/n1')] join_message = json.dumps(join_message).encode() # Wrap recv() in an async async def recv(): msg = await subscriber.recv() return msg tasks = asyncio.gather( p1.peer_service.start( ), # Start the PeerService which will process RPC and emit events d.serve( ), # Start Discovery so PeerService can verify they are online services.get(_socket('ipc:///tmp/peers'), msg=join_message, ctx=self.ctx, timeout=3000), # Push out a join request stop_server(p1.peer_service, 1), stop_server(d, 1), recv() # Collect the subscription result ) loop = asyncio.get_event_loop() res = loop.run_until_complete(tasks) expected_list = ['join', [w2.verifying_key().hex(), 'ipc:///tmp/n1']] got_list = json.loads(res[-1].decode()) self.assertListEqual(expected_list, got_list)
async def find_node(self, client_address: struct.SocketStruct = None, vk_to_find=None, retries=3): # Search locally if this is the case if str(client_address) == str(self.peer_service_address) or \ vk_to_find == self.wallet.verifying_key().hex() or \ client_address is None: response = { vk_to_find: self.peer_service.table.get(vk_to_find) } if self.peer_service.table.get( vk_to_find) is not None else self.peer_service.table # Otherwise, send out a network request else: find_message = ['find', vk_to_find] find_message = json.dumps(find_message, cls=struct.SocketEncoder).encode() response = await services.get(client_address, msg=find_message, ctx=self.ctx, timeout=1000) join_message = [ 'join', (self.wallet.verifying_key().hex(), self.socket_base) ] join_msg = json.dumps(join_message).encode() asyncio.ensure_future( services.get(client_address, msg=join_msg, ctx=self.ctx, timeout=1000)) if response is None: return None response = json.loads(response.decode()) if response.get(vk_to_find) is not None: return response if retries <= 1: return None # Recursive crawl goes 'retries' levels deep for vk, ip in response.items(): return await self.find_node(self.params.resolve( ip, ServiceType.PEER), vk_to_find, retries=retries - 1)
def test_other_peers_add_new_nodes_when_join_event_occurs_ipc(self): # N3 runs discovery server and pings N1 # N1 checks to see if N3 is valid, and if so, adds to their table and pings N2 about the new join # Create Network service w1 = Wallet() p1 = Network(wallet=w1, ctx=self.ctx, socket_base='ipc:///tmp/n1') # Create Network service w2 = Wallet() p2 = Network(wallet=w2, ctx=self.ctx, socket_base='ipc:///tmp/n2') p2.peer_service.event_service.add_subscription( _socket('ipc:///tmp/n1/events')) # Create Discovery Server w3 = Wallet() d = DiscoveryServer(wallet=w3, socket_id=_socket('ipc:///tmp/n3/discovery'), pepper=PEPPER.encode(), ctx=self.ctx, poll_timeout=2000, linger=2000) # TCP takes a bit longer to bind and is prone to dropping messages... sleep(1) # Construct the join RPC message join_message = ['join', (w3.verifying_key().hex(), 'ipc:///tmp/n3')] join_message = json.dumps(join_message).encode() tasks = asyncio.gather( p1.peer_service.start(), p2.peer_service.start(), d.serve(), services.get(_socket('ipc:///tmp/n1/peers'), msg=join_message, ctx=self.ctx, timeout=1000), stop_server(p1.peer_service, 2), stop_server(p2.peer_service, 2), stop_server(d, 2), ) loop = asyncio.get_event_loop() loop.run_until_complete(tasks) self.assertTrue(w3.verifying_key().hex() in p2.peer_service.table)
def test_peer_server_returns_self_when_asked(self): w1 = Wallet() p1 = Network(wallet=w1, socket_base='tcp://127.0.0.1', ctx=self.ctx) find_message = ['find', w1.verifying_key().hex()] find_message = json.dumps(find_message).encode() tasks = asyncio.gather( p1.peer_service.serve(), stop_server(p1.peer_service, 0.3), services.get(_socket('tcp://127.0.0.1:19002'), msg=find_message, ctx=self.ctx, timeout=300)) loop = asyncio.get_event_loop() res = loop.run_until_complete(tasks) response = res[-1] response = response.decode() response = json.loads(response) self.assertEqual(response.get(w1.verifying_key().hex()), 'tcp://127.0.0.1')