Skip to content

Commit 98e6c45

Browse files
committed
Simplify initIndexingOnchainEvents function
1 parent e1d6d04 commit 98e6c45

5 files changed

Lines changed: 123 additions & 36 deletions

File tree

apps/ensindexer/src/lib/indexing-engines/init-indexing-onchain-events.ts

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,25 @@ import {
3434
import { indexingMetadataContextBuilder } from "@/lib/indexing-metadata-context-builder/singleton";
3535
import { logger } from "@/lib/logger";
3636

37+
async function upsertIndexingMetadataContextRecord(): Promise<void> {
38+
const indexingMetadataContext = await indexingMetadataContextBuilder.getIndexingMetadataContext();
39+
40+
logger.info({
41+
msg: `Upserting Indexing Metadata Context Initialized`,
42+
});
43+
logger.debug({
44+
msg: `Indexing Metadata Context`,
45+
indexingStatus: indexingMetadataContext.indexingStatus,
46+
stackInfo: indexingMetadataContext.stackInfo,
47+
});
48+
49+
await ensDbClient.upsertIndexingMetadataContext(indexingMetadataContext);
50+
51+
logger.info({
52+
msg: `Successfully upserted Indexing Metadata Context Initialized`,
53+
});
54+
}
55+
3756
/**
3857
* Prepare for executing the "onchain" event handlers.
3958
*
@@ -74,21 +93,8 @@ export async function initIndexingOnchainEvents(): Promise<void> {
7493
// by the time ENSIndexer instance executes `initIndexingOnchainEvents`.
7594
await waitForEnsRainbowToBeHealthy();
7695

77-
const indexingMetadataContext =
78-
await indexingMetadataContextBuilder.getIndexingMetadataContext();
79-
80-
logger.info({
81-
msg: `Upserting Indexing Metadata Context Initialized`,
82-
});
83-
logger.debug({
84-
msg: `Indexing Metadata Context`,
85-
indexingStatus: indexingMetadataContext.indexingStatus,
86-
stackInfo: indexingMetadataContext.stackInfo,
87-
});
88-
await ensDbClient.upsertIndexingMetadataContext(indexingMetadataContext);
89-
logger.info({
90-
msg: `Successfully upserted Indexing Metadata Context Initialized`,
91-
});
96+
// Upsert the Indexing Metadata Context record into ENSDb
97+
await upsertIndexingMetadataContextRecord();
9298

9399
// Before starting to process onchain events, we want to make sure that
94100
// ENSRainbow is ready to serve the "heal" requests.

apps/ensindexer/src/lib/indexing-metadata-context-builder/indexing-metadata-context-builder.test.ts

Lines changed: 82 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
type OmnichainIndexingStatusSnapshot,
1414
validateEnsIndexerPublicConfigCompatibility,
1515
} from "@ensnode/ensnode-sdk";
16+
import type { LocalPonderClient } from "@ensnode/ponder-sdk";
1617

1718
import "@/lib/__test__/mockLogger";
1819

@@ -92,6 +93,28 @@ function createMockStackInfoBuilder(
9293
} as unknown as StackInfoBuilder;
9394
}
9495

96+
function createMockLocalPonderClient(options: { isInDevMode?: boolean } = {}): LocalPonderClient {
97+
return {
98+
isInDevMode: options.isInDevMode ?? false,
99+
} as unknown as LocalPonderClient;
100+
}
101+
102+
function createIndexingMetadataContextBuilder(
103+
overrides: {
104+
ensDbClient?: EnsDbReader;
105+
indexingStatusBuilder?: IndexingStatusBuilder;
106+
stackInfoBuilder?: StackInfoBuilder;
107+
localPonderClient?: LocalPonderClient;
108+
} = {},
109+
): IndexingMetadataContextBuilder {
110+
return new IndexingMetadataContextBuilder(
111+
overrides.ensDbClient ?? createMockEnsDbReader(),
112+
overrides.indexingStatusBuilder ?? createMockIndexingStatusBuilder(),
113+
overrides.stackInfoBuilder ?? createMockStackInfoBuilder(),
114+
overrides.localPonderClient ?? createMockLocalPonderClient(),
115+
);
116+
}
117+
95118
describe("IndexingMetadataContextBuilder", () => {
96119
beforeEach(() => {
97120
vi.clearAllMocks();
@@ -109,11 +132,11 @@ describe("IndexingMetadataContextBuilder", () => {
109132
const indexingStatusBuilder = createMockIndexingStatusBuilder(omnichainSnapshotUnstarted);
110133
const stackInfoBuilder = createMockStackInfoBuilder();
111134

112-
const builder = new IndexingMetadataContextBuilder(
135+
const builder = createIndexingMetadataContextBuilder({
113136
ensDbClient,
114137
indexingStatusBuilder,
115138
stackInfoBuilder,
116-
);
139+
});
117140
const result = await builder.getIndexingMetadataContext();
118141

119142
expect(ensDbClient.getIndexingMetadataContext).toHaveBeenCalledOnce();
@@ -133,11 +156,9 @@ describe("IndexingMetadataContextBuilder", () => {
133156
it("throws when indexing status is not unstarted", async () => {
134157
const indexingStatusBuilder = createMockIndexingStatusBuilder(omnichainSnapshotFollowing);
135158

136-
const builder = new IndexingMetadataContextBuilder(
137-
createMockEnsDbReader(),
159+
const builder = createIndexingMetadataContextBuilder({
138160
indexingStatusBuilder,
139-
createMockStackInfoBuilder(),
140-
);
161+
});
141162

142163
await expect(builder.getIndexingMetadataContext()).rejects.toThrow(
143164
/Omnichain indexing status must be "unstarted"/,
@@ -146,18 +167,20 @@ describe("IndexingMetadataContextBuilder", () => {
146167
});
147168

148169
describe("when stored context is Initialized", () => {
149-
it("builds and returns initialized context after validating compatibility", async () => {
170+
it("validates compatibility when not in dev mode", async () => {
150171
const ensDbClient = createMockEnsDbReader({
151172
getIndexingMetadataContext: vi.fn().mockResolvedValue(indexingMetadataContextInitialized),
152173
});
153174
const indexingStatusBuilder = createMockIndexingStatusBuilder(omnichainSnapshotFollowing);
154175
const stackInfoBuilder = createMockStackInfoBuilder();
176+
const localPonderClient = createMockLocalPonderClient({ isInDevMode: false });
155177

156-
const builder = new IndexingMetadataContextBuilder(
178+
const builder = createIndexingMetadataContextBuilder({
157179
ensDbClient,
158180
indexingStatusBuilder,
159181
stackInfoBuilder,
160-
);
182+
localPonderClient,
183+
});
161184
const result = await builder.getIndexingMetadataContext();
162185

163186
expect(validateEnsIndexerPublicConfigCompatibility).toHaveBeenCalledWith(
@@ -172,7 +195,32 @@ describe("IndexingMetadataContextBuilder", () => {
172195
expect(result).toBe(indexingMetadataContextInitialized);
173196
});
174197

175-
it("throws when stored and in-memory configs are incompatible", async () => {
198+
it("skips compatibility validation when in dev mode", async () => {
199+
const ensDbClient = createMockEnsDbReader({
200+
getIndexingMetadataContext: vi.fn().mockResolvedValue(indexingMetadataContextInitialized),
201+
});
202+
const indexingStatusBuilder = createMockIndexingStatusBuilder(omnichainSnapshotFollowing);
203+
const stackInfoBuilder = createMockStackInfoBuilder();
204+
const localPonderClient = createMockLocalPonderClient({ isInDevMode: true });
205+
206+
const builder = createIndexingMetadataContextBuilder({
207+
ensDbClient,
208+
indexingStatusBuilder,
209+
stackInfoBuilder,
210+
localPonderClient,
211+
});
212+
const result = await builder.getIndexingMetadataContext();
213+
214+
// Compatibility validation should NOT be called in dev mode
215+
expect(validateEnsIndexerPublicConfigCompatibility).not.toHaveBeenCalled();
216+
expect(buildIndexingMetadataContextInitialized).toHaveBeenCalledWith(
217+
crossChainSnapshot,
218+
stackInfo,
219+
);
220+
expect(result).toBe(indexingMetadataContextInitialized);
221+
});
222+
223+
it("throws when stored and in-memory configs are incompatible (not in dev mode)", async () => {
176224
vi.mocked(validateEnsIndexerPublicConfigCompatibility).mockImplementation(() => {
177225
throw new Error("Incompatible ENSIndexer config");
178226
});
@@ -181,16 +229,34 @@ describe("IndexingMetadataContextBuilder", () => {
181229
getIndexingMetadataContext: vi.fn().mockResolvedValue(indexingMetadataContextInitialized),
182230
});
183231

184-
const builder = new IndexingMetadataContextBuilder(
232+
const builder = createIndexingMetadataContextBuilder({
185233
ensDbClient,
186-
createMockIndexingStatusBuilder(omnichainSnapshotFollowing),
187-
createMockStackInfoBuilder(),
188-
);
234+
indexingStatusBuilder: createMockIndexingStatusBuilder(omnichainSnapshotFollowing),
235+
localPonderClient: createMockLocalPonderClient({ isInDevMode: false }),
236+
});
189237

190238
await expect(builder.getIndexingMetadataContext()).rejects.toThrow(
191239
"Incompatible ENSIndexer config",
192240
);
193241
});
242+
243+
it("does not throw on incompatible configs when in dev mode", async () => {
244+
vi.mocked(validateEnsIndexerPublicConfigCompatibility).mockImplementation(() => {
245+
throw new Error("Incompatible ENSIndexer config");
246+
});
247+
248+
const ensDbClient = createMockEnsDbReader({
249+
getIndexingMetadataContext: vi.fn().mockResolvedValue(indexingMetadataContextInitialized),
250+
});
251+
252+
const builder = createIndexingMetadataContextBuilder({
253+
ensDbClient,
254+
indexingStatusBuilder: createMockIndexingStatusBuilder(omnichainSnapshotFollowing),
255+
localPonderClient: createMockLocalPonderClient({ isInDevMode: true }),
256+
});
257+
258+
await expect(builder.getIndexingMetadataContext()).resolves.toBeDefined();
259+
});
194260
});
195261

196262
it("fetches all three data sources in parallel", async () => {
@@ -215,11 +281,11 @@ describe("IndexingMetadataContextBuilder", () => {
215281
return stackInfo;
216282
});
217283

218-
const builder = new IndexingMetadataContextBuilder(
284+
const builder = createIndexingMetadataContextBuilder({
219285
ensDbClient,
220286
indexingStatusBuilder,
221287
stackInfoBuilder,
222-
);
288+
});
223289
await builder.getIndexingMetadataContext();
224290

225291
// All three should have been called (ordering is not deterministic for parallel)

apps/ensindexer/src/lib/indexing-metadata-context-builder/indexing-metadata-context-builder.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
type OmnichainIndexingStatusSnapshot,
1212
validateEnsIndexerPublicConfigCompatibility,
1313
} from "@ensnode/ensnode-sdk";
14+
import type { LocalPonderClient } from "@ensnode/ponder-sdk";
1415

1516
import type { IndexingStatusBuilder } from "@/lib/indexing-status-builder/indexing-status-builder";
1617
import { logger } from "@/lib/logger";
@@ -46,6 +47,7 @@ export class IndexingMetadataContextBuilder {
4647
private readonly ensDbClient: EnsDbReader,
4748
private readonly indexingStatusBuilder: IndexingStatusBuilder,
4849
private readonly stackInfoBuilder: StackInfoBuilder,
50+
private readonly localPonderClient: LocalPonderClient,
4951
) {}
5052

5153
/**
@@ -94,10 +96,18 @@ export class IndexingMetadataContextBuilder {
9496
stackInfo: storedIndexingMetadataContext.stackInfo,
9597
});
9698

97-
invariant_ensIndexerPublicConfigIsCompatibleWithStackInfo(
98-
storedIndexingMetadataContext.stackInfo,
99-
inMemoryEnsIndexerStackInfo,
100-
);
99+
// Validate in-memory config object compatibility with the stored one,
100+
// if the stored one is available.
101+
// The validation is skipped if the local Ponder app is running in dev mode.
102+
// This is to improve the development experience during ENSIndexer
103+
// development, by allowing to override the stored config in ENSDb with
104+
// the current in-memory config, without having to keep them compatible.
105+
if (!this.localPonderClient.isInDevMode) {
106+
invariant_ensIndexerPublicConfigIsCompatibleWithStackInfo(
107+
storedIndexingMetadataContext.stackInfo,
108+
inMemoryEnsIndexerStackInfo,
109+
);
110+
}
101111
}
102112

103113
return inMemoryIndexingMetadataContext;

apps/ensindexer/src/lib/indexing-metadata-context-builder/singleton.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ensDbClient } from "@/lib/ensdb/singleton";
22
import { IndexingMetadataContextBuilder } from "@/lib/indexing-metadata-context-builder/indexing-metadata-context-builder";
33
import { indexingStatusBuilder } from "@/lib/indexing-status-builder/singleton";
4+
import { localPonderClient } from "@/lib/local-ponder-client";
45
import { stackInfoBuilder } from "@/lib/stack-info-builder/singleton";
56

67
/**
@@ -10,4 +11,5 @@ export const indexingMetadataContextBuilder = new IndexingMetadataContextBuilder
1011
ensDbClient,
1112
indexingStatusBuilder,
1213
stackInfoBuilder,
14+
localPonderClient,
1315
);

packages/ensdb-sdk/src/client/ensnode-metadata.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ export interface EnsNodeMetadataIndexingMetadataContext {
2323
/**
2424
* ENSNode Metadata
2525
*
26-
* Union type gathering all variants of ENSNode Metadata.
26+
* Type alias for ENSNode Metadata records,
27+
* currently only includes the record for Indexing Metadata Context,
28+
* but can be extended in the future to include more types of
29+
* ENSNode Metadata records as needed.
2730
*/
2831
export type EnsNodeMetadata = EnsNodeMetadataIndexingMetadataContext;

0 commit comments

Comments
 (0)