Exemple #1
0
def account(ctx):
    """Manage accounts.
    For accounts to be accessible by pyethapp, their keys must be stored in the keystore directory.
    Its path can be configured through "accounts.keystore_dir".
    """
    app = Casper(ctx.obj['config'])
    ctx.obj['app'] = app
    AccountsService.register_with_app(app)
    unlock_accounts(ctx.obj['unlock'], app.services.accounts, password=ctx.obj['password'])
Exemple #2
0
def account(ctx):
    """Manage accounts.

    For accounts to be accessible by pyethapp, their keys must be stored in the keystore directory.
    Its path can be configured through "accounts.keystore_dir".
    """
    app = EthApp(ctx.obj['config'])
    ctx.obj['app'] = app
    AccountsService.register_with_app(app)
    unlock_accounts(ctx.obj['unlock'], app.services.accounts, password=ctx.obj['password'])
def export_blocks(ctx, from_, to, file):
    """Export the blockchain to FILE.

    The chain will be stored in binary format, i.e. as a concatenated list of RLP encoded blocks,
    starting with the earliest block.

    If the file already exists, the additional blocks are appended. Otherwise, a new file is
    created.

    Use - to write to stdout.
    """
    app = EthApp(ctx.obj['config'])
    DBService.register_with_app(app)
    AccountsService.register_with_app(app)
    ChainService.register_with_app(app)

    if from_ is None:
        from_ = 0
    head_number = app.services.chain.chain.head.number
    if to is None:
        to = head_number
    if from_ < 0:
        log.fatal('block numbers must not be negative')
        sys.exit(1)
    if to < from_:
        log.fatal('"to" block must be newer than "from" block')
        sys.exit(1)
    if to > head_number:
        log.fatal(
            '"to" block not known (current head: {})'.format(head_number))
        sys.exit(1)

    log.info('Starting export')
    for n in xrange(from_, to + 1):
        log.debug('Exporting block {}'.format(n))
        if (n - from_) % 50000 == 0:
            log.info('Exporting block {} to {}'.format(n, min(n + 50000, to)))
        block_hash = app.services.chain.chain.index.get_block_by_number(n)
        # bypass slow block decoding by directly accessing db
        block_rlp = app.services.db.get(block_hash)
        file.write(block_rlp)
    log.info('Export complete')
Exemple #4
0
def export_blocks(ctx, from_, to, file):
    """Export the blockchain to FILE.

    The chain will be stored in binary format, i.e. as a concatenated list of RLP encoded blocks,
    starting with the earliest block.

    If the file already exists, the additional blocks are appended. Otherwise, a new file is
    created.

    Use - to write to stdout.
    """
    app = EthApp(ctx.obj['config'])
    DBService.register_with_app(app)
    AccountsService.register_with_app(app)
    ChainService.register_with_app(app)

    if from_ is None:
        from_ = 0
    head_number = app.services.chain.chain.head.number
    if to is None:
        to = head_number
    if from_ < 0:
        log.fatal('block numbers must not be negative')
        sys.exit(1)
    if to < from_:
        log.fatal('"to" block must be newer than "from" block')
        sys.exit(1)
    if to > head_number:
        log.fatal('"to" block not known (current head: {})'.format(head_number))
        sys.exit(1)

    log.info('Starting export')
    for n in xrange(from_, to + 1):
        log.debug('Exporting block {}'.format(n))
        if (n - from_) % 50000 == 0:
            log.info('Exporting block {} to {}'.format(n, min(n + 50000, to)))
        block_hash = app.services.chain.chain.index.get_block_by_number(n)
        # bypass slow block decoding by directly accessing db
        block_rlp = app.services.db.get(block_hash)
        file.write(block_rlp)
    log.info('Export complete')
def import_blocks(ctx, file):
    """Import blocks from FILE.

    Blocks are expected to be in binary format, i.e. as a concatenated list of RLP encoded blocks.

    Blocks are imported sequentially. If a block can not be imported (e.g. because it is badly
    encoded, it is in the chain already or its parent is not in the chain) it will be ignored, but
    the process will continue. Sole exception: If neither the first block nor its parent is known,
    importing will end right away.

    Use - to read from stdin.
    """
    app = EthApp(ctx.obj['config'])
    DBService.register_with_app(app)
    AccountsService.register_with_app(app)
    ChainService.register_with_app(app)
    chain = app.services.chain
    assert chain.block_queue.empty()

    data = file.read()
    app.start()

    def blocks():
        """Generator for blocks encoded in `data`."""
        i = 0
        while i < len(data):
            try:
                block_data, next_i = rlp.codec.consume_item(data, i)
            except rlp.DecodingError:
                log.fatal('invalid RLP encoding', byte_index=i)
                sys.exit(1)  # have to abort as we don't know where to continue
            try:
                if not isinstance(block_data, list) or len(block_data) != 3:
                    raise rlp.DeserializationError('', block_data)
                yield eth_protocol.TransientBlock(block_data)
            except (IndexError, rlp.DeserializationError):
                log.warning('not a valid block',
                            byte_index=i)  # we can still continue
                yield None
            i = next_i

    log.info('importing blocks')
    # check if it makes sense to go through all blocks
    first_block = next(blocks())
    if first_block is None:
        log.fatal('first block invalid')
        sys.exit(1)
    if not (chain.knows_block(first_block.header.hash)
            or chain.knows_block(first_block.header.prevhash)):
        log.fatal('unlinked chains',
                  newest_known_block=chain.chain.head.number,
                  first_unknown_block=first_block.header.number)
        sys.exit(1)

    # import all blocks
    for n, block in enumerate(blocks()):
        if block is None:
            log.warning('skipping block', number_in_file=n)
            continue
        log.debug('adding block to queue',
                  number_in_file=n,
                  number_in_chain=block.header.number)
        app.services.chain.add_block(block, None)  # None for proto

    # let block processing finish
    while not app.services.chain.block_queue.empty():
        gevent.sleep()
    app.stop()
    log.info('import finished',
             head_number=app.services.chain.chain.head.number)
def run(ctx, dev, nodial, fake, console):
    """Start the client ( --dev to stop on error)"""
    config = ctx.obj['config']
    if nodial:
        # config['deactivated_services'].append(PeerManager.name)
        # config['deactivated_services'].append(NodeDiscovery.name)
        config['discovery']['bootstrap_nodes'] = []
        config['discovery']['listen_port'] = 29873
        config['p2p']['listen_port'] = 29873
        config['p2p']['min_peers'] = 0

    if fake:
        from ethereum import blocks
        blocks.GENESIS_DIFFICULTY = 1024
        blocks.BLOCK_DIFF_FACTOR = 16
        blocks.MIN_GAS_LIMIT = blocks.default_config['GENESIS_GAS_LIMIT'] / 2
        config['eth']['block']['GENESIS_DIFFICULTY'] = 1024
        config['eth']['block']['BLOCK_DIFF_FACTOR'] = 16

    # create app
    app = EthApp(config)

    # development mode
    if dev:
        enable_greenlet_debugger()
        try:
            config['client_version'] += '/' + os.getlogin()
        except:
            log.warn("can't get and add login name to client_version")
            pass

    # dump config
    dump_config(config)

    # init and unlock accounts first to check coinbase
    if AccountsService in services:
        AccountsService.register_with_app(app)
        unlock_accounts(ctx.obj['unlock'],
                        app.services.accounts,
                        password=ctx.obj['password'])
        try:
            app.services.accounts.coinbase
        except ValueError as e:
            log.fatal('invalid coinbase',
                      coinbase=config.get('pow', {}).get('coinbase_hex'),
                      error=e.message)
            sys.exit()

    app.start_console = console

    # register services
    contrib_services = load_contrib_services(config)

    for service in services + contrib_services:
        assert issubclass(service, BaseService)
        if service.name not in app.config['deactivated_services'] + [
                AccountsService.name
        ]:
            assert service.name not in app.services
            service.register_with_app(app)
            assert hasattr(app.services, service.name)

    # start app
    log.info('starting')
    app.start()

    if ctx.obj['log_file']:
        log.info("Logging to file %s", ctx.obj['log_file'])
        # User requested file logging - remove stderr handler
        root_logger = slogging.getLogger()
        for hndlr in root_logger.handlers:
            if isinstance(hndlr, StreamHandler) and hndlr.stream == sys.stderr:
                root_logger.removeHandler(hndlr)
                break

    if config['post_app_start_callback'] is not None:
        config['post_app_start_callback'](app)

    # wait for interrupt
    evt = Event()
    gevent.signal(signal.SIGQUIT, evt.set)
    gevent.signal(signal.SIGTERM, evt.set)
    evt.wait()

    # finally stop
    app.stop()
Exemple #7
0
def import_blocks(ctx, file):
    """Import blocks from FILE.

    Blocks are expected to be in binary format, i.e. as a concatenated list of RLP encoded blocks.

    Blocks are imported sequentially. If a block can not be imported (e.g. because it is badly
    encoded, it is in the chain already or its parent is not in the chain) it will be ignored, but
    the process will continue. Sole exception: If neither the first block nor its parent is known,
    importing will end right away.

    Use - to read from stdin.
    """
    app = EthApp(ctx.obj['config'])
    DBService.register_with_app(app)
    AccountsService.register_with_app(app)
    ChainService.register_with_app(app)
    chain = app.services.chain
    assert chain.block_queue.empty()

    data = file.read()
    app.start()

    def blocks():
        """Generator for blocks encoded in `data`."""
        i = 0
        while i < len(data):
            try:
                block_data, next_i = rlp.codec.consume_item(data, i)
            except rlp.DecodingError:
                log.fatal('invalid RLP encoding', byte_index=i)
                sys.exit(1)  # have to abort as we don't know where to continue
            try:
                if not isinstance(block_data, list) or len(block_data) != 3:
                    raise rlp.DeserializationError('', block_data)
                yield eth_protocol.TransientBlock(block_data)
            except (IndexError, rlp.DeserializationError):
                log.warning('not a valid block', byte_index=i)  # we can still continue
                yield None
            i = next_i

    log.info('importing blocks')
    # check if it makes sense to go through all blocks
    first_block = next(blocks())
    if first_block is None:
        log.fatal('first block invalid')
        sys.exit(1)
    if not (chain.knows_block(first_block.header.hash) or
            chain.knows_block(first_block.header.prevhash)):
        log.fatal('unlinked chains', newest_known_block=chain.chain.head.number,
                  first_unknown_block=first_block.header.number)
        sys.exit(1)

    # import all blocks
    for n, block in enumerate(blocks()):
        if block is None:
            log.warning('skipping block', number_in_file=n)
            continue
        log.debug('adding block to queue', number_in_file=n, number_in_chain=block.header.number)
        app.services.chain.add_block(block, None)  # None for proto

    # let block processing finish
    while not app.services.chain.block_queue.empty():
        gevent.sleep()
    app.stop()
    log.info('import finished', head_number=app.services.chain.chain.head.number)