Exemplo n.º 1
0
def run(options, design):
    options = parser.parse_args()

    logger.from_argparse(logger, options)
    logger.set_level(logging.FATAL, 'http')
    logger.set_level(logging.FATAL, 'transport')

    filename = options.design
    if not pathlib.Path(filename).exists():
        parser.error('file, `%s` does not exists.' % filename)

    if not pathlib.Path(filename).is_file():
        parser.error('file, `%s` is not valid file.' % filename)

    design = load_design(filename)

    log = logger.get_logger(__name__)
    log_state = logger.get_logger('consensus.state')

    log.info('design loaded:\n%s',
             pprint.pformat(convert_namedtuple_to_dict(design), width=1))

    log.debug('trying to run %d / %d (faulty nodes / all nodes)',
              len(design.faulties), len(design.nodes))

    run_func = run_default
    if options.case is not None:
        try:
            os.chdir(pathlib.Path(options.case).absolute())
            sys.path.insert(0, '.')

            run_func = getattr(get_module('main'), 'run', None)
        except (FileNotFoundError, AttributeError):
            log.debug('failed to load case, %s', options.case)
        else:
            log.debug('loaded case from %s', options.case)

    blockchains = run_func(options, design)

    prev = None
    while True:
        time.sleep(1)

        now = set(
            map(lambda x: (x.consensus.node.name, x.consensus), blockchains))
        if now == prev:
            continue

        prev = now
        log_current_state(now, design, log_state)

    return
Exemplo n.º 2
0
if __name__ == '__main__':
    options = parser.parse_args()

    logger.from_argparse(logger, options)
    logger.set_level(logging.FATAL, 'http')
    logger.set_level(logging.FATAL, 'transport')

    if not pathlib.Path(options.design).exists():
        parser.error('file, `%s` does not exists.' % options.design)

    if not pathlib.Path(options.design).is_file():
        parser.error('file, `%s` is not valid file.' % options.design)

    design = load_design(options.design)

    log = logger.get_logger(__name__)
    log_state = logger.get_logger('consensus.state')

    log.debug('options: %s', options)

    log.info('design loaded:\n%s',
             pprint.pformat(convert_namedtuple_to_dict(design), width=1))

    if options.action in ('run', ):
        run(options, design)
    elif options.action in ('check', ):
        check(options, design)

    sys.exit(0)
def load_design(filename):
    design = None

    with open(filename) as f:
        if filename.split('.')[-1] == 'yml':
            design = convert_dict_to_namedtuple(yaml.load(f.read()))
        elif filename.split('.')[-1] == 'json':
            temp_design = convert_json_config(json.load(f))
            design = convert_dict_to_namedtuple(temp_design)
        else:
            print(
                '# error: \"file `%s` is not valid file. yml or json type is needed\"'
                % filename)
            sys.exit(1)

    defined_ports = list()
    for name, config in design.nodes._asdict().items():
        port = getattr(config, 'port', None)
        if port is None:
            continue

        defined_ports.append(port)

    faulty_nodes = dict()
    nodes = dict()
    for name, config in design.nodes._asdict().items():
        port = getattr(config, 'port', None)
        if port is None:
            port = get_free_port(defined_ports)

        endpoint = Endpoint(NETWORK_MODULE.SCHEME,
                            get_local_ipaddress(),
                            port,
                            name=name)
        node = node_factory(name, endpoint, 0)

        if hasattr(config.quorum, 'threshold'):
            threshold = config.quorum.threshold
        else:
            threshold = design.common.threshold

        nodes[name] = dict(node=node,
                           quorum=dict(validators=list(), threshold=threshold))

        faulties = list()
        faulty = getattr(getattr(design, 'faulties', None), name, None)
        if faulty is not None:
            for case in faulty:
                kind = FaultyNodeKind.get_from_name(case.case.kind)
                if kind in (FaultyNodeKind.Unknown, ):
                    continue

                dict_case = convert_namedtuple_to_dict(case.case)
                dict_case['kind'] = kind
                faulties.append(dict_case)

        if len(faulties) > 0:
            faulty_nodes[name] = faulties

    for name, config in design.nodes._asdict().items():
        for node_name in config.quorum.validators:
            nodes[name]['quorum']['validators'].append(
                nodes[node_name]['node'])

    design_dict = convert_namedtuple_to_dict(design)

    if 'audit_waiting' not in design_dict['common']:
        design_dict['common']['audit_waiting'] = 1
    if 'audit_time_limit' not in design_dict['common']:
        design_dict['common']['audit_time_limit'] = 2
    design_dict['common']['network_module'] = NETWORK_MODULE
    design_dict['nodes'] = list(nodes.values())
    design_dict['nodes_by_name'] = nodes
    design_dict['faulties'] = faulty_nodes

    return convert_dict_to_namedtuple(design_dict)