コード例 #1
0
ファイル: genesis.py プロジェクト: MrShoks/sawtooth-core
    def requires_genesis(self):
        """
        Determines if the system should be put in genesis mode
        """

        genesis_file = os.path.join(self._data_dir, 'genesis.batch')
        has_genesis_batches = Path(genesis_file).is_file()
        LOGGER.debug('genesis_batch_file: %s',
                     genesis_file if has_genesis_batches else 'None')

        has_chain_head = "chain_head_id" in self._block_store
        LOGGER.debug(
            'chain_head: %s',
            self._block_store['chain_head_id'] if has_chain_head else 'None')

        block_chain_id = self._get_block_chain_id()
        is_genesis_node = block_chain_id is None
        LOGGER.debug('network_name: %s', block_chain_id)

        if has_genesis_batches and has_chain_head:
            raise InvalidGenesisStateError(
                'Cannot have a genesis_batch_file and an existing chain')

        if has_genesis_batches and not is_genesis_node:
            raise InvalidGenesisStateError(
                'Cannot have a genesis_batch_file and join an existing network'
            )

        ret = has_genesis_batches and not has_chain_head and is_genesis_node
        LOGGER.debug('Requires genesis: %s', ret)
        return ret
コード例 #2
0
    def _get_block_publisher(self, state_hash):
        """Returns the block publisher based on the consensus module set by the
        "sawtooth_config" transaction family.

        Args:
            state_hash (str): The current state root hash for reading settings.

        Raises:
            InvalidGenesisStateError: if any errors occur getting the
                BlockPublisher.
        """
        state_view = self._state_view_factory.create_view(state_hash)
        try:

            class BatchPublisher(object):
                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.')

            consensus = ConsensusFactory.get_configured_consensus_module(
                state_view)
            return consensus.BlockPublisher(BlockCache(self._block_store),
                                            state_view=state_view,
                                            batch_publisher=BatchPublisher(),
                                            data_dir=self._data_dir)
        except UnknownConsensusModuleError as e:
            raise InvalidGenesisStateError(e)
コード例 #3
0
ファイル: genesis.py プロジェクト: bestonly125/DGT-Kawartha
    def requires_genesis(self):
        """
        Determines if the system should be put in genesis mode

        Returns:
            bool: return whether or not a genesis block is required to be
                generated.

        Raises:
            InvalidGenesisStateError: raises this error if there is invalid
                combination of the following: genesis.batch, existing chain
                head, and block chain id.
        """

        genesis_file = os.path.join(self._data_dir, 'genesis.batch')
        has_genesis_batches = Path(genesis_file).is_file()
        LOGGER.debug('genesis_batch_file: %s',
                     genesis_file if has_genesis_batches else 'not found')

        chain_head = self._block_store.chain_head
        has_chain_head = chain_head is not None
        if has_chain_head:
            LOGGER.debug('chain_head: %s', chain_head)

        block_chain_id = self._chain_id_manager.get_block_chain_id()
        is_genesis_node = block_chain_id is None
        LOGGER.debug(
            'block_chain_id: %s',
            block_chain_id if not is_genesis_node else 'not yet specified')

        if has_genesis_batches and has_chain_head:
            raise InvalidGenesisStateError(
                'Cannot have a genesis_batch_file and an existing chain')

        if has_genesis_batches and not is_genesis_node:
            raise InvalidGenesisStateError(
                'Cannot have a genesis_batch_file and join an existing network'
            )

        if not has_genesis_batches and not has_chain_head:
            LOGGER.info(
                'No chain head and not the genesis node: starting in PEERING MODE!\n'
            )

        return has_genesis_batches and not has_chain_head and is_genesis_node
コード例 #4
0
ファイル: genesis.py プロジェクト: ducmnguy/sawtooth-core
 def _save_block_chain_id(self, block_chain_id):
     LOGGER.debug('writing block chain id')
     block_chain_id_file = os.path.join(self._data_dir, 'block-chain-id')
     try:
         with open(block_chain_id_file, 'w') as f:
             f.write(block_chain_id)
     except IOError:
         raise InvalidGenesisStateError(
             'The block-chain-id file exists, but is unwriteable')
コード例 #5
0
ファイル: genesis.py プロジェクト: ducmnguy/sawtooth-core
    def _get_block_chain_id(self):
        block_chain_id_file = os.path.join(self._data_dir, 'block-chain-id')
        if not Path(block_chain_id_file).is_file():
            return None

        try:
            with open(block_chain_id_file, 'r') as f:
                block_chain_id = f.read()
                return block_chain_id if block_chain_id else None
        except IOError:
            raise InvalidGenesisStateError(
                'The block-chain-id file exists, but is unreadable')
コード例 #6
0
ファイル: genesis.py プロジェクト: ducmnguy/sawtooth-core
    def requires_genesis(self):
        """
        Determines if the system should be put in genesis mode

        Returns:
            bool: return whether or not a genesis block is required to be
                generated.

        Raises:
            InvalidGenesisStateError: raises this error if there is invalid
                combination of the following: genesis.batch, existing chain
                head, and block chain id.
        """

        genesis_file = os.path.join(self._data_dir, 'genesis.batch')
        has_genesis_batches = Path(genesis_file).is_file()
        LOGGER.debug('genesis_batch_file: %s',
                     genesis_file if has_genesis_batches else 'None')

        has_chain_head = "chain_head_id" in self._block_store
        LOGGER.debug(
            'chain_head: %s',
            self._block_store['chain_head_id'] if has_chain_head else 'None')

        block_chain_id = self._get_block_chain_id()
        is_genesis_node = block_chain_id is None
        LOGGER.debug('block_chain_id: %s', block_chain_id)

        if has_genesis_batches and has_chain_head:
            raise InvalidGenesisStateError(
                'Cannot have a genesis_batch_file and an existing chain')

        if has_genesis_batches and not is_genesis_node:
            raise InvalidGenesisStateError(
                'Cannot have a genesis_batch_file and join an existing network'
            )

        ret = has_genesis_batches and not has_chain_head and is_genesis_node
        LOGGER.debug('Requires genesis: %s', ret)
        return ret
コード例 #7
0
    def _get_block_publisher(self, state_hash):
        """Returns the block publisher based on the consensus module set by the
        "sawtooth_config" transaction family.

        Args:
            state_hash (str): The current state root hash for reading settings.

        Raises:
            InvalidGenesisStateError: if any errors occur getting the
                BlockPublisher.
        """
        state_view = self._state_view_factory.create_view(state_hash)
        try:
            consensus = ConsensusFactory.get_configured_consensus_module(
                state_view)
            return consensus.BlockPublisher(BlockCache(self._block_store),
                                            state_view=state_view)
        except UnknownConsensusModuleError as e:
            raise InvalidGenesisStateError(e)
コード例 #8
0
ファイル: genesis.py プロジェクト: sambacha/sprawl
    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()
コード例 #9
0
ファイル: genesis.py プロジェクト: MrShoks/sawtooth-core
    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()