def create_chain_commit_state(self, blocks, uncommitted_blocks=None, chain_head=None): block_store = BlockStore(DictDatabase()) block_store.update_chain(blocks) if chain_head is None: chain_head = block_store.chain_head.identifier if uncommitted_blocks is None: uncommitted_blocks = [] return ChainCommitState(block_store, uncommitted_blocks)
def test_iterate_chain(self): """Given a block store, create an predecessor iterator. 1. Create a chain of length 5. 2. Iterate the chain using the get_predecessor_iter from the chain head 3. Verify that the block ids match the chain, in reverse order """ block_store = BlockStore(DictDatabase()) chain = self._create_chain(5) block_store.update_chain(chain) ids = [b.identifier for b in block_store.get_predecessor_iter()] self.assertEqual(['abcd4', 'abcd3', 'abcd2', 'abcd1', 'abcd0'], ids)
def create_chain_commit_state( self, committed_blocks, uncommitted_blocks, head_id, ): block_store = BlockStore( DictDatabase(indexes=BlockStore.create_index_configuration())) block_store.update_chain(committed_blocks) block_cache = BlockCache(block_store=block_store) for block in uncommitted_blocks: block_cache[block.header_signature] = block return ChainCommitState(head_id, block_cache, block_store)
def test_iterate_chain(self): """Given a block store, create an predecessor iterator. 1. Create a chain of length 5. 2. Iterate the chain using the get_predecessor_iter from the chain head 3. Verify that the block ids match the chain, in reverse order """ block_store = BlockStore(DictDatabase()) chain = self._create_chain(5) block_store.update_chain(chain) ids = [b.identifier for b in block_store.get_predecessor_iter()] self.assertEqual( ['abcd4', 'abcd3', 'abcd2', 'abcd1', 'abcd0'], ids)
def test_iterate_chain_from_starting_block(self): """Given a block store, iterate if using an predecessor iterator from a particular start point in the chain. 1. Create a chain of length 5. 2. Iterate the chain using the get_predecessor_iter from block 3 3. Verify that the block ids match the chain, in reverse order """ block_store = BlockStore(DictDatabase()) chain = self._create_chain(5) block_store.update_chain(chain) block = block_store['abcd2'] ids = [b.identifier for b in block_store.get_predecessor_iter(block)] self.assertEqual(['abcd2', 'abcd1', 'abcd0'], ids)
def test_fork_detection_on_iteration(self): """Given a block store where a fork occurred while using the predecessor iterator, it should throw a PossibleForkDetectedError. The fork occurrance will be simulated. """ block_store = BlockStore(DictDatabase()) chain = self._create_chain(5) block_store.update_chain(chain) iterator = block_store.get_predecessor_iter() self.assertEqual('abcd4', next(iterator).identifier) del block_store['abcd3'] with self.assertRaises(PossibleForkDetectedError): next(iterator)
def test_fork_detection_on_iteration(self): """Given a block store where a fork occurred while using the predecessor iterator, it should throw a PossibleForkDetectedError. The fork occurrance will be simulated. """ block_store = BlockStore(DictDatabase()) chain = self._create_chain(5) block_store.update_chain(chain) iterator = block_store.get_predecessor_iter() self.assertEqual('abcd4', next(iterator).identifier) del block_store['abcd3'] with self.assertRaises(PossibleForkDetectedError): next(iterator)
def test_iterate_chain_from_starting_block(self): """Given a block store, iterate if using an predecessor iterator from a particular start point in the chain. 1. Create a chain of length 5. 2. Iterate the chain using the get_predecessor_iter from block 3 3. Verify that the block ids match the chain, in reverse order """ block_store = BlockStore(DictDatabase()) chain = self._create_chain(5) block_store.update_chain(chain) block = block_store['abcd2'] ids = [b.identifier for b in block_store.get_predecessor_iter(block)] self.assertEqual( ['abcd2', 'abcd1', 'abcd0'], ids)
class BlockTreeManager(object): def __str__(self): return str(self.block_cache) def __repr__(self): return repr(self.block_cache) def __init__(self, with_genesis=True): self.block_sender = MockBlockSender() self.batch_sender = MockBatchSender() self.block_store = BlockStore( DictDatabase(indexes=BlockStore.create_index_configuration())) self.block_cache = BlockCache(self.block_store) self.state_db = {} # add the mock reference to the consensus consensus_setting_addr = SettingsView.setting_address( 'sawtooth.consensus.algorithm') self.state_db[consensus_setting_addr] = _setting_entry( 'sawtooth.consensus.algorithm', 'test_journal.mock_consensus') self.state_view_factory = MockStateViewFactory(self.state_db) context = create_context('secp256k1') private_key = context.new_random_private_key() crypto_factory = CryptoFactory(context) self.signer = crypto_factory.new_signer(private_key) identity_private_key = context.new_random_private_key() self.identity_signer = crypto_factory.new_signer(identity_private_key) chain_head = None if with_genesis: self.genesis_block = self.generate_genesis_block() self.set_chain_head(self.genesis_block) chain_head = self.genesis_block self.block_publisher = BlockPublisher( transaction_executor=MockTransactionExecutor(), block_cache=self.block_cache, state_view_factory=self.state_view_factory, block_sender=self.block_sender, batch_sender=self.block_sender, squash_handler=None, chain_head=chain_head, identity_signer=self.identity_signer, data_dir=None, config_dir=None, permission_verifier=MockPermissionVerifier(), check_publish_block_frequency=0.1, batch_observers=[]) @property def chain_head(self): return self.block_store.chain_head def set_chain_head(self, block): self.block_store.update_chain([block], []) 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 generate_chain(self, root_block, blocks, params=None): """ Generate a new chain based on the root block and place it in the block cache. """ if params is None: params = {} if root_block is None: previous = self.generate_genesis_block() self.block_store[previous.identifier] = previous else: previous = self._get_block(root_block) try: block_defs = [self._block_def(**params) for _ in range(blocks)] block_defs[-1] = self._block_def() except TypeError: block_defs = blocks out = [] for block_def in block_defs: new_block = self.generate_block(previous_block=previous, **block_def) out.append(new_block) previous = new_block return out 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 generate_genesis_block(self): return self.create_block(payload='Genesis', previous_block_id=NULL_BLOCK_IDENTIFIER, block_num=0) def _block_def(self, add_to_store=False, add_to_cache=False, batch_count=1, status=BlockStatus.Unknown, invalid_consensus=False, invalid_batch=False, invalid_signature=False, weight=0): return { "add_to_cache": add_to_cache, "add_to_store": add_to_store, "batch_count": batch_count, "status": status, "invalid_consensus": invalid_consensus, "invalid_batch": invalid_batch, "invalid_signature": invalid_signature, "weight": weight } def _get_block_id(self, block): if block is None: return None elif isinstance(block, (Block, BlockWrapper)): return block.header_signature else: return str(block) def _get_block(self, block): if block is None: return None elif isinstance(block, Block): return BlockWrapper(block) elif isinstance(block, BlockWrapper): return block elif isinstance(block, str): return self.block_cache[block] else: # WTF try something crazy return self.block_cache[str(block)] def generate_batch(self, txn_count=2, missing_deps=False, txns=None): batch = self._generate_batch(txn_count, missing_deps, txns) LOGGER.debug("Generated Batch:\n%s", dumps_batch(batch)) return batch def _generate_batch(self, txn_count=2, missing_deps=False, txns=None): if txns is None: txns = [] if txn_count != 0: txns += [ self.generate_transaction('txn_' + str(i)) for i in range(txn_count) ] if missing_deps: target_txn = txns[-1] txn_missing_deps = self.generate_transaction( payload='this one has a missing dependency', deps=[target_txn.header_signature]) # replace the targeted txn with the missing deps txn txns[-1] = txn_missing_deps batch_header = BatchHeader( signer_public_key=self.signer.get_public_key().as_hex(), transaction_ids=[txn.header_signature for txn in txns]).SerializeToString() batch = Batch(header=batch_header, header_signature=self.signer.sign(batch_header), transactions=txns) return batch def generate_transaction(self, payload='txn', deps=None): payload_encoded = payload.encode('utf-8') hasher = hashlib.sha512() hasher.update(payload_encoded) txn_header = TransactionHeader( dependencies=([] if deps is None else deps), batcher_public_key=self.signer.get_public_key().as_hex(), family_name='test', family_version='1', nonce=_generate_id(16), payload_sha512=hasher.hexdigest().encode(), signer_public_key=self.signer.get_public_key().as_hex( )).SerializeToString() txn = Transaction(header=txn_header, header_signature=self.signer.sign(txn_header), payload=payload_encoded) return txn def _generate_batch_from_payload(self, payload): txn = self.generate_transaction(payload) batch_header = BatchHeader( signer_public_key=self.signer.get_public_key().as_hex(), transaction_ids=[txn.header_signature]).SerializeToString() batch = Batch(header=batch_header, header_signature=self.signer.sign(batch_header), transactions=[txn]) return batch
class BlockTreeManager(object): def __str__(self): return str(self.block_cache) def __repr__(self): return repr(self.block_cache) def __init__(self, with_genesis=True): self.block_sender = MockBlockSender() self.batch_sender = MockBatchSender() self.block_store = BlockStore(DictDatabase()) self.block_cache = BlockCache(self.block_store) self.state_db = {} # add the mock reference to the consensus consensus_setting_addr = ConfigView.setting_address( 'sawtooth.consensus.algorithm') self.state_db[consensus_setting_addr] = _setting_entry( 'sawtooth.consensus.algorithm', 'test_journal.mock_consensus') self.state_view_factory = MockStateViewFactory(self.state_db) self.signing_key = signing.generate_privkey() self.public_key = signing.generate_pubkey(self.signing_key) self.identity_signing_key = signing.generate_privkey() chain_head = None if with_genesis: self.genesis_block = self.generate_genesis_block() self.set_chain_head(self.genesis_block) chain_head = self.genesis_block self.block_publisher = BlockPublisher( transaction_executor=MockTransactionExecutor(), block_cache=self.block_cache, state_view_factory=self.state_view_factory, block_sender=self.block_sender, batch_sender=self.block_sender, squash_handler=None, chain_head=chain_head, identity_signing_key=self.identity_signing_key, data_dir=None, config_dir=None) @property def chain_head(self): return self.block_store.chain_head def set_chain_head(self, block): self.block_store.update_chain([block], []) def generate_block(self, previous_block=None, add_to_store=False, add_to_cache=False, batch_count=0, 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 self.block_publisher.on_chain_updated(previous) while self.block_sender.new_block is None: self.block_publisher.on_batch_received( self._generate_batch_from_payload('')) self.block_publisher.on_check_publish_block(True) block_from_sender = self.block_sender.new_block self.block_sender.new_block = None block_wrapper = BlockWrapper(block_from_sender) if invalid_signature: block_wrapper.block.header_signature = "BAD" if invalid_consensus: block_wrapper.header.consensus = b'BAD' if invalid_batch: block_wrapper.block.batches.extend( [self._generate_batch_from_payload('BAD')]) block_wrapper.weight = weight 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 return block_wrapper def generate_chain(self, root_block, blocks, params=None): """ Generate a new chain based on the root block and place it in the block cache. """ if params is None: params = {} if root_block is None: previous = self.generate_genesis_block() self.block_store[previous.identifier] = previous else: previous = self._get_block(root_block) try: block_defs = [self._block_def(**params) for _ in range(blocks)] except TypeError: block_defs = blocks out = [] for block_def in block_defs: new_block = self.generate_block(previous_block=previous, **block_def) out.append(new_block) previous = new_block return out 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 generate_genesis_block(self): return self._generate_block(payload='Genesis', previous_block_id=NULL_BLOCK_IDENTIFIER, block_num=0) def _block_def(self, add_to_store=False, add_to_cache=False, batch_count=0, status=BlockStatus.Unknown, invalid_consensus=False, invalid_batch=False, invalid_signature=False, weight=0): return { "add_to_cache": add_to_cache, "add_to_store": add_to_store, "batch_count": batch_count, "status": status, "invalid_consensus": invalid_consensus, "invalid_batch": invalid_batch, "invalid_signature": invalid_signature, "weight": weight } def _get_block_id(self, block): if block is None: return None elif isinstance(block, Block) or\ isinstance(block, BlockWrapper): return block.header_signature elif isinstance(block, basestring): return block else: return str(block) def _get_block(self, block): if block is None: return None elif isinstance(block, Block): return BlockWrapper(block) elif isinstance(block, BlockWrapper): return block elif isinstance(block, str): return self.block_cache[block] else: # WTF try something crazy return self.block_cache[str(block)] def generate_batch(self, txn_count=2, missing_deps=False, txns=None): if txns is None: txns = [ self.generate_transaction('txn_' + str(i)) for i in range(txn_count) ] if missing_deps: target_txn = txns[-1] txn_missing_deps = self.generate_transaction( payload='this one has a missing dependency', deps=[target_txn.header_signature]) # replace the targeted txn with the missing deps txn txns[-1] = txn_missing_deps batch_header = BatchHeader(signer_pubkey=self.public_key, transaction_ids=[ txn.header_signature for txn in txns ]).SerializeToString() batch = Batch(header=batch_header, header_signature=self._signed_header(batch_header), transactions=txns) return batch def generate_transaction(self, payload='txn', deps=None): payload_encoded = payload.encode('utf-8') hasher = hashlib.sha512() hasher.update(payload_encoded) txn_header = TransactionHeader( dependencies=([] if deps is None else deps), batcher_pubkey=self.public_key, family_name='test', family_version='1', nonce=_generate_id(16), payload_encoding="text", payload_sha512=hasher.hexdigest().encode(), signer_pubkey=self.public_key).SerializeToString() txn = Transaction(header=txn_header, header_signature=self._signed_header(txn_header), payload=payload_encoded) return txn def _generate_batch_from_payload(self, payload): txn = self.generate_transaction(payload) batch_header = BatchHeader(signer_pubkey=self.public_key, transaction_ids=[txn.header_signature ]).SerializeToString() batch = Batch(header=batch_header, header_signature=self._signed_header(batch_header), transactions=[txn]) return batch def _signed_header(self, header): return signing.sign(header, self.signing_key)
class BlockTreeManager(object): def __str__(self): return str(self.block_cache) def __repr__(self): return repr(self.block_cache) def __init__(self, with_genesis=True): self.block_sender = MockBlockSender() self.batch_sender = MockBatchSender() self.block_store = BlockStore(DictDatabase( indexes=BlockStore.create_index_configuration())) self.block_cache = BlockCache(self.block_store) self.state_db = {} # add the mock reference to the consensus consensus_setting_addr = SettingsView.setting_address( 'sawtooth.consensus.algorithm') self.state_db[consensus_setting_addr] = _setting_entry( 'sawtooth.consensus.algorithm', 'test_journal.mock_consensus') self.state_view_factory = MockStateViewFactory(self.state_db) context = create_context('secp256k1') private_key = context.new_random_private_key() crypto_factory = CryptoFactory(context) self.signer = crypto_factory.new_signer(private_key) identity_private_key = context.new_random_private_key() self.identity_signer = crypto_factory.new_signer(identity_private_key) chain_head = None if with_genesis: self.genesis_block = self.generate_genesis_block() self.set_chain_head(self.genesis_block) chain_head = self.genesis_block self.block_publisher = BlockPublisher( transaction_executor=MockTransactionExecutor(), block_cache=self.block_cache, state_view_factory=self.state_view_factory, settings_cache=SettingsCache( SettingsViewFactory(self.state_view_factory), ), block_sender=self.block_sender, batch_sender=self.block_sender, squash_handler=None, chain_head=chain_head, identity_signer=self.identity_signer, data_dir=None, config_dir=None, permission_verifier=MockPermissionVerifier(), check_publish_block_frequency=0.1, batch_observers=[]) @property def chain_head(self): return self.block_store.chain_head def set_chain_head(self, block): self.block_store.update_chain([block], []) 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 generate_chain(self, root_block, blocks, params=None): """ Generate a new chain based on the root block and place it in the block cache. """ if params is None: params = {} if root_block is None: previous = self.generate_genesis_block() self.block_store[previous.identifier] = previous else: previous = self._get_block(root_block) try: block_defs = [self._block_def(**params) for _ in range(blocks)] block_defs[-1] = self._block_def() except TypeError: block_defs = blocks out = [] for block_def in block_defs: new_block = self.generate_block( previous_block=previous, **block_def) out.append(new_block) previous = new_block return out 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 generate_genesis_block(self): return self.create_block( payload='Genesis', previous_block_id=NULL_BLOCK_IDENTIFIER, block_num=0) def _block_def(self, add_to_store=False, add_to_cache=False, batch_count=1, status=BlockStatus.Unknown, invalid_consensus=False, invalid_batch=False, invalid_signature=False, weight=0): return { "add_to_cache": add_to_cache, "add_to_store": add_to_store, "batch_count": batch_count, "status": status, "invalid_consensus": invalid_consensus, "invalid_batch": invalid_batch, "invalid_signature": invalid_signature, "weight": weight } def _get_block_id(self, block): if block is None: return None elif isinstance(block, (Block, BlockWrapper)): return block.header_signature else: return str(block) def _get_block(self, block): if block is None: return None elif isinstance(block, Block): return BlockWrapper(block) elif isinstance(block, BlockWrapper): return block elif isinstance(block, str): return self.block_cache[block] else: # WTF try something crazy return self.block_cache[str(block)] def generate_batch(self, txn_count=2, missing_deps=False, txns=None): batch = self._generate_batch(txn_count, missing_deps, txns) LOGGER.debug("Generated Batch:\n%s", dumps_batch(batch)) return batch def _generate_batch(self, txn_count=2, missing_deps=False, txns=None): if txns is None: txns = [] if txn_count != 0: txns += [ self.generate_transaction('txn_' + str(i)) for i in range(txn_count) ] if missing_deps: target_txn = txns[-1] txn_missing_deps = self.generate_transaction( payload='this one has a missing dependency', deps=[target_txn.header_signature]) # replace the targeted txn with the missing deps txn txns[-1] = txn_missing_deps batch_header = BatchHeader( signer_public_key=self.signer.get_public_key().as_hex(), transaction_ids=[txn.header_signature for txn in txns] ).SerializeToString() batch = Batch( header=batch_header, header_signature=self.signer.sign(batch_header), transactions=txns) return batch def generate_transaction(self, payload='txn', deps=None): payload_encoded = payload.encode('utf-8') hasher = hashlib.sha512() hasher.update(payload_encoded) txn_header = TransactionHeader( dependencies=([] if deps is None else deps), batcher_public_key=self.signer.get_public_key().as_hex(), family_name='test', family_version='1', nonce=_generate_id(16), payload_sha512=hasher.hexdigest().encode(), signer_public_key=self.signer.get_public_key().as_hex() ).SerializeToString() txn = Transaction( header=txn_header, header_signature=self.signer.sign(txn_header), payload=payload_encoded) return txn def _generate_batch_from_payload(self, payload): txn = self.generate_transaction(payload) batch_header = BatchHeader( signer_public_key=self.signer.get_public_key().as_hex(), transaction_ids=[txn.header_signature] ).SerializeToString() batch = Batch( header=batch_header, header_signature=self.signer.sign(batch_header), transactions=[txn]) return batch
class BlockTreeManager(object): def block_def(self, add_to_store=False, add_to_cache=False, batch_count=0, status=BlockStatus.Unknown, invalid_consensus=False, invalid_batch=False, invalid_signature=False, weight=None): return { "add_to_cache": add_to_cache, "add_to_store": add_to_store, "batch_count": batch_count, "status": status, "invalid_consensus": invalid_consensus, "invalid_batch": invalid_batch, "invalid_signature": invalid_signature, "weight": weight } def __init__(self): self.block_sender = MockBlockSender() self.block_store = BlockStore(DictDatabase()) self.block_cache = BlockCache(self.block_store) self.state_db = {} # add the mock reference to the consensus self.state_db[_setting_address('sawtooth.consensus.algorithm')] = \ _setting_entry('sawtooth.consensus.algorithm', 'test_journal.mock_consensus') self.state_view_factory = MockStateViewFactory(self.state_db) self.signing_key = signing.generate_privkey() self.public_key = signing.encode_pubkey( signing.generate_pubkey(self.signing_key), "hex") self.identity_signing_key = signing.generate_privkey() self.genesis_block = self._generate_genesis_block() self.set_chain_head(self.genesis_block) self.block_publisher = BlockPublisher( transaction_executor=MockTransactionExecutor(), block_cache=self.block_cache, state_view_factory=self.state_view_factory, block_sender=self.block_sender, squash_handler=None, chain_head=self.genesis_block, identity_signing_key=self.identity_signing_key) def _get_block_id(self, block): if (block is None): return None elif isinstance(block, Block) or\ isinstance(block, BlockWrapper): return block.header_signature elif isinstance(block, basestring): return block else: return str(block) def _get_block(self, block): if (block is None): return None elif isinstance(block, Block): return BlockWrapper(block) elif isinstance(block, BlockWrapper): return block elif isinstance(block, str): return self.block_cache[block] else: # WTF try something crazy return self.block_cache[str(block)] @property def chain_head(self): return self.block_store.chain_head def set_chain_head(self, block): self.block_store.update_chain([block], []) def generate_block(self, previous_block=None, add_to_store=False, add_to_cache=False, batch_count=0, status=BlockStatus.Unknown, invalid_consensus=False, invalid_batch=False, invalid_signature=False, weight=None): previous = self._get_block(previous_block) if previous is None: previous = self.chain_head self.block_publisher.on_chain_updated(previous) while self.block_sender.new_block is None: self.block_publisher.on_batch_received(self._generate_batch('')) self.block_publisher.on_check_publish_block(True) block = self.block_sender.new_block self.block_sender.new_block = None block = BlockWrapper(block) if invalid_signature: block.block.header_signature = "BAD" block.weight = weight block.status = status if add_to_cache: self.block_cache[block.identifier] = block if add_to_store: self.block_store[block.identifier] = block return block def _generate_batch(self, payload): payload_encoded = payload.encode('utf-8') hasher = hashlib.sha512() hasher.update(payload_encoded) header = TransactionHeader() header.batcher_pubkey = self.public_key # txn.dependencies not yet header.family_name = 'test' header.family_version = '1' header.nonce = _generate_id(16) header.payload_encoding = "text" header.payload_sha512 = hasher.hexdigest().encode() header.signer_pubkey = self.public_key txn = Transaction() header_bytes = header.SerializeToString() txn.header = header_bytes txn.header_signature = signing.sign(header_bytes, self.signing_key) txn.payload = payload_encoded batch_header = BatchHeader() batch_header.signer_pubkey = self.public_key batch_header.transaction_ids.extend([txn.header_signature]) batch = Batch() header_bytes = batch_header.SerializeToString() batch.header = header_bytes batch.header_signature = signing.sign(header_bytes, self.signing_key) batch.transactions.extend([txn]) return batch 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_chain(self, root_block, blocks, params=None): """ Generate a new chain based on the root block and place it in the block cache. """ if params is None: params = {} out = [] if not isinstance(blocks, list): blocks = self.generate_chain_definition(int(blocks), params) if root_block is None: previous = self._generate_genesis_block() self.block_store[previous.identifier] = previous else: previous = self._get_block(root_block) for block in blocks: new_block = self.generate_block(previous_block=previous, **block) out.append(new_block) previous = new_block return out def generate_chain_definition(self, count, params=None): if params is None: params = {} out = [] for _ in range(0, count): out.append(self.block_def(**params)) return out def __str__(self): return str(self.block_cache) def __repr__(self): return repr(self.block_cache)
from test_journal.block_tree_manager import BlockTreeManager from sawtooth_validator.database.dict_database import DictDatabase from sawtooth_validator.journal.block_store import BlockStore if __name__ == '__main__': print("\n====== cProfile: ./validator/cprof_block_store.py ======\n") pr = cProfile.Profile() pr.enable() block_tree_manager = BlockTreeManager() block = block_tree_manager.create_block() block_store = BlockStore( DictDatabase({ block.header_signature: block, }, indexes=BlockStore.create_index_configuration())) block_store.update_chain([block]) batch_id = block.batches[0].header_signature stored = block_store.get_block_by_batch_id(batch_id) batch = block.batches[0] txn_id = batch.transactions[0].header_signature stored = block_store.get_batch_by_transaction(txn_id) batch_id = batch.header_signature stored_batch = block_store.get_batch(batch_id) pr.disable() pr.print_stats(sort='time')