Ejemplo n.º 1
0
def transaction_benchmark_ctx(contract_dir: str, log_filename='log') -> ContextManager[Any]:
    use_configuration_from_manifest(contract_dir)
    cfg.verbosity = 0
    cfg.log_dir = contract_dir
    log_file = my_logging.get_log_file(filename=log_filename, include_timestamp=False, label=None)
    my_logging.prepare_logger(log_file)
    with time_measure('all_transactions', should_print=True):
        yield load_transaction_interface_from_directory(contract_dir)
        pass
Ejemplo n.º 2
0
def main():
    # parse arguments
    a = parse_arguments()

    from zkay.config_version import Versions

    if a.cmd == 'version':
        print(Versions.ZKAY_VERSION)
        return

    if a.cmd == 'update-solc':
        try:
            import solcx
            solcx.install_solc_pragma(
                Versions.ZKAY_SOLC_VERSION_COMPATIBILITY.expression)
        except Exception as e:
            print(f'ERROR: Error while updating solc\n{e}')
        return

    from pathlib import Path

    import zkay.zkay_frontend as frontend
    from zkay import my_logging
    from zkay.config import cfg
    from zkay.utils.helpers import read_file, save_to_file
    from zkay.errors.exceptions import ZkayCompilerError
    from zkay.my_logging.log_context import log_context
    from zkay.utils.progress_printer import fail_print, success_print
    from zkay.zkay_ast.process_ast import get_processed_ast, get_parsed_ast_and_fake_code

    # Load configuration files
    try:
        cfg.load_configuration_from_disk(a.config_file)
    except Exception as e:
        with fail_print():
            print(f"ERROR: Failed to load configuration files\n{e}")
            exit(42)

    # Support for overriding any user config setting via command line
    # The evaluation order for configuration loading is:
    # Default values in config.py -> Site config.json -> user config.json -> local config.json -> cmdline arguments
    # Settings defined at a later stage override setting values defined at an earlier stage
    override_dict = {}
    for name in vars(UserConfig):
        if name[0] != '_' and hasattr(a, name):
            val = getattr(a, name)
            if val is not None:
                override_dict[name] = val
    cfg.override_defaults(override_dict)

    if a.cmd in ['deploy-pki', 'deploy-crypto-libs']:
        import tempfile
        from zkay.compiler.privacy import library_contracts
        from zkay.transaction.runtime import Runtime
        with tempfile.TemporaryDirectory() as tmpdir:
            try:
                with cfg.library_compilation_environment():
                    if a.cmd == 'deploy-pki':
                        file = save_to_file(
                            tmpdir, f'{cfg.pki_contract_name}.sol',
                            library_contracts.get_pki_contract())
                        addr = Runtime.blockchain().deploy_solidity_contract(
                            file, cfg.pki_contract_name, a.account)
                        print(f'Deployed pki contract at: {addr}')
                    else:
                        if not cfg.external_crypto_lib_names:
                            print(
                                'Current proving scheme does not require library deployment'
                            )
                        else:
                            file = save_to_file(
                                tmpdir, 'verify_libs.sol',
                                library_contracts.get_verify_libs_code())
                            for lib in cfg.external_crypto_lib_names:
                                addr = Runtime.blockchain(
                                ).deploy_solidity_contract(
                                    file, lib, a.account)
                                print(
                                    f'Deployed crypto library {lib} at: {addr}'
                                )
            except Exception as e:
                with fail_print():
                    print(f"ERROR: Deployment failed\n{e}")
    else:
        # Solc version override
        if hasattr(a, 'solc_version') and a.solc_version is not None:
            try:
                cfg.override_solc(a.solc_version)
            except ValueError as e:
                with fail_print():
                    print(f'Error: {e}')
                exit(10)
        print(f'Using solc version {Versions.SOLC_VERSION}')

        input_path = Path(a.input)
        if not input_path.exists():
            with fail_print():
                print(f'Error: input file \'{input_path}\' does not exist')
            exit(1)

        if a.cmd == 'check':
            # only type-check
            print(f'Type checking file {input_path.name}:')

            code = read_file(str(input_path))
            try:
                get_processed_ast(code)
            except ZkayCompilerError as e:
                with fail_print():
                    print(f'{e}')
                exit(3)
        elif a.cmd == 'solify':
            was_unit_test = cfg.is_unit_test
            cfg._is_unit_test = True  # Suppress other output
            try:
                _, fake_code = get_parsed_ast_and_fake_code(
                    read_file(str(input_path)))
                print(fake_code)
            except ZkayCompilerError as e:
                with fail_print():
                    print(f'{e}')
                exit(3)
            finally:
                cfg._is_unit_test = was_unit_test
            exit(0)
        elif a.cmd == 'compile':
            # create output directory
            output_dir = Path(a.output).absolute()
            if not output_dir.exists():
                os.makedirs(output_dir)
            elif not output_dir.is_dir():
                with fail_print():
                    print(f'Error: \'{output_dir}\' is not a directory')
                exit(2)

            # Enable logging
            if a.log:
                log_file = my_logging.get_log_file(filename='compile',
                                                   include_timestamp=False,
                                                   label=None)
                my_logging.prepare_logger(log_file)

            # only type-check
            print(f'Compiling file {input_path.name}:')

            # compile
            with log_context('inputfile', os.path.basename(a.input)):
                try:
                    frontend.compile_zkay_file(str(input_path),
                                               str(output_dir))
                except ZkayCompilerError as e:
                    with fail_print():
                        print(f'{e}')
                    exit(3)
        elif a.cmd == 'import':
            # create output directory
            output_dir = Path(a.output).absolute()
            if output_dir.exists():
                with fail_print():
                    print(f'Error: \'{output_dir}\' already exists')
                exit(2)

            try:
                frontend.extract_zkay_package(str(input_path), str(output_dir))
            except ZkayCompilerError as e:
                with fail_print():
                    print(
                        f"ERROR while compiling unpacked zkay contract.\n{e}")
                exit(3)
            except Exception as e:
                with fail_print():
                    print(f"ERROR while unpacking zkay contract\n{e}")
                exit(5)
        elif a.cmd == 'export':
            output_filename = Path(a.output).absolute()
            os.makedirs(output_filename.parent, exist_ok=True)
            try:
                frontend.package_zkay_contract(str(input_path),
                                               str(output_filename))
            except Exception as e:
                with fail_print():
                    print(f"ERROR while exporting zkay contract\n{e}")
                exit(4)
        elif a.cmd in ['run', 'deploy', 'connect']:
            from enum import IntEnum
            from zkay.transaction.offchain import ContractSimulator

            def echo_only_simple_expressions(e):
                if isinstance(e, (bool, int, str, list, tuple, IntEnum)):
                    print(e)

            # Enable logging
            if a.log:
                log_file = my_logging.get_log_file(
                    filename=f'transactions_{input_path.name}',
                    include_timestamp=True,
                    label=None)
                my_logging.prepare_logger(log_file)

            contract_dir = str(input_path.absolute())
            frontend.use_configuration_from_manifest(contract_dir)
            if a.account is not None:
                me = a.account
            else:
                me = ContractSimulator.default_address()
                if me is not None:
                    me = me.val

            import code
            import sys
            if a.cmd == 'run':
                # Dynamically load module and replace globals with module globals
                contract_mod = frontend.load_transaction_interface_from_directory(
                    contract_dir)
                contract_mod.me = me
                sys.displayhook = echo_only_simple_expressions
                code.interact(local=contract_mod.__dict__)
            else:
                cmod = frontend.load_transaction_interface_from_directory(
                    contract_dir)
                c = frontend.load_contract_transaction_interface_from_module(
                    cmod)
                if a.cmd == 'deploy':
                    from ast import literal_eval
                    cargs = a.constructor_args
                    args = []
                    for arg in cargs:
                        try:
                            val = literal_eval(arg)
                        except Exception:
                            val = arg
                        args.append(val)
                    try:
                        c.deploy(*args, user=me, project_dir=contract_dir)
                    except (ValueError, TypeError) as e:
                        with fail_print():
                            print(
                                f'ERROR invalid arguments.\n{e}\n\nExpected contructor signature: ',
                                end='')
                            if hasattr(c, 'constructor'):
                                from inspect import signature
                                sig = str(signature(c.constructor))
                                sig = sig[5:] if not sig[5:].startswith(
                                    ",") else sig[7:]  # without self
                                print(f'({sig}')
                            else:
                                print('()')
                            exit(11)
                    except Exception as e:
                        with fail_print():
                            print(f'ERROR: failed to deploy contract\n{e}')
                            exit(12)
                elif a.cmd == 'connect':
                    try:
                        c_inst = c.connect(address=a.address,
                                           user=me,
                                           project_dir=contract_dir)
                    except Exception as e:
                        with fail_print():
                            print(f'ERROR: failed to connect to contract\n{e}')
                            exit(13)

                    # Open interactive shell in context of contract object
                    import inspect
                    contract_scope = {name: getattr(c_inst, name) for name in dir(c_inst)
                                      if inspect.isclass(getattr(c_inst, name)) \
                                         or (name != 'constructor' and hasattr(getattr(c_inst, name), '_can_be_external')
                                             and getattr(c_inst, name)._can_be_external)
                                         or name in ['state', 'api']}
                    contract_scope['me'] = me
                    contract_scope['help'] = lambda o=None: help(
                        o
                    ) if o is not None else ContractSimulator.reduced_help(c)
                    sys.displayhook = echo_only_simple_expressions
                    code.interact(local=contract_scope)
                else:
                    raise ValueError(f'unexpected command {a.cmd}')
            exit(0)
        else:
            raise NotImplementedError(a.cmd)

        with success_print():
            print("Finished successfully")
Ejemplo n.º 3
0
import json
import warnings

from zkay import my_logging
from zkay.tests.zkay_unit_test import ZkayTestCase
from zkay.utils.helpers import read_file

default_log_file = my_logging.get_log_file(label='TestLogger')


class TestLogger(ZkayTestCase):
    def test_logger(self):
        # ignore warnings
        warnings.simplefilter("ignore")

        # log something
        log_file = default_log_file + '_basic_test'
        my_logging.prepare_logger(log_file)
        my_logging.info("ABCD")
        my_logging.shutdown()

        # check logfile
        success = 'ABCD' in read_file(log_file + '_info.log')
        self.assertTrue(success)

    def test_data(self):
        log_file = default_log_file + '_data_test'
        my_logging.prepare_logger(log_file)
        my_logging.data('key', 2)
        my_logging.info('ABCD')
        my_logging.shutdown()
Ejemplo n.º 4
0
import json
import time

from zkay import my_logging
from zkay.tests.zkay_unit_test import ZkayTestCase
from zkay.utils.helpers import read_file
from zkay.utils.timer import Timer, time_measure


@Timer('mykey')
def sleep(n):
    time.sleep(n)


base_log_file = my_logging.get_log_file(label='TestTimer')


class TestTimer(ZkayTestCase):

    def test_timer_decorator(self):
        log_file = base_log_file + '_decorator'
        my_logging.prepare_logger(log_file)
        sleep(0.5)
        my_logging.shutdown()

        content = read_file(log_file + '_data.log')

        d = json.loads(content)
        self.assertAlmostEqual(0.5, d['value'], 1)

    def test_timer_context_manager(self):