Skip to content

Instantly share code, notes, and snippets.

@belopash
Last active May 6, 2023 16:08
Show Gist options
  • Save belopash/aa6b67dc374add44b9bdff1c9c1eee17 to your computer and use it in GitHub Desktop.
Save belopash/aa6b67dc374add44b9bdff1c9c1eee17 to your computer and use it in GitHub Desktop.
import {
BlockHeader,
DataHandlerContext,
EvmBatchProcessor,
FieldSelection,
Log,
Transaction,
} from '@subsquid/evm-processor'
type GetSelector<K extends keyof FieldSelection> = Exclude<FieldSelection[K], undefined>
type BaseFieldSelection = Omit<FieldSelection, 'log' | 'transaction'> & {
log: {address: true} & Omit<GetSelector<'log'>, 'address'>
transaction: {to: true} & Omit<GetSelector<'transaction'>, 'to'>
}
export type LogItem<Fields extends FieldSelection> = {
kind: 'evmLog'
address: string
evmLog: Log<Fields>
transaction?: Transaction<Fields>
}
export type TransactionItem<Fields extends FieldSelection> = {
kind: 'transaction'
address: string
transaction: Transaction<Fields>
}
export type Item<Fields extends FieldSelection> = LogItem<Fields> | TransactionItem<Fields>
export interface OldBlockData<Fields extends FieldSelection> {
header: BlockHeader<Fields>
items: Item<Fields>[]
}
export type OldHandlerContext<Store, Fields extends FieldSelection> = Omit<
DataHandlerContext<Store, Fields>,
'blocks'
> & {blocks: OldBlockData<Fields>[]}
export type BatchProcessorItem<T> = T extends EvmBatchProcessor<infer F> ? Item<F> : never
export type BatchProcessorLogItem<T> = Extract<BatchProcessorItem<T>, {kind: 'evmLog'}>
export type BatchProcessorTransactionItem<T> = Extract<BatchProcessorItem<T>, {kind: 'transaction'}>
export function transformContext<Store, Fields extends BaseFieldSelection>(
ctx: DataHandlerContext<Store, Fields>
): OldHandlerContext<Store, Fields> {
let {blocks, ...restCtx} = ctx
const newCtx: OldHandlerContext<Store, Fields> = {
...restCtx,
blocks: [],
}
for (const block of ctx.blocks) {
let items: Item<Fields>[] = []
for (let log of block.logs) {
items.push({
kind: 'evmLog',
address: (log as any).address,
evmLog: log,
transaction: log.transaction,
})
}
for (let transaction of block.transactions) {
if ((transaction as any).to == null) continue
items.push({
kind: 'transaction',
address: (transaction as any).to,
transaction,
})
}
items.sort((a, b) => {
if (a.kind === 'evmLog' && b.kind === 'evmLog') {
return a.evmLog.logIndex - b.evmLog.logIndex
} else if (a.kind === 'transaction' && b.kind === 'transaction') {
return a.transaction.transactionIndex - b.transaction.transactionIndex
} else if (a.kind === 'evmLog' && b.kind === 'transaction') {
return a.evmLog.transactionIndex - b.transaction.transactionIndex || -1 // transaction after logs
} else if (a.kind === 'transaction' && b.kind === 'evmLog') {
return a.transaction.transactionIndex - b.evmLog.transactionIndex || 1
} else {
throw new Error('Unexpected case')
}
})
newCtx.blocks.push({
header: block.header,
items,
})
}
return newCtx
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment