]> nmode's Git Repositories - signal-cli/commitdiff
Fix storage sync issues
authorAsamK <asamk@gmx.de>
Sun, 28 Jan 2024 10:46:34 +0000 (11:46 +0100)
committerAsamK <asamk@gmx.de>
Sun, 28 Jan 2024 21:38:41 +0000 (22:38 +0100)
lib/src/main/java/org/asamk/signal/manager/helper/StorageHelper.java
lib/src/main/java/org/asamk/signal/manager/helper/SyncHelper.java
lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java
lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java
lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupStore.java
lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientStore.java
lib/src/main/java/org/asamk/signal/manager/syncStorage/ContactRecordProcessor.java
lib/src/main/java/org/asamk/signal/manager/syncStorage/DefaultStorageRecordProcessor.java

index 5bccfd05d7cacbb368ac77dc99c3a38562d51e2d..c18e8df323513aed5d05372b4336d23c3ca76fe8 100644 (file)
@@ -155,7 +155,7 @@ public class StorageHelper {
 
                 if (updated > 0) {
                     logger.warn(
-                            "Found {} records that were deleted remotely but only marked unregistered locally. Removed those from local store. Recalculating diff.",
+                            "Found {} records that were deleted remotely but only marked unregistered locally. Removed those from local store.",
                             updated);
                 }
             }
@@ -502,7 +502,7 @@ public class StorageHelper {
             final var remote = remoteByRawId.get(rawId);
             final var local = localByRawId.get(rawId);
 
-            if (remote.getType() != local.getType()) {
+            if (remote.getType() != local.getType() && local.getType() != 0) {
                 remoteOnlyRawIds.remove(rawId);
                 localOnlyRawIds.remove(rawId);
                 hasTypeMismatch = true;
index ac61104624aa7314d758cc89c953eea674dfed2e..de3a495aa3a336c246e911f235871e1a601161d1 100644 (file)
@@ -324,7 +324,12 @@ public class SyncHelper {
             final var recipientId = account.getRecipientTrustedResolver().resolveRecipientTrusted(c.getAddress());
             var contact = account.getContactStore().getContact(recipientId);
             final var builder = contact == null ? Contact.newBuilder() : Contact.newBuilder(contact);
-            if (c.getName().isPresent()) {
+            if (c.getName().isPresent() && (
+                    contact == null || (
+                            contact.givenName() == null
+                                    && contact.familyName() == null
+                    )
+            )) {
                 builder.withGivenName(c.getName().get());
                 builder.withFamilyName(null);
             }
index a2575e90dc0a60ca71fb3eff863ed87a94a1b2ac..75dcb138d44664b3e3d4d81d41d0d59edd07480e 100644 (file)
@@ -1355,8 +1355,8 @@ public class ManagerImpl implements Manager {
         if (thread != null) {
             stopReceiveThread(thread);
         }
-        executor.close();
         context.close();
+        executor.close();
 
         dependencies.getSignalWebSocket().disconnect();
         dependencies.getPushServiceSocket().close();
index 41c05b98d866cb5c617071a6002ec030e0de1572..fa5496d2e21681f4d9448948093f9b68dd2d9207 100644 (file)
@@ -362,7 +362,7 @@ public class SignalAccount implements Closeable {
     }
 
     private void init() {
-        this.selfRecipientId = getRecipientResolver().resolveRecipient(getSelfRecipientAddress());
+        this.selfRecipientId = getRecipientTrustedResolver().resolveSelfRecipientTrusted(getSelfRecipientAddress());
     }
 
     private void migrateLegacyConfigs() {
index e7cf57528657addada03faea06c515d9f761c997..5079da07f0f118f656262a21fb0c07f145c7007b 100644 (file)
@@ -122,13 +122,25 @@ public class GroupStore {
     public void storeStorageRecord(
             final Connection connection, final GroupId groupId, final StorageId storageId, final byte[] storageRecord
     ) throws SQLException {
+        final var groupTable = groupId instanceof GroupIdV1 ? TABLE_GROUP_V1 : TABLE_GROUP_V2;
+        final var deleteSql = (
+                """
+                UPDATE %s
+                SET storage_id = NULL
+                WHERE storage_id = ?
+                """
+        ).formatted(groupTable);
+        try (final var statement = connection.prepareStatement(deleteSql)) {
+            statement.setBytes(1, storageId.getRaw());
+            statement.executeUpdate();
+        }
         final var sql = (
                 """
                 UPDATE %s
                 SET storage_id = ?, storage_record = ?
                 WHERE group_id = ?
                 """
-        ).formatted(groupId instanceof GroupIdV1 ? TABLE_GROUP_V1 : TABLE_GROUP_V2);
+        ).formatted(groupTable);
         try (final var statement = connection.prepareStatement(sql)) {
             statement.setBytes(1, storageId.getRaw());
             if (storageRecord == null) {
index 46f8652c0bc64f6c10a35ffa6f65537be47e9069..285d5cf6c0d35423c1291fecf13bf6d1e309528e 100644 (file)
@@ -37,8 +37,6 @@ import java.util.Set;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
-import static org.asamk.signal.manager.config.ServiceConfig.UNREGISTERED_LIFESPAN;
-
 public class RecipientStore implements RecipientIdCreator, RecipientResolver, RecipientTrustedResolver, ContactsStore, ProfileStore {
 
     private static final Logger logger = LoggerFactory.getLogger(RecipientStore.class);
@@ -524,7 +522,7 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
                 """
                 SELECT r._id
                 FROM %s r
-                WHERE r.storage_id IS NULL AND (r.unregistered_timestamp IS NULL OR r.unregistered_timestamp > ?)
+                WHERE r.storage_id IS NULL AND r.unregistered_timestamp IS NULL
                 """
         ).formatted(TABLE_RECIPIENT);
         final var updateSql = (
@@ -537,7 +535,6 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
         try (final var connection = database.getConnection()) {
             connection.setAutoCommit(false);
             try (final var selectStmt = connection.prepareStatement(selectSql)) {
-                selectStmt.setLong(1, System.currentTimeMillis() - UNREGISTERED_LIFESPAN);
                 final var recipientIds = Utils.executeQueryForStream(selectStmt, this::getRecipientIdFromResultSet)
                         .toList();
                 try (final var updateStmt = connection.prepareStatement(updateSql)) {
@@ -735,14 +732,25 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
             final StorageId storageId,
             final byte[] storageRecord
     ) throws SQLException {
-        final var sql = (
+        final var deleteSql = (
+                """
+                UPDATE %s
+                SET storage_id = NULL
+                WHERE storage_id = ?
+                """
+        ).formatted(TABLE_RECIPIENT);
+        try (final var statement = connection.prepareStatement(deleteSql)) {
+            statement.setBytes(1, storageId.getRaw());
+            statement.executeUpdate();
+        }
+        final var insertSql = (
                 """
                 UPDATE %s
                 SET storage_id = ?, storage_record = ?
                 WHERE _id = ?
                 """
         ).formatted(TABLE_RECIPIENT);
-        try (final var statement = connection.prepareStatement(sql)) {
+        try (final var statement = connection.prepareStatement(insertSql)) {
             statement.setBytes(1, storageId.getRaw());
             if (storageRecord == null) {
                 statement.setNull(2, Types.BLOB);
@@ -846,7 +854,7 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
                 """
                 UPDATE %s
                 SET storage_id = NULL
-                WHERE storage_id = ? AND storage_id IS NOT NULL AND unregistered_timestamp IS NOT NULL
+                WHERE storage_id = ? AND unregistered_timestamp IS NOT NULL
                 """
         ).formatted(TABLE_RECIPIENT);
         var count = 0;
@@ -1002,6 +1010,7 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
         }
 
         if (!pair.second().isEmpty()) {
+            logger.debug("Resolved address {}, merging {} other recipients", address, pair.second().size());
             try (final var connection = database.getConnection()) {
                 connection.setAutoCommit(false);
                 mergeRecipients(connection, pair.first(), pair.second());
index 2e557e1a015e240f6b252d502f2eb14341fdc1ea..6114a0184561208388b6e1b068c93e185efcc361 100644 (file)
@@ -105,8 +105,12 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
 
         IdentityState identityState;
         byte[] identityKey;
-        if ((remote.getIdentityState() != local.getIdentityState() && remote.getIdentityKey().isPresent())
-                || (remote.getIdentityKey().isPresent() && local.getIdentityKey().isEmpty())) {
+        if (remote.getIdentityKey().isPresent() && (
+                remote.getIdentityState() != local.getIdentityState()
+                        || local.getIdentityKey().isEmpty()
+                        || !account.isPrimaryDevice()
+
+        )) {
             identityState = remote.getIdentityState();
             identityKey = remote.getIdentityKey().get();
         } else {
@@ -114,9 +118,10 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
             identityKey = local.getIdentityKey().orElse(null);
         }
 
-        if (local.getAci().isPresent() && identityKey != null && remote.getIdentityKey().isPresent() && !Arrays.equals(
-                identityKey,
-                remote.getIdentityKey().get())) {
+        if (local.getAci().isPresent()
+                && local.getIdentityKey().isPresent()
+                && remote.getIdentityKey().isPresent()
+                && !Arrays.equals(local.getIdentityKey().get(), remote.getIdentityKey().get())) {
             logger.debug("The local and remote identity keys do not match for {}. Enqueueing a profile fetch.",
                     local.getAci().orElse(null));
             final var address = getRecipientAddress(local);
@@ -141,13 +146,12 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
 
         PNI pni;
         String e164;
-        if (e164sMatchButPnisDont) {
-            logger.debug("Matching E164s, but the PNIs differ! Trusting our local pair.");
-            // TODO [pnp] Schedule CDS fetch?
-            pni = local.getPni().get();
-            e164 = local.getNumber().get();
-        } else if (pnisMatchButE164sDont) {
-            logger.debug("Matching PNIs, but the E164s differ! Trusting our local pair.");
+        if (!account.isPrimaryDevice() && (e164sMatchButPnisDont || pnisMatchButE164sDont)) {
+            if (e164sMatchButPnisDont) {
+                logger.debug("Matching E164s, but the PNIs differ! Trusting our local pair.");
+            } else if (pnisMatchButE164sDont) {
+                logger.debug("Matching PNIs, but the E164s differ! Trusting our local pair.");
+            }
             // TODO [pnp] Schedule CDS fetch?
             pni = local.getPni().get();
             e164 = local.getNumber().get();
@@ -235,41 +239,25 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
                 || profileShared != contactRecord.isProfileSharingEnabled()
                 || archived != contactRecord.isArchived()
                 || hidden != contactRecord.isHidden()
-                || (
-                contactRecord.getSystemGivenName().isPresent() && !contactRecord.getSystemGivenName()
-                        .get()
-                        .equals(contactGivenName)
-        )
-                || (
-                contactRecord.getSystemFamilyName().isPresent() && !contactRecord.getSystemFamilyName()
-                        .get()
-                        .equals(contactFamilyName)
-        )) {
+                || !Objects.equals(contactRecord.getSystemGivenName().orElse(null), contactGivenName)
+                || !Objects.equals(contactRecord.getSystemFamilyName().orElse(null), contactFamilyName)) {
             logger.debug("Storing new or updated contact {}", recipientId);
             final var contactBuilder = contact == null ? Contact.newBuilder() : Contact.newBuilder(contact);
             final var newContact = contactBuilder.withIsBlocked(contactRecord.isBlocked())
                     .withIsProfileSharingEnabled(contactRecord.isProfileSharingEnabled())
                     .withIsArchived(contactRecord.isArchived())
-                    .withIsHidden(contactRecord.isHidden());
-            if (contactRecord.getSystemGivenName().isPresent() || contactRecord.getSystemFamilyName().isPresent()) {
-                newContact.withGivenName(contactRecord.getSystemGivenName().orElse(null))
-                        .withFamilyName(contactRecord.getSystemFamilyName().orElse(null));
-            }
+                    .withIsHidden(contactRecord.isHidden())
+                    .withGivenName(contactRecord.getSystemGivenName().orElse(null))
+                    .withFamilyName(contactRecord.getSystemFamilyName().orElse(null));
             account.getRecipientStore().storeContact(connection, recipientId, newContact.build());
         }
 
         final var profile = recipient.getProfile();
         final var profileGivenName = profile == null ? null : profile.getGivenName();
         final var profileFamilyName = profile == null ? null : profile.getFamilyName();
-        if ((
-                contactRecord.getProfileGivenName().isPresent() && !contactRecord.getProfileGivenName()
-                        .get()
-                        .equals(profileGivenName)
-        ) || (
-                contactRecord.getProfileFamilyName().isPresent() && !contactRecord.getProfileFamilyName()
-                        .get()
-                        .equals(profileFamilyName)
-        )) {
+        if (!Objects.equals(contactRecord.getProfileGivenName().orElse(null), profileGivenName) || !Objects.equals(
+                contactRecord.getProfileFamilyName().orElse(null),
+                profileFamilyName)) {
             final var profileBuilder = profile == null ? Profile.newBuilder() : Profile.newBuilder(profile);
             final var newProfile = profileBuilder.withGivenName(contactRecord.getProfileGivenName().orElse(null))
                     .withFamilyName(contactRecord.getProfileFamilyName().orElse(null))
@@ -285,7 +273,7 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
                 logger.warn("Received invalid contact profile key from storage");
             }
         }
-        if (contactRecord.getIdentityKey().isPresent() && contactRecord.getAci().orElse(null) != null) {
+        if (contactRecord.getIdentityKey().isPresent() && contactRecord.getAci().isPresent()) {
             try {
                 logger.trace("Storing identity key {}", recipientId);
                 final var identityKey = new IdentityKey(contactRecord.getIdentityKey().get());
index 2b6334e08d0062513c9d5bc87794d884e93a999c..68b5f9cc599438d6f3d4b88bfe20bd07d1f07897 100644 (file)
@@ -55,7 +55,9 @@ abstract class DefaultStorageRecordProcessor<E extends SignalRecord> implements
         }
 
         if (matchedRecords.contains(local.get())) {
-            debug(remote.getId(), remote, "Multiple remote records map to the same local record! Ignoring this one.");
+            debug(remote.getId(),
+                    remote,
+                    "Multiple remote records map to the same local record " + local.get() + "! Ignoring this one.");
             return;
         }