Skip to content

Generic event processing#63

Closed
DZakh wants to merge 8 commits into
mainfrom
dz/generic-event-processing
Closed

Generic event processing#63
DZakh wants to merge 8 commits into
mainfrom
dz/generic-event-processing

Conversation

@DZakh

@DZakh DZakh commented Jul 9, 2024

Copy link
Copy Markdown
Member

No description provided.

@DZakh DZakh marked this pull request as draft July 9, 2024 14:27
@github-actions

github-actions Bot commented Jul 9, 2024

Copy link
Copy Markdown

Here's the diff of the codegen output.🙌🧠🦜

@DZakh DZakh force-pushed the dz/generic-event-processing branch from 8cb65d1 to 8f55503 Compare July 9, 2024 14:41
@DZakh DZakh mentioned this pull request Jul 9, 2024
7 tasks

@DZakh DZakh left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of the PR in a nutshell is to select an eventMod related to an event when we parse a log and store it in the batch item. This way we can use the eventMod to get an eventName without generating a switch. Later I want to include more functions to eventMod, so we can remove more generated parts.
For example, for decoding it'll allow to have different implementations for Evm and Fuel.

Comment on lines +162 to +164
decodedEvent
->{{contract.name.capitalized}}.{{event.name.capitalized}}.convertViemDecodedEvent
->{{contract.name.capitalized}}.{{event.name.capitalized}}.convertLogViem(~log, ~blockTimestamp, ~chainId, ~txOrigin, ~txTo)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next step. Move Converters to static and get the decoder from eventMod

}

Ok(event)
Ok(event, eventMod)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a small performance regression, but it shouldn't be noticeable considering the whole indexer codebase.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed 👍🏼,

But I guess you could always just store contract name and event name and look up the module where needed

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say it's better to store eventMod and get contract name and event name from it whenever we need. This is actually how it's done. Later I think we'll separate eventMod lookup and event decoding, so there won't be the tuple anymore.

~schema: S.t<'a>,
~variantAccessor: Types.eventLog<'a> => Types.event,
~eventMod: module(Types.Event),
~eventAccessor: Types.eventLog<eventArgs> => Types.event,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next step: Move eventAccessor to the eventMod and apply it only when we expose event to users. Work with eventLog internally

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is what you mean but we can always add eventMod to the data structure of "Event", then cast the inner event type to some opaque type and deal with the inner values using eventMod functions

@DZakh DZakh Jul 11, 2024

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually think we don't need the Types.event type whatsoever. So, instead of what I said above, I'll eliminate the Types.event.

~txOrigin: option<Ethers.ethAddress>,
~txTo: option<Ethers.ethAddress>,
): result<Types.eventBatchQueueItem, S.error> => {
let module(Event) = eventMod->(Utils.magic: module(Types.Event) => module(Types.Event with type eventArgs = eventArgs))

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope we won't need to do this type castings when we start using eventLog instead of event

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you casting here rather than just having the module type in the function parameter?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case it'd complain on type mismatch when we create Types.eventBatchQueueItem, because it expects module(Types.Event) instead of module(Types.Event with type eventArgs = eventArgs). So I decided to cast only the part which is used inside of the function

events: [
{{#each contract.events as | event |}}
{{event.event_type.full}},
module(Types.{{contract.name.capitalized}}.{{event.name.capitalized}}),

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here it's not really needed to use mod yet, but later we should use the array from config to find the correct eventMod for an event. Currently it's codegened in Types and Converters

| Error(e) => S.Error.raise(e)
},
eventType: Event.eventName,
params: event.params->S.serializeToJsonStringOrRaiseWith(Event.eventArgsSchema),

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice addition of rescript-schema v7 ☺️

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But not needed, since params are Js.Json.t now 😅

Comment on lines +133 to +134
let eventBatches = await eventBatchPromises->Promise.all
let parsedQueueItemsPreFilter = eventBatches

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think eventBatchPromises is something weird and should be awaited in the place where it's used. But I decided not to change here anything, in case there's some reason to apply Promise.all only at the step.

@DZakh DZakh marked this pull request as ready for review July 10, 2024 10:13
@DZakh DZakh requested a review from JonoPrest July 10, 2024 10:13
Comment on lines -211 to +218
let getHandlerArgs = (contextEnv, ~asyncGetters, ~inMemoryStore, ~loaderReturn) => {
let getHandlerArgs = (contextEnv, ~asyncGetters=asyncGetters, ~inMemoryStore, ~loaderReturn) => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not punned? 🤔, would have thought the formatter would do that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the default value

@JonoPrest JonoPrest left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LFG

@DZakh

DZakh commented Jul 12, 2024

Copy link
Copy Markdown
Member Author

Merged as part of #67

@DZakh DZakh closed this Jul 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants