def initialize(path_to_config_file, path_to_key_info_json): log = logging.getLogger('werkzeug') log.setLevel(logging.ERROR) success = ConfigManager.load(path_to_config_file) if not success: return False config = ConfigManager.getConfig() Logger.setLogFolder(config.server_log_file_folder) success = TransactionSigner.initialize() if not success: return False success = KeyInfoManager.load(path_to_key_info_json) if not success: return False if KeyInfoManager.getKeyInfo(KeyAlias.WHITELIST_CONTROLLER) == None: Logger.printError('%s key info not loaded!' % (KeyAlias.WHITELIST_CONTROLLER)) return False if KeyInfoManager.getKeyInfo(KeyAlias.EXCHANGE_RATE_CONTROLLER) == None: Logger.printError('%s key info not loaded!' % (KeyAlias.EXCHANGE_RATE_CONTROLLER)) return False success = TransactionSigner.initialize() if not success: return False return True
def _connect(self, http_method, rel_path, params, return_raw_response = False): url = self._base_url + rel_path data = params if http_method == HttpMethod.GET: connect = self._http_connect_lib.get elif http_method == HttpMethod.PUT: connect = self._http_connect_lib.put elif http_method == HttpMethod.POST: connect = self._http_connect_lib.post elif http_method == HttpMethod.DELETE: connect = self._http_connect_lib.delete else: return None # not supported success, raw_response_json = False, None try: # TODO: verify certificate for Https connections raw_response_str = connect(url = url, data = data, verify = False) raw_response_json = json.loads(raw_response_str) success = True except Exception as e: Logger.printError('Failed to call API: %s, data: %s, error: %s'%(url, data, e.message)) traceback.print_exc() sys.stdout.flush() pass if return_raw_response: return raw_response_str else: api_response = self._parseRawResponse(success, raw_response_json) return api_response
def _parseRawResponse(self, success, raw_response_json): if not success: Logger.printError('Invalid server response! raw_response_json: %s'%(raw_response_json)) return HttpError(ApiErrorCode.SERVER_CONNECTION_ERROR, 'Failed to connect to server!') status = ApiStatus.OK body = raw_response_json['result'] return HttpSuccess(body)
def load(path_to_key_info_list_json): with open(path_to_key_info_list_json) as key_info_list_json_file: key_info_list_json = json.load(key_info_list_json_file) _key_info_map = {} for key_info_json in key_info_list_json: success, key_info = KeyInfo.fromJson(key_info_json) if not success: Logger.printError('Failed to parse key info: %s' % (key_info_json)) return False KeyInfoManager._key_info_map[key_info.alias] = key_info return True
def load(path_to_config_json): with open(path_to_config_json) as config_json_file: config_json = json.load(config_json_file) config = ConfigManager.config try: config.load(config_json) except: Logger.printError('Failed to load config file! file path: %s %s' % (path_to_config_json, traceback.print_exc())) return False return True
def exportTokenBalance(ethereum_rpc_url, smart_contract_address, expected_total_supply, genesis_height, target_height, balance_file_path): export_folder = "./data/events" if not os.path.exists(export_folder): os.makedirs(export_folder) Logger.printInfo('') Logger.printInfo('Start exporting Ethereum events...') eee = EthereumEventExtractor(ethereum_rpc_url, smart_contract_address, export_folder) eee.Export(genesis_height, target_height) Logger.printInfo('Ethereum events exported.') Logger.printInfo('') Logger.printInfo('Start extracting token holders...') eea = EthereumEventAnalyzer() analyzed_balance_map = eea.Analyze(export_folder, target_height) Logger.printInfo('Token holders extracted.') Logger.printInfo('') #with open(balance_file_path + '.analyzed', 'w') as balance_file: # json.dump(analyzed_balance_map, balance_file, indent=2) Logger.printInfo( 'Start querying the balance of each holder at block height %s, may take a while...' % (target_height)) token_holder_addresses = analyzed_balance_map.keys() tbe = TokenBalanceExtractor(ethereum_rpc_url, smart_contract_address) queried_balance_map = tbe.Query(token_holder_addresses, target_height) Logger.printInfo('Token holders balance retrieved.') Logger.printInfo('') #with open(balance_file_path + '.queried', 'w') as balance_file: # json.dump(queried_balance_map, balance_file, indent=2) Logger.printInfo('Start sanity checks...') if not sanityChecks(analyzed_balance_map, queried_balance_map, expected_total_supply): Logger.printError('Sanity checks failed.') exit(1) Logger.printInfo('Sanity checks all passed.') Logger.printInfo('') with open(balance_file_path, 'w') as balance_file: json.dump(queried_balance_map, balance_file, indent=2) Logger.printInfo('Token balances calculated and exported to: %s' % (balance_file_path)) Logger.printInfo('')
def _executeJobs(self): if self._jobs_enabled: self._disableJobs() for job in self._job_list: try: job.execute(self._second_counter) except Exception as e: Logger.printError('Caught job exception: ' + str(e)) traceback.print_exc() pass self._job_invocation_count += 1 self._enableJobs() self._second_counter += self._wakeup_interval_in_seconds if self._second_counter >= JobScheduler.MAX_SECOND_COUNT: self._second_counter = 0
def _parseRawResponse(self, success, raw_response_json): if not success: Logger.printError( 'Invalid server response! raw_response_json: %s' % (raw_response_json)) return HttpError(ApiErrorCode.SERVER_CONNECTION_ERROR, 'Failed to connect to server!') if raw_response_json.get(ApiKey.STATUS, None) is None: # Likely to be HTTP error like 404, 500, etc. # e.g.: {u'message': u'HTTP 404 Not Found', u'code': 404} Logger.printError( 'Invalid server response! raw_response_json: %s' % (raw_response_json)) return HttpError(ApiErrorCode.INVALID_RESPONSE_FORMAT, 'Response does not have a status code!') if raw_response_json.get(ApiKey.BODY, None) is None: Logger.printError( 'Invalid server response! raw_response_json: %s' % (raw_response_json)) return HttpError(ApiErrorCode.INVALID_RESPONSE_FORMAT, 'Response does not have a body!') status = raw_response_json[ApiKey.STATUS] body = raw_response_json[ApiKey.BODY] error_code = raw_response_json.get(ApiKey.ERROR_CODE, 0) message = raw_response_json.get(ApiKey.MESSAGE, "") if status in [ApiStatus.OK, ApiStatus.SUCCESS]: return HttpSuccess(body) else: return HttpError(error_code, message)
def sanityChecks(analyzed_balance_map, queried_balance_map, expected_total_supply): total_supply = 0 for address in analyzed_balance_map.keys(): analyzed_balance = analyzed_balance_map[address] queried_balance = queried_balance_map.get(address, -1) if (analyzed_balance != queried_balance) or (queried_balance == -1): Logger.printError( "Balance mismatch for address: %s, analyzed_balance = %s, queried_balance = %s" % (address, analyzed_balance, queried_balance)) return False total_supply += int(queried_balance) Logger.printInfo('Expected total supply : %s' % (expected_total_supply)) Logger.printInfo('Sum of queried balances: %s' % (total_supply)) if total_supply != expected_total_supply: Logger.printError( 'Token total supply mismatch. expected = %s, calculated = %s' % (expected_total_supply, total_supply)) return False return True
def load(path_to_config_json): with open(path_to_config_json) as config_json_file: config_json = json.load(config_json_file) config = ConfigManager._config try: config.port = config_json[ConfigKey.PORT] config.server_log_file_folder = config_json[ ConfigKey.SERVER_LOG_FILE_FOLDER] config.theta_contract_address = config_json[ ConfigKey.THETA_CONTRACT_ADDRESS] config.theta_abi_file_path = config_json[ ConfigKey.THETA_ABI_FILE_PATH] config.theta_token_sale_contract_address = config_json[ ConfigKey.THETA_TOKEN_SALE_CONTRACT_ADDRESS] config.theta_token_sale_abi_file_path = config_json[ ConfigKey.THETA_TOKEN_SALE_ABI_FILE_PATH] except: Logger.printError('Failed to load config file! file path: %s %s' % (path_to_config_json, traceback.print_exc())) return False ConfigManager._initialized = True return True
# "expected_total_supply" : 1000000000000000000000000000 # } # if __name__ == '__main__': if len(sys.argv) != 4: print( "\nUsage: python run.py <config_file_path> <target_height> <balance_file_path>\n" ) exit(1) #Logger.enableDebugLog() config_file_path = sys.argv[1] target_height = int(sys.argv[2]) balance_file_path = sys.argv[3] cfgMgr = ConfigManager() if not cfgMgr.load(config_file_path): Logger.printError('Failed to load config: %s' % (config_file_path)) exit(1) config = cfgMgr.config ethereum_rpc_url = config.ethereum_rpc_url smart_contract_address = config.smart_contract_address expected_total_supply = config.expected_total_supply genesis_height = config.genesis_height exportTokenBalance(ethereum_rpc_url, smart_contract_address, expected_total_supply, genesis_height, target_height, balance_file_path)