def start(self, on_done): """ Starts the genesis block creation process. Will call the given `on_done` callback on successful completion. Args: on_done (function): a function called on completion Raises: InvalidGenesisStateError: raises this error if a genesis block is unable to be produced, or the resulting block-chain-id saved. """ genesis_file = os.path.join(self._data_dir, 'genesis.batch') try: with open(genesis_file, 'rb') as batch_file: genesis_data = genesis_pb2.GenesisData() genesis_data.ParseFromString(batch_file.read()) LOGGER.info('Producing genesis block from %s', genesis_file) except IOError: raise InvalidGenesisStateError( "Genesis File {} specified, but unreadable".format( genesis_file)) initial_state_root = self._context_manager.get_first_root() genesis_batches = [batch for batch in genesis_data.batches] if genesis_batches: scheduler = SerialScheduler( self._context_manager.get_squash_handler(), initial_state_root, always_persist=True) LOGGER.debug('Adding %s batches', len(genesis_data.batches)) for batch in genesis_data.batches: scheduler.add_batch(batch) self._transaction_executor.execute(scheduler) scheduler.finalize() scheduler.complete(block=True) state_hash = initial_state_root for batch in genesis_batches: result = scheduler.get_batch_execution_result( batch.header_signature) if result is None or not result.is_valid: raise InvalidGenesisStateError( 'Unable to create genesis block, due to batch {}'.format( batch.header_signature)) if result.state_hash is not None: state_hash = result.state_hash LOGGER.debug('Produced state hash %s for genesis block.', state_hash) block_builder = self._generate_genesis_block() block_builder.add_batches(genesis_batches) block_builder.set_state_hash(state_hash) block_publisher = self._get_block_publisher(initial_state_root) if not block_publisher.initialize_block(block_builder.block_header): LOGGER.error('Consensus refused to initialize consensus block.') raise InvalidGenesisConsensusError( 'Consensus refused to initialize genesis block.') if not block_publisher.finalize_block(block_builder.block_header): LOGGER.error('Consensus refused to finalize genesis block.') raise InvalidGenesisConsensusError( 'Consensus refused to finalize genesis block.') self._sign_block(block_builder) block = block_builder.build_block() blkw = BlockWrapper(block=block, status=BlockStatus.Valid) LOGGER.info('Genesis block created: %s', blkw) self._completer.add_block(block) self._block_store.update_chain([blkw]) self._chain_id_manager.save_block_chain_id(block.header_signature) LOGGER.debug('Deleting genesis data.') os.remove(genesis_file) if on_done is not None: on_done()
def start(self, on_done): """ Starts the genesis block creation process. Will call the given `on_done` callback on successful completion. Params: on_done - a function called on completion """ genesis_file = os.path.join(self._data_dir, 'genesis.batch') try: with open(genesis_file, 'rb') as batch_file: genesis_data = genesis_pb2.GenesisData() genesis_data.ParseFromString(batch_file.read()) LOGGER.info('Producing genesis block from %s', genesis_file) except IOError: raise InvalidGenesisStateError( "Genesis File {} specified, but unreadable".format( genesis_file)) initial_state_root = self._context_manager.get_first_root() block = GenesisController._generate_genesis_block() genesis_batches = [batch for batch in genesis_data.batches] if len(genesis_batches) > 0: scheduler = SerialScheduler( self._context_manager.get_squash_handler(), initial_state_root) LOGGER.debug('Adding %s batches', len(genesis_data.batches)) for batch in genesis_data.batches: scheduler.add_batch(batch) self._transaction_executor.execute(scheduler, require_txn_processors=True) scheduler.finalize() scheduler.complete(block=True) state_hash = initial_state_root for batch in genesis_batches: result = scheduler.get_batch_execution_result( batch.header_signature) if result is None or not result.is_valid: raise InvalidGenesisStateError( 'Unable to create genesis block, due to batch {}' .format(batch.header_signature)) state_hash = result.state_hash LOGGER.debug('Produced state hash %s for genesis block.', state_hash) block.add_batches(genesis_batches) block.set_state_hash(state_hash) GenesisController._sign_block(block) LOGGER.info('genesis block created: %s', block.header_signature) self._completer.add_block(block.get_block()) self._block_store['chain_head_id'] = block.header_signature block_state = BlockState(block_wrapper=block, weight=0, status=BlockStatus.Valid) self._block_store[block.header_signature] = block_state self._save_block_chain_id(block.header_signature) LOGGER.debug('deleting genesis data') os.remove(genesis_file) if on_done is not None: on_done()