def __init__(self, account, contract_dir, wasm_file=None, abi_file=None, permission=None, expiration_sec=30, skip_signature=0, dont_broadcast=0, forceUnique=0, max_cpu_usage=0, max_net_usage=0, ref_block=None, is_verbose=True, json=False): files = contract_is_built(contract_dir, wasm_file, abi_file) if not files: raise errors.Error(""" Cannot determine the contract directory. The clue is {}. """.format(contract_dir)) return self.contract_path_absolute = files[0] wasm_file = files[1] abi_file = files[2] self.account_name = interface.account_arg(account) args = [self.account_name, self.contract_path_absolute] if json: args.append("--json") if not permission is None: p = interface.permission_arg(permission) for perm in p: args.extend(["--permission", perm]) args.extend(["--expiration", str(expiration_sec)]) if skip_signature: args.append("--skip-sign") if dont_broadcast: args.append("--dont-broadcast") if forceUnique: args.append("--force-unique") if max_cpu_usage: args.extend(["--max-cpu-usage-ms", str(max_cpu_usage)]) if max_net_usage: args.extend(["--max-net-usage", str(max_net_usage)]) if not ref_block is None: args.extend(["--ref-block", ref_block]) if wasm_file: args.append(wasm_file) if abi_file: args.append(abi_file) _Cleos.__init__(self, args, "set", "contract", is_verbose) self.printself()
def activity_got_once(self, _id, user): """ :raises: Error """ qa = self.get_activity_by_id(_id=_id) if qa is None: raise errors.NotFound(message=_('活动不存在')) record = self.check_activity_pre_got(qa=qa, user=user) with transaction.atomic(): r = QuotaActivity.objects.filter( id=_id, got_count__lt=F('count')).update(got_count=F('got_count') + 1) if r <= 0: raise errors.ConflictError(code='NoneLeft', message=_('配额已经被领完了')) try: r = QuotaActivityGotRecord.objects.filter( id=record.id, got_count__lt=qa.times_per_user).update( got_count=F('got_count') + 1) if r <= 0: raise errors.ConflictError(code='TooMany', message=_('不能领取更多了')) except Exception as exc: raise errors.convert_to_error(exc) quota = qa.build_quota_obj(user_id=user.id) try: quota.save() except Exception as e: raise errors.Error(message=_('创建配额时错误') + str(e)) return quota
def node_probe(verbosity=None): count = 15 num = 5 block_num = None while True: time.sleep(1) try: get_info = cleos.GetInfo(is_verbose=0) count = count - 1 head_block_num = int(get_info.json["head_block_num"]) except: head_block_num = 0 finally: print(".", end="", flush=True) if block_num is None: block_num = head_block_num if head_block_num - block_num >= num: print() logger.INFO( ''' Local node is running. Block number is {} '''.format(head_block_num), verbosity) break if count <= 0: raise errors.Error(''' The local node does not respond. ''')
def clear_testnet_cache(verbosity=None): ''' Remove wallet files associated with the current testnet. ''' if not setup.file_prefix(): return logger.TRACE(''' Removing testnet cache for prefix `{}` '''.format(setup.file_prefix())) kill_keosd() # otherwise the manager may protects the wallet files dir = wallet_dir() files = os.listdir(dir) try: for file in files: if file.startswith(setup.file_prefix()): os.remove(os.path.join(dir, file)) except Exception as e: raise errors.Error(''' Cannot remove testnet cache. The error message is: {} '''.format(str(e))) logger.TRACE(''' Testnet cache successfully removed. ''')
def remove_key(self, account_or_key): ''' ''' self.open_unlock() removed_keys = [] account_name = None if isinstance(account_or_key, interface.Account): cleos.WalletRemove_key(interface.key_arg(account_or_key, is_owner_key=True, is_private_key=True), self.name, is_verbose=False) removed_keys.append( interface.key_arg(account_or_key, is_owner_key=True, is_private_key=False)) cleos.WalletRemove_key(interface.key_arg(account_or_key, is_owner_key=False, is_private_key=True), self.name, is_verbose=False) removed_keys.append( interface.key_arg(account_or_key, is_owner_key=False, is_private_key=False)) else: cleos.WalletRemove_key(interface.key_arg(account_or_key, is_private_key=True), self.name, is_verbose=False) removed_keys.append( interface.key_arg(account_or_key, is_private_key=False)) if account_name is None: if len(removed_keys) > 0: logger.TRACE( ''' Removing key '{}' from the wallet '{}' '''.format(removed_keys[0], self.name), verbosity) else: logger.TRACE(''' Removing keys of the account '{}' from the wallet '{}' '''.format(account_name, self.name)) wallet_keys = cleos.WalletKeys(is_verbose=False) for key in removed_keys: if key in wallet_keys.json: raise errors.Error(''' Failed to remove key '{}' from the wallet '{}' '''.format(key, self.name)) logger.TRACE(''' * Cross-checked: all listed keys removed from the wallet. ''') return True
def getSourceDir(): config_value = configValue("EOSIO_SOURCE_DIR") if config_value: return config_value raise errors.Error(''' Cannot determine the EOSIO source directory. ''')
def getEosFactoryDir(): config_value = configValue("EOSIO_EOSFACTORY_DIR") if config_value: return config_value raise errors.Error(''' Cannot determine the context directory. ''')
def getContractFile(contract_dir_hint, contract_file_hint): ''' Given contract dir and contract file hints, determine the file. Contract files are those extended with ``wast``, ``wasm`` and ``abi``. First, the ``contract_file_hint`` may be an absolute path. Next, it may be relative to the contract directory. The contract directory is the container for the project of a contract. This directory is determined with the ``getContractDir`` function, basing on the ``contract_dir_hint``. Any contract directory contains directories and files structured according to few schemes: flat structure with all the files in this directory as in the ``eos/contracts/*`` contract directories in the EOS repository; structure with a directory named ``build`` as resulting from the EOSFactory templates; ''' contract_dir_hint = utils.wslMapWindowsLinux(contract_dir_hint) contract_file_hint = utils.wslMapWindowsLinux(contract_file_hint) # ? ``contract_file_hint`` may be an absolute path to a file trace = contract_file_hint + "\n" if os.path.isabs(contract_file_hint) \ and os.path.isfile(contract_file_hint): return contract_file_hint # ? it may be relative to the contract directory. contract_dir = getContractDir(contract_dir_hint) # ? flat structure with all the files in this directory contract_file = os.path.join(contract_dir, contract_file_hint) trace = trace + contract_file + "\n" if os.path.isfile(contract_file): return contract_file # ? structure with a directory named ``build`` # and ``contract_file_hint`` is relative file contract_file = os.path.join(contract_dir, "build", contract_file_hint) trace = trace + contract_file + "\n" if os.path.isfile(contract_file): return contract_file # ? structure with a directory named ``build`` # and ``contract_file_hint`` is a file extension merely build_dir = os.path.join(contract_dir, "build") trace = trace + build_dir + "\n" files = os.listdir(build_dir) for file in files: if os.path.splitext(file)[1] == contract_file_hint: return os.path.join(build_dir, file) raise errors.Error(''' Cannot determine the contract file basing on hints: contract dir hint: {} contract file hint: {} Tried path list: {} '''.format(contract_dir_hint, contract_file_hint, trace))
def read_map(file_name, text_editor="nano"): '''Return json account map Attempt to open the account map file named ``setup.account_map``, located in the wallet directory ``wallet_dir()``, to return its json contents. If the file does not exist, return an empty json. If the file is corrupted, offer editing the file with the ``nano`` linux editor. Return ``None`` if the the offer is rejected. ''' wallet_dir_ = wallet_dir() path = os.path.join(wallet_dir_, file_name) while True: try: # whether the setup map file exists: with open(path, "r") as input_file: return json.load(input_file) except Exception as e: if isinstance(e, FileNotFoundError): return {} else: raise errors.Error(''' The json file {} is misformed. The error message is: {} Do you want to edit the file? '''.format(str(path), str(e)), is_fatal=False, translate=False) answer = input("y/n <<< ") if answer == "y": import subprocess subprocess.run([text_editor, path]) continue else: raise errors.Error(''' Use the function 'efman.edit_account_map(text_editor="nano")' or the corresponding method of any object of the 'pyteos.wallet.Wallet` class to edit the file. ''', translate=False) return None
def config_map(): path = config_file() if os.path.exists(path): with open(path, "r") as input: return json.load(input) raise errors.Error(''' Cannot find the config json file. ''')
def __init__(self, name=None, password="", verbosity=None, file=False): cleos.set_local_nodeos_address_if_none() if name is None: name = setup.wallet_default_name else: name = setup.file_prefix() + name if not self.wallet is None: raise errors.Error(''' It can be only one ``Wallet`` object in the script; there is one named ``{}``. '''.format(wallet.name)) return self.wallet_dir = manager.wallet_dir() logger.INFO(''' * Wallet name is ``{}``, wallet directory is {}. '''.format(name, self.wallet_dir)) if not password: # look for password: passwords = wallet_json_read() if name in passwords: password = passwords[name] logger.INFO( ''' The password is restored from the file: {} '''.format( os.path.join(self.wallet_dir, setup.password_map)), verbosity) cleos.WalletCreate.__init__(self, name, password, is_verbose=False) if self.is_created: # new password logger.INFO( ''' * Created wallet ``{}``. '''.format(self.name), verbosity) if manager.is_local_testnet() or file: password_map = wallet_json_read() password_map[name] = self.password wallet_json_write(password_map) logger.INFO( ''' * Password is saved to the file ``{}`` in the wallet directory. '''.format(setup.password_map), verbosity) else: logger.OUT(self.out_msg) else: logger.TRACE(''' Opened wallet ``{}`` '''.format(self.name))
def deploy(self, permission=None, dont_broadcast=None, payer=None): if not self.is_built(): raise errors.Error(''' Contract needs to be built before deployment. ''') return if dont_broadcast is None: dont_broadcast = self.dont_broadcast try: result = cleos.SetContract(self.account, self.contract_dir, self.wasm_file, self.abi_file, permission, self.expiration_sec, self.skip_signature, dont_broadcast, self.forceUnique, self.max_cpu_usage, self.max_net_usage, self.ref_block, is_verbose=False, json=True) except errors.LowRamError as e: logger.TRACE(''' * RAM needed is {}.kByte, buying RAM {}.kByte. '''.format(e.needs_kbyte, e.deficiency_kbyte)) buy_ram_kbytes = str(e.deficiency_kbyte + 1) if not payer: payer = self.account payer.buy_ram(buy_ram_kbytes, self.account) result = cleos.SetContract(self.account, self.contract_dir, self.wasm_file, self.abi_file, permission, self.expiration_sec, self.skip_signature, dont_broadcast, self.forceUnique, self.max_cpu_usage, self.max_net_usage, self.ref_block, is_verbose=False, json=True) logger.INFO(''' * Contract {} is deployed. '''.format(self.contract_dir)) self.contract = result
def verify_testnet_production(): result = is_head_block_num() domain = "LOCAL" if is_local_testnet() else "REMOTE" if not result: raise errors.Error(''' {} testnet is not running or is not responding @ {}. '''.format(domain, setup.nodeos_address())) else: logger.INFO(''' {} testnet is active @ {}. '''.format(domain, setup.nodeos_address())) return result
def process(command_line, throw_error=True): process = subprocess.run(command_line, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out_msg = process.stdout.decode("utf-8") out_err = process.stderr.decode("utf-8") returncode = process.returncode if returncode and throw_error: raise errors.Error(out_err) return returncode
def getGenesisJson(): path = configValue("EOSIO_GENESIS_JSON") if not os.path.isabs(path): path = os.path.join(getConfigDir(), path) if os.path.isfile(path): return path raise errors.Error(''' Cannot determine the genesis file. Tried path is {} '''.format(path))
def getTeosDir(): path = configValue("EOSIO_TEOS_DIR") if not os.path.isabs(path): path = os.path.join(configValue(EOSIO_EOSFACTORY_DIR), path) if os.path.isdir(path): return path raise errors.Error(''' Cannot find the teos directory. Tried path is {} '''.format(path))
def getContractDir(contract_dir_hint): ''' Given a hint, determine the contract directory. The contract directory is the container for the project of a contract. The hint is probed to be one of the following pieces of information: the absolute path to a contract directory; the relative path to a contract directory, relative to the directory set with the EOSIO_CONTRACT_WORKSPACE variable; the relative path to a contract directory, relative to the ``contracts`` directory in the repository of EOSFactory; the relative path to a contract directory, relative to the ``contracts`` directory in the repository of EOSIO. ''' contract_dir_hint = utils.wslMapWindowsLinux(contract_dir_hint) # ? the absolute path to a contract directory trace = contract_dir_hint + "\n" if os.path.isfile(contract_dir_hint): contract_dir_hint = os.path.dirname(contract_dir_hint) if os.path.isabs(contract_dir_hint): return contract_dir_hint # ? the relative path to a contract directory, relative to the directory # set with the EOSIO_CONTRACT_WORKSPACE variable contract_dir = os.path.join( configValue("EOSIO_CONTRACT_WORKSPACE"), contract_dir_hint) trace = trace + contract_dir + "\n" if os.path.isdir(contract_dir): return contract_dir # ? the relative path to a contract directory, relative to the # ``contracts`` directory in the repository of EOSFactory contract_dir = os.path.join( configValue("EOSIO_EOSFACTORY_DIR"), setup.CONTRACTS_DIR, contract_dir_hint) trace = trace + contract_dir + "\n" if os.path.isdir(contract_dir): return contract_dir # ? the relative path to a contract directory, relative to the # ``contracts`` directory in the repository of EOSIO contract_dir = os.path.join( configValue("EOSIO_SOURCE_DIR"), setup.EOSIO_CONTRACT_DIR, contract_dir_hint) trace = trace + contract_dir + "\n" if os.path.isdir(contract_dir): return contract_dir raise errors.Error(''' Cannot determine the contract directory. Tried path list: {} '''.format(trace))
def DaemonStop(): pid = get_pid() count = 10 if pid: os.system("kill " + str(pid[0])) while pid and count > 0: time.sleep(1) pid = get_pid() count = count -1 if count <= 0: raise errors.Error(''' Failed to kill {}. Pid is {}. '''.format(config.getDaemonName(), pid[0]) )
def config_file(): if not "EOSIO_EOSFACTORY_DIR" in os.environ: raise errors.Error(''' EOSIO_EOSFACTORY_DIR not defined ''') file = os.path.join(os.environ["EOSIO_EOSFACTORY_DIR"], setup.CONFIG_JSON) if os.path.exists(file): return file with open(file, "w") as output: output.write("{}") logger.INFO('''Creating an empty config file: {}'''.format(file)) return file
def getConfigDir(): path = configValue("EOSIO_CONFIG_DIR") if not os.path.isabs(path): contextDir = configValue("EOSIO_EOSFACTORY_DIR") if contextDir: path = os.path.join(contextDir, path) if os.path.isdir(path): return path raise errors.Error(''' Cannot find the 'config-dir' directory. Tried path is {} '''.format(path))
def getDataDir(): path = configValue("EOSIO_DATA_DIR") if not os.path.isabs(path): contextDir = configValue("EOSIO_EOSFACTORY_DIR") if contextDir: path = os.path.join(contextDir, path) if os.path.isdir(path): return path raise errors.Error(''' Cannot determine the 'data-dir' directory. Tried path is {} '''.format(path))
def __init__(self, contract_dir, verbosity=None, abi_file=None, wasm_file=None): self.contract_dir = config.getContractDir(contract_dir) if not self.contract_dir: raise errors.Error(""" Cannot determine the contract directory. The path is ``{}``. """.format(contract_dir)) return self.abi_file = abi_file self.wasm_file = wasm_file
def is_name_taken(self, account_object_name, account_name): while True: account_map_json = manager.account_map(self) if account_map_json is None: return False is_taken = False for name, object_name in account_map_json.items(): if object_name == account_object_name: if not name == account_name: logger.OUT(''' The given account object name ``{}`` points to an existing account, of the name {}, mapped in a file in directory: {} Cannot overwrite it. However, you can free the name by changing the mapping. Do you want to edit the file? '''.format(account_object_name, name, self.wallet_dir)) is_taken = True break if is_taken: temp = None if account_object_name in Wallet.globals: temp = Wallet.globals[account_object_name] del Wallet.globals[account_object_name] answer = input("y/n <<< ") if answer == "y": manager.edit_account_map() continue else: if temp: Wallet.globals[account_object_name] = temp raise errors.Error(''' Use the function 'manager.edit_account_map(text_editor="nano")' or the corresponding method of any object of the 'pyteos.wallet.Wallet` class to edit the file. ''') else: break
def getDaemonExe(): path = os.path.join(getSourceDir(), "build/programs/", configValue("EOSIO_DAEMON_NAME"), configValue("EOSIO_DAEMON_NAME")) trace = path + "\n" if os.path.exists(path): return path path = os.path.join("/usr/local/bin", configValue("EOSIO_DAEMON_NAME")) trace = trace + path + "\n" if os.path.exists(path): return path raise errors.Error(''' Cannot determine the EOS test node executable file. Tried path list: {} '''.format(trace))
def getContractWorkspace(): '''Return the absolute path to the contract workspace of the user. ''' workspacePath = configValue("EOSIO_CONTRACT_WORKSPACE") trace = workspacePath + "\n" if not os.path.isabs(workspacePath): workspacePath = os.path.join( configValue("EOSIO_EOSFACTORY_DIR"), workspacePath) trace = trace + workspacePath + "\n" if os.path.exists(workspacePath): return workspacePath raise errors.Error(''' Cannot determine the contract workspace. Tried path list: {} '''.format(trace))
def getContractSourceFiles(contract_dir_hint): contract_dir = getContractDir(utils.wslMapWindowsLinux(contract_dir_hint)) trace = contract_dir + "\n" srcs = getSourceFiles(contract_dir) if srcs: return srcs source_path = os.path.join(contract_dir, "src") trace = trace + source_path + "\n" srcs = getSourceFiles(source_path) if srcs: return srcs raise errors.Error(''' Cannot find any contract source directory. Tried path list: {} '''.format(trace))
def is_wallet_defined(logger, globals=None): ''' ''' global wallet_globals if not wallet_globals is None: return global wallet_singleton wallet_singleton = wallet.Wallet.wallet if wallet_singleton is None: wallet.create_wallet(globals=globals) wallet_singleton = wallet.Wallet.wallet if wallet_singleton is None: raise errors.Error(''' Cannot find any `Wallet` object. Add the definition of an `Wallet` object, for example: `create_wallet()` ''') wallet_globals = wallet.Wallet.globals
def exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ if isinstance(exc, exceptions.Error): set_rollback() return Response(exc.err_data(), status=exc.status_code) if isinstance(exc, Http404): exc = exceptions.NotFound() elif isinstance(exc, PermissionDenied): exc = exceptions.AccessDenied() elif isinstance(exc, AuthenticationFailed): exc = exceptions.AuthenticationFailed() elif isinstance(exc, NotAuthenticated): exc = exceptions.NotAuthenticated() elif isinstance(exc, APIException): if isinstance(exc.detail, (list, dict)): data = exc.detail else: data = {'detail': exc.detail} exc = exceptions.Error(message=str(data), status_code=exc.status_code, code=exc.default_code) else: exc = exceptions.convert_to_error(exc) set_rollback() return Response(exc.err_data(), status=exc.status_code)
def node_stop(verbosity=None): # You can see if the process is a zombie by using top or # the following command: # ps aux | awk '$8=="Z" {print $2}' pid = get_pid() count = 10 if pid: os.system("kill " + str(pid[0])) while count > 0: time.sleep(1) if not is_local_node_process_running(): break count = count - 1 if count <= 0: raise errors.Error(''' Failed to kill {}. Pid is {}. '''.format(config.getDaemonName(), pid[0])) else: logger.INFO( ''' Local node is stopped {}. '''.format(pid), verbosity)
def exception_response(exc): if not isinstance(exc, exceptions.Error): exc = exceptions.Error(message=str(exc)) return Response(data=exc.err_data(), status=exc.status_code)