From aaacfabc1b33c8ea95c0cd6d232abb3767dc77a0 Mon Sep 17 00:00:00 2001 From: MeiMei <30769358+mei23@users.noreply.github.com> Date: Wed, 28 Feb 2024 16:44:01 +0900 Subject: [PATCH] perf(federation): Use hint for getAuthUserFromApId (#13470) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Hint for getAuthUserFromApId * とどのつまりこれでいいのか? --- .../core/activitypub/ApDbResolverService.ts | 41 +------------------ .../queue/processors/InboxProcessorService.ts | 32 +++++---------- 2 files changed, 13 insertions(+), 60 deletions(-) diff --git a/packages/backend/src/core/activitypub/ApDbResolverService.ts b/packages/backend/src/core/activitypub/ApDbResolverService.ts index 904c89b990..4013eaddc0 100644 --- a/packages/backend/src/core/activitypub/ApDbResolverService.ts +++ b/packages/backend/src/core/activitypub/ApDbResolverService.ts @@ -35,7 +35,6 @@ export type UriParseResult = { @Injectable() export class ApDbResolverService implements OnApplicationShutdown { - private publicKeyCache: MemoryKVCache; private publicKeyByUserIdCache: MemoryKVCache; constructor( @@ -54,7 +53,6 @@ export class ApDbResolverService implements OnApplicationShutdown { private cacheService: CacheService, private apPersonService: ApPersonService, ) { - this.publicKeyCache = new MemoryKVCache(1e3 * 60 * 20); // 20分 this.publicKeyByUserIdCache = new MemoryKVCache(1e3 * 60 * 20); // 20分 } @@ -116,41 +114,11 @@ export class ApDbResolverService implements OnApplicationShutdown { } } - /** - * AP KeyId => Misskey User and Key - */ - @bindThis - public async getAuthUserFromKeyId(keyId: string): Promise<{ - user: MiRemoteUser; - key: MiUserPublickey; - } | null> { - const key = await this.publicKeyCache.fetch(keyId, async () => { - const key = await this.userPublickeysRepository.findOneBy({ - keyId, - }); - - if (key == null) return null; - - return key; - }, key => key != null); - - if (key == null) return null; - - const user = await this.cacheService.findUserById(key.userId).catch(() => null) as MiRemoteUser | null; - if (user == null) return null; - if (user.isDeleted) return null; - - return { - user, - key, - }; - } - /** * AP Actor id => Misskey User and Key */ @bindThis - public async getAuthUserFromApId(uri: string): Promise<{ + public async getAuthUserFromApId(uri: string, keyId?: string): Promise<{ user: MiRemoteUser; key: MiUserPublickey | null; } | null> { @@ -170,6 +138,7 @@ export class ApDbResolverService implements OnApplicationShutdown { keys[0] : keys.find(x => { try { + if (x.keyId === keyId) return true; const url = new URL(x.keyId); const path = url.pathname.split('/').pop()?.toLowerCase(); if (url.hash) { @@ -193,16 +162,10 @@ export class ApDbResolverService implements OnApplicationShutdown { @bindThis public refreshCacheByUserId(userId: MiUser['id']): void { this.publicKeyByUserIdCache.delete(userId); - for (const [k, v] of this.publicKeyCache.cache.entries()) { - if (v.value?.userId === userId) { - this.publicKeyCache.delete(k); - } - } } @bindThis public dispose(): void { - this.publicKeyCache.dispose(); this.publicKeyByUserIdCache.dispose(); } diff --git a/packages/backend/src/queue/processors/InboxProcessorService.ts b/packages/backend/src/queue/processors/InboxProcessorService.ts index bc593147bb..ac7f8e6cd9 100644 --- a/packages/backend/src/queue/processors/InboxProcessorService.ts +++ b/packages/backend/src/queue/processors/InboxProcessorService.ts @@ -77,20 +77,18 @@ export class InboxProcessorService { let authUser: { user: MiRemoteUser; key: MiUserPublickey | null; - } | null = await this.apDbResolverService.getAuthUserFromKeyId(signature.keyId); + } | null = null; // keyIdでわからなければ、activity.actorを元にDBから取得 || activity.actorを元にリモートから取得 - if (authUser == null) { - try { - authUser = await this.apDbResolverService.getAuthUserFromApId(getApId(activity.actor)); - } catch (err) { - // 対象が4xxならスキップ - if (err instanceof StatusError) { - if (!err.isRetryable) { - throw new Bull.UnrecoverableError(`skip: Ignored deleted actors on both ends ${activity.actor} - ${err.statusCode}`); - } - throw new Error(`Error in actor ${activity.actor} - ${err.statusCode}`); + try { + authUser = await this.apDbResolverService.getAuthUserFromApId(getApId(activity.actor), signature.keyId); + } catch (err) { + // 対象が4xxならスキップ + if (err instanceof StatusError) { + if (!err.isRetryable) { + throw new Bull.UnrecoverableError(`skip: Ignored deleted actors on both ends ${activity.actor} - ${err.statusCode}`); } + throw new Error(`Error in actor ${activity.actor} - ${err.statusCode}`); } } @@ -110,21 +108,13 @@ export class InboxProcessorService { // また、signatureのsignerは、activity.actorと一致する必要がある if (!httpSignatureValidated || authUser.user.uri !== activity.actor) { // 一致しなくても、でもLD-Signatureがありそうならそっちも見る - if (activity.signature) { + if (activity.signature?.creator) { if (activity.signature.type !== 'RsaSignature2017') { throw new Bull.UnrecoverableError(`skip: unsupported LD-signature type ${activity.signature.type}`); } - // activity.signature.creator: https://example.oom/users/user#main-key - // みたいになっててUserを引っ張れば公開キーも入ることを期待する - if (activity.signature.creator) { - const candicate = activity.signature.creator.replace(/#.*/, ''); - const user = await this.apPersonService.resolvePerson(candicate).catch(() => null); - if (user) this.apDbResolverService.refreshCacheByUserId(user.id); - } + authUser = await this.apDbResolverService.getAuthUserFromApId(activity.signature.creator.replace(/#.*/, '')); - // keyIdからLD-Signatureのユーザーを取得 - authUser = await this.apDbResolverService.getAuthUserFromKeyId(activity.signature.creator); if (authUser == null) { throw new Bull.UnrecoverableError('skip: LD-Signatureのユーザーが取得できませんでした'); }