# Buggy code
def update_properties(self, update_dict):
    # Sanity checks: check that we don't create a recursive dependency or an orphaned channel
    new_origin_id = update_dict.get("origin_id", self.origin_id)
    if new_origin_id not in (0, self.origin_id):
        new_parent = CollectionNode.get(public_key=self.public_key, id_=new_origin_id)
        if not new_parent:
            raise ValueError("Target collection does not exists")
        root_path = new_parent.get_parents_ids()
        if new_origin_id == self.id_ or self.id_ in root_path:
            raise ValueError("Can't move collection into itself or its descendants!")
        if 0 not in root_path:
            # TODO: add orphan-cleaning hook here
            raise ValueError("Tried to move collection into an orphaned hierarchy!")
    updated_self = super(CollectionNode, self).update_properties(update_dict)
    if updated_self.origin_id == 0 and self.metadata_type == COLLECTION_NODE:
        # Coerce to ChannelMetadata
        # ACHTUNG! This is a somewhat awkward way to re-create the entry as an instance of
        # another class. Be very careful with it!
        self_dict = updated_self.to_dict()
        updated_self.delete(recursive=False)
        self_dict.pop("rowid")
        self_dict.pop("metadata_type")
        self_dict["infohash"] = random_infohash()
        self_dict["sign_with"] = self._my_key
        updated_self = db.ChannelMetadata.from_dict(self_dict)
    return updated_self


# Traceback (TypeError)
[PID:20194] 2020-09-13 09:46:48,913 - INFO - TorrentChecker(132) - Selected 1 new torrents to check on tracker: http://www.mvgroup.org:2710/announc
[PID:20194] 2020-09-13 09:46:48,982 - ERROR <taskmanager:135> GigaChannelCommunity.done_cb(): Task resulted in error: Invalid discriminator attribute value for ChannelMetadata. Expected: 400, got: 220
Traceback (most recent call last):
File "ipv8/taskmanager.py", line 131, in done_cb
File "tribler_core/modules/metadata_store/community/gigachannel_community.py", line 204, in on_blob
File "concurrent/futures/thread.py", line 57, in run
File "tribler_core/modules/metadata_store/community/gigachannel_community.py", line 175, in _process_received_blob
File "tribler_core/modules/metadata_store/community/gigachannel_community.py", line 154, in _update_db_with_blob
File "tribler_core/modules/metadata_store/store.py", line 295, in process_compressed_mdblob
File "tribler_core/modules/metadata_store/store.py", line 328, in process_squashed_mdblob
File "<string>", line 2, in process_payload
File "pony/orm/core.py", line 515, in new_func
File "tribler_core/modules/metadata_store/store.py", line 462, in process_payload
File "pony/orm/core.py", line 5072, in set
File "pony/orm/core.py", line 5146, in _keyargs_to_avdicts_
File "pony/orm/core.py", line 2594, in validate
File "pony/utils/utils.py", line 106, in throw
TypeError: Invalid discriminator attribute value for ChannelMetadata. Expected: 400, got: 220

# Fixed code
def update_properties(self, update_dict):
    # Sanity checks: check that we don't create a recursive dependency or an orphaned channel
    new_origin_id = update_dict.get("origin_id", self.origin_id)
    if new_origin_id not in (0, self.origin_id):
        new_parent = CollectionNode.get(public_key=self.public_key, id_=new_origin_id)
        if not new_parent:
            raise ValueError("Target collection does not exists")
        root_path = new_parent.get_parents_ids()
        if new_origin_id == self.id_ or self.id_ in root_path:
            raise ValueError("Can't move collection into itself or its descendants!")
        if 0 not in root_path:
            # TODO: add orphan-cleaning hook here
            raise ValueError("Tried to move collection into an orphaned hierarchy!")
    updated_self = super(CollectionNode, self).update_properties(update_dict)
    if updated_self.origin_id == 0 and self.metadata_type == COLLECTION_NODE:
        # Coerce to ChannelMetadata
        # ACHTUNG! This is a somewhat awkward way to re-create the entry as an instance of
        # another class. Be very careful with it!
        self_dict = updated_self.to_dict()
        updated_self.delete(recursive=False)
        self_dict.pop("rowid")
        self_dict.pop("metadata_type")
        self_dict.pop("timestamp")
        self_dict["infohash"] = random_infohash()
        self_dict["sign_with"] = self._my_key
        updated_self = db.ChannelMetadata.from_dict(self_dict)
    return updated_self