code: def build_state(self, stop_key: Optional[str] = None) -> dict:
      sorted_dict = sort_dict_naturally(self.protocol_history)
      state_dict = defaultdict(dict)
      for protocol_number in sorted_dict:
          object_versions = sorted_dict[protocol_number][
              "object_versions"
          ]
          for canonical_name, versions in object_versions.items():
              for version, object_metadata in versions.items():
                  action = object_metadata["action"]
                  version = object_metadata["version"]
                  hash_str = object_metadata["hash"]
                  state_versions = state_dict[canonical_name]
                  state_version_hashes = [
                      val[0] for val in state_versions.values()
                  ]
                  if action == "add" and (
                      str(version) in state_versions.keys()
                      or hash_str in state_version_hashes
                  ):
                      raise Exception(
                          f"Can't add {object_metadata} already in state {versions}"
                      )
                  elif action == "remove" and (
                      str(version) not in state_versions.keys()
                      and hash_str not in state_version_hashes
                  ):
                      raise Exception(
                          f"Can't remove {object_metadata} missing from state {versions} for object {canonical_name}."
                      )
                  if action == "add":
                      state_dict[canonical_name][str(version)] = (
                          hash_str,
                          protocol_number,
                      )
                  elif action == "remove":
                      del state_dict[canonical_name][str(version)]
          # stop early
          if stop_key == protocol_number:
              return state_dict
      return state_dict
  
imports: from collections import defaultdict
  from collections.abc import MutableMapping
  from collections.abc import MutableSequence
  import hashlib
  import json
  import os
  from pathlib import Path
  import re
  from typing import Any
  from typing import Dict
  from typing import Optional
  from typing import Tuple
  from typing import Type
  from typing import Union
  from result import OkErr
  from result import Result
  from ..serde.recursive import TYPE_BANK
  from ..service.response import SyftError
  from ..service.response import SyftException
  from ..service.response import SyftSuccess
  from ..types.dicttuple import DictTuple
  from ..types.syft_object import SyftBaseObject
label_desc: Use image node_id 8 for calling the DataProtocol obj's underlying member method code with example usage: obj.build_state(stop_key) and returns: state_dict, state_dict