Skip to content

Commit c739a0f

Browse files
committed
fix(explorer): optimize contract creation lookup with caching
The binary search was taking ~40 seconds due to slow historical RPC calls. Optimizations: - Add in-memory cache to avoid repeated lookups for the same contract - Parallelize the final batch of block checks - Start search from block 1 instead of 0 This significantly improves response time for repeated requests.
1 parent bbe570c commit c739a0f

File tree

1 file changed

+48
-10
lines changed
  • apps/explorer/src/routes/api/contract/creation

1 file changed

+48
-10
lines changed

apps/explorer/src/routes/api/contract/creation/$address.ts

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,30 @@ import { getChainId, getPublicClient } from 'wagmi/actions'
44
import { zAddress } from '#lib/zod'
55
import { getWagmiConfig } from '#wagmi.config'
66

7+
const creationCache = new Map<
8+
string,
9+
{ blockNumber: bigint; timestamp: bigint }
10+
>()
11+
712
export const Route = createFileRoute('/api/contract/creation/$address')({
813
server: {
914
handlers: {
1015
GET: async ({ params }: { params: { address: string } }) => {
1116
try {
1217
const address = zAddress().parse(params.address)
1318
Address.assert(address)
19+
const cacheKey = address.toLowerCase()
20+
21+
const cached = creationCache.get(cacheKey)
22+
if (cached) {
23+
return Response.json({
24+
creation: {
25+
blockNumber: cached.blockNumber.toString(),
26+
timestamp: cached.timestamp.toString(),
27+
},
28+
error: null,
29+
})
30+
}
1431

1532
const config = getWagmiConfig()
1633
const chainId = getChainId(config)
@@ -32,7 +49,7 @@ export const Route = createFileRoute('/api/contract/creation/$address')({
3249
const creationBlock = await binarySearchCreationBlock(
3350
client,
3451
address,
35-
0n,
52+
1n,
3653
latestBlock,
3754
)
3855

@@ -42,6 +59,11 @@ export const Route = createFileRoute('/api/contract/creation/$address')({
4259

4360
const block = await client.getBlock({ blockNumber: creationBlock })
4461

62+
creationCache.set(cacheKey, {
63+
blockNumber: creationBlock,
64+
timestamp: block.timestamp,
65+
})
66+
4567
return Response.json({
4668
creation: {
4769
blockNumber: creationBlock.toString(),
@@ -63,14 +85,14 @@ export const Route = createFileRoute('/api/contract/creation/$address')({
6385
})
6486

6587
async function binarySearchCreationBlock(
66-
client: ReturnType<typeof getPublicClient>,
88+
client: NonNullable<ReturnType<typeof getPublicClient>>,
6789
address: Address.Address,
6890
low: bigint,
6991
high: bigint,
7092
): Promise<bigint | null> {
71-
if (!client) return null
93+
const MAX_BATCH_SIZE = 10
7294

73-
while (low < high) {
95+
while (high - low > BigInt(MAX_BATCH_SIZE)) {
7496
const mid = (low + high) / 2n
7597

7698
try {
@@ -89,13 +111,29 @@ async function binarySearchCreationBlock(
89111
}
90112
}
91113

92-
const finalCode = await client.getCode({
93-
address,
94-
blockNumber: low,
95-
})
114+
const blocksToCheck = []
115+
for (let b = low; b <= high; b++) {
116+
blocksToCheck.push(b)
117+
}
118+
119+
const results = await Promise.all(
120+
blocksToCheck.map(async (blockNum) => {
121+
try {
122+
const code = await client.getCode({
123+
address,
124+
blockNumber: blockNum,
125+
})
126+
return { blockNum, hasCode: Boolean(code && code !== '0x') }
127+
} catch {
128+
return { blockNum, hasCode: false }
129+
}
130+
}),
131+
)
96132

97-
if (finalCode && finalCode !== '0x') {
98-
return low
133+
for (const result of results) {
134+
if (result.hasCode) {
135+
return result.blockNum
136+
}
99137
}
100138

101139
return null

0 commit comments

Comments
 (0)