def add_transaction(self, transaction, computation, block): """ Add a transaction to the given block and return `trie_data` to store the transaction data in chaindb in VM layer. Update the bloom_filter, transaction trie and receipt trie roots, bloom_filter, bloom, and used_gas of the block. :param transaction: the executed transaction :param computation: the Computation object with executed result :param block: the Block which the transaction is added in :type transaction: Transaction :type computation: Computation :type block: Block :return: the block and the trie_data :rtype: (Block, dict[bytes, bytes]) """ receipt = self.make_receipt(transaction, computation) self.add_receipt(receipt) # Create a new Block object block_header = block.header.clone() transactions = list(block.transactions) block = self.block_class(block_header, transactions) block.transactions.append(transaction) # Get trie roots and changed key-values. tx_root_hash, tx_kv_nodes = make_trie_root_and_nodes( block.transactions, self.trie_class, ) receipt_root_hash, receipt_kv_nodes = make_trie_root_and_nodes( self.receipts, self.trie_class, ) trie_data = merge(tx_kv_nodes, receipt_kv_nodes) block.bloom_filter |= receipt.bloom block.header.transaction_root = tx_root_hash block.header.receipt_root = receipt_root_hash block.header.bloom = int(block.bloom_filter) block.header.gas_used = receipt.gas_used return block, trie_data