async def make_finalize_from_confirm(self, confirm_block: BaseBlock, vt_list) -> BaseBlock: tx_trie = make_hash_root(confirm_block.list_transactions) permit_header = self.get_header_from_hash(confirm_block.previous) wagon = self.prepare_wagon(permit_header) if confirm_block.header.hash_transaction_root != tx_trie.root: raise ValidationError("tx root not matched") confirm_block.list_vote.extend(vt_list) vt_trie = make_hash_root(vt_list) confirm_block.header.hash_vote_root = vt_trie.root block = await wagon.execute_transactions(self.version, confirm_block) block.header.hash_vote_root = vt_trie.root block.header.timestamp_finalize = time.time() signature = self.make_signature(block.hash) wagon.clear() return block.copy(header=block.header.copy(hash_block=block.hash, byte_signature=signature), list_vote=vt_list)
def _commit(self, block) -> None: # TODO: exceptions -> snapshot revert. try: self.state.commit() trie = make_hash_root(block.list_transactions) self._db_context.chain.set_trie(trie) self._db_context.chain.set_trie(self._trie) trie = make_hash_root(block.list_vote) self._db_context.chain.set_trie(trie) self._db_context.chain.commit(block) except CacheError: raise FinalizeError finally: self.clear()
async def execute_transactions(self, version, block: BaseBlock) -> BaseBlock: """ execute transactions :param int version: chain version. :param Block block: next height block. :return: Block class """ if block.height != self.header.num_height + 1: raise ValidationError( "wagon is execute on height={}, " "currently doesn't execute on height={}".format( self.header.num_height, block.height)) for index, transaction in enumerate(block.list_transactions): # self._tasks.add( # asyncio.ensure_future( # self.execute_transaction(version, index, block.header, transaction)) # ) await self.execute_transaction(version, index, block.header, transaction) # await self.event() self._receipts.sort(key=lambda obj: obj[0]) self._trie = make_hash_root([receipt for _, receipt in self._receipts]) self._pre_finalize(block) return block.copy(header=block.header.copy( hash_receipt_root=self._trie.root, hash_state_root=self.state.cache_trie_root))
def make_candidate(block: BaseBlock, event: BaseEvent, chain: BaseChain): # make candidate with prepared block if chain.is_validator: transactions = event.get_transaction() try: validate_transactions = validate_has_transactions(transactions, chain) except ValidationError: manager = getattr(event.event, 'transaction') manager.storage.delete_keys([tx.hash for tx in transactions]) return False chain.logger.info("build new height ({})".format(chain.height + 1)) trie = make_hash_root(validate_transactions) block.header.hash_transaction_root = trie.root block.header.timestamp = time.time() block.header.hash_candidate_block = block.pre_hash signature = chain.make_signature(block.pre_hash) return block.copy(header=block.header.copy(byte_signature=signature), list_transactions=validate_transactions)
async def validate_header(self, permit_header: BaseHeader, block: BaseBlock): header = block.header if self.chain_id != header.chain_id: raise ValidationError("main chain id: {} " "current header chain id: {}".format( self.chain_id, header.chain_id)) validate_header_slots(header.to_dict()) await verify(header.hash, header.byte_signature, header.address_creator) if permit_header.num_height + 1 != header.num_height: raise FinalizeError("permit header height: {} " "current header height: {}".format( permit_header.num_height, header.num_height)) if permit_header.hash != block.previous: raise FinalizeError("previous hash: {}, " "current block previous hash: {} ".format( permit_header.hash, block.previous)) if permit_header.timestamp >= header.timestamp: raise ValidationError("permit header time: {} " "current header time: {}".format( permit_header.timestamp, header.timestamp)) tx_root = make_hash_root(block.list_transactions).root if tx_root != block.header.hash_transaction_root: raise ValidationError("current header tx root: {} " "digest tx root: {}".format( block.header.hash_transaction_root, tx_root)) vt_root = make_hash_root(block.list_vote).root if vt_root != block.header.hash_vote_root: raise ValidationError("vote root error")
async def validate_candidate(block: BaseBlock) -> None: if block.pre_hash != block.header.hash_candidate_block: raise ValidationError("candidate hash: {} " "current candidate hash: {}".format( block.pre_hash, block.header.hash_candidate_block)) await verify(block.pre_hash, block.header.byte_signature, block.header.address_creator) trie = make_hash_root(block.list_transactions) if block.header.hash_transaction_root != trie.root: raise ValidationError("block tx root: {}" "current block tx root: {}".format( trie.root, block.header.hash_transaction_root))