Repository: Chia-Network/chia-blockchain
File: chia/data_layer/data_store.py (Python)

Code before:
        else:
            resolved_root_hash = root_hash

        merkle_blob = await self.get_merkle_blob(store_id=store_id, root_hash=resolved_root_hash)
        kid, vid = merkle_blob.get_node_by_hash(node_hash)
        return await self.get_terminal_node(kid, vid, store_id)

    async def get_first_generation(self, node_hash: bytes32, store_id: bytes32) -> Optional[int]:
        async with self.db_wrapper.reader() as reader:
            cursor = await reader.execute(
                "SELECT generation FROM nodes WHERE hash = ? AND store_id = ?",
                (
                    node_hash,
                    store_id,
                ),
            )

            row = await cursor.fetchone()
            if row is None:
                return None

            return int(row[0])

    async def get_existing_hashes(self, node_hashes: list[bytes32], store_id: bytes32) -> set[bytes32]:
        result: set[bytes32] = set()
        batch_size = min(500, SQLITE_MAX_VARIABLE_NUMBER - 10)

        async with self.db_wrapper.reader() as reader:
            for i in range(0, len(node_hashes), batch_size):
                chunk = node_hashes[i : i + batch_size]
                placeholders = ",".join(["?"] * len(chunk))
                query = f"SELECT hash FROM nodes WHERE store_id = ? AND hash IN ({placeholders}) LIMIT {len(chunk)}"

                async with reader.execute(query, (store_id, *chunk)) as cursor:
                    rows = await cursor.fetchall()
                    result.update(row["hash"] for row in rows)

        return result

    async def add_node_hashes(self, store_id: bytes32, generation: Optional[int] = None) -> None:
        root = await self.get_tree_root(store_id=store_id, generation=generation)
        if root.node_hash is None:
            return

        merkle_blob = await self.get_merkle_blob(
            store_id=store_id, root_hash=root.node_hash, read_only=True, update_cache=False
        )
        hash_to_index = merkle_blob.get_hashes_indexes()

        existing_hashes = await self.get_existing_hashes(list(hash_to_index.keys()), store_id)
        async with self.db_wrapper.writer() as writer:

Review comment (suggestion):
```suggestion
        kv_ids_unpacked = (
            KeyOrValueId(id.raw)
            for node_hash in node_hashes
            for id in merkle_blob.get_node_by_hash(node_hash)
        )
```

Code after:
        else:
            resolved_root_hash = root_hash

        merkle_blob = await self.get_merkle_blob(store_id=store_id, root_hash=resolved_root_hash)
        kid, vid = merkle_blob.get_node_by_hash(node_hash)
        return await self.get_terminal_node(kid, vid, store_id)

    async def get_terminal_nodes_by_hashes(
        self,
        node_hashes: list[bytes32],
        store_id: bytes32,
        root_hash: Union[bytes32, Unspecified] = unspecified,
    ) -> list[TerminalNode]:
        resolved_root_hash: Optional[bytes32]
        if root_hash is unspecified:
            root = await self.get_tree_root(store_id=store_id)
            resolved_root_hash = root.node_hash
        else:
            resolved_root_hash = root_hash

        merkle_blob = await self.get_merkle_blob(store_id=store_id, root_hash=resolved_root_hash)
        kv_ids: list[tuple[KeyId, ValueId]] = []
        for node_hash in node_hashes:
            kid, vid = merkle_blob.get_node_by_hash(node_hash)
            kv_ids.append((kid, vid))
        kv_ids_unpacked = (KeyOrValueId(id.raw) for kv_id in kv_ids for id in kv_id)
        table_blobs = await self.get_table_blobs(kv_ids_unpacked, store_id)

        terminal_nodes: list[TerminalNode] = []
        for kid, vid in kv_ids:
            terminal_nodes.append(self.get_terminal_node_from_table_blobs(kid, vid, table_blobs, store_id))

        return terminal_nodes

    async def get_first_generation(self, node_hash: bytes32, store_id: bytes32) -> Optional[int]:
        async with self.db_wrapper.reader() as reader:
            cursor = await reader.execute(
                "SELECT generation FROM nodes WHERE hash = ? AND store_id = ?",
                (
                    node_hash,
                    store_id,
                ),
            )

            row = await cursor.fetchone()
            if row is None:
                return None

            return int(row[0])

    async def get_existing_hashes(self, node_hashes: list[bytes32], store_id: bytes32) -> set[bytes32]: