From 3dfc29de3d8c297cabf1c244acd05ec1f684234d Mon Sep 17 00:00:00 2001 From: Sanjay Date: Thu, 13 Jul 2023 17:39:08 -0700 Subject: [PATCH] fix: Throw error if unable to fetch fname server signature (#1120) --- .changeset/four-beds-prove.md | 5 ++++ .../eth/fnameRegistryEventsProvider.test.ts | 5 ++++ .../src/eth/fnameRegistryEventsProvider.ts | 30 ++++++++++++++----- 3 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 .changeset/four-beds-prove.md diff --git a/.changeset/four-beds-prove.md b/.changeset/four-beds-prove.md new file mode 100644 index 0000000000..e358f2314b --- /dev/null +++ b/.changeset/four-beds-prove.md @@ -0,0 +1,5 @@ +--- +"@farcaster/hubble": patch +--- + +fix: throw error if unable to fetch fname server signature diff --git a/apps/hubble/src/eth/fnameRegistryEventsProvider.test.ts b/apps/hubble/src/eth/fnameRegistryEventsProvider.test.ts index 177899e95c..83db013072 100644 --- a/apps/hubble/src/eth/fnameRegistryEventsProvider.test.ts +++ b/apps/hubble/src/eth/fnameRegistryEventsProvider.test.ts @@ -208,4 +208,9 @@ describe("fnameRegistryEventsProvider", () => { expect(await getUserNameProof(db, utf8ToBytes("farcaster"))).toBeTruthy(); }); }); + + test("throws for invalid signer", async () => { + mockFnameRegistryClient.setSignerAddress("0x"); + await expect(provider.start()).rejects.toThrowError("Failed to parse server address"); + }); }); diff --git a/apps/hubble/src/eth/fnameRegistryEventsProvider.ts b/apps/hubble/src/eth/fnameRegistryEventsProvider.ts index f79578ef3a..86e97187a5 100644 --- a/apps/hubble/src/eth/fnameRegistryEventsProvider.ts +++ b/apps/hubble/src/eth/fnameRegistryEventsProvider.ts @@ -8,6 +8,7 @@ import { UserNameType, utf8StringToBytes, makeUserNameProofClaim, + HubError, } from "@farcaster/hub-nodejs"; import { Result } from "neverthrow"; @@ -61,6 +62,7 @@ export class FNameRegistryEventsProvider { private resyncEvents: boolean; private pollTimeoutId: ReturnType | undefined; private serverSignerAddress: Uint8Array; + private shouldStop = false; constructor(fnameRegistryClient: FNameRegistryClientInterface, hub: HubInterface, resyncEvents = false) { this.client = fnameRegistryClient; @@ -83,14 +85,18 @@ export class FNameRegistryEventsProvider { } const rawAddress = await this.client.getSigner(); const signerAddress = hexStringToBytes(rawAddress); - if (signerAddress.isOk()) { + if (signerAddress.isOk() && signerAddress.value.length > 0) { this.serverSignerAddress = signerAddress.value; + } else { + log.error(`Failed to parse server address: ${signerAddress}`); + throw new HubError("bad_request.invalid_param", `Failed to parse server address: ${signerAddress}`); } log.info(`Starting fname events provider from ${this.lastTransferId} using signer: ${rawAddress}`); return this.pollForNewEvents(); } public async stop() { + this.shouldStop = true; if (this.pollTimeoutId) { clearTimeout(this.pollTimeoutId); } @@ -102,10 +108,15 @@ export class FNameRegistryEventsProvider { } private async fetchAndMergeTransfers(fromId: number) { + if (this.serverSignerAddress.length === 0) { + log.warn("No signer address, unable to merge name proofs"); + return; + } + this.lastTransferId = fromId; let transfers = await this.safeGetTransfers(fromId); let transfersCount = 0; - while (transfers.length > 0) { + while (transfers.length > 0 && !this.shouldStop) { transfersCount += transfers.length; await this.mergeTransfers(transfers); const lastTransfer = transfers[transfers.length - 1]; @@ -135,11 +146,6 @@ export class FNameRegistryEventsProvider { } private async mergeTransfers(transfers: FNameTransfer[]) { - if (this.serverSignerAddress.length === 0) { - log.warn("No signer address, unable to merge name proofs"); - return; - } - for (const transfer of transfers) { const serialized = Result.combine([ utf8StringToBytes(transfer.username), @@ -172,7 +178,15 @@ export class FNameRegistryEventsProvider { if (verificationResult.isOk() && verificationResult.value) { await this.hub.submitUserNameProof(usernameProof, "fname-registry"); } else { - log.warn(`Failed to verify username proof for ${transfer.username} id: ${transfer.id}`); + const context: Record = { signature: serverSignature.toString() }; + if (verificationResult.isErr()) { + context["errCode"] = verificationResult.error.errCode; + context["errMsg"] = verificationResult.error.message; + } + log.warn( + context, + `Failed to verify username proof for ${transfer.username} for fid ${transfer.to} id: ${transfer.id} with address: ${this.serverSignerAddress}`, + ); } } }