From 06d47e46268e90b00f43da97f2cae95ed2b53b88 Mon Sep 17 00:00:00 2001 From: Matt <90358481+xbtmatt@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:03:14 -0800 Subject: [PATCH] [ECO-2619] Bump the processor submodule to include the new indexer logic for `event_index`; add simple checks in e2e tests to verify correctness (#477) --- src/rust/processor | 2 +- .../sdk/src/emojicoin_dot_fun/events.ts | 3 ++ .../sdk/src/emojicoin_dot_fun/utils.ts | 28 +++++++++++++++---- .../sdk/tests/e2e/queries/equality-checks.ts | 28 +++++++++++++++++++ 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/rust/processor b/src/rust/processor index f09cb58b5..f0697ce8c 160000 --- a/src/rust/processor +++ b/src/rust/processor @@ -1 +1 @@ -Subproject commit f09cb58b5c02bc000b856445eff8615773a864ca +Subproject commit f0697ce8c6547ae8ab7b055cfe637716556cb97d diff --git a/src/typescript/sdk/src/emojicoin_dot_fun/events.ts b/src/typescript/sdk/src/emojicoin_dot_fun/events.ts index d25ce6cb9..d46858e8a 100644 --- a/src/typescript/sdk/src/emojicoin_dot_fun/events.ts +++ b/src/typescript/sdk/src/emojicoin_dot_fun/events.ts @@ -44,6 +44,9 @@ export const toCamelCaseEventName = (s: T): PascalToCam }; export type Events = { [K in CamelCaseEventNames]: Types[Capitalize>][] }; +export type EventsWithIndices = { + [K in keyof Events]: (Events[K][number] & { eventIndex: number })[]; +}; export const createEmptyEvents = (): Events => ({ swapEvents: [], diff --git a/src/typescript/sdk/src/emojicoin_dot_fun/utils.ts b/src/typescript/sdk/src/emojicoin_dot_fun/utils.ts index 7d81609d3..ae3de7a26 100644 --- a/src/typescript/sdk/src/emojicoin_dot_fun/utils.ts +++ b/src/typescript/sdk/src/emojicoin_dot_fun/utils.ts @@ -14,6 +14,7 @@ import { createEmptyEvents, toCamelCaseEventName, isAnEmojicoinStructName, + type EventsWithIndices, } from "./events"; import { typeTagInputToStructName } from "../utils/type-tags"; import { createNamedObjectAddress } from "../utils/aptos-utils"; @@ -66,25 +67,42 @@ export async function getRegistryAddress(args: { return AccountAddress.from(registryAddressResource.registry_address); } -export function getEvents( +export const getEvents = (response?: UserTransactionResponse | PendingTransactionResponse | null) => + getEventsMaybeWithIndices(response, false); + +export const getEventsWithIndices = ( response?: UserTransactionResponse | PendingTransactionResponse | null -): Events { - const events = createEmptyEvents(); +) => getEventsMaybeWithIndices(response, true); + +function getEventsMaybeWithIndices( + response: UserTransactionResponse | PendingTransactionResponse | null | undefined, + withIndices?: false | undefined +): Events; +function getEventsMaybeWithIndices( + response: UserTransactionResponse | PendingTransactionResponse | null | undefined, + withIndices: true +): EventsWithIndices; +function getEventsMaybeWithIndices( + response: UserTransactionResponse | PendingTransactionResponse | null | undefined, + withIndices: boolean = false +): Events | EventsWithIndices { + const events = createEmptyEvents() as EventsWithIndices; if (!response || !isUserTransactionResponse(response)) { return events; } - response.events.forEach((event): void => { + response.events.forEach((event, eventIndex): void => { const structName = typeTagInputToStructName(event.type); if (!structName || !isAnEmojicoinStructName(structName)) { return; } const data = converter[structName](event.data, response.version); const camelCasedAndPlural = `${toCamelCaseEventName(structName)}s` as const; + const eventData = withIndices ? { ...data, eventIndex } : data; // TypeScript can't infer or narrow the type. It's too difficult to figure out how to get it to // do it properly so we must use `as any` here, although we know for sure its type is correct. /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ - events[camelCasedAndPlural].push(data as any); + events[camelCasedAndPlural].push(eventData as any); }); return events; } diff --git a/src/typescript/sdk/tests/e2e/queries/equality-checks.ts b/src/typescript/sdk/tests/e2e/queries/equality-checks.ts index a7e7cf360..af23684d2 100644 --- a/src/typescript/sdk/tests/e2e/queries/equality-checks.ts +++ b/src/typescript/sdk/tests/e2e/queries/equality-checks.ts @@ -24,8 +24,10 @@ import { type MarketLatestStateEventModel, } from "../../../src/indexer-v2/types"; import { + type AnyEmojicoinEvent, calculateTvlGrowth, getEvents, + getEventsWithIndices, getMarketResourceFromWriteSet, Period, rawPeriodToEnum, @@ -62,6 +64,30 @@ const checkTuples = (args: [string, JsonValue | undefined, JsonValue | undefined expect(rows).toEqual(responses); }; +const checkEventIndex = ( + row: SwapEventModel | LiquidityEventModel, + // This *has* to be the event GUID from the Event, not the EventModel type, + // because the GUIDs are created differently. This is used to map the event + // to an event index to easily compare to the emojicoin indexer event index. + eventGuid: AnyEmojicoinEvent["guid"], + response: UserTransactionResponse +) => { + const events = getEventsWithIndices(response); + const flattenedGuidsToEventIndices = Object.values(events).flatMap((v) => + v.map(({ guid, eventIndex }) => [guid, eventIndex] as const) + ); + const eventsAndIndices = new Map(flattenedGuidsToEventIndices); + const eventIndex = eventsAndIndices.get(eventGuid)!; + if (!eventIndex) { + throw new Error(`${row.eventName}Event not in response version: ${row.transaction.version}`); + } + + // It would be nice to check the block number/height here if possible, but it's not returned by + // the fullnode and graphql is a pain to work with in jest unit tests, and this can just be + // verified manually. + expect(eventIndex.toString()).toEqual(row.blockAndEvent?.eventIndex.toString()); +}; + // ------------------------------------------------------------------------------------------------- // // @@ -425,6 +451,7 @@ const Swap = (row: SwapEventModel, response: UserTransactionResponse) => { compareMarketAndStateMetadata(row, stateEvent); compareStateEvents(row, stateEvent); compareSwapEvents(row, swapEvent); + checkEventIndex(row, swapEvent.guid, response); }; const Chat = (row: ChatEventModel, response: UserTransactionResponse) => { @@ -447,6 +474,7 @@ const Liquidity = (row: LiquidityEventModel, response: UserTransactionResponse) compareMarketAndStateMetadata(row, stateEvent); compareLastSwap(row, stateEvent); compareLiquidityEvents(row, liquidityEvent); + checkEventIndex(row, liquidityEvent.guid, response); }; const MarketLatestState = (row: MarketLatestStateEventModel, response: UserTransactionResponse) => {