def get_nodes_to_connect(self) -> Generator[Node, None, None]: from evm.chains.ropsten import RopstenChain from evm.chains.mainnet import MainnetChain if self.network_id == MainnetChain.network_id: yield Node(keys.PublicKey(decode_hex("1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082")), # noqa: E501 Address("52.74.57.123", 30303, 30303)) yield Node(keys.PublicKey(decode_hex("78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d")), # noqa: E501 Address("191.235.84.50", 30303, 30303)) yield Node(keys.PublicKey(decode_hex("ddd81193df80128880232fc1deb45f72746019839589eeb642d3d44efbb8b2dda2c1a46a348349964a6066f8afb016eb2a8c0f3c66f32fadf4370a236a4b5286")), # noqa: E501 Address("52.231.202.145", 30303, 30303)) yield Node(keys.PublicKey(decode_hex("3f1d12044546b76342d59d4a05532c14b85aa669704bfe1f864fe079415aa2c02d743e03218e57a33fb94523adb54032871a6c51b2cc5514cb7c7e35b3ed0a99")), # noqa: E501 Address("13.93.211.84", 30303, 30303)) elif self.network_id == RopstenChain.network_id: yield Node(keys.PublicKey(decode_hex("88c2b24429a6f7683fbfd06874ae3f1e7c8b4a5ffb846e77c705ba02e2543789d66fc032b6606a8d8888eb6239a2abe5897ce83f78dcdcfcb027d6ea69aa6fe9")), # noqa: E501 Address("163.172.157.61", 30303, 30303)) yield Node(keys.PublicKey(decode_hex("a1ef9ba5550d5fac27f7cbd4e8d20a643ad75596f307c91cd6e7f85b548b8a6bf215cca436d6ee436d6135f9fe51398f8dd4c0bd6c6a0c332ccb41880f33ec12")), # noqa: E501 Address("51.15.218.125", 30303, 30303)) yield Node(keys.PublicKey(decode_hex("e80276aabb7682a4a659f4341c1199de79d91a2e500a6ee9bed16ed4ce927ba8d32ba5dea357739ffdf2c5bcc848d3064bb6f149f0b4249c1f7e53f8bf02bfc8")), # noqa: E501 Address("51.15.39.57", 30303, 30303)) yield Node(keys.PublicKey(decode_hex("584c0db89b00719e9e7b1b5c32a4a8942f379f4d5d66bb69f9c7fa97fa42f64974e7b057b35eb5a63fd7973af063f9a1d32d8c60dbb4854c64cb8ab385470258")), # noqa: E501 Address("51.15.35.2", 30303, 30303)) yield Node(keys.PublicKey(decode_hex("d40871fc3e11b2649700978e06acd68a24af54e603d4333faecb70926ca7df93baa0b7bf4e927fcad9a7c1c07f9b325b22f6d1730e728314d0e4e6523e5cebc2")), # noqa: E501 Address("51.15.132.235", 30303, 30303)) yield Node(keys.PublicKey(decode_hex("482484b9198530ee2e00db89791823244ca41dcd372242e2e1297dd06f6d8dd357603960c5ad9cc8dc15fcdf0e4edd06b7ad7db590e67a0b54f798c26581ebd7")), # noqa: E501 Address("51.15.75.138", 30303, 30303)) else: raise ValueError("Unknown network_id: {}".format(self.network_id))
async def _run(self) -> None: external_ip = "0.0.0.0" address = Address(external_ip, self.trinity_config.port, self.trinity_config.port) if self.trinity_config.use_discv5: protocol = get_protocol(self.trinity_config) topic = get_discv5_topic(self.trinity_config, protocol) discovery_protocol: DiscoveryProtocol = DiscoveryByTopicProtocol( topic, self.trinity_config.nodekey, address, self.trinity_config.bootstrap_nodes, self.cancel_token, ) else: discovery_protocol = PreferredNodeDiscoveryProtocol( self.trinity_config.nodekey, address, self.trinity_config.bootstrap_nodes, self.trinity_config.preferred_nodes, self.cancel_token, ) discovery_service = DiscoveryService( discovery_protocol, self.trinity_config.port, self.event_bus, self.cancel_token, ) await discovery_service.run()
async def _run(self) -> None: self.logger.info("Running server...") upnp_dev = await self._discover_upnp_device() external_ip = '0.0.0.0' if upnp_dev is not None: external_ip = upnp_dev.WANIPConn1.GetExternalIPAddress( )['NewExternalIPAddress'] await self._add_nat_portmap(upnp_dev) await self._start_tcp_listener() self.logger.info( "enode://%s@%s:%s", self.privkey.public_key.to_hex()[2:], external_ip, self.port, ) self.logger.info('network: %s', self.network_id) addr = Address(external_ip, self.port, self.port) self.discovery = DiscoveryProtocol( self.privkey, addr, bootstrap_nodes=self.bootstrap_nodes) await self._start_udp_listener(self.discovery) self.peer_pool = self._make_peer_pool(self.discovery) asyncio.ensure_future(self.refresh_nat_portmap()) asyncio.ensure_future(self.discovery.bootstrap()) asyncio.ensure_future(self.peer_pool.run()) self.syncer = self._make_syncer(self.peer_pool) await self.syncer.run()
async def _run(self) -> None: external_ip = "0.0.0.0" address = Address(external_ip, self.trinity_config.port, self.trinity_config.port) discovery_protocol = PreferredNodeDiscoveryProtocol( self.trinity_config.nodekey, address, self.trinity_config.bootstrap_nodes, self.trinity_config.preferred_nodes, self.cancel_token, ) if self.is_discovery_disabled: discovery_service: BaseService = StaticDiscoveryService( self.event_bus, self.trinity_config.preferred_nodes, self.cancel_token, ) else: discovery_service = DiscoveryService( discovery_protocol, self.trinity_config.port, self.event_bus, self.cancel_token, ) try: await discovery_service.run() except Exception: await self.event_bus.broadcast( ShutdownRequest("Discovery ended unexpectedly"))
async def _run(self) -> None: self.logger.info("Running server...") mapped_external_ip = await self.upnp_service.add_nat_portmap() if mapped_external_ip is None: external_ip = '0.0.0.0' else: external_ip = mapped_external_ip await self._start_tcp_listener() self.logger.info( "enode://%s@%s:%s", self.privkey.public_key.to_hex()[2:], external_ip, self.port, ) self.logger.info('network: %s', self.network_id) self.logger.info('peers: max_peers=%s', self.max_peers) addr = Address(external_ip, self.port, self.port) discovery_proto = PreferredNodeDiscoveryProtocol( self.privkey, addr, self.bootstrap_nodes, self.preferred_nodes, self.cancel_token) self.discovery = DiscoveryService(discovery_proto, self.peer_pool, self.port, self.cancel_token) self.run_daemon(self.peer_pool) self.run_daemon(self.discovery) # UPNP service is still experimental and not essential, so we don't use run_daemon() for # it as that means if it crashes we'd be terminated as well. self.run_child_service(self.upnp_service) self.syncer = self._make_syncer(self.peer_pool) await self.syncer.run()
def _get_max_neighbours_per_packet() -> int: # As defined in https://github.com/ethereum/devp2p/blob/master/rlpx.md, the max size of a # datagram must be 1280 bytes, so when sending neighbours packets we must include up to # _max_neighbours_per_packet and if there's more than that split them across multiple # packets. # Use an IPv6 address here as we're interested in the size of the biggest possible node # representation. addr = Address('::1', 30303, 30303) node_data = addr.to_endpoint() + [b'\x00' * (constants.KADEMLIA_PUBLIC_KEY_SIZE // 8)] neighbours = [node_data] expiration = rlp.sedes.big_endian_int.serialize(_get_msg_expiration()) payload = rlp.encode([neighbours] + [expiration]) while HEAD_SIZE + len(payload) <= 1280: neighbours.append(node_data) payload = rlp.encode([neighbours] + [expiration]) return len(neighbours) - 1
def run_fullnode_process(chain_config: ChainConfig, listen_on: str) -> None: manager = create_dbmanager(chain_config.database_ipc_path) db = manager.get_db() # type: ignore headerdb = manager.get_headerdb() # type: ignore chaindb = manager.get_chaindb() # type: ignore chain = manager.get_chain() # type: ignore address = Address(listen_on, 30303) peer_pool_class = HardCodedNodesPeerPool server = Server( chain_config.nodekey, address, chain, chaindb, headerdb, db, chain_config.network_id, peer_pool_class=peer_pool_class) loop = asyncio.get_event_loop() # Use a ProcessPoolExecutor as the default so that we can offload cpu-intensive tasks from the # main thread. loop.set_default_executor(ProcessPoolExecutor()) sigint_received = asyncio.Event() for sig in [signal.SIGINT, signal.SIGTERM]: loop.add_signal_handler(sig, sigint_received.set) async def exit_on_sigint(): await sigint_received.wait() await server.cancel() loop.stop() asyncio.ensure_future(exit_on_sigint()) asyncio.ensure_future(server.run()) loop.run_forever() loop.close()
async def do_run(cls, boot_info: BootInfo, event_bus: EndpointAPI) -> None: config = boot_info.trinity_config external_ip = "0.0.0.0" address = Address(external_ip, config.port, config.port) if boot_info.args.disable_discovery: discovery_service: Service = StaticDiscoveryService( event_bus, config.preferred_nodes, ) else: external_ip = "0.0.0.0" socket = trio.socket.socket(family=trio.socket.AF_INET, type=trio.socket.SOCK_DGRAM) await socket.bind((external_ip, config.port)) discovery_service = PreferredNodeDiscoveryService( boot_info.trinity_config.nodekey, address, config.bootstrap_nodes, config.preferred_nodes, event_bus, socket, ) try: await TrioManager.run_service(discovery_service) except Exception: await event_bus.broadcast(ShutdownRequest("Discovery ended unexpectedly")) raise
async def _run(self) -> None: self.logger.info("Running server...") mapped_external_ip = await self.upnp_service.add_nat_portmap() if mapped_external_ip is None: external_ip = '0.0.0.0' else: external_ip = mapped_external_ip await self._start_tcp_listener() self.logger.info( "enode://%s@%s:%s", self.privkey.public_key.to_hex()[2:], external_ip, self.port, ) self.logger.info('network: %s', self.network_id) self.logger.info('peers: max_peers=%s', self.max_peers) addr = Address(external_ip, self.port, self.port) self.discovery = DiscoveryProtocol( self.privkey, addr, bootstrap_nodes=self.bootstrap_nodes) await self._start_udp_listener(self.discovery) self.peer_pool = self._make_peer_pool(self.discovery) asyncio.ensure_future(self.discovery.bootstrap()) asyncio.ensure_future(self.peer_pool.run()) asyncio.ensure_future(self.upnp_service.run()) self.syncer = self._make_syncer(self.peer_pool) await self.syncer.run()
async def _run(self) -> None: self.logger.info("Running server...") mapped_external_ip = await self.upnp_service.add_nat_portmap() if mapped_external_ip is None: external_ip = '0.0.0.0' else: external_ip = mapped_external_ip await self._start_tcp_listener() self.logger.info( "enode://%s@%s:%s", self.privkey.public_key.to_hex()[2:], external_ip, self.port, ) self.logger.info('network: %s', self.network_id) self.logger.info('peers: max_peers=%s', self.max_peers) addr = Address(external_ip, self.port, self.port) discovery_proto = PreferredNodeDiscoveryProtocol( self.privkey, addr, self.bootstrap_nodes, self.preferred_nodes) await self._start_udp_listener(discovery_proto) self.discovery = DiscoveryService(discovery_proto, self.peer_pool, self.cancel_token) self.run_child_service(self.peer_pool) self.run_child_service(self.discovery) self.run_child_service(self.upnp_service) self.syncer = self._make_syncer(self.peer_pool) await self.syncer.run()
def test_check_relayed_addr(): public_host = Address('8.8.8.8', 80, 80) local_host = Address('127.0.0.1', 80, 80) assert check_relayed_addr(local_host, local_host) assert not check_relayed_addr(public_host, local_host) private = Address('192.168.1.1', 80, 80) assert check_relayed_addr(private, private) assert not check_relayed_addr(public_host, private) reserved = Address('240.0.0.1', 80, 80) assert not check_relayed_addr(local_host, reserved) assert not check_relayed_addr(public_host, reserved) unspecified = Address('0.0.0.0', 80, 80) assert not check_relayed_addr(local_host, unspecified) assert not check_relayed_addr(public_host, unspecified)
async def test_shard_syncer(n_peers, connections): cancel_token = CancelToken("canceltoken") PeerTuple = collections.namedtuple("PeerTuple", ["node", "server", "syncer"]) peer_tuples = [] for i in range(n_peers): private_key = keys.PrivateKey(pad32(int_to_big_endian(i + 1))) port = get_open_port() address = Address("127.0.0.1", port, port) node = Node(private_key.public_key, address) server = ShardingServer(private_key, address, network_id=9324090483, min_peers=0, peer_class=ShardingPeer) asyncio.ensure_future(server.run()) peer_tuples.append( PeerTuple( node=node, server=server, syncer=server.syncer, )) # connect peers to each other await asyncio.gather(*[ peer_tuples[i].server.peer_pool._connect_to_nodes( [peer_tuples[j].node]) for i, j in connections ]) for i, j in connections: peer_remotes = [ peer.remote for peer in peer_tuples[i].server.peer_pool.peers ] assert peer_tuples[j].node in peer_remotes # let each node propose and check that collation appears at all other nodes for proposer in peer_tuples: collation = proposer.syncer.propose() await asyncio.wait_for(asyncio.gather(*[ peer_tuple.syncer.collations_received_event.wait() for peer_tuple in peer_tuples if peer_tuple != proposer ]), timeout=10) for peer_tuple in peer_tuples: assert peer_tuple.syncer.shard.get_collation_by_hash( collation.hash) == collation # stop everything cancel_token.trigger() await asyncio.gather( *[peer_tuple.server.cancel() for peer_tuple in peer_tuples]) await asyncio.gather( *[peer_tuple.syncer.cancel() for peer_tuple in peer_tuples])
async def _manually_driven_discovery(seed, socket, nursery): discovery = ManuallyDrivenDiscoveryService(keys.PrivateKey(keccak(seed)), Address(*socket.getsockname()), bootstrap_nodes=[], event_bus=None, socket=socket) nursery.start_soon(TrioManager.run_service, discovery) await discovery.ready_to_drive.wait() return discovery
def enodeToMultiAddress(_node): u = urllib.parse.urlparse(_node) pubkey = bytearray.fromhex(u.username) xpub = keys.PublicKey(pubkey) nn = Node.from_pubkey_and_addr(xpub, Address(u.hostname, u.port, u.port)) nodeid = base58.b58encode(nn.id) return multiaddr.Multiaddr("/ip4/" + u.hostname + "/tcp/" + str(u.port) + "/p2p/" + nodeid.decode("utf-8"))
def _extract_nodes_from_payload( sender: AddressAPI, payload: List[Tuple[str, bytes, bytes, bytes]], logger: ExtendedDebugLogger) -> Iterator[NodeAPI]: for item in payload: ip, udp_port, tcp_port, node_id = item address = Address.from_endpoint(ip, udp_port, tcp_port) if check_relayed_addr(sender, address): yield Node(keys.PublicKey(node_id), address) else: logger.debug("Skipping invalid address %s relayed by %s", address, sender)
async def receive_handshake(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> None: # Use reader to read the auth_init msg until EOF msg = await reader.read(ENCRYPTED_AUTH_MSG_LEN) # Use HandshakeResponder.decode_authentication(auth_init_message) on auth init msg try: ephem_pubkey, initiator_nonce, initiator_pubkey = decode_authentication( msg, self.privkey) # Try to decode as EIP8 except DecryptionError: msg_size = big_endian_to_int(msg[:2]) remaining_bytes = msg_size - ENCRYPTED_AUTH_MSG_LEN + 2 msg += await reader.read(remaining_bytes) ephem_pubkey, initiator_nonce, initiator_pubkey = decode_authentication( msg, self.privkey) # Get remote's address: IPv4 or IPv6 ip, port, *_ = writer.get_extra_info("peername") remote_address = Address(ip, port) # Create `HandshakeResponder(remote: kademlia.Node, privkey: datatypes.PrivateKey)` instance initiator_remote = Node(initiator_pubkey, remote_address) responder = HandshakeResponder(initiator_remote, self.privkey) # Call `HandshakeResponder.create_auth_ack_message(nonce: bytes)` to create the reply responder_nonce = secrets.token_bytes(HASH_LEN) auth_ack_msg = responder.create_auth_ack_message(nonce=responder_nonce) auth_ack_ciphertext = responder.encrypt_auth_ack_message(auth_ack_msg) # Use the `writer` to send the reply to the remote writer.write(auth_ack_ciphertext) await writer.drain() # Call `HandshakeResponder.derive_shared_secrets()` and use return values to create `Peer` aes_secret, mac_secret, egress_mac, ingress_mac = responder.derive_secrets( initiator_nonce=initiator_nonce, responder_nonce=responder_nonce, remote_ephemeral_pubkey=ephem_pubkey, auth_init_ciphertext=msg, auth_ack_ciphertext=auth_ack_ciphertext) # Create and register peer in peer_pool eth_peer = ETHPeer(remote=initiator_remote, privkey=self.privkey, reader=reader, writer=writer, aes_secret=aes_secret, mac_secret=mac_secret, egress_mac=egress_mac, ingress_mac=ingress_mac, chaindb=self.chaindb, network_id=self.network_id) self.peer_pool.add_peer(eth_peer)
def __init__(self, chain_config: ChainConfig) -> None: super().__init__(chain_config) self.network_id = chain_config.network_id self.nodekey = chain_config.nodekey self._port = chain_config.port self._discovery = DiscoveryProtocol( chain_config.nodekey, Address('0.0.0.0', chain_config.port, chain_config.port), bootstrap_nodes=chain_config.bootstrap_nodes, ) self._peer_pool = self._create_peer_pool(chain_config) self.add_service(self._peer_pool)
async def _manually_driven_discovery(seed, socket, nursery): discovery = ManuallyDrivenDiscoveryService(keys.PrivateKey(keccak(seed)), Address(*socket.getsockname()), bootstrap_nodes=[], event_bus=None, socket=socket) async with background_trio_service(discovery): # At this point we know the service has started (i.e. its run() method has been scheduled), # but maybe it hasn't had a chance to run yet, so we wait until the _local_enr is set to # ensure run() has actually executed. with trio.fail_after(1): while discovery._local_enr is None: await trio.hazmat.checkpoint() yield discovery
def __init__(self, plugin_manager: PluginManager, chain_config: ChainConfig) -> None: super().__init__(plugin_manager, chain_config) self.network_id = chain_config.network_id self.nodekey = chain_config.nodekey self._port = chain_config.port self._discovery_proto = PreferredNodeDiscoveryProtocol( chain_config.nodekey, Address('0.0.0.0', chain_config.port, chain_config.port), bootstrap_nodes=chain_config.bootstrap_nodes, preferred_nodes=chain_config.preferred_nodes, ) self._peer_pool = self._create_peer_pool(chain_config) self._discovery = DiscoveryService( self._discovery_proto, self._peer_pool, self.cancel_token) self._peer_chain = LightPeerChain(self.headerdb, self._peer_pool, self.cancel_token) self.notify_resource_available()
async def _run(self) -> None: external_ip = "0.0.0.0" address = Address(external_ip, self.trinity_config.port, self.trinity_config.port) if self.trinity_config.use_discv5: protocol = get_protocol(self.trinity_config) topic = get_discv5_topic(self.trinity_config, protocol) discovery_protocol: DiscoveryProtocol = DiscoveryByTopicProtocol( topic, self.trinity_config.nodekey, address, self.trinity_config.bootstrap_nodes, self.cancel_token, ) else: discovery_protocol = PreferredNodeDiscoveryProtocol( self.trinity_config.nodekey, address, self.trinity_config.bootstrap_nodes, self.trinity_config.preferred_nodes, self.cancel_token, ) if self.is_discovery_disabled: discovery_service: BaseService = StaticDiscoveryService( self.event_bus, self.trinity_config.preferred_nodes, self.cancel_token, ) else: discovery_service = DiscoveryService( discovery_protocol, self.trinity_config.port, self.event_bus, self.cancel_token, ) try: await discovery_service.run() except Exception: self.event_bus.request_shutdown("Discovery ended unexpectedly")
def __init__(self, chain_config: ChainConfig) -> None: super().__init__(chain_config) self.network_id = chain_config.network_id self.nodekey = chain_config.nodekey self._port = chain_config.port self._discovery_proto = PreferredNodeDiscoveryProtocol( chain_config.nodekey, Address('0.0.0.0', chain_config.port, chain_config.port), bootstrap_nodes=chain_config.bootstrap_nodes, preferred_nodes=chain_config.preferred_nodes, ) self._peer_pool = self._create_peer_pool(chain_config) self._discovery = DiscoveryService( self._discovery_proto, self._peer_pool, self.cancel_token) self.add_service(self._discovery) self.add_service(self._peer_pool) self.create_and_add_tx_pool()
async def do_run(cls, boot_info: BootInfo, event_bus: EndpointAPI) -> None: config = boot_info.trinity_config db = DBClient.connect(config.database_ipc_path) external_ip = "0.0.0.0" address = Address(external_ip, config.port, config.port) if boot_info.args.disable_discovery: discovery_service: async_service.Service = StaticDiscoveryService( event_bus, config.preferred_nodes, ) else: vm_config = config.get_app_config( Eth1AppConfig).get_chain_config().vm_configuration headerdb = TrioHeaderDB(db) eth_cap_provider = functools.partial(generate_eth_cap_enr_field, vm_config, headerdb) external_ip = "0.0.0.0" socket = trio.socket.socket(family=trio.socket.AF_INET, type=trio.socket.SOCK_DGRAM) enr_db = FileEnrDb(default_identity_scheme_registry, config.enr_db_dir) await socket.bind((external_ip, config.port)) discovery_service = PreferredNodeDiscoveryService( config.nodekey, address, config.bootstrap_nodes, config.preferred_nodes, event_bus, socket, enr_db, (eth_cap_provider, ), ) try: with db: await async_service.run_trio_service(discovery_service) except Exception: await event_bus.broadcast( ShutdownRequest("Discovery ended unexpectedly")) raise
try: peer = next(self.iter) if not peer.is_closing: return peer except StopIteration: raise StopAsyncIteration DEFAULT_PREFERRED_NODES: Dict[int, Tuple[Node, ...]] = { MAINNET_NETWORK_ID: ( Node( keys.PublicKey( decode_hex( "1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082" )), # noqa: E501 Address("52.74.57.123", 30303, 30303)), Node( keys.PublicKey( decode_hex( "78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d" )), # noqa: E501 Address("191.235.84.50", 30303, 30303)), Node( keys.PublicKey( decode_hex( "ddd81193df80128880232fc1deb45f72746019839589eeb642d3d44efbb8b2dda2c1a46a348349964a6066f8afb016eb2a8c0f3c66f32fadf4370a236a4b5286" )), # noqa: E501 Address("52.231.202.145", 30303, 30303)), Node( keys.PublicKey( decode_hex(
async def _receive_handshake(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> None: msg = await self.wait(reader.read(ENCRYPTED_AUTH_MSG_LEN), timeout=REPLY_TIMEOUT) ip, socket, *_ = writer.get_extra_info("peername") remote_address = Address(ip, socket) self.logger.debug("Receiving handshake from %s", remote_address) got_eip8 = False try: ephem_pubkey, initiator_nonce, initiator_pubkey = decode_authentication( msg, self.privkey) except DecryptionError: # Try to decode as EIP8 got_eip8 = True msg_size = big_endian_to_int(msg[:2]) remaining_bytes = msg_size - ENCRYPTED_AUTH_MSG_LEN + 2 msg += await self.wait(reader.read(remaining_bytes), timeout=REPLY_TIMEOUT) try: ephem_pubkey, initiator_nonce, initiator_pubkey = decode_authentication( msg, self.privkey) except DecryptionError as e: self.logger.debug("Failed to decrypt handshake: %s", e) return initiator_remote = Node(initiator_pubkey, remote_address) responder = HandshakeResponder(initiator_remote, self.privkey, got_eip8, self.cancel_token) responder_nonce = secrets.token_bytes(HASH_LEN) auth_ack_msg = responder.create_auth_ack_message(responder_nonce) auth_ack_ciphertext = responder.encrypt_auth_ack_message(auth_ack_msg) # Use the `writer` to send the reply to the remote writer.write(auth_ack_ciphertext) await self.wait(writer.drain()) # Call `HandshakeResponder.derive_shared_secrets()` and use return values to create `Peer` aes_secret, mac_secret, egress_mac, ingress_mac = responder.derive_secrets( initiator_nonce=initiator_nonce, responder_nonce=responder_nonce, remote_ephemeral_pubkey=ephem_pubkey, auth_init_ciphertext=msg, auth_ack_ciphertext=auth_ack_ciphertext) # Create and register peer in peer_pool peer = self.peer_class( remote=initiator_remote, privkey=self.privkey, reader=reader, writer=writer, aes_secret=aes_secret, mac_secret=mac_secret, egress_mac=egress_mac, ingress_mac=ingress_mac, headerdb=self.headerdb, network_id=self.network_id, inbound=True, ) if self.peer_pool.is_full: peer.disconnect(DisconnectReason.too_many_peers) else: # We use self.wait() here as a workaround for # https://github.com/ethereum/py-evm/issues/670. await self.wait(self.do_handshake(peer))
def _test(): """ Create a Peer instance connected to a local geth instance and log messages exchanged with it. Use the following command line to run geth: ./build/bin/geth -vmodule p2p=4,p2p/discv5=0,eth/*=0 \ -nodekeyhex 45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8 \ -testnet -lightserv 90 """ import argparse import signal from evm.chains.ropsten import RopstenChain, ROPSTEN_GENESIS_HEADER from evm.db.backends.memory import MemoryDB from tests.p2p.integration_test_helpers import FakeAsyncChainDB logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s: %(message)s') # The default remoteid can be used if you pass nodekeyhex as above to geth. nodekey = keys.PrivateKey(decode_hex( "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8")) remoteid = nodekey.public_key.to_hex() parser = argparse.ArgumentParser() parser.add_argument('-remoteid', type=str, default=remoteid) parser.add_argument('-light', action='store_true', help="Connect as a light node") args = parser.parse_args() peer_class = ETHPeer # type: ignore if args.light: peer_class = LESPeer # type: ignore remote = Node( keys.PublicKey(decode_hex(args.remoteid)), Address('127.0.0.1', 30303, 30303)) chaindb = FakeAsyncChainDB(MemoryDB()) chaindb.persist_header(ROPSTEN_GENESIS_HEADER) network_id = RopstenChain.network_id loop = asyncio.get_event_loop() peer = loop.run_until_complete( asyncio.wait_for( handshake(remote, ecies.generate_privkey(), peer_class, chaindb, network_id), HANDSHAKE_TIMEOUT)) async def request_stuff(): # Request some stuff from ropsten's block 2440319 # (https://ropsten.etherscan.io/block/2440319), just as a basic test. nonlocal peer block_hash = decode_hex( '0x59af08ab31822c992bb3dad92ddb68d820aa4c69e9560f07081fa53f1009b152') if peer_class == ETHPeer: peer = cast(ETHPeer, peer) peer.sub_proto.send_get_block_headers(block_hash, 1) peer.sub_proto.send_get_block_bodies([block_hash]) peer.sub_proto.send_get_receipts([block_hash]) else: peer = cast(LESPeer, peer) request_id = 1 peer.sub_proto.send_get_block_headers(block_hash, 1, request_id) peer.sub_proto.send_get_block_bodies([block_hash], request_id + 1) peer.sub_proto.send_get_receipts(block_hash, request_id + 2) for sig in [signal.SIGINT, signal.SIGTERM]: loop.add_signal_handler(sig, peer.cancel_token.trigger) asyncio.ensure_future(request_stuff()) loop.run_until_complete(peer.run()) loop.close()
def get_nodes_to_connect(self) -> Generator[Node, None, None]: from evm.chains.ropsten import RopstenChain from evm.chains.mainnet import MainnetChain if self.network_id == MainnetChain.network_id: nodes = [ Node(keys.PublicKey(decode_hex("1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082")), # noqa: E501 Address("52.74.57.123", 30303, 30303)), Node(keys.PublicKey(decode_hex("78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d")), # noqa: E501 Address("191.235.84.50", 30303, 30303)), Node(keys.PublicKey(decode_hex("ddd81193df80128880232fc1deb45f72746019839589eeb642d3d44efbb8b2dda2c1a46a348349964a6066f8afb016eb2a8c0f3c66f32fadf4370a236a4b5286")), # noqa: E501 Address("52.231.202.145", 30303, 30303)), Node(keys.PublicKey(decode_hex("3f1d12044546b76342d59d4a05532c14b85aa669704bfe1f864fe079415aa2c02d743e03218e57a33fb94523adb54032871a6c51b2cc5514cb7c7e35b3ed0a99")), # noqa: E501 Address("13.93.211.84", 30303, 30303)), ] elif self.network_id == RopstenChain.network_id: nodes = [ Node(keys.PublicKey(decode_hex("c8b9ec645cd7fe570bc73740579064c528771338c31610f44d160d2ae63fd00699caa163f84359ab268d4a0aed8ead66d7295be5e9c08b0ec85b0198273bae1f")), # noqa: E501 Address("178.62.246.6", 30303, 30303)), Node(keys.PublicKey(decode_hex("7a34c02d5ef9de43475580cbb88fb492afb2858cfc45f58cf5c7088ceeded5f58e65be769b79c31c5ae1f012c99b3e9f2ea9ef11764d553544171237a691493b")), # noqa: E501 Address("35.227.38.243", 30303, 30303)), Node(keys.PublicKey(decode_hex("bbb3ad8be9684fa1d67ac057d18f7357dd236dc01a806fef6977ac9a259b352c00169d092c50475b80aed9e28eff12d2038e97971e0be3b934b366e86b59a723")), # noqa: E501 Address("81.169.153.213", 30303, 30303)), Node(keys.PublicKey(decode_hex("30b7ab30a01c124a6cceca36863ece12c4f5fa68e3ba9b0b51407ccc002eeed3b3102d20a88f1c1d3c3154e2449317b8ef95090e77b312d5cc39354f86d5d606")), # noqa: E501 Address("52.176.7.10", 30303, 30303)), Node(keys.PublicKey(decode_hex("02508da84b37a1b7f19f77268e5b69acc9e9ab6989f8e5f2f8440e025e633e4277019b91884e46821414724e790994a502892144fc1333487ceb5a6ce7866a46")), # noqa: E501 Address("54.175.255.230", 30303, 30303)), Node(keys.PublicKey(decode_hex("0eec3472a46f0b637045e41f923ce1d4a585cd83c1c7418b183c46443a0df7405d020f0a61891b2deef9de35284a0ad7d609db6d30d487dbfef72f7728d09ca9")), # noqa: E501 Address("181.168.193.197", 30303, 30303)), Node(keys.PublicKey(decode_hex("643c31104d497e3d4cd2460ff0dbb1fb9a6140c8bb0fca66159bbf177d41aefd477091c866494efd3f1f59a0652c93ab2f7bb09034ed5ab9f2c5c6841aef8d94")), # noqa: E501 Address("34.198.237.7", 30303, 30303)), Node(keys.PublicKey(decode_hex("88c2b24429a6f7683fbfd06874ae3f1e7c8b4a5ffb846e77c705ba02e2543789d66fc032b6606a8d8888eb6239a2abe5897ce83f78dcdcfcb027d6ea69aa6fe9")), # noqa: E501 Address("163.172.157.61", 30303, 30303)), Node(keys.PublicKey(decode_hex("a1ef9ba5550d5fac27f7cbd4e8d20a643ad75596f307c91cd6e7f85b548b8a6bf215cca436d6ee436d6135f9fe51398f8dd4c0bd6c6a0c332ccb41880f33ec12")), # noqa: E501 Address("51.15.218.125", 30303, 30303)), Node(keys.PublicKey(decode_hex("e80276aabb7682a4a659f4341c1199de79d91a2e500a6ee9bed16ed4ce927ba8d32ba5dea357739ffdf2c5bcc848d3064bb6f149f0b4249c1f7e53f8bf02bfc8")), # noqa: E501 Address("51.15.39.57", 30303, 30303)), Node(keys.PublicKey(decode_hex("584c0db89b00719e9e7b1b5c32a4a8942f379f4d5d66bb69f9c7fa97fa42f64974e7b057b35eb5a63fd7973af063f9a1d32d8c60dbb4854c64cb8ab385470258")), # noqa: E501 Address("51.15.35.2", 30303, 30303)), Node(keys.PublicKey(decode_hex("d40871fc3e11b2649700978e06acd68a24af54e603d4333faecb70926ca7df93baa0b7bf4e927fcad9a7c1c07f9b325b22f6d1730e728314d0e4e6523e5cebc2")), # noqa: E501 Address("51.15.132.235", 30303, 30303)), Node(keys.PublicKey(decode_hex("482484b9198530ee2e00db89791823244ca41dcd372242e2e1297dd06f6d8dd357603960c5ad9cc8dc15fcdf0e4edd06b7ad7db590e67a0b54f798c26581ebd7")), # noqa: E501 Address("51.15.75.138", 30303, 30303)), ] else: raise ValueError("Unknown network_id: {}".format(self.network_id)) random.shuffle(nodes) for node in nodes: yield node
async def _receive_handshake( self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> None: msg = await self.wait_first( reader.read(ENCRYPTED_AUTH_MSG_LEN), timeout=REPLY_TIMEOUT) ip, socket, *_ = writer.get_extra_info("peername") remote_address = Address(ip, socket) self.logger.debug("Receiving handshake from %s", remote_address) try: ephem_pubkey, initiator_nonce, initiator_pubkey = decode_authentication( msg, self.privkey) except DecryptionError: # Try to decode as EIP8 msg_size = big_endian_to_int(msg[:2]) remaining_bytes = msg_size - ENCRYPTED_AUTH_MSG_LEN + 2 msg += await self.wait_first( reader.read(remaining_bytes), timeout=REPLY_TIMEOUT) try: ephem_pubkey, initiator_nonce, initiator_pubkey = decode_authentication( msg, self.privkey) except DecryptionError as e: self.logger.debug("Failed to decrypt handshake: %s", e) return # Create `HandshakeResponder(remote: kademlia.Node, privkey: datatypes.PrivateKey)` instance initiator_remote = Node(initiator_pubkey, remote_address) responder = HandshakeResponder(initiator_remote, self.privkey, self.cancel_token) # Call `HandshakeResponder.create_auth_ack_message(nonce: bytes)` to create the reply responder_nonce = secrets.token_bytes(HASH_LEN) auth_ack_msg = responder.create_auth_ack_message(nonce=responder_nonce) auth_ack_ciphertext = responder.encrypt_auth_ack_message(auth_ack_msg) # Use the `writer` to send the reply to the remote writer.write(auth_ack_ciphertext) await writer.drain() # Call `HandshakeResponder.derive_shared_secrets()` and use return values to create `Peer` aes_secret, mac_secret, egress_mac, ingress_mac = responder.derive_secrets( initiator_nonce=initiator_nonce, responder_nonce=responder_nonce, remote_ephemeral_pubkey=ephem_pubkey, auth_init_ciphertext=msg, auth_ack_ciphertext=auth_ack_ciphertext ) # Create and register peer in peer_pool peer = self.peer_class( remote=initiator_remote, privkey=self.privkey, reader=reader, writer=writer, aes_secret=aes_secret, mac_secret=mac_secret, egress_mac=egress_mac, ingress_mac=ingress_mac, headerdb=self.headerdb, network_id=self.network_id, inbound=True, ) await self.do_handshake(peer)
from tests.trinity.core.dumb_peer import DumbPeer from tests.trinity.core.integration_test_helpers import FakeAsyncHeaderDB def get_open_port(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(("", 0)) s.listen(1) port = s.getsockname()[1] s.close() return port port = get_open_port() NETWORK_ID = 99 SERVER_ADDRESS = Address('127.0.0.1', udp_port=port, tcp_port=port) RECEIVER_PRIVKEY = keys.PrivateKey(eip8_values['receiver_private_key']) RECEIVER_PUBKEY = RECEIVER_PRIVKEY.public_key RECEIVER_REMOTE = Node(RECEIVER_PUBKEY, SERVER_ADDRESS) INITIATOR_PRIVKEY = keys.PrivateKey(eip8_values['initiator_private_key']) INITIATOR_PUBKEY = INITIATOR_PRIVKEY.public_key INITIATOR_ADDRESS = Address('127.0.0.1', get_open_port() + 1) INITIATOR_REMOTE = Node(INITIATOR_PUBKEY, INITIATOR_ADDRESS) class MockPeerPool: is_full = False connected_nodes = {} def __init__(self):
async def receive_connection(cls, reader: asyncio.StreamReader, writer: asyncio.StreamWriter, private_key: datatypes.PrivateKey, token: CancelToken) -> TransportAPI: try: msg = await token.cancellable_wait( reader.readexactly(ENCRYPTED_AUTH_MSG_LEN), timeout=REPLY_TIMEOUT, ) except asyncio.IncompleteReadError as err: raise HandshakeFailure from err try: ephem_pubkey, initiator_nonce, initiator_pubkey = decode_authentication( msg, private_key, ) except DecryptionError as non_eip8_err: # Try to decode as EIP8 msg_size = big_endian_to_int(msg[:2]) remaining_bytes = msg_size - ENCRYPTED_AUTH_MSG_LEN + 2 try: msg += await token.cancellable_wait( reader.readexactly(remaining_bytes), timeout=REPLY_TIMEOUT, ) except asyncio.IncompleteReadError as err: raise HandshakeFailure from err try: ephem_pubkey, initiator_nonce, initiator_pubkey = decode_authentication( msg, private_key, ) except DecryptionError as eip8_err: raise HandshakeFailure( f"Failed to decrypt both EIP8 handshake: {eip8_err} and " f"non-EIP8 handshake: {non_eip8_err}") else: got_eip8 = True else: got_eip8 = False peername = writer.get_extra_info("peername") if peername is None: socket = writer.get_extra_info("socket") sockname = writer.get_extra_info("sockname") raise HandshakeFailure( "Received incoming connection with no remote information:" f"socket={repr(socket)} sockname={sockname}") ip, socket, *_ = peername remote_address = Address(ip, socket) cls.logger.debug("Receiving handshake from %s", remote_address) initiator_remote = Node(initiator_pubkey, remote_address) responder = HandshakeResponder(initiator_remote, private_key, got_eip8, token) responder_nonce = secrets.token_bytes(HASH_LEN) auth_ack_msg = responder.create_auth_ack_message(responder_nonce) auth_ack_ciphertext = responder.encrypt_auth_ack_message(auth_ack_msg) # Use the `writer` to send the reply to the remote writer.write(auth_ack_ciphertext) await token.cancellable_wait(writer.drain()) # Call `HandshakeResponder.derive_shared_secrets()` and use return values to create `Peer` aes_secret, mac_secret, egress_mac, ingress_mac = responder.derive_secrets( initiator_nonce=initiator_nonce, responder_nonce=responder_nonce, remote_ephemeral_pubkey=ephem_pubkey, auth_init_ciphertext=msg, auth_ack_ciphertext=auth_ack_ciphertext) transport = cls( remote=initiator_remote, private_key=private_key, reader=reader, writer=writer, aes_secret=aes_secret, mac_secret=mac_secret, egress_mac=egress_mac, ingress_mac=ingress_mac, ) return transport
def get_nodes_to_connect(self) -> Generator[Node, None, None]: from evm.chains.ropsten import RopstenChain from evm.chains.mainnet import MainnetChain if self.network_id == MainnetChain.network_id: nodes = [ Node( keys.PublicKey( decode_hex( "1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082" )), # noqa: E501 Address("52.74.57.123", 30303, 30303)), Node( keys.PublicKey( decode_hex( "78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d" )), # noqa: E501 Address("191.235.84.50", 30303, 30303)), Node( keys.PublicKey( decode_hex( "ddd81193df80128880232fc1deb45f72746019839589eeb642d3d44efbb8b2dda2c1a46a348349964a6066f8afb016eb2a8c0f3c66f32fadf4370a236a4b5286" )), # noqa: E501 Address("52.231.202.145", 30303, 30303)), Node( keys.PublicKey( decode_hex( "3f1d12044546b76342d59d4a05532c14b85aa669704bfe1f864fe079415aa2c02d743e03218e57a33fb94523adb54032871a6c51b2cc5514cb7c7e35b3ed0a99" )), # noqa: E501 Address("13.93.211.84", 30303, 30303)), ] elif self.network_id == RopstenChain.network_id: nodes = [ Node( keys.PublicKey( decode_hex( "0d7f627a9a139c1fbff6731d6e0123561738c5155908e32c3a1eea00a3e0c3b460d97c8aea1935c19bfb4e7013651488b8d328b9c142c0b820e221fde7894253" )), # noqa: E501 Address("58.250.0.61", 30303, 30303)), Node( keys.PublicKey( decode_hex( "360aeace83f0771dd671f253a023b4757e920aca3598563779d8edb2f4d4ca001b5dc2f900ec1547edcd34cfd5cf858e717647e9b5c1f88cef1934081337678b" )), # noqa: E501 Address("34.212.25.61", 30303, 30303)), Node( keys.PublicKey( decode_hex( "49f9e25549aaa9d2bbbedb32bc22029833a8ce457ce54310e44ed8097082379ac94ff5319ff57da0afa91584c271d17324bc3ea3a74e01a9684fbe9a392b239d" )), # noqa: E501 Address("34.237.139.163", 30303, 30303)), Node( keys.PublicKey( decode_hex( "5740300afd843ce51b2ca734e30ec690f1b61b163f67a289888757e8962f8046d46f8b6a8d2663246f0b81a75cbc7604619721567054309f15bc360490c8c4da" )), # noqa: E501 Address("172.104.183.123", 30303, 30303)), Node( keys.PublicKey( decode_hex( "7f3c9e7472a28904c7b5066bce561ac230801147fb6cffae10967baf058a9fcffe03e386c55e5c1397172aef36d78b9f35b6d4f0dc831707c66530194f4867fb" )), # noqa: E501 Address("114.242.249.161", 30303, 30303)), Node( keys.PublicKey( decode_hex( "8d24ff3d32b0fc70bf41cf828b98940e2ef18ab82fc37de779c206cbec88d5c11a3e3af9700953b9f5e6582f73cddd76f90fc1688992fbdf3b9216228c80654c" )), # noqa: E501 Address("202.9.6.81", 30303, 30303)), Node( keys.PublicKey( decode_hex( "bbb3ad8be9684fa1d67ac057d18f7357dd236dc01a806fef6977ac9a259b352c00169d092c50475b80aed9e28eff12d2038e97971e0be3b934b366e86b59a723" )), # noqa: E501 Address("81.169.153.213", 30303, 30303)), Node( keys.PublicKey( decode_hex( "a147a3adde1daddc0d86f44f1a76404914e44cee018c26d49248142d4dc8a9fb0e7dd14b5153df7e60f23b037922ae1f33b8f318844ef8d2b0453b9ab614d70d" )), # noqa: E501 Address("72.36.89.11", 30303, 30303)), Node( keys.PublicKey( decode_hex( "bd2867892d879b57734d571b208bb7adc04fa412fbdfe73b89b1a0ec5b7978932cc776609e4ac7bac231049975ecb22c74988da36cbc5111d116b1edf7d44802" )), # noqa: E501 Address("185.68.101.99", 30303, 30303)), Node( keys.PublicKey( decode_hex( "c2bb011038530b60b40a342705246a84e6d2d22d9f8d8d3df4ae1c7464f302396e7be7673a3971b2de16ebd66574ade262fc292b6de7715983f0f15f9c9922ea" )), # noqa: E501 Address("36.225.32.203", 30303, 30303)), Node( keys.PublicKey( decode_hex( "d8714127db3c10560a2463c557bbe509c99969078159c69f9ce4f71c2cd1837bcd33db3b9c3c3e88c971b4604bbffa390a0a7f53fc37f122e2e6e0022c059dfd" )), # noqa: E501 Address("51.15.217.106", 30303, 30303)), Node( keys.PublicKey( decode_hex( "efc75f109d91cdebc62f33be992ca86fce2637044d49a954a8bdceb439b1239afda32e642456e9dfd759af5b440ef4d8761b9bda887e2200001c5f3ab2614043" )), # noqa: E501 Address("34.228.166.142", 30303, 30303)), Node( keys.PublicKey( decode_hex( "c8b9ec645cd7fe570bc73740579064c528771338c31610f44d160d2ae63fd00699caa163f84359ab268d4a0aed8ead66d7295be5e9c08b0ec85b0198273bae1f" )), # noqa: E501 Address("178.62.246.6", 30303, 30303)), Node( keys.PublicKey( decode_hex( "7a34c02d5ef9de43475580cbb88fb492afb2858cfc45f58cf5c7088ceeded5f58e65be769b79c31c5ae1f012c99b3e9f2ea9ef11764d553544171237a691493b" )), # noqa: E501 Address("35.227.38.243", 30303, 30303)), Node( keys.PublicKey( decode_hex( "bbb3ad8be9684fa1d67ac057d18f7357dd236dc01a806fef6977ac9a259b352c00169d092c50475b80aed9e28eff12d2038e97971e0be3b934b366e86b59a723" )), # noqa: E501 Address("81.169.153.213", 30303, 30303)), Node( keys.PublicKey( decode_hex( "30b7ab30a01c124a6cceca36863ece12c4f5fa68e3ba9b0b51407ccc002eeed3b3102d20a88f1c1d3c3154e2449317b8ef95090e77b312d5cc39354f86d5d606" )), # noqa: E501 Address("52.176.7.10", 30303, 30303)), Node( keys.PublicKey( decode_hex( "02508da84b37a1b7f19f77268e5b69acc9e9ab6989f8e5f2f8440e025e633e4277019b91884e46821414724e790994a502892144fc1333487ceb5a6ce7866a46" )), # noqa: E501 Address("54.175.255.230", 30303, 30303)), Node( keys.PublicKey( decode_hex( "0eec3472a46f0b637045e41f923ce1d4a585cd83c1c7418b183c46443a0df7405d020f0a61891b2deef9de35284a0ad7d609db6d30d487dbfef72f7728d09ca9" )), # noqa: E501 Address("181.168.193.197", 30303, 30303)), Node( keys.PublicKey( decode_hex( "643c31104d497e3d4cd2460ff0dbb1fb9a6140c8bb0fca66159bbf177d41aefd477091c866494efd3f1f59a0652c93ab2f7bb09034ed5ab9f2c5c6841aef8d94" )), # noqa: E501 Address("34.198.237.7", 30303, 30303)), Node( keys.PublicKey( decode_hex( "88c2b24429a6f7683fbfd06874ae3f1e7c8b4a5ffb846e77c705ba02e2543789d66fc032b6606a8d8888eb6239a2abe5897ce83f78dcdcfcb027d6ea69aa6fe9" )), # noqa: E501 Address("163.172.157.61", 30303, 30303)), Node( keys.PublicKey( decode_hex( "a1ef9ba5550d5fac27f7cbd4e8d20a643ad75596f307c91cd6e7f85b548b8a6bf215cca436d6ee436d6135f9fe51398f8dd4c0bd6c6a0c332ccb41880f33ec12" )), # noqa: E501 Address("51.15.218.125", 30303, 30303)), Node( keys.PublicKey( decode_hex( "e80276aabb7682a4a659f4341c1199de79d91a2e500a6ee9bed16ed4ce927ba8d32ba5dea357739ffdf2c5bcc848d3064bb6f149f0b4249c1f7e53f8bf02bfc8" )), # noqa: E501 Address("51.15.39.57", 30303, 30303)), Node( keys.PublicKey( decode_hex( "584c0db89b00719e9e7b1b5c32a4a8942f379f4d5d66bb69f9c7fa97fa42f64974e7b057b35eb5a63fd7973af063f9a1d32d8c60dbb4854c64cb8ab385470258" )), # noqa: E501 Address("51.15.35.2", 30303, 30303)), Node( keys.PublicKey( decode_hex( "d40871fc3e11b2649700978e06acd68a24af54e603d4333faecb70926ca7df93baa0b7bf4e927fcad9a7c1c07f9b325b22f6d1730e728314d0e4e6523e5cebc2" )), # noqa: E501 Address("51.15.132.235", 30303, 30303)), Node( keys.PublicKey( decode_hex( "482484b9198530ee2e00db89791823244ca41dcd372242e2e1297dd06f6d8dd357603960c5ad9cc8dc15fcdf0e4edd06b7ad7db590e67a0b54f798c26581ebd7" )), # noqa: E501 Address("51.15.75.138", 30303, 30303)), ] else: raise ValueError("Unknown network_id: {}".format(self.network_id)) random.shuffle(nodes) for node in nodes: yield node