From f4fd19dc9282755f7d358dd3869dd89e5e02d187 Mon Sep 17 00:00:00 2001 From: Aditi Srinivasan Date: Tue, 18 Jun 2024 22:14:49 -0400 Subject: [PATCH] feat: add lastSyncTimestamp to GetInfo rpc endpoint --- .changeset/five-students-crash.md | 7 +++++++ apps/hubble/src/network/sync/syncEngine.ts | 9 +++++++++ apps/hubble/src/rpc/server.ts | 1 + apps/hubble/src/rpc/test/syncService.test.ts | 2 ++ apps/hubble/www/docs/docs/api.md | 1 + packages/core/src/protobufs/generated/message.ts | 2 +- .../src/protobufs/generated/request_response.ts | 15 +++++++++++++++ packages/hub-nodejs/src/generated/message.ts | 2 +- .../hub-nodejs/src/generated/request_response.ts | 15 +++++++++++++++ packages/hub-web/src/generated/message.ts | 2 +- .../hub-web/src/generated/request_response.ts | 15 +++++++++++++++ protobufs/schemas/request_response.proto | 1 + 12 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 .changeset/five-students-crash.md diff --git a/.changeset/five-students-crash.md b/.changeset/five-students-crash.md new file mode 100644 index 0000000000..af72ab352d --- /dev/null +++ b/.changeset/five-students-crash.md @@ -0,0 +1,7 @@ +--- +"@farcaster/hub-nodejs": minor +"@farcaster/hub-web": minor +"@farcaster/hubble": minor +--- + +feat: added lastSyncTimestamp to GetInfo rpc diff --git a/apps/hubble/src/network/sync/syncEngine.ts b/apps/hubble/src/network/sync/syncEngine.ts index e309d0c25d..565a3b795f 100644 --- a/apps/hubble/src/network/sync/syncEngine.ts +++ b/apps/hubble/src/network/sync/syncEngine.ts @@ -263,6 +263,9 @@ class SyncEngine extends TypedEmitter { // Has the syncengine started yet? private _started = false; + // Time of last successful sync + private _lastSyncTimestamp?: number; + private _dbStats: DbStats = { approxSize: 0, numItems: 0, @@ -511,6 +514,10 @@ class SyncEngine extends TypedEmitter { log.info("Sync engine stopped"); } + public getLastSyncTimestamp(): number | undefined { + return this._lastSyncTimestamp; + } + public getBadPeerIds(): string[] { return this._peerScorer.getBadPeerIds(); } @@ -907,6 +914,8 @@ class SyncEngine extends TypedEmitter { await auditPeerPromise; // Wait for audit to complete + this._lastSyncTimestamp = Date.now(); + log.info({ syncResult: this.curSync.fullResult }, "Perform sync: Sync Complete"); statsd().timing("syncengine.sync_time_ms", Date.now() - startTimestamp); } catch (e) { diff --git a/apps/hubble/src/rpc/server.ts b/apps/hubble/src/rpc/server.ts index f2e9743a69..06f5734022 100644 --- a/apps/hubble/src/rpc/server.ts +++ b/apps/hubble/src/rpc/server.ts @@ -462,6 +462,7 @@ export default class Server { (e) => e, )().unwrapOr(""), hubOperatorFid: this.hub?.hubOperatorFid ?? 0, + lastSyncTimestamp: this.syncEngine?.getLastSyncTimestamp() ?? 0, }); if (call.request.dbStats && this.syncEngine) { diff --git a/apps/hubble/src/rpc/test/syncService.test.ts b/apps/hubble/src/rpc/test/syncService.test.ts index 4cb97d5065..42c088af2b 100644 --- a/apps/hubble/src/rpc/test/syncService.test.ts +++ b/apps/hubble/src/rpc/test/syncService.test.ts @@ -75,6 +75,7 @@ describe("getInfo", () => { await engine.mergeOnChainEvent(storageEvent); await engine.mergeMessage(castAdd); await engine.mergeMessage(castAdd2); + await syncEngine.performSync("test", client); await sleepWhile(() => syncEngine.syncTrieQSize > 0, SLEEPWHILE_TIMEOUT); @@ -84,6 +85,7 @@ describe("getInfo", () => { expect(result._unsafeUnwrap().dbStats?.numFidEvents).toEqual(1); expect(result._unsafeUnwrap().dbStats?.numFnameEvents).toEqual(0); expect(result._unsafeUnwrap().dbStats?.approxSize).toBeGreaterThan(0); + expect(result._unsafeUnwrap().lastSyncTimestamp).toBeGreaterThan(0); }); }); diff --git a/apps/hubble/www/docs/docs/api.md b/apps/hubble/www/docs/docs/api.md index 62590360ea..57dde255aa 100644 --- a/apps/hubble/www/docs/docs/api.md +++ b/apps/hubble/www/docs/docs/api.md @@ -340,6 +340,7 @@ Response Types for the Sync RPC Methods | nickname | [string](#string) | | | | root_hash | [string](#string) | | | | db_stats | [DbStats](#DbStats) | | | +| last_sync_timestamp | [uint64]([#uint64]) | | | ### SyncStatusRequest diff --git a/packages/core/src/protobufs/generated/message.ts b/packages/core/src/protobufs/generated/message.ts index dd051df245..3bc697599b 100644 --- a/packages/core/src/protobufs/generated/message.ts +++ b/packages/core/src/protobufs/generated/message.ts @@ -288,7 +288,7 @@ export function userDataTypeToJSON(object: UserDataType): string { } } -/** Type of Protocol to disambiguate verification addresses */ +/** Type of cast */ export enum CastType { CAST = 0, LONG_CAST = 1, diff --git a/packages/core/src/protobufs/generated/request_response.ts b/packages/core/src/protobufs/generated/request_response.ts index 2aabe3cf58..3dc9949314 100644 --- a/packages/core/src/protobufs/generated/request_response.ts +++ b/packages/core/src/protobufs/generated/request_response.ts @@ -102,6 +102,7 @@ export interface HubInfoResponse { dbStats: DbStats | undefined; peerId: string; hubOperatorFid: number; + lastSyncTimestamp: number; } export interface DbStats { @@ -580,6 +581,7 @@ function createBaseHubInfoResponse(): HubInfoResponse { dbStats: undefined, peerId: "", hubOperatorFid: 0, + lastSyncTimestamp: 0, }; } @@ -606,6 +608,9 @@ export const HubInfoResponse = { if (message.hubOperatorFid !== 0) { writer.uint32(56).uint64(message.hubOperatorFid); } + if (message.lastSyncTimestamp !== 0) { + writer.uint32(64).uint64(message.lastSyncTimestamp); + } return writer; }, @@ -665,6 +670,13 @@ export const HubInfoResponse = { message.hubOperatorFid = longToNumber(reader.uint64() as Long); continue; + case 8: + if (tag != 64) { + break; + } + + message.lastSyncTimestamp = longToNumber(reader.uint64() as Long); + continue; } if ((tag & 7) == 4 || tag == 0) { break; @@ -683,6 +695,7 @@ export const HubInfoResponse = { dbStats: isSet(object.dbStats) ? DbStats.fromJSON(object.dbStats) : undefined, peerId: isSet(object.peerId) ? String(object.peerId) : "", hubOperatorFid: isSet(object.hubOperatorFid) ? Number(object.hubOperatorFid) : 0, + lastSyncTimestamp: isSet(object.lastSyncTimestamp) ? Number(object.lastSyncTimestamp) : 0, }; }, @@ -695,6 +708,7 @@ export const HubInfoResponse = { message.dbStats !== undefined && (obj.dbStats = message.dbStats ? DbStats.toJSON(message.dbStats) : undefined); message.peerId !== undefined && (obj.peerId = message.peerId); message.hubOperatorFid !== undefined && (obj.hubOperatorFid = Math.round(message.hubOperatorFid)); + message.lastSyncTimestamp !== undefined && (obj.lastSyncTimestamp = Math.round(message.lastSyncTimestamp)); return obj; }, @@ -713,6 +727,7 @@ export const HubInfoResponse = { : undefined; message.peerId = object.peerId ?? ""; message.hubOperatorFid = object.hubOperatorFid ?? 0; + message.lastSyncTimestamp = object.lastSyncTimestamp ?? 0; return message; }, }; diff --git a/packages/hub-nodejs/src/generated/message.ts b/packages/hub-nodejs/src/generated/message.ts index dd051df245..3bc697599b 100644 --- a/packages/hub-nodejs/src/generated/message.ts +++ b/packages/hub-nodejs/src/generated/message.ts @@ -288,7 +288,7 @@ export function userDataTypeToJSON(object: UserDataType): string { } } -/** Type of Protocol to disambiguate verification addresses */ +/** Type of cast */ export enum CastType { CAST = 0, LONG_CAST = 1, diff --git a/packages/hub-nodejs/src/generated/request_response.ts b/packages/hub-nodejs/src/generated/request_response.ts index 2aabe3cf58..3dc9949314 100644 --- a/packages/hub-nodejs/src/generated/request_response.ts +++ b/packages/hub-nodejs/src/generated/request_response.ts @@ -102,6 +102,7 @@ export interface HubInfoResponse { dbStats: DbStats | undefined; peerId: string; hubOperatorFid: number; + lastSyncTimestamp: number; } export interface DbStats { @@ -580,6 +581,7 @@ function createBaseHubInfoResponse(): HubInfoResponse { dbStats: undefined, peerId: "", hubOperatorFid: 0, + lastSyncTimestamp: 0, }; } @@ -606,6 +608,9 @@ export const HubInfoResponse = { if (message.hubOperatorFid !== 0) { writer.uint32(56).uint64(message.hubOperatorFid); } + if (message.lastSyncTimestamp !== 0) { + writer.uint32(64).uint64(message.lastSyncTimestamp); + } return writer; }, @@ -665,6 +670,13 @@ export const HubInfoResponse = { message.hubOperatorFid = longToNumber(reader.uint64() as Long); continue; + case 8: + if (tag != 64) { + break; + } + + message.lastSyncTimestamp = longToNumber(reader.uint64() as Long); + continue; } if ((tag & 7) == 4 || tag == 0) { break; @@ -683,6 +695,7 @@ export const HubInfoResponse = { dbStats: isSet(object.dbStats) ? DbStats.fromJSON(object.dbStats) : undefined, peerId: isSet(object.peerId) ? String(object.peerId) : "", hubOperatorFid: isSet(object.hubOperatorFid) ? Number(object.hubOperatorFid) : 0, + lastSyncTimestamp: isSet(object.lastSyncTimestamp) ? Number(object.lastSyncTimestamp) : 0, }; }, @@ -695,6 +708,7 @@ export const HubInfoResponse = { message.dbStats !== undefined && (obj.dbStats = message.dbStats ? DbStats.toJSON(message.dbStats) : undefined); message.peerId !== undefined && (obj.peerId = message.peerId); message.hubOperatorFid !== undefined && (obj.hubOperatorFid = Math.round(message.hubOperatorFid)); + message.lastSyncTimestamp !== undefined && (obj.lastSyncTimestamp = Math.round(message.lastSyncTimestamp)); return obj; }, @@ -713,6 +727,7 @@ export const HubInfoResponse = { : undefined; message.peerId = object.peerId ?? ""; message.hubOperatorFid = object.hubOperatorFid ?? 0; + message.lastSyncTimestamp = object.lastSyncTimestamp ?? 0; return message; }, }; diff --git a/packages/hub-web/src/generated/message.ts b/packages/hub-web/src/generated/message.ts index dd051df245..3bc697599b 100644 --- a/packages/hub-web/src/generated/message.ts +++ b/packages/hub-web/src/generated/message.ts @@ -288,7 +288,7 @@ export function userDataTypeToJSON(object: UserDataType): string { } } -/** Type of Protocol to disambiguate verification addresses */ +/** Type of cast */ export enum CastType { CAST = 0, LONG_CAST = 1, diff --git a/packages/hub-web/src/generated/request_response.ts b/packages/hub-web/src/generated/request_response.ts index 2aabe3cf58..3dc9949314 100644 --- a/packages/hub-web/src/generated/request_response.ts +++ b/packages/hub-web/src/generated/request_response.ts @@ -102,6 +102,7 @@ export interface HubInfoResponse { dbStats: DbStats | undefined; peerId: string; hubOperatorFid: number; + lastSyncTimestamp: number; } export interface DbStats { @@ -580,6 +581,7 @@ function createBaseHubInfoResponse(): HubInfoResponse { dbStats: undefined, peerId: "", hubOperatorFid: 0, + lastSyncTimestamp: 0, }; } @@ -606,6 +608,9 @@ export const HubInfoResponse = { if (message.hubOperatorFid !== 0) { writer.uint32(56).uint64(message.hubOperatorFid); } + if (message.lastSyncTimestamp !== 0) { + writer.uint32(64).uint64(message.lastSyncTimestamp); + } return writer; }, @@ -665,6 +670,13 @@ export const HubInfoResponse = { message.hubOperatorFid = longToNumber(reader.uint64() as Long); continue; + case 8: + if (tag != 64) { + break; + } + + message.lastSyncTimestamp = longToNumber(reader.uint64() as Long); + continue; } if ((tag & 7) == 4 || tag == 0) { break; @@ -683,6 +695,7 @@ export const HubInfoResponse = { dbStats: isSet(object.dbStats) ? DbStats.fromJSON(object.dbStats) : undefined, peerId: isSet(object.peerId) ? String(object.peerId) : "", hubOperatorFid: isSet(object.hubOperatorFid) ? Number(object.hubOperatorFid) : 0, + lastSyncTimestamp: isSet(object.lastSyncTimestamp) ? Number(object.lastSyncTimestamp) : 0, }; }, @@ -695,6 +708,7 @@ export const HubInfoResponse = { message.dbStats !== undefined && (obj.dbStats = message.dbStats ? DbStats.toJSON(message.dbStats) : undefined); message.peerId !== undefined && (obj.peerId = message.peerId); message.hubOperatorFid !== undefined && (obj.hubOperatorFid = Math.round(message.hubOperatorFid)); + message.lastSyncTimestamp !== undefined && (obj.lastSyncTimestamp = Math.round(message.lastSyncTimestamp)); return obj; }, @@ -713,6 +727,7 @@ export const HubInfoResponse = { : undefined; message.peerId = object.peerId ?? ""; message.hubOperatorFid = object.hubOperatorFid ?? 0; + message.lastSyncTimestamp = object.lastSyncTimestamp ?? 0; return message; }, }; diff --git a/protobufs/schemas/request_response.proto b/protobufs/schemas/request_response.proto index 0b63bfb186..ab42bb44f9 100644 --- a/protobufs/schemas/request_response.proto +++ b/protobufs/schemas/request_response.proto @@ -32,6 +32,7 @@ message HubInfoResponse { DbStats db_stats = 5; string peerId = 6; uint64 hub_operator_fid = 7; + uint64 last_sync_timestamp = 8; } message DbStats {