Transform events into logs

This commit is contained in:
Prathamesh Musale 2024-09-16 16:03:04 +05:30
parent 8d5fb20d2e
commit 190580f668
2 changed files with 49 additions and 27 deletions

View File

@ -91,6 +91,12 @@ export class Indexer implements IndexerInterface {
return undefined; return undefined;
} }
async getEvents (options: FindManyOptions<EventInterface>): Promise<Array<EventInterface>> {
assert(options);
return [];
}
async getSyncStatus (): Promise<SyncStatusInterface | undefined> { async getSyncStatus (): Promise<SyncStatusInterface | undefined> {
return undefined; return undefined;
} }

View File

@ -17,7 +17,9 @@ const ERROR_CONTRACT_NOT_RECOGNIZED = 'Contract not recognized';
const ERROR_CONTRACT_METHOD_NOT_FOUND = 'Contract method not found'; const ERROR_CONTRACT_METHOD_NOT_FOUND = 'Contract method not found';
const ERROR_METHOD_NOT_IMPLEMENTED = 'Method not implemented'; const ERROR_METHOD_NOT_IMPLEMENTED = 'Method not implemented';
const ERROR_INVALID_BLOCK_TAG = 'Invalid block tag'; const ERROR_INVALID_BLOCK_TAG = 'Invalid block tag';
const ERROR_INVALID_BLOCK_HASH = 'Invalid block hash';
const ERROR_BLOCK_NOT_FOUND = 'Block not found'; const ERROR_BLOCK_NOT_FOUND = 'Block not found';
const ERROR_TOPICS_FILTER_NOT_SUPPORTED = 'Topics filter not supported';
const DEFAULT_BLOCK_TAG = 'latest'; const DEFAULT_BLOCK_TAG = 'latest';
@ -101,7 +103,6 @@ export const createEthRPCHandlers = async (
}, },
eth_getLogs: async (args: any, callback: any) => { eth_getLogs: async (args: any, callback: any) => {
// TODO: Implement
try { try {
if (args.length === 0) { if (args.length === 0) {
throw new ErrorWithCode(CODE_INVALID_PARAMS, ERROR_CONTRACT_INSUFFICIENT_PARAMS); throw new ErrorWithCode(CODE_INVALID_PARAMS, ERROR_CONTRACT_INSUFFICIENT_PARAMS);
@ -109,9 +110,15 @@ export const createEthRPCHandlers = async (
const params = args[0]; const params = args[0];
// Parse arg params in to where options // Parse arg params into where options
const where: FindConditions<EventInterface> = {}; const where: FindConditions<EventInterface> = {};
// TODO: Support topics filter
if (params.topics) {
throw new ErrorWithCode(CODE_INVALID_PARAMS, ERROR_TOPICS_FILTER_NOT_SUPPORTED);
}
// Address filter, address or a list of addresses
if (params.address) { if (params.address) {
if (Array.isArray(params.address)) { if (Array.isArray(params.address)) {
where.contract = In(params.address); where.contract = In(params.address);
@ -120,39 +127,35 @@ export const createEthRPCHandlers = async (
} }
} }
let blockFilter = false; // Block hash takes precedence over fromBlock / toBlock if provided
if (params.blockHash) { if (params.blockHash) {
// TODO: validate blockHash? // Validate input block hash
blockFilter = true; if (!utils.isHexString(params.blockHash, 32)) {
throw new ErrorWithCode(CODE_INVALID_PARAMS, ERROR_INVALID_BLOCK_HASH);
}
where.block = { where.block = {
blockHash: params.blockHash blockHash: params.blockHash
}; };
} else if (params.fromBlock || params.toBlock) { } else if (params.fromBlock || params.toBlock) {
blockFilter = true; const fromBlockNumber = params.fromBlock ? await parseEthGetLogsBlockTag(indexer, params.fromBlock) : null;
const toBlockNumber = params.toBlock ? await parseEthGetLogsBlockTag(indexer, params.toBlock) : null;
if (!params.fromBlock) { if (fromBlockNumber && toBlockNumber) {
const toBlockNumber = await parseEthGetLogsBlockTag(indexer, params.toBlock); // Both fromBlock and toBlock set
where.block = { where.block = { blockNumber: Between(fromBlockNumber, toBlockNumber) };
blockNumber: LessThanOrEqual(toBlockNumber) } else if (fromBlockNumber) {
}; // Only fromBlock set
} else if (!params.toBlock) { where.block = { blockNumber: MoreThanOrEqual(fromBlockNumber) };
const fromBlockNumber = await parseEthGetLogsBlockTag(indexer, params.fromBlock); } else if (toBlockNumber) {
where.block = { // Only toBlock set
blockNumber: MoreThanOrEqual(fromBlockNumber) where.block = { blockNumber: LessThanOrEqual(toBlockNumber) };
};
} else {
const fromBlockNumber = await parseEthGetLogsBlockTag(indexer, params.fromBlock);
const toBlockNumber = await parseEthGetLogsBlockTag(indexer, params.toBlock);
where.block = {
blockNumber: Between(fromBlockNumber, toBlockNumber)
};
} }
} }
// TODO: Construct topics filter
// Fetch events from the db // Fetch events from the db
const events = await indexer.getEvents({ where, relations: blockFilter ? ['block'] : undefined }); // Load block relation
const events = await indexer.getEvents({ where, relations: ['block'] });
// Transform events into result logs // Transform events into result logs
const result = await transformEventsToLogs(events); const result = await transformEventsToLogs(events);
@ -218,6 +221,19 @@ const parseEthGetLogsBlockTag = async (indexer: IndexerInterface, blockTag: stri
}; };
const transformEventsToLogs = async (events: Array<EventInterface>): Promise<any[]> => { const transformEventsToLogs = async (events: Array<EventInterface>): Promise<any[]> => {
// TODO: Implement return events.map(event => {
return events; const parsedExtraInfo = JSON.parse(event.extraInfo);
return {
address: event.contract.toLowerCase(),
blockHash: event.block.blockHash,
blockNumber: `0x${event.block.blockNumber.toString(16)}`,
transactionHash: event.txHash,
transactionIndex: `0x${parsedExtraInfo.tx.index.toString(16)}`,
logIndex: `0x${parsedExtraInfo.logIndex.toString(16)}`,
data: parsedExtraInfo.data,
topics: parsedExtraInfo.topics,
removed: event.block.isPruned
};
});
}; };