Skip to content

Commit

Permalink
[ECO-2619] Bump the processor submodule to include the new indexer lo…
Browse files Browse the repository at this point in the history
…gic for `event_index`; add simple checks in e2e tests to verify correctness (#477)
  • Loading branch information
xbtmatt authored Dec 21, 2024
1 parent a79759e commit 06d47e4
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 6 deletions.
3 changes: 3 additions & 0 deletions src/typescript/sdk/src/emojicoin_dot_fun/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ export const toCamelCaseEventName = <T extends FullEventName>(s: T): PascalToCam
};

export type Events = { [K in CamelCaseEventNames]: Types[Capitalize<RemovePlurality<K>>][] };
export type EventsWithIndices = {
[K in keyof Events]: (Events[K][number] & { eventIndex: number })[];
};

export const createEmptyEvents = (): Events => ({
swapEvents: [],
Expand Down
28 changes: 23 additions & 5 deletions src/typescript/sdk/src/emojicoin_dot_fun/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
createEmptyEvents,
toCamelCaseEventName,
isAnEmojicoinStructName,
type EventsWithIndices,
} from "./events";
import { typeTagInputToStructName } from "../utils/type-tags";
import { createNamedObjectAddress } from "../utils/aptos-utils";
Expand Down Expand Up @@ -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;
}
28 changes: 28 additions & 0 deletions src/typescript/sdk/tests/e2e/queries/equality-checks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ import {
type MarketLatestStateEventModel,
} from "../../../src/indexer-v2/types";
import {
type AnyEmojicoinEvent,
calculateTvlGrowth,
getEvents,
getEventsWithIndices,
getMarketResourceFromWriteSet,
Period,
rawPeriodToEnum,
Expand Down Expand Up @@ -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());
};

// -------------------------------------------------------------------------------------------------
//
//
Expand Down Expand Up @@ -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) => {
Expand All @@ -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) => {
Expand Down

0 comments on commit 06d47e4

Please sign in to comment.