def __init__( self, # Ursula rest_host: str, rest_port: int, domains: Set = ( GLOBAL_DOMAIN, ), # For now, serving and learning domains will be the same. certificate: Certificate = None, certificate_filepath: str = None, db_filepath: str = None, is_me: bool = True, interface_signature=None, timestamp=None, # Blockchain identity_evidence: bytes = constants.NOT_SIGNED, checksum_public_address: str = None, # Character password: str = None, abort_on_learning_error: bool = False, federated_only: bool = False, start_learning_now: bool = None, crypto_power=None, tls_curve: EllipticCurve = None, known_nodes: Iterable = None, **character_kwargs) -> None: # # Character # self._work_orders = list() Character.__init__(self, is_me=is_me, checksum_public_address=checksum_public_address, start_learning_now=start_learning_now, federated_only=federated_only, crypto_power=crypto_power, abort_on_learning_error=abort_on_learning_error, known_nodes=known_nodes, domains=domains, **character_kwargs) # # Self-Ursula # if is_me is True: # TODO: 340 self._stored_treasure_maps = dict() # # Staking Ursula # if not federated_only: Miner.__init__(self, is_me=is_me, checksum_address=checksum_public_address) # Access staking node via node's transacting keys TODO: Better handle ephemeral staking self ursula blockchain_power = BlockchainPower( blockchain=self.blockchain, account=self.checksum_public_address) self._crypto_power.consume_power_up(blockchain_power) # Use blockchain power to substantiate stamp, instead of signing key self.substantiate_stamp( password=password) # TODO: Derive from keyring # # ProxyRESTServer and TLSHostingPower # TODO: Maybe we want _power_ups to be public after all? # if not crypto_power or (TLSHostingPower not in crypto_power._power_ups): # # Ephemeral Self-Ursula # if is_me: self.suspicious_activities_witnessed = { 'vladimirs': [], 'bad_treasure_maps': [] } # # REST Server (Ephemeral Self-Ursula) # rest_app, datastore = make_rest_app( db_filepath=db_filepath, network_middleware=self.network_middleware, federated_only=self.federated_only, # TODO: 466 treasure_map_tracker=self.treasure_maps, node_tracker=self.known_nodes, node_bytes_caster=self.__bytes__, work_order_tracker=self._work_orders, node_recorder=self.remember_node, stamp=self.stamp, verifier=self.verify_from, suspicious_activity_tracker=self. suspicious_activities_witnessed, serving_domains=domains, ) # # TLSHostingPower (Ephemeral Self-Ursula) # tls_hosting_keypair = HostingKeypair( curve=tls_curve, host=rest_host, checksum_public_address=self.checksum_public_address) tls_hosting_power = TLSHostingPower( keypair=tls_hosting_keypair, host=rest_host) self.rest_server = ProxyRESTServer( rest_host=rest_host, rest_port=rest_port, rest_app=rest_app, datastore=datastore, hosting_power=tls_hosting_power) # # Stranger-Ursula # else: # TLSHostingPower if certificate or certificate_filepath: tls_hosting_power = TLSHostingPower( host=rest_host, public_certificate_filepath=certificate_filepath, public_certificate=certificate) else: tls_hosting_keypair = HostingKeypair( curve=tls_curve, host=rest_host, generate_certificate=False) tls_hosting_power = TLSHostingPower( host=rest_host, keypair=tls_hosting_keypair) # REST Server # Unless the caller passed a crypto power we'll make our own TLSHostingPower for this stranger. self.rest_server = ProxyRESTServer( rest_host=rest_host, rest_port=rest_port, hosting_power=tls_hosting_power) # # OK - Now we have a ProxyRestServer and a TLSHostingPower for some Ursula # self._crypto_power.consume_power_up(tls_hosting_power) # Consume! # # Verifiable Node # certificate_filepath = self._crypto_power.power_ups( TLSHostingPower).keypair.certificate_filepath certificate = self._crypto_power.power_ups( TLSHostingPower).keypair.certificate Teacher.__init__( self, domains=domains, certificate=certificate, certificate_filepath=certificate_filepath, interface_signature=interface_signature, timestamp=timestamp, identity_evidence=identity_evidence, substantiate_immediately=is_me and not federated_only, ) # # Logging / Updating # if is_me: self.known_nodes.record_fleet_state( additional_nodes_to_track=[self]) message = "THIS IS YOU: {}: {}".format(self.__class__.__name__, self) self.log.info(message) else: message = "Initialized Stranger {} | {}".format( self.__class__.__name__, self) self.log.debug(message)
def __init__(self, influx_host: str, influx_port: int, crawler_http_port: int = DEFAULT_CRAWLER_HTTP_PORT, registry: BaseContractRegistry = None, node_storage_filepath: str = CrawlerNodeStorage. DEFAULT_DB_FILEPATH, refresh_rate=DEFAULT_REFRESH_RATE, restart_on_error=True, *args, **kwargs): # Settings self.federated_only = False # Nope - for compatibility with Learner TODO # nucypher/466 Teacher.set_federated_mode(False) self.registry = registry or InMemoryContractRegistry.from_latest_publication( ) self._refresh_rate = refresh_rate self._restart_on_error = restart_on_error # TODO: Needs cleanup # Tracking node_storage = CrawlerNodeStorage( storage_filepath=node_storage_filepath) class MonitoringTracker(FleetStateTracker): def record_fleet_state(self, *args, **kwargs): new_state_or_none = super().record_fleet_state(*args, **kwargs) if new_state_or_none: _, new_state = new_state_or_none state = self.abridged_state_details(new_state) node_storage.store_state_metadata(state) self.tracker_class = MonitoringTracker super().__init__(save_metadata=True, node_storage=node_storage, *args, **kwargs) self.log = Logger(self.__class__.__name__) self.log.info( f"Storing node metadata in DB: {node_storage.db_filepath}") self.log.info( f"Storing blockchain metadata in DB: {influx_host}:{influx_port}") # In-memory Metrics self._stats = {'status': 'initializing'} self._crawler_client = None # Initialize InfluxDB self._db_host = influx_host self._db_port = influx_port self._influx_client = None # Agency self.staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=self.registry) # Crawler Tasks self.__collection_round = 0 self.__collecting_nodes = False # thread tracking self.__collecting_stats = False self.__events_from_block = 0 # from the beginning self.__collecting_events = False self._node_details_task = task.LoopingCall(self._learn_about_nodes) self._stats_collection_task = task.LoopingCall(self._collect_stats, threaded=True) self._events_collection_task = task.LoopingCall(self._collect_events) # JSON Endpoint self._crawler_http_port = crawler_http_port self._flask = None