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: use websockets to ingest blocks near chain tip #1170

Open
kyscott18 opened this issue Oct 15, 2024 · 0 comments
Open

feat: use websockets to ingest blocks near chain tip #1170

kyscott18 opened this issue Oct 15, 2024 · 0 comments
Labels
A: Sync engine Area: Sync engine T: Feature Type: Feature

Comments

@kyscott18
Copy link
Collaborator

Description

Explore using websockets to watch for new blocks in sync-realtime rather than relying on polling. This would be an improvement for latency critical application, and save on rpc credits for some apps as well.

Specifically, I think we could use the "eth_subscribe" method in replacement of the eth_getBlockByNumber and setInterval.

const enqueue = async () => {
try {
const block = await _eth_getBlockByNumber(args.requestQueue, {
blockTag: "latest",
});
const latestBlock = getLatestUnfinalizedBlock();
// We already saw and handled this block. No-op.
if (latestBlock.hash === block.hash) {
args.common.logger.trace({
service: "realtime",
msg: `Skipped processing '${args.network.name}' block ${hexToNumber(block.number)}, already synced`,
});
return;
}
const blockWithEventData = await fetchBlockEventData(block);
consecutiveErrors = 0;
return queue.add(blockWithEventData);
} catch (_error) {
if (isKilled) return;
const error = _error as Error;
args.common.logger.warn({
service: "realtime",
msg: `Failed to fetch latest '${args.network.name}' block`,
error,
});
// After a certain number of attempts, emit a fatal error.
if (++consecutiveErrors === ERROR_TIMEOUT.length) {
args.common.logger.error({
service: "realtime",
msg: `Fatal error: Unable to fetch latest '${args.network.name}' block after ${ERROR_TIMEOUT.length} attempts.`,
error,
});
args.onFatalError(error);
}
}
};
interval = setInterval(enqueue, args.network.pollingInterval);

After this upgrade and #1115, Ponder would be close to the minimum latency possible. It would be good to start to get an intuition around the short comings of the "eth_subscribe" rpc method and what work arounds we would need.

This would most likely require changes to ponder.config.ts. I think it could look like:

{
  chains: [mainnet, optimism],
  rpcUrls: {
    [mainnet.id]: ["https://mainnet.alchemy.com/...", ...],
    [optimism.id]: "https://mainnet.optimism.io",
  },
}

We probably would still need to preserve the polling option when there is no available websocket connection.

Related

@kyscott18 kyscott18 added T: Feature Type: Feature A: Sync engine Area: Sync engine labels Oct 15, 2024
@typedarray typedarray changed the title feat: use websockets to injest blocks near chain tip feat: use websockets to ingest blocks near chain tip Oct 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A: Sync engine Area: Sync engine T: Feature Type: Feature
Projects
None yet
Development

No branches or pull requests

1 participant