From 3bebb3ef7fe6eea7194d7c283029e84175ad66ff Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Wed, 29 Jan 2025 10:29:59 +1100 Subject: [PATCH 1/3] feat: add correct url for group v1 banner deprecated --- ts/components/conversation/SessionConversation.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/components/conversation/SessionConversation.tsx b/ts/components/conversation/SessionConversation.tsx index b57541844..061319bb1 100644 --- a/ts/components/conversation/SessionConversation.tsx +++ b/ts/components/conversation/SessionConversation.tsx @@ -667,7 +667,7 @@ function OutdatedLegacyGroupBanner(props: { { - showLinkVisitWarningDialog('https://getsession.org/blog/session-groups-v2', dispatch); + showLinkVisitWarningDialog('https://getsession.org/groups', dispatch); }} icon="externalLink" dataTestId="legacy-group-banner" From 2e6f09cbec3d881402d8c7d2932a62691de95fb9 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Wed, 29 Jan 2025 10:33:51 +1100 Subject: [PATCH 2/3] fix: deleteMemberContent is optional --- .../group_v2/to_group/GroupUpdateDeleteMemberContentMessage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/session/messages/outgoing/controlMessage/group_v2/to_group/GroupUpdateDeleteMemberContentMessage.ts b/ts/session/messages/outgoing/controlMessage/group_v2/to_group/GroupUpdateDeleteMemberContentMessage.ts index 91ac70306..daf0a4d63 100644 --- a/ts/session/messages/outgoing/controlMessage/group_v2/to_group/GroupUpdateDeleteMemberContentMessage.ts +++ b/ts/session/messages/outgoing/controlMessage/group_v2/to_group/GroupUpdateDeleteMemberContentMessage.ts @@ -54,7 +54,7 @@ export class GroupUpdateDeleteMemberContentMessage extends GroupUpdateMessage { public dataProto(): SignalService.DataMessage { // If we have the secretKey, we can delete it for anyone `"DELETE_CONTENT" || timestamp || sessionId[0] || ... || messageHashes[0] || ...` - let adminSignature = new Uint8Array(); + let adminSignature: Uint8Array | undefined; if (this.secretKey && !_.isEmpty(this.secretKey) && this.sodium) { adminSignature = this.sodium.crypto_sign_detached( stringToUint8Array( From 91a71f0604024c1da70777291ac081fc2ab63f29 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Wed, 29 Jan 2025 14:18:53 +1100 Subject: [PATCH 3/3] fix: ignore errors on dump/confirmPush for groups to avoid race cond --- .../utils/job_runners/jobs/GroupSyncJob.ts | 16 ++++++-- .../utils/libsession/libsession_utils.ts | 41 ++++++++++++------- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/ts/session/utils/job_runners/jobs/GroupSyncJob.ts b/ts/session/utils/job_runners/jobs/GroupSyncJob.ts index cc393efc0..cdaa19452 100644 --- a/ts/session/utils/job_runners/jobs/GroupSyncJob.ts +++ b/ts/session/utils/job_runners/jobs/GroupSyncJob.ts @@ -79,9 +79,19 @@ async function confirmPushedAndDump( assertUnreachable(namespace, 'buildAndSaveDumpsToDB assertUnreachable'); } } - - await MetaGroupWrapperActions.metaConfirmPushed(...toConfirm); - return LibSessionUtil.saveDumpsToDb(groupPk); + try { + await MetaGroupWrapperActions.metaConfirmPushed(...toConfirm); + await LibSessionUtil.saveDumpsToDb(groupPk); + } catch (e) { + // The reason we catch exception here is because sometimes we can have a race condition where + // - we push a change to the group (req1 takes 10s) + // - while req1 is running, a poll merge results with the group marked as destroyed + // - this means we have free the wrapper + // - then, req finishes, and tries to metaConfirmPushed/saveDumpsToDb which fails as the wrapper was freed. + window.log.warn( + `metaConfirmPushed/saveDumpsToDb for group ${ed25519Str(groupPk)} failed with ${e.message}. This can safely be ignored` // I hope + ); + } } async function pushChangesToGroupSwarmIfNeeded({ diff --git a/ts/session/utils/libsession/libsession_utils.ts b/ts/session/utils/libsession/libsession_utils.ts index 423f34501..d9c8cbe8e 100644 --- a/ts/session/utils/libsession/libsession_utils.ts +++ b/ts/session/utils/libsession/libsession_utils.ts @@ -345,21 +345,32 @@ function batchResultsToUserSuccessfulChange( async function saveDumpsToDb(pubkey: PubkeyType | GroupPubkeyType) { // first check if this is relating a group if (PubKey.is03Pubkey(pubkey)) { - const metaNeedsDump = await MetaGroupWrapperActions.needsDump(pubkey); - // save the concatenated dumps as a single entry in the DB if any of the dumps had a need for dump - if (metaNeedsDump) { - window.log.debug(`About to make and save dumps for metagroup ${ed25519Str(pubkey)}`); - - const dump = await MetaGroupWrapperActions.metaDump(pubkey); - await ConfigDumpData.saveConfigDump({ - data: dump, - publicKey: pubkey, - variant: `MetaGroupConfig-${pubkey}`, - }); - - window.log.info(`Saved dumps for metagroup ${ed25519Str(pubkey)}`); - } else { - window.log.debug(`No need to update local dumps for metagroup ${ed25519Str(pubkey)}`); + try { + const metaNeedsDump = await MetaGroupWrapperActions.needsDump(pubkey); + // save the concatenated dumps as a single entry in the DB if any of the dumps had a need for dump + if (metaNeedsDump) { + window.log.debug(`About to make and save dumps for metagroup ${ed25519Str(pubkey)}`); + + const dump = await MetaGroupWrapperActions.metaDump(pubkey); + await ConfigDumpData.saveConfigDump({ + data: dump, + publicKey: pubkey, + variant: `MetaGroupConfig-${pubkey}`, + }); + + window.log.info(`Saved dumps for metagroup ${ed25519Str(pubkey)}`); + } else { + window.log.debug(`No need to update local dumps for metagroup ${ed25519Str(pubkey)}`); + } + } catch (e) { + // The reason we catch exception here is because sometimes we can have a race condition where + // - we push a change to the group (req1 takes 10s) + // - while req1 is running, a poll merge results with the group marked as destroyed + // - this means we have to free the wrapper + // - then, req finishes, and tries to saveDumpsToDb which fails as the wrapper was freed. + window.log.warn( + `saveDumpsToDb for group ${ed25519Str(pubkey)} failed with ${e.message}. This can safely be ignored` // I hope + ); } return; }