Skip to content

Commit

Permalink
chore: improve perf of parseEventLogs
Browse files Browse the repository at this point in the history
  • Loading branch information
jxom committed Sep 11, 2024
1 parent f0cc7a6 commit 4e9ea72
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/gorgeous-dryers-act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"viem": patch
---

Improved performance of `parseEventLogs`
11 changes: 11 additions & 0 deletions src/utils/abi/decodeEventLog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,17 @@ test("errors: event doesn't exist", () => {
name: 'Bar',
type: 'event',
},
{
inputs: [
{
indexed: true,
name: 'message',
type: 'string',
},
],
name: 'Baz',
type: 'event',
},
],
topics: [
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
Expand Down
14 changes: 9 additions & 5 deletions src/utils/abi/decodeEventLog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,15 @@ export function decodeEventLog<
const [signature, ...argTopics] = topics
if (!signature) throw new AbiEventSignatureEmptyTopicsError({ docsPath })

const abiItem = abi.find(
(x) =>
x.type === 'event' &&
signature === toEventSelector(formatAbiItem(x) as EventDefinition),
)
const abiItem = (() => {
if (abi.length === 1) return abi[0]
return abi.find(
(x) =>
x.type === 'event' &&
signature === toEventSelector(formatAbiItem(x) as EventDefinition),
)
})()

if (!(abiItem && 'name' in abiItem) || abiItem.type !== 'event')
throw new AbiEventSignatureNotFoundError(signature, { docsPath })

Expand Down
81 changes: 81 additions & 0 deletions src/utils/abi/parseEventLogs.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { bench } from 'vitest'

import { anvilMainnet } from '../../../test/src/anvil.js'
import { getLogs } from '../../actions/public/getLogs.js'
import { mainnet } from '../../chains/index.js'
import { createClient } from '../../clients/createClient.js'
import { http } from '../../clients/transports/http.js'
import { parseEventLogs } from './parseEventLogs.js'

const client = createClient({
chain: mainnet,
transport: http(),
})

const abi = [
{
name: 'Transfer',
type: 'event',
inputs: [
{
indexed: true,
name: 'from',
type: 'address',
},
{
indexed: true,
name: 'to',
type: 'address',
},
{
indexed: false,
name: 'value',
type: 'uint256',
},
],
},
{
type: 'event',
name: 'Approval',
inputs: [
{
indexed: true,
name: 'owner',
type: 'address',
},
{
indexed: true,
name: 'spender',
type: 'address',
},
{
indexed: false,
name: 'value',
type: 'uint256',
},
],
},
{
inputs: [
{
indexed: true,
name: 'message',
type: 'string',
},
],
name: 'Foo',
type: 'event',
},
] as const

const logs = await getLogs(client, {
fromBlock: anvilMainnet.forkBlockNumber - 5n,
toBlock: anvilMainnet.forkBlockNumber,
})

bench('parseEventLogs', async () => {
parseEventLogs({
abi,
logs,
})
})
11 changes: 6 additions & 5 deletions src/utils/abi/parseEventLogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import type { RpcLog } from '../../types/rpc.js'
import { isAddressEqual } from '../address/isAddressEqual.js'
import { toBytes } from '../encoding/toBytes.js'
import { keccak256 } from '../hash/keccak256.js'
import { toEventSelector } from '../hash/toEventSelector.js'
import {
type DecodeEventLogErrorType,
decodeEventLog,
} from './decodeEventLog.js'
import { getAbiItem } from './getAbiItem.js'

export type ParseEventLogsParameters<
abi extends Abi | readonly unknown[] = Abi,
Expand Down Expand Up @@ -116,10 +116,11 @@ export function parseEventLogs<
return logs
.map((log) => {
try {
const abiItem = getAbiItem({
abi: abi as Abi,
name: log.topics[0] as string,
}) as AbiEvent
const abiItem = (abi as Abi).find(
(abiItem) =>
abiItem.type === 'event' &&
log.topics[0] === toEventSelector(abiItem),
) as AbiEvent
if (!abiItem) return null

const event = decodeEventLog({
Expand Down

0 comments on commit 4e9ea72

Please sign in to comment.