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'])
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')
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()