Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(starknet): firehose trigger filter #5322

Closed

Conversation

xJonathanLEI
Copy link
Contributor

@xJonathanLEI xJonathanLEI commented Apr 8, 2024

Supersedes #5201.

This PR adds 2 trigger filters to Starknet:

  • block trigger that specifies a list of ranges
  • event trigger that's capable of filtering by contract address, event topic, and block ranges

When used without turning on the filters feature on the Firehose provider, these filters only work on the graph-node side - meaning that full blocks are still always streamed to graph-node. Filters are applied only to avoid excessive trigger parsing. This part was what #5201 enabled.

What's new in this new PR is the additional implementation of Firhose triggers (i.e. to_firehose_filter), allowing graph-node to send a transforms field in its Firehose stream subscription requests when the filters feature is enabled for the provider. Note that all blocks are still always streamed - the filters only affects the list of transactions that are included (which dominates the size of blocks streamed as block headers are thin).

This new feature should (haven't benchmarked though) significantly improve Starknet subgraph indexing performance, as the actual data sent over the wire should now be much smaller for most real-world subgraphs. (Notably, if a subgraph tracks ETH transfers for example, it won't see much difference as ETH is transferred to sequencer in most transactions)

firehose-starknet has already implemented support for filters. This PR has been tested against that implementation and it works as expected - blocks without matching events have empty transactions, and those with matching ones only come with relevant transactions.

@mangas mangas self-requested a review April 8, 2024 12:13
@mangas mangas self-assigned this Apr 8, 2024
Chain,
};

type TopicWithRanges = HashMap<Felt, Vec<BlockRange>>;
Copy link
Contributor

Choose a reason for hiding this comment

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

This type is quite opaque in how it's supposed to work, what does Felt represent here? Elsewhere it seems to be an address, here seems to be a "topic".

Can you please make sure the Felt type comment covers what is represents?

How many topics do we expect to represent in these? HashMap is probably overkill if it's only handling a handful of values.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh sorry for the confusion. Felt is the universal primitive type in Starknet. Everything is a Felt: from addresses to contract call params to event logs, literally everything. I will make sure to cover this fact in the Felt type comment itself.

As for "topic", probably bad naming but what it means is the first element in any event keys, similar to Ethereum event signatures (which are the first element of any log "topics"). I should probably name this signature instead?

Copy link
Contributor

@mangas mangas Apr 9, 2024

Choose a reason for hiding this comment

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

maybe something like EventPrefix or EventFirstKey something along those lines, signature could make sense too if that's how it's treated, I think adding rust comments to the types will make that clearer regardless of the name :)

ps: I'm terrible at naming things eheh


#[derive(Default, Clone)]
pub struct StarknetEventFilter {
pub contract_addresses: HashMap<Felt, TopicWithRanges>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you please make this field private and keep the matching logic with the filter? eg: matches_addresses or matches_event in order to avoid leaking the implementation into a few like trigger_in_block

Copy link
Contributor

Choose a reason for hiding this comment

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

Also somewhat related would be great to have test coverage here

}

fn to_firehose_filter(self) -> Vec<prost_types::Any> {
todo!()
// An empty event filter list means that the subgraph is not interested in events at all.
Copy link
Contributor

Choose a reason for hiding this comment

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

can you please add some unit tests here

block: shared_block.clone(),
transaction: transaction.clone(),
})
.filter_map(|event| {
Copy link
Contributor

Choose a reason for hiding this comment

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

As mentioned in a different comment, would be great if you could move the matching logic into the filter itself leave this implementation focused on extract the triggers from the block rather than dealing with internals from the filter

Copy link
Contributor

Choose a reason for hiding this comment

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

Would also be great if we can have some tests, near has some examples you can follow.

Copy link
Contributor

@mangas mangas left a comment

Choose a reason for hiding this comment

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

See other comments

@xJonathanLEI
Copy link
Contributor Author

Pushed changes:

  • encapsulated trigger filter logic
  • renamed a few type aliases to reduce ambiguity
  • added trigger filter matching tests

Notably, since the trigger filter type is now completely encapsulated, it's now rather difficult to construct a TriggerFilter instance from chain.rs. So I just tested everything inside adapter.rs instead.

@xJonathanLEI xJonathanLEI requested a review from mangas April 9, 2024 20:23
@mangas
Copy link
Contributor

mangas commented May 28, 2024

As I understand it this integration was taken in a different direction, I'll close the PR for now, re-open if needed. Also if not needed anymore would be great to remove the existing stakrnet code.

@mangas mangas closed this May 28, 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