diff --git a/yarn-project/archiver/src/store/kv_archiver_store.test.ts b/yarn-project/archiver/src/store/kv_archiver_store.test.ts index e84fa3d43710..d2057ed482d1 100644 --- a/yarn-project/archiver/src/store/kv_archiver_store.test.ts +++ b/yarn-project/archiver/src/store/kv_archiver_store.test.ts @@ -2782,6 +2782,24 @@ describe('KVArchiverDataStore', () => { } }); + it('"tag" filter param is respected', async () => { + // Get a random tag from the logs + const targetBlockIndex = randomInt(numBlocksForPublicLogs); + const targetBlock = publishedCheckpoints[targetBlockIndex].checkpoint.blocks[0]; + const targetTxIndex = randomInt(getTxsPerBlock(targetBlock)); + const targetLogIndex = randomInt(getPublicLogsPerTx(targetBlock, targetTxIndex)); + const targetTag = targetBlock.body.txEffects[targetTxIndex].publicLogs[targetLogIndex].fields[0]; + + const response = await store.getPublicLogs({ tag: targetTag }); + + expect(response.maxLogsHit).toBeFalsy(); + expect(response.logs.length).toBeGreaterThan(0); + + for (const extendedLog of response.logs) { + expect(extendedLog.log.fields[0].equals(targetTag)).toBeTruthy(); + } + }); + it('"afterLog" filter param is respected', async () => { // Get a random log as reference const targetBlockIndex = randomInt(numBlocksForPublicLogs); @@ -2817,13 +2835,13 @@ describe('KVArchiverDataStore', () => { } }); - it('"txHash" filter param is ignored when "afterLog" is set', async () => { - // Get random txHash + it('"txHash" filter param is respected when "afterLog" is set', async () => { + // A random txHash should match nothing, even with afterLog set const txHash = TxHash.random(); const afterLog = new LogId(BlockNumber(1), BlockHash.random(), TxHash.random(), 0, 0); const response = await store.getPublicLogs({ txHash, afterLog }); - expect(response.logs.length).toBeGreaterThan(1); + expect(response.logs.length).toBe(0); }); it('intersecting works', async () => { diff --git a/yarn-project/archiver/src/store/log_store.ts b/yarn-project/archiver/src/store/log_store.ts index e389cba458e2..e2230e7c2847 100644 --- a/yarn-project/archiver/src/store/log_store.ts +++ b/yarn-project/archiver/src/store/log_store.ts @@ -588,11 +588,24 @@ export class LogStore { txLogs: PublicLog[], filter: LogFilter = {}, ): boolean { + if (filter.fromBlock && blockNumber < filter.fromBlock) { + return false; + } + if (filter.toBlock && blockNumber >= filter.toBlock) { + return false; + } + if (filter.txHash && !txHash.equals(filter.txHash)) { + return false; + } + let maxLogsHit = false; let logIndex = typeof filter.afterLog?.logIndex === 'number' ? filter.afterLog.logIndex + 1 : 0; for (; logIndex < txLogs.length; logIndex++) { const log = txLogs[logIndex]; - if (!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) { + if ( + (!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) && + (!filter.tag || log.fields[0]?.equals(filter.tag)) + ) { results.push( new ExtendedPublicLog(new LogId(BlockNumber(blockNumber), blockHash, txHash, txIndex, logIndex), log), ); @@ -616,6 +629,16 @@ export class LogStore { txLogs: ContractClassLog[], filter: LogFilter = {}, ): boolean { + if (filter.fromBlock && blockNumber < filter.fromBlock) { + return false; + } + if (filter.toBlock && blockNumber >= filter.toBlock) { + return false; + } + if (filter.txHash && !txHash.equals(filter.txHash)) { + return false; + } + let maxLogsHit = false; let logIndex = typeof filter.afterLog?.logIndex === 'number' ? filter.afterLog.logIndex + 1 : 0; for (; logIndex < txLogs.length; logIndex++) { diff --git a/yarn-project/stdlib/src/logs/log_filter.ts b/yarn-project/stdlib/src/logs/log_filter.ts index d2c191a803a9..75f97cd1ee20 100644 --- a/yarn-project/stdlib/src/logs/log_filter.ts +++ b/yarn-project/stdlib/src/logs/log_filter.ts @@ -1,3 +1,5 @@ +import type { Fr } from '@aztec/foundation/curves/bn254'; + import { z } from 'zod'; import type { AztecAddress } from '../aztec-address/index.js'; @@ -20,6 +22,8 @@ export type LogFilter = { afterLog?: LogId; /** The contract address to filter logs by. */ contractAddress?: AztecAddress; + /** The tag (first field of the log) to filter logs by. */ + tag?: Fr; }; export const LogFilterSchema: ZodFor = z.object({ @@ -28,4 +32,5 @@ export const LogFilterSchema: ZodFor = z.object({ toBlock: schemas.Integer.optional(), afterLog: LogId.schema.optional(), contractAddress: schemas.AztecAddress.optional(), + tag: schemas.Fr.optional(), });