示例#1
0
 def send(self, transactions):
     # Consensus implementations are expected to have handling
     # in place for genesis operation. This should includes
     # adding any authorization and registrations required
     # for the genesis node to the Genesis Batch list and
     # detecting validation of the Genesis Block and handle it
     # correctly. Batch publication is not allowed during
     # genesis operation since there is no network to validate
     # the batch yet.
     raise InvalidGenesisConsensusError(
         'Consensus cannot send transactions during genesis.')
示例#2
0
    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()