def run(self):
    try:
      while True:
          schedule.run_pending()
          time.sleep(1)
          
          if (self._max_job_invocation_count is not None) and \
             (self._job_invocation_count >= self._max_job_invocation_count):
            Logger.printInfo('Max job invocation count reached. Exiting...')
            break 

    except (KeyboardInterrupt, SystemExit):
      pass
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 get(self):
        addresses = request.args.getlist(ApiKey.ADDRESS, None)
        nonce = request.args.get(ApiKey.NONCE, None)
        gas_price = request.args.get(ApiKey.GAS_PRICE, None)
        start_gas = request.args.get(ApiKey.START_GAS, None)
        if None in [addresses, nonce, gas_price, start_gas]:
            return HttpError(
                error_code=ApiErrorCode.QUERY_PARAM_MISSING,
                message=
                'Query parameter missing! requires address, nonce, gas_price, and start_gas!'
            ).toJson()

        nonce = int(nonce)
        gas_price = int(gas_price)
        start_gas = int(start_gas)
        function_name = SupportedFunctionName.ADD_ACCOUNTS_TO_WHITELIST
        function_params = addresses
        key_info = KeyInfoManager.getKeyInfo(KeyAlias.WHITELIST_CONTROLLER)

        success, signed_tx = TransactionSigner.signTransaction(
            from_addr=key_info.address,
            nonce=nonce,
            gas_price=gas_price,
            start_gas=start_gas,
            smart_contract_name=SmartContractName.THETA_TOKEN_SALE,
            function_name=function_name,
            function_params=function_params,
            private_key=key_info.private_key)

        if not success:
            return HttpError(
                error_code=ApiErrorCode.TX_SIGNING_FAILURE,
                message='Failed to sign the transaction!').toJson()

        Logger.printInfo('Signed transaction - nonce: %s, function_name: %s, function_params: %s, signed_tx: %s'%\
          (nonce, function_name, function_params, signed_tx))

        return HttpSuccess({ApiKey.SIGNED_TX: signed_tx}).toJson()
 def Export(self, start_height, end_height):
     Logger.printInfo("Start to extract events from height %s to %s..." %
                      (start_height, end_height))
     current_height = self.getProcessedHeight()
     if current_height >= start_height:
         Logger.printInfo("Already extracted up to height %s" %
                          (current_height))
         if current_height < end_height:
             Logger.printInfo("Continue from height %s..." %
                              (current_height + 1))
     else:
         current_height = start_height - 1
     while current_height < end_height:
         from_height = current_height + 1
         to_height = min(
             from_height + EthereumEventExtractor.HEIGHT_STEP - 1,
             end_height)
         self.export(from_height, to_height)
         current_height = to_height
         Logger.printInfo("Extracted events from height %s to %s" %
                          (from_height, to_height))
Beispiel #5
0
 def Query(self, addresses, target_height):
     num_addresses = len(addresses)
     Logger.printInfo("Total number of addresses: %s" % (num_addresses))
     queried_balance_map = {}
     num_addresses_queried = 0
     for address in addresses:
         balance = self.ethereum_rpc_service.GetTokenBalance(
             smart_contract_address=self.smart_contract_address,
             account_address=address,
             target_height=hex(target_height))
         balance_str = str(balance)
         queried_balance_map[address] = balance_str
         num_addresses_queried += 1
         if num_addresses_queried % 1000 == 0:
             Logger.printInfo("%s addresses queried." %
                              (num_addresses_queried))
     Logger.printInfo("%s addresses queried." % (num_addresses_queried))
     return queried_balance_map
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('')
Beispiel #7
0
        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


app = Flask(__name__)
api = Api(app)
api.add_resource(WhitelistResource, '/whitelist/sign')
api.add_resource(ExchangeRateResource, '/exchange_rate/sign')

if __name__ == '__main__':
    path_to_config_file = '../config.json'
    path_to_key_info_json = '../data/key_info.json'
    success = initialize(path_to_config_file, path_to_key_info_json)
    if not success:
        exit(1)

    host = '0.0.0.0'
    port = ConfigManager.getConfig().getPort()
    Logger.printInfo('Running test server at %s:%s' % (host, port))
    app.run(threaded=True, debug=True, host=host, port=port)