def _generate_genesis_block(self, header_sig="genesis"): genesis_header = BlockHeader( previous_block_id="0000000000000000", block_num=0) block = BlockBuilder(genesis_header) block.set_signature(header_sig) return block
def _build_block(self, chain_head): """ Build a candidate block and construct the consensus object to validate it. """ prev_state = self._get_previous_block_root_state_hash(chain_head) state_view = self._state_view_factory. \ create_view(prev_state) self._consensus = self._consensus_module.\ BlockPublisher(block_cache=self._block_cache, state_view=state_view) block_header = BlockHeader( block_num=chain_head.block_num + 1, previous_block_id=chain_head.header_signature) self._consensus.initialize_block(block_header) # create a new scheduler # TBD move factory in to executor for easier mocking -- # Yes I want to make fun of it. self._scheduler = self._transaction_executor.create_scheduler( self._squash_handler, chain_head.state_root_hash) self._transaction_executor.execute(self._scheduler) for batch in self._pending_batches: self._scheduler.add_batch(batch) self._pending_batches = [] return BlockBuilder(block_header)
def _generate_genesis_block(): """ Returns a blocker wrapper with the basics of the block header in place """ genesis_header = block_pb2.BlockHeader( previous_block_id=NULL_BLOCK_IDENTIFIER, block_num=0) return BlockBuilder(genesis_header)
def _generate_genesis_block(self): """ Returns a blocker wrapper with the basics of the block header in place """ genesis_header = block_pb2.BlockHeader( block_num=0, previous_block_id=NULL_BLOCK_IDENTIFIER, signer_pubkey=self._identity_public_key) return BlockBuilder(genesis_header)
def _build_candidate_block(self, chain_head): """ Build a candidate block and construct the consensus object to validate it. :param chain_head: The block to build on top of. :return: (BlockBuilder) - The candidate block in a BlockBuilder wrapper. """ state_view = BlockWrapper.state_view_for_block( chain_head, self._state_view_factory) consensus_module = ConsensusFactory.get_configured_consensus_module( chain_head.header_signature, state_view) config_view = ConfigView(state_view) max_batches = config_view.get_setting( 'sawtooth.publisher.max_batches_per_block', default_value=0, value_type=int) consensus = consensus_module.\ BlockPublisher(block_cache=self._block_cache, state_view_factory=self._state_view_factory, batch_publisher=self._batch_publisher, data_dir=self._data_dir, config_dir=self._config_dir, validator_id=self._identity_public_key) block_header = BlockHeader( block_num=chain_head.block_num + 1, previous_block_id=chain_head.header_signature, signer_pubkey=self._identity_public_key) block_builder = BlockBuilder(block_header) if not consensus.initialize_block(block_builder.block_header): LOGGER.debug("Consensus not ready to build candidate block.") return None # create a new scheduler scheduler = self._transaction_executor.create_scheduler( self._squash_handler, chain_head.state_root_hash) # build the TransactionCache committed_txn_cache = TransactionCache(self._block_cache.block_store) self._transaction_executor.execute(scheduler) self._candidate_block = _CandidateBlock(self._block_cache.block_store, consensus, scheduler, committed_txn_cache, block_builder, max_batches) for batch in self._pending_batches: if self._candidate_block.can_add_batch: self._candidate_block.add_batch(batch) else: break
def initialize_block(self, previous_block): """Begin building a new candidate block. Args: previous_block (BlockWrapper): The block to base the new block on. Raises: ConsensusNotReady Consensus is not ready to build a block """ # using previous_block so so we can use the setting_cache max_batches = int( self._settings_cache.get_setting( 'sawtooth.publisher.max_batches_per_block', previous_block.state_root_hash, default_value=0)) state_view = BlockWrapper.state_view_for_block( previous_block, self._state_view_factory) public_key = self._identity_signer.get_public_key().as_hex() consensus = self._load_consensus(previous_block, state_view, public_key) batch_injectors = self._load_injectors(previous_block) block_header = BlockHeader( block_num=previous_block.block_num + 1, previous_block_id=previous_block.header_signature, signer_public_key=public_key) block_builder = BlockBuilder(block_header) if not consensus.initialize_block(block_builder.block_header): raise ConsensusNotReady() # create a new scheduler scheduler = self._transaction_executor.create_scheduler( previous_block.state_root_hash) # build the TransactionCommitCache committed_txn_cache = TransactionCommitCache( self._block_cache.block_store) self._transaction_executor.execute(scheduler) self._candidate_block = _CandidateBlock( self._block_cache.block_store, consensus, scheduler, committed_txn_cache, block_builder, max_batches, batch_injectors, SettingsView(state_view), self._identity_signer) for batch in self._pending_batches: if self._candidate_block.can_add_batch(): self._candidate_block.add_batch(batch) else: break
def _build_block(self, chain_head): """ Build a candidate block and construct the consensus object to validate it. :param chain_head: The block to build on top of. :return: (BlockBuilder) - The candidate block in a BlockBuilder wrapper. """ state_view = BlockWrapper.state_view_for_block( chain_head, self._state_view_factory) consensus_module = ConsensusFactory.get_configured_consensus_module( chain_head.header_signature, state_view) self._consensus = consensus_module.\ BlockPublisher(block_cache=self._block_cache, state_view_factory=self._state_view_factory, batch_publisher=self._batch_publisher, data_dir=self._data_dir, validator_id=self._identity_public_key) block_header = BlockHeader( block_num=chain_head.block_num + 1, previous_block_id=chain_head.header_signature, signer_pubkey=self._identity_public_key) block_builder = BlockBuilder(block_header) if not self._consensus.initialize_block(block_builder.block_header): LOGGER.debug("Consensus not ready to build candidate block.") return None # Cancel the previous scheduler if it did not complete. if self._scheduler is not None \ and not self._scheduler.complete(block=False): self._scheduler.cancel() # create a new scheduler self._scheduler = self._transaction_executor.create_scheduler( self._squash_handler, chain_head.state_root_hash) # build the TransactionCache self._committed_txn_cache = TransactionCache( self._block_cache.block_store) if chain_head.header_signature not in self._block_cache.block_store: # if we opportunistically building a block # we need to check make sure we track that blocks transactions # as recorded. for batch in chain_head.block.batches: for txn in batch.transactions: self._committed_txn_cache.add_txn(txn.header_signature) self._transaction_executor.execute(self._scheduler) for batch in self._pending_batches: self._validate_batch(batch) return block_builder
def _generate_genesis_block(self): genesis_header = BlockHeader(previous_block_id=NULL_BLOCK_IDENTIFIER, signer_pubkey=self.public_key, block_num=0) block = BlockBuilder(genesis_header) block.add_batches([self._generate_batch("Genesis")]) header_bytes = block.block_header.SerializeToString() signature = signing.sign(header_bytes, self.identity_signing_key) block.set_signature(signature) return BlockWrapper(block.build_block())
def _generate_block(self, payload, previous_block_id, block_num): header = BlockHeader(previous_block_id=previous_block_id, signer_pubkey=self.public_key, block_num=block_num) block_builder = BlockBuilder(header) block_builder.add_batches([self._generate_batch_from_payload(payload)]) header_bytes = block_builder.block_header.SerializeToString() signature = signing.sign(header_bytes, self.identity_signing_key) block_builder.set_signature(signature) return BlockWrapper(block_builder.build_block())
def create_block(self, payload='payload', batch_count=1, previous_block_id=NULL_BLOCK_IDENTIFIER, block_num=0): header = BlockHeader( previous_block_id=previous_block_id, signer_pubkey=self.public_key, block_num=block_num) block_builder = BlockBuilder(header) block_builder.add_batches( [self._generate_batch_from_payload(payload) for _ in range(batch_count)]) block_builder.set_state_hash('0'*70) header_bytes = block_builder.block_header.SerializeToString() signature = signing.sign(header_bytes, self.identity_signing_key) block_builder.set_signature(signature) block_wrapper = BlockWrapper(block_builder.build_block()) LOGGER.debug("Generated %s", dumps_block(block_wrapper)) return block_wrapper
def create_block(self, payload='payload', batch_count=1, previous_block_id=NULL_BLOCK_IDENTIFIER, block_num=0): header = BlockHeader( previous_block_id=previous_block_id, signer_public_key=self.identity_signer.get_public_key().as_hex(), block_num=block_num) block_builder = BlockBuilder(header) block_builder.add_batches( [self._generate_batch_from_payload(payload) for _ in range(batch_count)]) block_builder.set_state_hash('0' * 70) header_bytes = block_builder.block_header.SerializeToString() signature = self.identity_signer.sign(header_bytes) block_builder.set_signature(signature) block_wrapper = BlockWrapper(block_builder.build_block()) LOGGER.debug("Generated %s", dumps_block(block_wrapper)) return block_wrapper
def _build_block(self, chain_head): """ Build a candidate block """ block_header = BlockHeader( block_num=chain_head.block_num + 1, previous_block_id=chain_head.header_signature) self._consensus.initialize_block(block_header) # create a new scheduler # TBD move factory in to executor for easier mocking -- # Yes I want to make fun of it. self._scheduler = self._transaction_executor.create_scheduler( self._squash_handler, chain_head.state_root_hash) self._transaction_executor.execute(self._scheduler) for batch in self._pending_batches: self._scheduler.add_batch(batch) self._pending_batches = [] return BlockBuilder(block_header)
def _build_block(self, chain_head): """ Build a candidate block and construct the consensus object to validate it. :param chain_head: The block to build on top of. :return: (BlockBuilder) - The candidate block in a BlockBuilder wrapper. """ prev_state = self._get_previous_block_root_state_hash(chain_head) state_view = self._state_view_factory. \ create_view(prev_state) consensus_module = ConsensusFactory.get_configured_consensus_module( state_view) self._consensus = consensus_module.\ BlockPublisher(block_cache=self._block_cache, state_view=state_view) block_header = BlockHeader( block_num=chain_head.block_num + 1, previous_block_id=chain_head.header_signature) block_builder = BlockBuilder(block_header) if not self._consensus.initialize_block(block_builder.block_header): LOGGER.debug("Consensus not ready to build candidate block.") # create a new scheduler self._scheduler = self._transaction_executor.create_scheduler( self._squash_handler, chain_head.state_root_hash) # build the TransactionCache self._committed_txn_cache = TransactionCache( self._block_cache.block_store) if chain_head.header_signature not in self._block_cache.block_store: # if we opportunistically building a block # we need to check make sure we track that blocks transactions # as recorded. for batch in chain_head.block.batches: for txn in batch.transactions: self._committed_txn_cache.add_txn(txn.header_signature) self._transaction_executor.execute(self._scheduler) for batch in self._pending_batches: self._validate_batch(batch) return block_builder
def _generate_block(self, payload, previous_block_id, block_num): header = BlockHeader( previous_block_id=previous_block_id, signer_pubkey=self.public_key, block_num=block_num) block_builder = BlockBuilder(header) block_builder.add_batches( [self._generate_batch_from_payload(payload)]) header_bytes = block_builder.block_header.SerializeToString() signature = signing.sign(header_bytes, self.identity_signing_key) block_builder.set_signature(signature) block_wrapper = BlockWrapper(block_builder.build_block()) LOGGER.debug("Generated %s", dumps_block(block_wrapper)) return block_wrapper
def generate_block(self, previous_block=None, add_to_store=False, add_to_cache=False, batch_count=1, batches=None, status=BlockStatus.Unknown, invalid_consensus=False, invalid_batch=False, invalid_signature=False, weight=0): previous = self._get_block(previous_block) if previous is None: previous = self.chain_head header = BlockHeader( previous_block_id=previous.identifier, signer_public_key=self.identity_signer.get_public_key().as_hex(), block_num=previous.block_num + 1) block_builder = BlockBuilder(header) if batches: block_builder.add_batches(batches) if batch_count != 0: block_builder.add_batches( [self._generate_batch() for _ in range(batch_count)]) if invalid_batch: block_builder.add_batches( [self._generate_batch_from_payload('BAD')]) block_builder.set_state_hash('0' * 70) consensus = mock_consensus.BlockPublisher() consensus.finalize_block(block_builder.block_header, weight=weight) header_bytes = block_builder.block_header.SerializeToString() signature = self.identity_signer.sign(header_bytes) block_builder.set_signature(signature) block_wrapper = BlockWrapper(block_builder.build_block()) if batches: block_wrapper.block.batches.extend(batches) if batch_count: block_wrapper.block.batches.extend( [self.generate_batch() for _ in range(batch_count)]) if invalid_signature: block_wrapper.block.header_signature = "BAD" if invalid_consensus: block_wrapper.header.consensus = b'BAD' block_wrapper.status = status if add_to_cache: self.block_cache[block_wrapper.identifier] = block_wrapper if add_to_store: self.block_store[block_wrapper.identifier] = block_wrapper LOGGER.debug("Generated %s", dumps_block(block_wrapper)) return block_wrapper
def _build_candidate_block(self, chain_head): """ Build a candidate block and construct the consensus object to validate it. :param chain_head: The block to build on top of. :return: (BlockBuilder) - The candidate block in a BlockBuilder wrapper. """ state_view = BlockWrapper.state_view_for_block( chain_head, self._state_view_factory) consensus_module = ConsensusFactory.get_configured_consensus_module( chain_head.header_signature, state_view) # using chain_head so so we can use the setting_cache max_batches = int( self._settings_cache.get_setting( 'sawtooth.publisher.max_batches_per_block', chain_head.state_root_hash, default_value=0)) public_key = self._identity_signer.get_public_key().as_hex() consensus = consensus_module.\ BlockPublisher(block_cache=self._block_cache, state_view_factory=self._state_view_factory, batch_publisher=self._batch_publisher, data_dir=self._data_dir, config_dir=self._config_dir, validator_id=public_key) batch_injectors = [] if self._batch_injector_factory is not None: batch_injectors = self._batch_injector_factory.create_injectors( chain_head.identifier) if batch_injectors: LOGGER.debug("Loaded batch injectors: %s", batch_injectors) block_header = BlockHeader( block_num=chain_head.block_num + 1, previous_block_id=chain_head.header_signature, signer_public_key=public_key) block_builder = BlockBuilder(block_header) if not consensus.initialize_block(block_builder.block_header): if not self._logging_states.consensus_not_ready: self._logging_states.consensus_not_ready = True LOGGER.debug("Consensus not ready to build candidate block.") return None if self._logging_states.consensus_not_ready: self._logging_states.consensus_not_ready = False LOGGER.debug("Consensus is ready to build candidate block.") # create a new scheduler scheduler = self._transaction_executor.create_scheduler( self._squash_handler, chain_head.state_root_hash) # build the TransactionCommitCache committed_txn_cache = TransactionCommitCache( self._block_cache.block_store) self._transaction_executor.execute(scheduler) self._candidate_block = _CandidateBlock( self._block_cache.block_store, consensus, scheduler, committed_txn_cache, block_builder, max_batches, batch_injectors, SettingsView(state_view), public_key) for batch in self._pending_batches: if self._candidate_block.can_add_batch: self._candidate_block.add_batch(batch) else: break
def generate_block(self, previous_block=None, add_to_store=False, add_to_cache=False, batch_count=1, batches=None, status=BlockStatus.Unknown, invalid_consensus=False, invalid_batch=False, invalid_signature=False, weight=0): previous = self._get_block(previous_block) if previous is None: previous = self.chain_head header = BlockHeader( previous_block_id=previous.identifier, signer_public_key=self.identity_signer.get_public_key().as_hex(), block_num=previous.block_num + 1) block_builder = BlockBuilder(header) if batches: block_builder.add_batches(batches) if batch_count != 0: block_builder.add_batches( [self._generate_batch() for _ in range(batch_count)]) if invalid_batch: block_builder.add_batches( [self._generate_batch_from_payload('BAD')]) block_builder.set_state_hash('0' * 70) consensus = mock_consensus.BlockPublisher() consensus.finalize_block(block_builder.block_header, weight=weight) header_bytes = block_builder.block_header.SerializeToString() signature = self.identity_signer.sign(header_bytes) block_builder.set_signature(signature) block_wrapper = BlockWrapper(block_builder.build_block()) if batches: block_wrapper.block.batches.extend(batches) if batch_count: block_wrapper.block.batches.extend( [self.generate_batch() for _ in range(batch_count)]) if invalid_signature: block_wrapper.block.header_signature = "BAD" if invalid_consensus: block_wrapper.header.consensus = b'BAD' block_wrapper.status = status if add_to_cache: self.block_cache[block_wrapper.identifier] = block_wrapper if add_to_store: self.block_store[block_wrapper.identifier] = block_wrapper LOGGER.debug("Generated %s", dumps_block(block_wrapper)) return block_wrapper