diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/JoinOpenGroupDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/JoinOpenGroupDialog.kt index 444c389e04..4e9332fb6f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/JoinOpenGroupDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/JoinOpenGroupDialog.kt @@ -40,7 +40,7 @@ class JoinOpenGroupDialog(private val name: String, private val url: String) : B ThreadUtils.queue { try { OpenGroupManager.add(openGroup.server, openGroup.room, openGroup.serverPublicKey, activity) - MessagingModuleConfiguration.shared.storage.onOpenGroupAdded(openGroup.server) + MessagingModuleConfiguration.shared.storage.onOpenGroupAdded(openGroup.server, openGroup.room) ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(activity) } catch (e: Exception) { Toast.makeText(activity, R.string.activity_join_public_chat_error, Toast.LENGTH_SHORT).show() diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index f765a02ae1..bae8c8856d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -7,13 +7,18 @@ import network.loki.messenger.libsession_util.Contacts import network.loki.messenger.libsession_util.ConversationVolatileConfig import network.loki.messenger.libsession_util.UserGroupsConfig import network.loki.messenger.libsession_util.UserProfile -import network.loki.messenger.libsession_util.util.* +import network.loki.messenger.libsession_util.util.BaseCommunityInfo +import network.loki.messenger.libsession_util.util.Conversation +import network.loki.messenger.libsession_util.util.ExpiryMode +import network.loki.messenger.libsession_util.util.GroupInfo +import network.loki.messenger.libsession_util.util.UserPic import org.session.libsession.avatars.AvatarHelper import org.session.libsession.database.StorageProtocol import org.session.libsession.messaging.BlindedIdMapping import org.session.libsession.messaging.calls.CallMessageType import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.jobs.AttachmentUploadJob +import org.session.libsession.messaging.jobs.BackgroundGroupAddJob import org.session.libsession.messaging.jobs.ConfigurationSyncJob import org.session.libsession.messaging.jobs.GroupAvatarDownloadJob import org.session.libsession.messaging.jobs.Job @@ -64,6 +69,7 @@ import org.session.libsignal.crypto.ecc.ECKeyPair import org.session.libsignal.messages.SignalServiceAttachmentPointer import org.session.libsignal.messages.SignalServiceGroup import org.session.libsignal.utilities.Base64 +import org.session.libsignal.utilities.Hex import org.session.libsignal.utilities.IdPrefix import org.session.libsignal.utilities.KeyHelper import org.session.libsignal.utilities.Log @@ -400,8 +406,11 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF val lgc = userGroups.allLegacyGroupInfo() val allOpenGroups = getAllOpenGroups() val toDeleteCommunities = allOpenGroups.filter { it.value.joinURL !in communities.map { it.community.fullUrl() } } - val existingOpenGroups: Map = allOpenGroups.filterKeys { it !in toDeleteCommunities.keys } - val existingJoinUrls = existingOpenGroups.values.map { it.joinURL } + + val existingCommunities: Map = allOpenGroups.filterKeys { it !in toDeleteCommunities.keys } + val toAddCommunities = communities.filter { it.community.fullUrl() !in existingCommunities.map { it.value.joinURL } } + + val existingJoinUrls = existingCommunities.values.map { it.joinURL } val existingClosedGroups = getAllGroups() val lgcIds = lgc.map { it.sessionId } val toDeleteClosedGroups = existingClosedGroups.filter { group -> @@ -422,6 +431,14 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF } } + toAddCommunities.forEach { toAddCommunity -> + val joinUrl = toAddCommunity.community.fullUrl() + if (!hasBackgroundGroupAddJob(joinUrl)) { + Log.d("Loki-DBG", "Doesn't contain background job for open group, adding from config update") + JobQueue.shared.add(BackgroundGroupAddJob(joinUrl)) + } + } + for (groupInfo in communities) { val groupBaseCommunity = groupInfo.community if (groupBaseCommunity.fullUrl() !in existingJoinUrls) { @@ -429,7 +446,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF val (threadId, _) = OpenGroupManager.add(groupBaseCommunity.baseUrl, groupBaseCommunity.room, groupBaseCommunity.pubKeyHex, context) threadDb.setPinned(threadId, groupInfo.priority >= 1) } else { - val (threadId, _) = existingOpenGroups.entries.first { (_, v) -> v.joinURL == groupInfo.community.fullUrl() } + val (threadId, _) = existingCommunities.entries.first { (_, v) -> v.joinURL == groupInfo.community.fullUrl() } threadDb.setPinned(threadId, groupInfo.priority >= 1) } } @@ -699,6 +716,10 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF val existingGroup = getGroup(groupID) ?: return Log.w("Loki-DBG", "No existing group for ${groupPublicKey.take(4)}...${groupPublicKey.takeLast(4)} when updating group config") val userGroups = configFactory.userGroups ?: return + if (!existingGroup.isActive) { + userGroups.eraseLegacyGroup(groupPublicKey) + return + } val name = existingGroup.title val admins = existingGroup.admins.map { it.serialize() } val members = existingGroup.members.map { it.serialize() } @@ -855,8 +876,19 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF return OpenGroupManager.addOpenGroup(urlAsString, context) } - override fun onOpenGroupAdded(server: String) { + override fun onOpenGroupAdded(server: String, room: String) { OpenGroupManager.restartPollerForServer(server.removeSuffix("/")) + val groups = configFactory.userGroups ?: return + val volatileConfig = configFactory.convoVolatile ?: return + val openGroup = getOpenGroup(room, server) ?: return + val (infoServer, infoRoom, pubKey) = BaseCommunityInfo.parseFullUrl(openGroup.joinURL) ?: return + val pubKeyHex = Hex.toStringCondensed(pubKey) + val communityInfo = groups.getOrConstructCommunityInfo(infoServer, infoRoom, pubKeyHex) + groups.set(communityInfo) + val volatile = volatileConfig.getOrConstructCommunity(infoServer, infoRoom, pubKey).copy( + lastRead = SnodeAPI.nowWithOffset, + ) + volatileConfig.set(volatile) } override fun hasBackgroundGroupAddJob(groupJoinUrl: String): Boolean { diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt index fe74683d5d..874589d20f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt @@ -11,6 +11,7 @@ import org.session.libsession.utilities.ConfigFactoryUpdateListener import org.session.libsignal.protos.SignalServiceProtos.SharedConfigMessage import org.thoughtcrime.securesms.database.ConfigDatabase import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities +import java.util.concurrent.Executors class ConfigFactory(private val context: Context, private val configDatabase: ConfigDatabase, @@ -34,6 +35,7 @@ class ConfigFactory(private val context: Context, private var _convoVolatileConfig: ConversationVolatileConfig? = null private val userGroupsLock = Object() private var _userGroups: UserGroupsConfig? = null + private val factoryExecutor = Executors.newSingleThreadExecutor() private val listeners: MutableList = mutableListOf() fun registerListener(listener: ConfigFactoryUpdateListener) { listeners += listener } @@ -127,15 +129,17 @@ class ConfigFactory(private val context: Context, } override fun persist(forConfigObject: ConfigBase) { - listeners.forEach { listener -> - listener.notifyUpdates(forConfigObject) - } - when (forConfigObject) { - is UserProfile -> persistUserConfigDump() - is Contacts -> persistContactsConfigDump() - is ConversationVolatileConfig -> persistConvoVolatileConfigDump() - is UserGroupsConfig -> persistUserGroupsConfigDump() - else -> throw UnsupportedOperationException("Can't support type of ${forConfigObject::class.simpleName} yet") + factoryExecutor.submit { + listeners.forEach { listener -> + listener.notifyUpdates(forConfigObject) + } + when (forConfigObject) { + is UserProfile -> persistUserConfigDump() + is Contacts -> persistContactsConfigDump() + is ConversationVolatileConfig -> persistConvoVolatileConfigDump() + is UserGroupsConfig -> persistUserGroupsConfigDump() + else -> throw UnsupportedOperationException("Can't support type of ${forConfigObject::class.simpleName} yet") + } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/JoinCommunityFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/JoinCommunityFragment.kt index d37b17ef9f..3afd98422d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/JoinCommunityFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/JoinCommunityFragment.kt @@ -79,7 +79,7 @@ class JoinCommunityFragment : Fragment() { val openGroupID = "$sanitizedServer.${openGroup.room}" OpenGroupManager.add(sanitizedServer, openGroup.room, openGroup.serverPublicKey, requireContext()) val storage = MessagingModuleConfiguration.shared.storage - storage.onOpenGroupAdded(sanitizedServer) + storage.onOpenGroupAdded(sanitizedServer, openGroup.room) val threadID = GroupManager.getOpenGroupThreadID(openGroupID, requireContext()) val groupID = GroupUtil.getEncodedOpenGroupID(openGroupID.toByteArray()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt index e873fb8087..5772b5d4ae 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt @@ -3,9 +3,11 @@ package org.thoughtcrime.securesms.sskenvironment import android.content.Context import network.loki.messenger.libsession_util.util.UserPic import org.session.libsession.messaging.contacts.Contact +import org.session.libsession.messaging.utilities.SessionId import org.session.libsession.utilities.SSKEnvironment import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.recipients.Recipient +import org.session.libsignal.utilities.IdPrefix import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.dependencies.ConfigFactory import org.thoughtcrime.securesms.dependencies.DatabaseComponent @@ -86,6 +88,8 @@ class ProfileManager(private val context: Context, private val configFactory: Co override fun contactUpdatedInternal(contact: Contact) { val contactConfig = configFactory.contacts ?: return if (contact.sessionID == TextSecurePreferences.getLocalNumber(context)) return + val sessionId = SessionId(contact.sessionID) + if (sessionId.prefix != IdPrefix.STANDARD) return // only internally store standard session IDs contactConfig.upsertContact(contact.sessionID) { this.name = contact.name.orEmpty() this.nickname = contact.nickname.orEmpty() diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt index 5a405a8bf7..e2121f4d3a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt @@ -6,7 +6,11 @@ import network.loki.messenger.libsession_util.Contacts import network.loki.messenger.libsession_util.ConversationVolatileConfig import network.loki.messenger.libsession_util.UserGroupsConfig import network.loki.messenger.libsession_util.UserProfile -import network.loki.messenger.libsession_util.util.* +import network.loki.messenger.libsession_util.util.BaseCommunityInfo +import network.loki.messenger.libsession_util.util.Contact +import network.loki.messenger.libsession_util.util.ExpiryMode +import network.loki.messenger.libsession_util.util.GroupInfo +import network.loki.messenger.libsession_util.util.UserPic import nl.komponents.kovenant.Promise import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.jobs.ConfigurationSyncJob @@ -17,7 +21,6 @@ import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsession.messaging.utilities.SessionId import org.session.libsession.utilities.Address import org.session.libsession.utilities.GroupUtil -import org.session.libsession.utilities.SSKEnvironment import org.session.libsession.utilities.TextSecurePreferences import org.session.libsignal.utilities.Hex import org.session.libsignal.utilities.Log @@ -167,6 +170,7 @@ object ConfigurationMessageUtilities { } val dump = contactConfig.dump() contactConfig.free() + if (dump.isEmpty()) return null return dump } @@ -177,7 +181,7 @@ object ConfigurationMessageUtilities { val threadDb = DatabaseComponent.get(context).threadDatabase() threadDb.approvedConversationList.use { cursor -> val reader = threadDb.readerFor(cursor) - var current = reader.current + var current = reader.next while (current != null) { val recipient = current.recipient val contact = when { @@ -210,6 +214,7 @@ object ConfigurationMessageUtilities { val dump = convoConfig.dump() convoConfig.free() + if (dump.isEmpty()) return null return dump } @@ -226,7 +231,7 @@ object ConfigurationMessageUtilities { GroupInfo.CommunityGroupInfo(baseInfo, if (isPinned) 1 else 0) } - val allLgc = storage.getAllGroups().filter { it.isClosedGroup }.mapNotNull { group -> + val allLgc = storage.getAllGroups().filter { it.isClosedGroup && it.isActive }.mapNotNull { group -> val groupAddress = Address.fromSerialized(group.encodedId) val groupPublicKey = GroupUtil.doubleDecodeGroupID(groupAddress.serialize()).toHexString() val recipient = storage.getRecipientSettings(groupAddress) ?: return@mapNotNull null @@ -252,6 +257,7 @@ object ConfigurationMessageUtilities { } val dump = groupConfig.dump() groupConfig.free() + if (dump.isEmpty()) return null return dump } diff --git a/libsession-util/src/main/cpp/user_groups.cpp b/libsession-util/src/main/cpp/user_groups.cpp index d2e416f399..0d4bebbd55 100644 --- a/libsession-util/src/main/cpp/user_groups.cpp +++ b/libsession-util/src/main/cpp/user_groups.cpp @@ -29,7 +29,7 @@ Java_network_loki_messenger_libsession_1util_UserGroupsConfig_00024Companion_new auto* user_groups = new session::config::UserGroups(secret_key, initial); - jclass contactsClass = env->FindClass("network/loki/messenger/libsession_util/Contacts"); + jclass contactsClass = env->FindClass("network/loki/messenger/libsession_util/UserGroupsConfig"); jmethodID constructor = env->GetMethodID(contactsClass, "", "(J)V"); jobject newConfig = env->NewObject(contactsClass, constructor, reinterpret_cast(user_groups)); @@ -126,40 +126,21 @@ Java_network_loki_messenger_libsession_1util_UserGroupsConfig_set__Lnetwork_loki } } -extern "C" -JNIEXPORT void JNICALL -Java_network_loki_messenger_libsession_1util_UserGroupsConfig_set__Lnetwork_loki_messenger_libsession_1util_util_GroupInfo_CommunityGroupInfo_2( - JNIEnv *env, jobject thiz, jobject community_info) { - auto conf = ptrToUserGroups(env, thiz); - auto deserialized = deserialize_community_info(env, community_info, conf); - conf->set(deserialized); -} extern "C" JNIEXPORT void JNICALL -Java_network_loki_messenger_libsession_1util_UserGroupsConfig_set__Lnetwork_loki_messenger_libsession_1util_util_GroupInfo_LegacyGroupInfo_2( - JNIEnv *env, jobject thiz, jobject legacy_group_info) { +Java_network_loki_messenger_libsession_1util_UserGroupsConfig_erase__Lnetwork_loki_messenger_libsession_1util_util_GroupInfo_2( + JNIEnv *env, jobject thiz, jobject group_info) { auto conf = ptrToUserGroups(env, thiz); - auto deserialized = deserialize_legacy_group_info(env, legacy_group_info, conf); - conf->set(deserialized); -} -#pragma clang diagnostic pop -extern "C" -JNIEXPORT void JNICALL -Java_network_loki_messenger_libsession_1util_UserGroupsConfig_erase__Lnetwork_loki_messenger_libsession_1util_util_GroupInfo_CommunityGroupInfo_2( - JNIEnv *env, jobject thiz, jobject community_info) { - auto conf = ptrToUserGroups(env, thiz); - auto deserialized = deserialize_community_info(env, community_info, conf); - conf->erase(deserialized); -} - -extern "C" -JNIEXPORT void JNICALL -Java_network_loki_messenger_libsession_1util_UserGroupsConfig_erase__Lnetwork_loki_messenger_libsession_1util_util_GroupInfo_LegacyGroupInfo_2( - JNIEnv *env, jobject thiz, jobject legacy_group_info) { - auto conf = ptrToUserGroups(env, thiz); - auto deserialized = deserialize_legacy_group_info(env, legacy_group_info, conf); - conf->erase(deserialized); + auto communityInfo = env->FindClass("network/loki/messenger/libsession_util/util/GroupInfo$CommunityGroupInfo"); + auto legacyInfo = env->FindClass("network/loki/messenger/libsession_util/util/GroupInfo$LegacyGroupInfo"); + if (env->GetObjectClass(group_info) == communityInfo) { + auto deserialized = deserialize_community_info(env, group_info, conf); + conf->erase(deserialized); + } else if (env->GetObjectClass(group_info) == legacyInfo) { + auto deserialized = deserialize_legacy_group_info(env, group_info, conf); + conf->erase(deserialized); + } } extern "C" diff --git a/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt b/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt index c3f92d1206..58dd20136d 100644 --- a/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt +++ b/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt @@ -1,6 +1,11 @@ package network.loki.messenger.libsession_util -import network.loki.messenger.libsession_util.util.* +import network.loki.messenger.libsession_util.util.BaseCommunityInfo +import network.loki.messenger.libsession_util.util.ConfigPush +import network.loki.messenger.libsession_util.util.Contact +import network.loki.messenger.libsession_util.util.Conversation +import network.loki.messenger.libsession_util.util.GroupInfo +import network.loki.messenger.libsession_util.util.UserPic import org.session.libsignal.protos.SignalServiceProtos.SharedConfigMessage.Kind @@ -152,10 +157,7 @@ class UserGroupsConfig(pointer: Long): ConfigBase(pointer) { external fun getOrConstructCommunityInfo(baseUrl: String, room: String, pubKeyHex: String): GroupInfo.CommunityGroupInfo external fun getOrConstructLegacyGroupInfo(sessionId: String): GroupInfo.LegacyGroupInfo external fun set(groupInfo: GroupInfo) - external fun set(communityInfo: GroupInfo.CommunityGroupInfo) - external fun set(legacyGroupInfo: GroupInfo.LegacyGroupInfo) - external fun erase(communityInfo: GroupInfo.CommunityGroupInfo) - external fun erase(legacyGroupInfo: GroupInfo.LegacyGroupInfo) + external fun erase(communityInfo: GroupInfo) external fun eraseCommunity(baseCommunityInfo: BaseCommunityInfo): Boolean external fun eraseLegacyGroup(sessionId: String): Boolean external fun sizeCommunityInfo(): Int diff --git a/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt b/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt index 2539547977..75f8b58718 100644 --- a/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt @@ -72,7 +72,7 @@ interface StorageProtocol { fun updateOpenGroup(openGroup: OpenGroup) fun getOpenGroup(threadId: Long): OpenGroup? fun addOpenGroup(urlAsString: String): OpenGroupApi.RoomInfo? - fun onOpenGroupAdded(server: String) + fun onOpenGroupAdded(server: String, room: String) fun hasBackgroundGroupAddJob(groupJoinUrl: String): Boolean fun setOpenGroupServerMessageID(messageID: Long, serverID: Long, threadID: Long, isSms: Boolean) fun getOpenGroup(room: String, server: String): OpenGroup? diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/BackgroundGroupAddJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/BackgroundGroupAddJob.kt index 8d08412042..10ba2458ba 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/BackgroundGroupAddJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/BackgroundGroupAddJob.kt @@ -45,7 +45,7 @@ class BackgroundGroupAddJob(val joinUrl: String): Job { JobQueue.shared.add(GroupAvatarDownloadJob(openGroup.server, openGroup.room, imageId)) } Log.d(KEY, "onOpenGroupAdded(${openGroup.server})") - storage.onOpenGroupAdded(openGroup.server) + storage.onOpenGroupAdded(openGroup.server, openGroup.room) } catch (e: Exception) { Log.e("OpenGroupDispatcher", "Failed to add group because",e) delegate?.handleJobFailed(this, dispatcherName, e) diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt index 680a583bec..286ea618b3 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt @@ -165,9 +165,9 @@ private fun handleConfigurationMessage(message: ConfigurationMessage) { .replace(OpenGroupApi.httpDefaultServer, OpenGroupApi.defaultServer) }) { if (allV2OpenGroups.contains(openGroup)) continue - Log.d("OpenGroup", "All open groups doesn't contain $openGroup") + Log.d("OpenGroup", "All open groups doesn't contain open group") if (!storage.hasBackgroundGroupAddJob(openGroup)) { - Log.d("OpenGroup", "Doesn't contain background job for $openGroup, adding") + Log.d("OpenGroup", "Doesn't contain background job for open group, adding") JobQueue.shared.add(BackgroundGroupAddJob(openGroup)) } } diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt index 21016f6640..09c3645721 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt @@ -136,9 +136,9 @@ class Poller(private val configFactory: ConfigFactoryProtocol, debounceTimer: Ti snode, userPublicKey, namespace, - updateLatestHash = false, - updateStoredHashes = false, - ).filter { (_, hash) -> !forConfigObject.currentHashes().contains(hash) } + updateLatestHash = true, + updateStoredHashes = true, + ) // TODO: might not be needed anymore .filter { (_, hash) -> !forConfigObject.currentHashes().contains(hash) } if (messages.isEmpty()) { // no new messages to process