perf: remove blocking calls from POI queries#6300
perf: remove blocking calls from POI queries#6300MoonBoi9001 wants to merge 3 commits intomasterfrom
Conversation
8045272 to
b6cd094
Compare
Remove synchronous `block_on` call in `resolve_proof_of_indexing` which was blocking tokio worker threads while waiting for database queries. Before this change, each POI query blocked an entire tokio worker thread. After this change, POI queries properly yield to the async runtime while waiting for database I/O, allowing the connection pool to be fully utilized. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
b6cd094 to
888a12e
Compare
|
The first commit is great and something that absolutely needs to happen. For the second commit, I am not quite clear on what the motivation is - are PoI requests slow? The worry I have is that when |
|
The motivation is POI verification tooling for dispute investigation. When investigating POI discrepancies (e.g., for arbitration disputes), we need to compute POIs across large block ranges to identify where divergence occurred. With sequential processing, throughput is bottlenecked at ~2k POIs/second even though the database connection pool has capacity. The publicProofsOfIndexing endpoint accepts batch requests (up to 10), but processing them sequentially means we're not utilizing available parallelism. Checking every block sequentially on a network with 100m blocks takes 13+ hours at ~2k blocks/second. |
8b2a3fc to
4f89b3f
Compare
The third commit addresses this, now pre-fetch all block hashes in a single batch query before parallel processing, reducing DB round-trips. |
Have you tried a binary search for PoI's? I assume you are looking for the point where the PoI's for some subgraph diverge between two indexers. Instead of a binary search, you could actually request multiple PoI's across some range (start with |
|
Binary search works well for finding divergence points between two indexers. This PR speeds up computations for finding which block a given POI actually corresponds to if it doesnt correspond to the block that it is claimed to (can be used to prove an indexer claimed rewards for block N, but only synced to block X). Under the assumption that an indexer force closes with a valid POI for a block x < n, but submits that block x POI for block n. |
|
Thanks for the explanation - if you use this to find the block for which a given POI was generated, how about we add a route in the resolver that just does that? That might be much faster than just speeding up POI lookup. |
6620768 to
bae0c11
Compare
Adds a new index-node GraphQL query that searches a block range to find which block produced a given POI. This supports dispute investigation where an indexer may have submitted a POI for block N that actually corresponds to block X < N. The resolver fetches all poi2$ digest entries in a single DB call, batch fetches block hashes in 50k chunks, and runs ProofOfIndexingFinisher for each block until a match is found. Also adds network_for_deployment to the StatusStore trait and its implementation chain (SubgraphStore, Store) as a supporting method for resolving the chain store from a deployment hash. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
bae0c11 to
b8bd47d
Compare
Summary
proofOfIndexingresolver async, removinggraph::block_oncalls that blocked the Tokio runtimeblockForPoiquery that finds which block number produced a given proof of indexing, supporting dispute investigation where an indexer may have submitted a POI for block N that actually corresponds to block X < NblockForPoidesignThe resolver queries all historical POI digest entries from
poi2$in a single DB call, then searches backwards fromendBlockin 1M-block chunks. Block hash fetching is pipelined (the next chunk is prefetched while the current one is being processed), and POI computation within each chunk is parallelized across all CPU cores via rayon'sfind_map_any.Key decisions:
endBlocktowardsstartBlockindexeris required so the caller specifies which address to use in the POI computationGenerated with Claude Code