示例#1
0
文件: cleos.py 项目: vt102/eosfactory
    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()
示例#2
0
    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
示例#3
0
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.
            ''')
示例#4
0
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.
    ''')
示例#5
0
    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
示例#6
0
def getSourceDir():
    config_value = configValue("EOSIO_SOURCE_DIR")
    if config_value:
        return config_value

    raise errors.Error('''
        Cannot determine the EOSIO source directory.
    ''')
示例#7
0
def getEosFactoryDir():
    config_value = configValue("EOSIO_EOSFACTORY_DIR")
    if config_value:
        return config_value

    raise errors.Error('''
        Cannot determine the context directory.
    ''')
示例#8
0
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))  
示例#9
0
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
示例#10
0
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.       
    ''')
示例#11
0
    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))
示例#12
0
    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
示例#13
0
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
示例#14
0
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
示例#15
0
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))
示例#16
0
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)) 
示例#17
0
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))
示例#18
0
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])
    )
示例#19
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
示例#20
0
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))         
示例#21
0
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))      
示例#22
0
    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
示例#23
0
    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
示例#24
0
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))
示例#25
0
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))    
示例#26
0
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))
示例#27
0
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
示例#28
0
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)
示例#29
0
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)
示例#30
0
    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)