def update_node_config(node: "AbstractGatewayNode"): config.init_file_in_data_dir(gateway_constants.CONFIG_FILE_NAME) config.init_file_in_data_dir(gateway_constants.CONFIG_OVERRIDE_NAME) default_node_config = read_config_file( config.get_data_file(gateway_constants.CONFIG_FILE_NAME)) override_node_config = read_config_file( config.get_data_file(gateway_constants.CONFIG_OVERRIDE_NAME)) node_config = GatewayNodeConfigModel() node_config.merge(default_node_config) node_config.merge(override_node_config) logger.trace({"type": "update_node_config", "data": node_config}) log_config_model = node_config.log_config if log_config_model is not None: try: if log_config_model.log_level is not None: # pyre-fixme[6]: Expected `str` for 1st param but got `Optional[str]`. compare_and_update( log_level.from_string(log_config_model.log_level), project_root_logger.level, setter=functools.partial(log_config.set_level, node.opts.logger_names), item="log_level") if log_config_model.log_level_overrides is not None: # pyre-fixme[6]: Expected `Dict[str, # typing.Union[log_level.LogLevel, str]]` for 1st param but got # `Dict[str, str]`. log_config.set_log_levels(log_config_model.log_level_overrides) except (AttributeError, KeyError): logger.warning(log_messages.INVALID_CONFIG_LOG_LEVEL, log_config_model.log_level) if node_config.cron_config is not None: compare_and_update(node_config.cron_config.config_update_interval, node.opts.config_update_interval, item="config_update_interval", setter=lambda val: node.opts.__setattr__( "config_update_interval", val)) compare_and_update(node_config.cron_config.info_stats_interval, node.opts.info_stats_interval, item="info_stats_interval", setter=lambda val: node.opts.__setattr__( "info_stats_interval", val)) compare_and_update(node_config.cron_config.throughput_stats_interval, node.opts.throughput_stats_interval, item="throughput_stats_interval", setter=lambda val: node.opts.__setattr__( "throughput_stats_interval", val)) compare_and_update(node_config.cron_config.memory_stats_interval, node.opts.memory_stats_interval, item="memory_stats_interval", setter=lambda val: node.opts.__setattr__( "memory_stats_interval", val))
def __init__(self, ipc_file: str, feed_manager: FeedManager, node: "AbstractGatewayNode"): self.ipc_path = config.get_data_file(ipc_file) self.node = node self.feed_manager = feed_manager self._server: Optional[WebSocketServer] = None self._connections: List[WsConnection] = [] self._started: bool = False
def _load_status_file(self) -> Tuple[Summary, Analysis, Environment, Network]: path = config.get_data_file(STATUS_FILE_NAME) self.assertTrue(os.path.exists(path)) with open(path, "r", encoding="utf-8") as json_file: status_file = json_file.read() diagnostics_loaded = model_loader.load_model_from_json(Diagnostics, status_file) summary_loaded = diagnostics_loaded.summary analysis_loaded = diagnostics_loaded.analysis network_loaded = analysis_loaded.network environment_loaded = analysis_loaded.environment return summary_loaded, analysis_loaded, environment_loaded, network_loaded
def _load_status_from_file(use_ext: bool, src_ver: str, ip_address: str, continent: str, country: str, update_required: bool, account_id: Optional[str], quota_level: Optional[int]) -> Diagnostics: path = config.get_data_file(STATUS_FILE_NAME) with open(path, "r", encoding="utf-8") as json_file: status_file = json_file.read() try: model_dict = json.loads(status_file) diagnostics = model_loader.load_model(Diagnostics, model_dict) except JSONDecodeError: logger.warning(log_messages.STATUS_FILE_JSON_LOAD_FAIL, path) diagnostics = initialize(use_ext, src_ver, ip_address, continent, country, update_required, account_id, quota_level) return diagnostics
def get_default_eth_private_key(): gateway_key_file_name = config.get_data_file( eth_common_constants.GATEWAY_PRIVATE_KEY_FILE_NAME) if os.path.exists(gateway_key_file_name): with open(gateway_key_file_name, "r") as key_file: private_key = key_file.read().strip() else: private_key = crypto_utils.generate_random_private_key_hex_str() with open(gateway_key_file_name, "w") as key_file: key_file.write(private_key) return private_key
def update(conn_pool: ConnectionPool, use_ext: bool, src_ver: str, ip_address: str, continent: str, country: str, update_required: bool, blockchain_peers: Set[BlockchainPeerInfo], account_id: Optional[str], quota_level: Optional[int]) -> Diagnostics: path = config.get_data_file(STATUS_FILE_NAME) if not os.path.exists(path): initialize(use_ext, src_ver, ip_address, continent, country, update_required, account_id, quota_level) diagnostics = _load_status_from_file(use_ext, src_ver, ip_address, continent, country, update_required, account_id, quota_level) analysis = diagnostics.analysis network = analysis.network for network_type, individual_network in network.iter_network_type_pairs(): for conn in individual_network: if conn.get_connection_state() == ConnectionState.DISCONNECTED or \ not conn_pool.has_connection(conn.ip_address, int(conn.port)): network.remove_connection(conn, network_type) for conn_type in CONN_TYPES: for conn in conn_pool.get_by_connection_types([conn_type]): network.add_connection(conn.CONNECTION_TYPE, conn.peer_desc, str(conn.file_no), conn.peer_id) for blockchain_peer in blockchain_peers: blockchain_ip_endpoint = IpEndpoint(blockchain_peer.ip, blockchain_peer.port) blockchain_conn = None if conn_pool.has_connection(blockchain_peer.ip, blockchain_peer.port): blockchain_conn = conn_pool.get_by_ipport(blockchain_peer.ip, blockchain_peer.port) if blockchain_conn: network.add_connection(ConnectionType.BLOCKCHAIN_NODE, str(blockchain_ip_endpoint), str(blockchain_conn.file_no), blockchain_conn.peer_id) else: network.add_connection(ConnectionType.BLOCKCHAIN_NODE, str(blockchain_ip_endpoint), None, None) summary = network.get_summary(ip_address, continent, country, update_required, account_id, quota_level) assert summary.gateway_status is not None # pyre-fixme[16]: `Optional` has no attribute `value`. gateway_status.state(summary.gateway_status.value) diagnostics = Diagnostics(summary, analysis) _save_status_to_file(diagnostics) return diagnostics
def main() -> None: logger_names = node_runner.LOGGER_NAMES.copy() logger_names.append("bxgateway") logging_messages_utils.logger_names = set(logger_names) opts = get_opts() get_node_class = functools.partial(get_gateway_node_type, opts.blockchain_protocol) node_runner.run_node(config.get_data_file(PID_FILE_NAME), opts, get_node_class, NodeType.EXTERNAL_GATEWAY, logger_names=logger_names, node_init_tasks=gateway_init_tasks.init_tasks)
def main() -> None: logger_names = node_runner.LOGGER_NAMES.copy() logger_names.append("bxgateway") logging_messages_utils.logger_names = set(logger_names) opts = get_opts() get_node_class = functools.partial(get_gateway_node_type, opts.blockchain_protocol) node_runner.run_node( config.get_data_file(PID_FILE_NAME), opts, get_node_class, NodeType.EXTERNAL_GATEWAY, logger_names=logger_names, # pyre-fixme[6] Expected `Optional[List[AbstractInitTask]]` but got `List[ValidateNetworkOpts]` node_init_tasks=node_init_tasks.gateway_node_init_tasks)
async def process_request(self) -> JsonRpcResponse: path = config.get_data_file(self._file_name) with open(path, "w", encoding="utf-8") as f: f.write( "transaction_hash,has_contents,has_short_id,contents_length,short_id,time_inserted\n" ) tx_service = self.node.get_tx_service() for tx_hash in tx_service.iter_transaction_hashes(): transaction_cache_key = tx_service._tx_hash_to_cache_key( tx_hash) has_contents = transaction_cache_key in tx_service._tx_cache_key_to_contents has_short_id = transaction_cache_key in tx_service._tx_cache_key_to_short_ids contents_length = 0 if has_contents: tx_contents = tx_service._tx_cache_key_to_contents[ transaction_cache_key] contents_length = len(tx_contents) if has_short_id: short_ids = tx_service._tx_cache_key_to_short_ids[ transaction_cache_key] for short_id in short_ids: time_inserted = tx_service.get_short_id_assign_time( short_id) if time_inserted == 0.0: time_inserted = None else: time_inserted = datetime.fromtimestamp( time_inserted) f.write(f"{tx_hash}," f"{has_contents}," f"{has_short_id}," f"{contents_length}," f"{short_id}," f"{time_inserted}\n") else: f.write(f"{tx_hash}," f"{has_contents}," f"{has_short_id}," f"{contents_length}," f"{None}," f"{None}\n") f.close() return self.ok({"file": path})
def read(opts: Union["CommonOpts", Namespace]) -> Optional[CacheNetworkInfo]: cache_file_info = None enable_node_cache = opts.__dict__.get("enable_node_cache", False) relative_path = opts.__dict__.get("cookie_file_path", None) if enable_node_cache and relative_path is not None: try: cookie_file_path = config.get_data_file(relative_path) if os.path.exists(cookie_file_path): with open(cookie_file_path, "r") as cookie_file: cache_file_info = model_loader.load_model( CacheNetworkInfo, json.load(cookie_file)) if cache_file_info.source_version != opts.source_version: os.remove(cookie_file_path) else: logger.warning(log_messages.READ_CACHE_FILE_WARNING, cookie_file_path) # pylint: disable=broad-except except Exception as e: logger.error( "Failed when tried to read from cache file: {} with exception: {}", relative_path, str(e)) return cache_file_info
def update_cache_file( opts: "CommonOpts", potential_relay_peers: Optional[List[OutboundPeerModel]] = None, blockchain_peers: Optional[List[BlockchainPeerInfo]] = None, accounts: Optional[Dict[str, Optional[BdnAccountModelBase]]] = None) -> None: data = read(opts) node_model = model_loader.load_model(NodeModel, opts.__dict__) if data is None: data = CacheNetworkInfo(source_version=opts.source_version, relay_peers=potential_relay_peers, blockchain_networks=opts.blockchain_networks, blockchain_peers=blockchain_peers, node_model=node_model, accounts=accounts) else: data.blockchain_networks = opts.blockchain_networks data.node_model = node_model if potential_relay_peers is not None: data.relay_peers = potential_relay_peers if blockchain_peers is not None: data.blockchain_peers = blockchain_peers if accounts is not None: if data.accounts: data.accounts.update(accounts) else: data.accounts = accounts try: cookie_file_path = config.get_data_file(opts.cookie_file_path) os.makedirs(os.path.dirname(cookie_file_path), exist_ok=True) with open(cookie_file_path, "w") as cookie_file: json.dump(data, cookie_file, indent=4, cls=EnhancedJSONEncoder) # pylint: disable=broad-except except Exception as e: logger.error( "Failed when tried to write to cache file: {} with exception: {}", opts.cookie_file_path, e)
def update(conn_pool: ConnectionPool, use_ext: bool, src_ver: str, ip_address: str, continent: str, country: str, update_required: bool, account_id: Optional[str], quota_level: Optional[int]) -> Diagnostics: path = config.get_data_file(STATUS_FILE_NAME) if not os.path.exists(path): initialize(use_ext, src_ver, ip_address, continent, country, update_required, account_id, quota_level) diagnostics = _load_status_from_file(use_ext, src_ver, ip_address, continent, country, update_required, account_id, quota_level) analysis = diagnostics.analysis network = analysis.network network.clear() for conn_type in CONN_TYPES: for conn in conn_pool.get_by_connection_types([conn_type]): network.add_connection(conn.CONNECTION_TYPE, conn.peer_desc, conn.file_no, conn.peer_id) summary = network.get_summary(ip_address, continent, country, update_required, account_id, quota_level) assert summary.gateway_status is not None # pyre-fixme[16]: `Optional` has no attribute `value`. gateway_status.state(summary.gateway_status.value) diagnostics = Diagnostics(summary, analysis) _save_status_to_file(diagnostics) return diagnostics
def _save_status_to_file(diagnostics: Diagnostics) -> None: path = config.get_data_file(STATUS_FILE_NAME) with open(path, "w", encoding="utf-8") as outfile: json.dump(diagnostics, outfile, cls=EnhancedJSONEncoder, indent=2)
from bxutils.encoding.json_encoder import Case if TYPE_CHECKING: from bxgateway.connections.abstract_gateway_node import AbstractGatewayNode logger = logging.get_logger(__name__) class IpcServer: def __init__(self, ipc_file: str, feed_manager: FeedManager, node: "AbstractGatewayNode", case: Case = Case.CAMEL): self.ipc_path = config.get_data_file(ipc_file) self.node = node self.feed_manager = feed_manager self.case = case self._server: Optional[WebSocketServer] = None self._connections: List[WsConnection] = [] self._started: bool = False def status(self) -> bool: return self._started async def start(self) -> None: if os.path.exists(self.ipc_path): os.remove(self.ipc_path) self._server = await websockets.unix_serve(self.handle_connection, self.ipc_path)
def setUp(self): self.conn_pool = ConnectionPool() self.source_version = "v1.0.0" self.ip_address = "0.0.0.0" self.continent = "NA" self.country = "United States" self.account_id = None self.fileno1 = 1 self.ip1 = "123.123.123.123" self.port1 = 1000 self.node1 = MockNode( helpers.get_common_opts(1001, external_ip="128.128.128.128")) self.node_id1 = str(uuid.uuid1()) self.conn1 = MockConnection( MockSocketConnection(self.fileno1, self.node1, ip_address=self.ip1, port=self.port1), self.node1) self.conn1.CONNECTION_TYPE = ConnectionType.RELAY_BLOCK self.fileno2 = 5 self.ip2 = "234.234.234.234" self.port2 = 2000 self.node2 = MockNode( helpers.get_common_opts(1003, external_ip="321.321.321.321")) self.node_id2 = str(uuid.uuid1()) self.conn2 = MockConnection( MockSocketConnection(self.fileno2, self.node2, ip_address=self.ip2, port=self.port2), self.node2) self.conn2.CONNECTION_TYPE = ConnectionType.RELAY_TRANSACTION self.fileno3 = 6 self.ip3 = "234.234.234.234" self.port3 = 3000 self.node3 = MockNode( helpers.get_common_opts(1003, external_ip="213.213.213.213")) self.node_id3 = str(uuid.uuid1()) self.conn3 = MockConnection( MockSocketConnection(self.fileno3, self.node3, ip_address=self.ip3, port=self.port3), self.node3) self.conn3.CONNECTION_TYPE = ConnectionType.BLOCKCHAIN_NODE self.fileno4 = 8 self.ip4 = "111.222.111.222" self.port4 = 3000 self.node4 = MockNode( helpers.get_common_opts(1003, external_ip="101.101.101.101")) self.node_id4 = str(uuid.uuid1()) self.conn4 = MockConnection( MockSocketConnection(self.fileno4, self.node4, ip_address=self.ip4, port=self.port4), self.node4) self.conn4.CONNECTION_TYPE = ConnectionType.REMOTE_BLOCKCHAIN_NODE self.quota_level = 0 initialize(False, self.source_version, self.ip_address, self.continent, self.country, False, self.account_id, self.quota_level) path = config.get_data_file(STATUS_FILE_NAME) self.addCleanup(os.remove, path)
def __init__(self, ipc_file: str): super().__init__(ipc_file) self.ipc_path: str = config.get_data_file(ipc_file)