diff --git a/common/changes/@subsquid/evm-processor/log-request-transaction-items_2024-01-15-08-33.json b/common/changes/@subsquid/evm-processor/log-request-transaction-items_2024-01-15-08-33.json new file mode 100644 index 000000000..602844ea5 --- /dev/null +++ b/common/changes/@subsquid/evm-processor/log-request-transaction-items_2024-01-15-08-33.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@subsquid/evm-processor", + "comment": "add transaction items to log and trace requests", + "type": "minor" + } + ], + "packageName": "@subsquid/evm-processor" +} \ No newline at end of file diff --git a/evm/evm-processor/src/ds-rpc/filter.ts b/evm/evm-processor/src/ds-rpc/filter.ts index 99bbcb437..544f3aef1 100644 --- a/evm/evm-processor/src/ds-rpc/filter.ts +++ b/evm/evm-processor/src/ds-rpc/filter.ts @@ -1,10 +1,14 @@ -import {assertNotNull, weakMemo} from '@subsquid/util-internal' +import {assertNotNull, groupBy, weakMemo} from '@subsquid/util-internal' import {EntityFilter, FilterBuilder} from '@subsquid/util-internal-processor-tools' import {Block, Log, StateDiff, Trace, Transaction} from '../mapping/entities' import {DataRequest} from '../interfaces/data-request' -function buildLogFilter(dataRequest: DataRequest): EntityFilter { +function buildLogFilter(dataRequest: DataRequest): EntityFilter { let items = new EntityFilter() for (let req of dataRequest.logs || []) { let {address, topic0, topic1, topic2, topic3, ...relations} = req @@ -40,6 +44,7 @@ function buildTransactionFilter(dataRequest: DataRequest): EntityFilter { @@ -130,8 +135,11 @@ class IncludeSet { export function filterBlock(block: Block, dataRequest: DataRequest): void { let items = getItemFilter(dataRequest) - let include = new IncludeSet() + let logsByTransaction = groupBy(block.logs, log => log.transactionIndex) + let tracesByTransaction = groupBy(block.traces, trace => trace.transactionIndex) + let include = new IncludeSet() + if (items.logs.present()) { for (let log of block.logs) { let rel = items.logs.match(log) @@ -140,6 +148,18 @@ export function filterBlock(block: Block, dataRequest: DataRequest): void { if (rel.transaction) { include.addTransaction(log.transaction) } + if (rel.transactionLogs) { + let logs = logsByTransaction.get(log.transactionIndex) ?? [] + for (let sibling of logs) { + include.addLog(sibling) + } + } + if (rel.transactionTraces) { + let traces = tracesByTransaction.get(log.transactionIndex) ?? [] + for (let trace of traces) { + include.addTrace(trace) + } + } } } @@ -182,6 +202,12 @@ export function filterBlock(block: Block, dataRequest: DataRequest): void { if (rel.transaction) { include.addTransaction(trace.transaction) } + if (rel.transactionLogs) { + let logs = logsByTransaction.get(trace.transactionIndex) ?? [] + for (let log of logs) { + include.addLog(log) + } + } } } diff --git a/evm/evm-processor/src/ds-rpc/request.ts b/evm/evm-processor/src/ds-rpc/request.ts index f7968eeaf..5b90752b6 100644 --- a/evm/evm-processor/src/ds-rpc/request.ts +++ b/evm/evm-processor/src/ds-rpc/request.ts @@ -53,6 +53,11 @@ function logsRequested(req?: DataRequest): boolean { if (tx.logs) return true } } + if (req.traces) { + for (let trace of req.traces) { + if (trace.transactionLogs) return true + } + } return false } @@ -65,6 +70,11 @@ function tracesRequested(req?: DataRequest): boolean { if (tx.traces) return true } } + if (req.logs) { + for (let log of req.logs) { + if (log.transactionTraces) return true + } + } return false } diff --git a/evm/evm-processor/src/interfaces/data-request.ts b/evm/evm-processor/src/interfaces/data-request.ts index 206a0b9e3..25e21fb47 100644 --- a/evm/evm-processor/src/interfaces/data-request.ts +++ b/evm/evm-processor/src/interfaces/data-request.ts @@ -20,6 +20,8 @@ export interface LogRequest { topic2?: Bytes32[] topic3?: Bytes32[] transaction?: boolean + transactionTraces?: boolean + transactionLogs?: boolean } @@ -41,6 +43,7 @@ export interface TraceRequest { suicideRefundAddress?: Bytes[] rewardAuthor?: Bytes20[] transaction?: boolean + transactionLogs?: boolean subtraces?: boolean parents?: boolean }