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: cross-chain cached RPC requests #1446

Open
damianmarti opened this issue Jan 17, 2025 · 2 comments
Open

feat: cross-chain cached RPC requests #1446

damianmarti opened this issue Jan 17, 2025 · 2 comments

Comments

@damianmarti
Copy link

Problem / use case

We have a Ponder index working on mainnet and Optimism, and we want to get the ENS name from an address when indexing.

If we use the client from the context, we get an error when we try to get the ENS name from an event on Optimism, saying that the resolver is not available on this chain.

We resolve it by creating a new viem client using mainnet as chain, something like:

// Create a viem client for the mainnet
const clientMainnet = createPublicClient({
  chain: mainnet,
  transport: http(process.env.PONDER_RPC_MAINNET),
});

ponder.on("eventName", async ({ event, context }) => {
  let ensName = null;

  try {
    ensName = await clientMainnet.getEnsName({
      address: event.args.to,
    });
  } catch (e) {
    console.error("Error resolving ENS name: ", e);
  }
});

It seems to be working ok, but the documentation says "don't do this", and opens an issue for this.

Is there a better way to do this?

Proposed solution

No response

@typedarray
Copy link
Collaborator

Hi! Thanks for opening, and especially for including a clear example / use case.

The reason we recommend against setting up your own viem clients is that the clients provided in context.client use a cache. This way, reindexing serves responses from the local cache rather than making a slow RPC request. It makes a huge difference for backfill performance.

We'd like to add support for caching across chains, because it's a common requirement. The single-chain caching solution uses the block number of the event currently being handled as the "blockTag" argument for any requests than accept one, like eth_call (which powers the readContract, getEnsName actions and many more). Without the block number, we can't safely cache the result, because it may change over time dependent on the block number.

So, the key question for cross-chain requests like this is what block number to use on the target chain. A few basic ideas to get the ball rolling:

  • We have access to the block timestamp on the source chain. So, a naive approach would be to make a series of eth_getBlockByNumber requests on the target chain to find the block with a timestamp closest to the block timestamp on the source chain.
  • We collect some basic information about the target chain when the service starts up, like the latest block and finalized block numbers and timestamps. So, we could use this information to make an informed guess without any additional RPC requests.

Appreciate any ideas!

@typedarray typedarray changed the title Allow to call getEnsName using client from context but using always mainnet feat: cross-chain cached RPC requests Jan 17, 2025
@damianmarti
Copy link
Author

Thanks for the fast response and full explanation!!

Yes, I understand, it's not so clear how to resolve this.

Maybe a good first approach is not to use a blockTag argument and use the current block number for the cache information. This solution will be at least enough for our use case.

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

No branches or pull requests

2 participants