From 4d1d25243f122cb41e88edf570331229d90a560d Mon Sep 17 00:00:00 2001 From: JQQQ Date: Wed, 22 Jan 2025 16:57:50 +1300 Subject: [PATCH 1/5] Fix 1 --- .../src/codegen/codegen-controller.spec.ts | 2 +- .../v1/starknetDictionaryV1.spec.ts | 22 ++- packages/node/src/indexer/project.service.ts | 2 +- packages/node/src/indexer/types.ts | 7 +- .../src/indexer/unfinalizedBlocks.service.ts | 4 +- .../src/starknet/api.service.starknet.test.ts | 7 - .../node/src/starknet/api.starknet.test.ts | 10 +- packages/node/src/starknet/api.starknet.ts | 167 +++++++----------- packages/node/src/starknet/utils.starknet.ts | 62 ++++--- packages/types/src/interfaces.ts | 4 +- packages/types/src/starknet/index.ts | 1 + packages/types/src/starknet/interfaces.ts | 19 +- packages/types/src/starknet/utils.ts | 10 ++ 13 files changed, 153 insertions(+), 164 deletions(-) create mode 100644 packages/types/src/starknet/utils.ts diff --git a/packages/common-starknet/src/codegen/codegen-controller.spec.ts b/packages/common-starknet/src/codegen/codegen-controller.spec.ts index 5fc120e..04f0b50 100644 --- a/packages/common-starknet/src/codegen/codegen-controller.spec.ts +++ b/packages/common-starknet/src/codegen/codegen-controller.spec.ts @@ -38,7 +38,7 @@ describe('Codegen spec', () => { await expect( generateAbis([ds], PROJECT_PATH, undefined as any, undefined as any, undefined as any) - ).rejects.toThrow(/Asset: "zkLend" not found in project/); + ).rejects.toThrow('Error: Asset zkLend, file ./abis/xxx.json does not exist'); }); it('render correct codegen from ejs', async () => { diff --git a/packages/node/src/indexer/dictionary/v1/starknetDictionaryV1.spec.ts b/packages/node/src/indexer/dictionary/v1/starknetDictionaryV1.spec.ts index d6dd130..34772c7 100644 --- a/packages/node/src/indexer/dictionary/v1/starknetDictionaryV1.spec.ts +++ b/packages/node/src/indexer/dictionary/v1/starknetDictionaryV1.spec.ts @@ -136,18 +136,16 @@ describe('buildDictionaryV1QueryEntries', () => { const result = buildDictionaryV1QueryEntries([ds]); expect(result).toEqual([ - [ - { - conditions: [ - { - field: 'type', - matcher: 'equalTo', - value: 'L1_HANDLER', - }, - ], - entity: 'calls', - }, - ], + { + conditions: [ + { + field: 'type', + matcher: 'equalTo', + value: 'L1_HANDLER', + }, + ], + entity: 'calls', + }, ]); }); diff --git a/packages/node/src/indexer/project.service.ts b/packages/node/src/indexer/project.service.ts index a965fa3..d643d0c 100644 --- a/packages/node/src/indexer/project.service.ts +++ b/packages/node/src/indexer/project.service.ts @@ -75,7 +75,7 @@ export class ProjectService extends BaseProjectService< protected async getBlockTimestamp(height: number): Promise { const block = await this.apiService.unsafeApi.api.getBlock(height); - return new Date(block.timestamp * 1000); // TODO test and make sure its in MS not S + return new Date(block.timestamp * 1000); } protected onProjectChange(project: SubqueryProject): void | Promise { diff --git a/packages/node/src/indexer/types.ts b/packages/node/src/indexer/types.ts index ef134e2..48ae4bd 100644 --- a/packages/node/src/indexer/types.ts +++ b/packages/node/src/indexer/types.ts @@ -7,6 +7,9 @@ import { isFullBlock } from '../starknet/block.starknet'; export type BlockContent = StarknetBlock | LightStarknetBlock; export function getBlockSize(block: BlockContent): number { - // TODO. not sure if this is the right way to determine the block size - return isFullBlock(block) ? (block as StarknetBlock).transactions.length : 0; + return isFullBlock(block) + ? block.transactions + .map((tx) => tx.receipt.execution_resources.steps) + .reduce((sum, steps) => sum + steps, 0) + : block.transactions.length; } diff --git a/packages/node/src/indexer/unfinalizedBlocks.service.ts b/packages/node/src/indexer/unfinalizedBlocks.service.ts index 9c94681..073ba08 100644 --- a/packages/node/src/indexer/unfinalizedBlocks.service.ts +++ b/packages/node/src/indexer/unfinalizedBlocks.service.ts @@ -19,9 +19,6 @@ import { BlockContent } from './types'; @Injectable() export class UnfinalizedBlocksService extends BaseUnfinalizedBlocksService { - private supportsFinalization?: boolean; - private startupCheck = true; - constructor( private readonly apiService: ApiService, nodeConfig: NodeConfig, @@ -38,6 +35,7 @@ export class UnfinalizedBlocksService extends BaseUnfinalizedBlocksService { const block = await this.apiService.api.getBlockByHeightOrHash(hash); + return starknetBlockToHeader(formatBlock(block)); } diff --git a/packages/node/src/starknet/api.service.starknet.test.ts b/packages/node/src/starknet/api.service.starknet.test.ts index 2424b33..772e31d 100644 --- a/packages/node/src/starknet/api.service.starknet.test.ts +++ b/packages/node/src/starknet/api.service.starknet.test.ts @@ -81,13 +81,6 @@ describe('ApiService', () => { ).resolves.toHaveLength(4); }); - it('can fetch block events with height', async () => { - //https://starkscan.co/block/500000#events - await expect(apiService.api.fetchBlockLogs(500000)).resolves.toHaveLength( - 637, - ); - }); - it('can get the finalized height', async () => { const height = (await apiService.api.getFinalizedBlock()).block_number; diff --git a/packages/node/src/starknet/api.starknet.test.ts b/packages/node/src/starknet/api.starknet.test.ts index 39dce83..54e79b4 100644 --- a/packages/node/src/starknet/api.starknet.test.ts +++ b/packages/node/src/starknet/api.starknet.test.ts @@ -71,18 +71,18 @@ describe('Api.starknet', () => { expect(blockData.logs[0].transaction.calldata.length).toBeGreaterThan(1); }); - it('should have the ability to get receipts via transactions from all types', async () => { - expect(await blockData.transactions[0].receipt?.()).toBeDefined(); + it('should have the ability to get receipts via transactions from all types', () => { + expect(blockData.transactions[0].receipt).toBeDefined(); - expect(typeof blockData.transactions[0].receipt).toEqual('function'); - expect(typeof blockData.logs[0].transaction.receipt).toEqual('function'); + expect(typeof blockData.transactions[0].receipt).toEqual('object'); + expect(typeof blockData.logs[0].transaction.receipt).toEqual('object'); expect(typeof blockData.logs[0].transaction.from).toEqual('string'); expect(typeof blockData.transactions[1].logs![0].transaction.from).toEqual( 'string', ); expect( typeof blockData.transactions[1].logs![0].transaction.receipt, - ).toEqual('function'); + ).toEqual('object'); }); //https://starkscan.co/tx/0x0153a20567e66728f3c4ba60913a6011b9c73db9ea4d960e959923ed5afd8a24 diff --git a/packages/node/src/starknet/api.starknet.ts b/packages/node/src/starknet/api.starknet.ts index b1d2ed4..52b40cf 100644 --- a/packages/node/src/starknet/api.starknet.ts +++ b/packages/node/src/starknet/api.starknet.ts @@ -3,35 +3,33 @@ import assert from 'assert'; import fs from 'fs'; -import http from 'http'; -import https from 'https'; import { EventEmitter2 } from '@nestjs/event-emitter'; -import { BlockWithTxs, SPEC } from '@starknet-io/types-js'; -import { getLogger, IBlock, timeout } from '@subql/node-core'; +import { BlockWithTxs } from '@starknet-io/types-js'; +import { getLogger, IBlock } from '@subql/node-core'; import { ApiWrapper, StarknetBlock, StarknetRuntimeDatasource, IStarknetEndpointConfig, LightStarknetBlock, - StarknetLogRaw, StarknetResult, StarknetTransaction, StarknetLog, StarknetContractCall, + isFulfilledBlock, } from '@subql/types-starknet'; import { - AbiInterfaces, ProviderInterface, RpcProvider, RpcProviderOptions, - TransactionReceipt, events, CallData, Abi, AbiEntry, FunctionAbi, + transaction, } from 'starknet'; +import { SPEC } from 'starknet-types-07'; import SafeStarknetProvider from './safe-api'; import { hexEq, @@ -40,7 +38,6 @@ import { formatBlock, formatBlockUtil, formatLog, - formatReceipt, formatTransaction, reverseToRawLog, } from './utils.starknet'; @@ -50,8 +47,6 @@ const { version: packageVersion } = require('../../package.json'); const logger = getLogger('api.starknet'); -const DEFAULT_EVENT_CHUNK_SIZE = 1000; - async function loadAssets( ds: StarknetRuntimeDatasource, ): Promise> { @@ -111,7 +106,7 @@ export class StarknetApi implements ApiWrapper { }, batch: this.config?.batchSize ?? false, }; - searchParams.forEach((value, name, searchParams) => { + searchParams.forEach((value, name) => { (connection.headers as any)[name] = value; }); this.client = new RpcProvider(connection); @@ -162,22 +157,26 @@ export class StarknetApi implements ApiWrapper { /*** * Get the latest block (with its header) - * we will try to get the latest block, if it is rejected, we will get the latest accepted block * @returns {Promise} */ - async getFinalizedBlock(): Promise { + async getFinalizedBlock(): Promise> { + // we can not direct use this.client.getBlockLatestAccepted(), because its return missing parent block hash,but we still can retrieve the block number. + // In the meantime we also fetch the latest block, if it is rejected, we will get the latest accepted and fetch more details const [latestBlock, latestAccepted] = await Promise.all([ this.client.getBlock('latest'), - await this.getFinalizedBlockHeight(), + this.getFinalizedBlockHeight(), ]); - // @ts-ignore - let b: SPEC.BLOCK_HEADER = latestBlock; + + // If latest block been reject, we need to fetch the latest accepted block if (latestBlock.status === 'REJECTED') { - b = (await this.getBlockByHeightOrHash( - latestAccepted, - )) as SPEC.BLOCK_WITH_TXS; + const block = await this.getBlockByHeightOrHash(latestAccepted); + return { + block_hash: block.block_hash, + block_number: block.block_number, + parent_hash: block.parent_hash, + }; } - return b; + return latestBlock; } async getFinalizedBlockHeight(): Promise { @@ -200,56 +199,46 @@ export class StarknetApi implements ApiWrapper { async getBlockByHeightOrHash( heightOrHash: number | string, - ): Promise { - // @ts-ignore - return this.client.getBlockWithTxs(heightOrHash); - } - - private async getBlockPromise(num: number, includeTx = true): Promise { - const rawBlock = includeTx - ? await this.client.getBlockWithTxs(num) - : await this.client.getBlockWithTxHashes(num); - - if (!rawBlock) { - throw new Error(`Failed to fetch block ${num}`); + ): Promise { + const block = await this.client.getBlockWithReceipts(heightOrHash); + if (!isFulfilledBlock(block)) { + throw `Block ${block} is not a fulfilled block, its parent is ${block.parent_hash}`; } - - const block = formatBlock(rawBlock); - return block; } - async getTransactionReceipt( - transactionHash: string, - ): Promise { - const receipt = await this.client.getTransactionReceipt(transactionHash); - return formatReceipt(receipt); - } - async fetchBlock(blockNumber: number): Promise> { try { - const block: StarknetBlock = await this.getBlockPromise( - blockNumber, - true, - ); - const logsRaw = await this.fetchBlockLogs(blockNumber); - - block.logs = logsRaw.map((l) => formatLog(l, block)); - // Cast as Tx still raw here - block.transactions = (block.transactions as Record).map( - (tx, index) => ({ - // Format done - ...formatTransaction(tx, block, index), - receipt: () => - this.getTransactionReceipt(tx.transaction_hash).then((r) => - formatReceipt(r), - ), - logs: block.logs.filter( - (l) => l.transactionHash === tx.transaction_hash, + const rawBlock = await this.getBlockByHeightOrHash(blockNumber); + const formattedBlock = formatBlock(rawBlock); + + const formattedTransactions = rawBlock.transactions.map((tx, index) => { + const formattedTransaction = formatTransaction( + tx.transaction, + formattedBlock, + index, + ); + return { + ...formattedTransaction, + logs: tx.receipt.events.map((l, logIndex) => + formatLog(l, logIndex, formattedTransaction, formattedBlock), ), - }), + }; + }); + + const logs: StarknetLog[] = formattedTransactions.flatMap((tx) => + tx.logs.map((l) => ({ + ...l, + transaction: tx, + })), ); + const block: StarknetBlock = { + ...formattedBlock, + transactions: formattedTransactions, + logs, + }; + this.eventEmitter.emit('fetchBlock'); return formatBlockUtil(block); } catch (e: any) { @@ -257,52 +246,22 @@ export class StarknetApi implements ApiWrapper { } } - // This follow method from official document https://starknetjs.com/docs/guides/events - async fetchBlockLogs(blockNumber: number): Promise { - let continuationToken: string | undefined = '0'; - let chunkNum = 1; - const allEvents: StarknetLogRaw[] = []; - - while (continuationToken) { - let eventsRes; - try { - eventsRes = await this.client.getEvents({ - from_block: { - block_number: blockNumber, - }, - to_block: { - block_number: blockNumber, - }, - chunk_size: DEFAULT_EVENT_CHUNK_SIZE, - continuation_token: - continuationToken === '0' ? undefined : continuationToken, - }); - } catch (e: any) { - if (!eventsRes) { - throw new Error( - `Fetch block ${blockNumber} events failed, ${e.message}`, - ); - } else { - throw e; - } - } - const nbEvents = eventsRes.events.length; - continuationToken = eventsRes.continuation_token; - for (let i = 0; i < nbEvents; i++) { - const event = eventsRes.events[i]; - allEvents.push(event); - } - chunkNum++; - } - return allEvents; - } - private async fetchLightBlock( blockNumber: number, ): Promise> { - const block = await this.getBlockPromise(blockNumber, false); + const block = (await this.client.getBlockWithTxHashes( + blockNumber, + )) as SPEC.BLOCK_WITH_TX_HASHES; const lightBlock: LightStarknetBlock = { ...block, + blockHash: block.block_hash, + blockNumber: block.block_number, + parentHash: block.parent_hash, + newRoot: block.new_root, + sequencerAddress: block.sequencer_address, + l1GasPrice: block.l1_gas_price, + starknetVersion: block.starknet_version, + logs: [], }; return formatBlockUtil(lightBlock); } @@ -314,7 +273,9 @@ export class StarknetApi implements ApiWrapper { async fetchBlocksLight( bufferBlocks: number[], ): Promise[]> { - return Promise.all(bufferBlocks.map(async (num) => this.fetchBlock(num))); + return Promise.all( + bufferBlocks.map(async (num) => this.fetchLightBlock(num)), + ); } get api(): RpcProvider { diff --git a/packages/node/src/starknet/utils.starknet.ts b/packages/node/src/starknet/utils.starknet.ts index a86ef4e..899d79e 100644 --- a/packages/node/src/starknet/utils.starknet.ts +++ b/packages/node/src/starknet/utils.starknet.ts @@ -11,6 +11,7 @@ import { StarknetLog, StarknetLogRaw, StarknetTransaction, + StarknetTransactionRaw, } from '@subql/types-starknet'; import { omit } from 'lodash'; import { @@ -29,7 +30,11 @@ export function calcInterval(api: ApiWrapper): number { return 6000; } -export function formatBlock(block: any): StarknetBlock { +export function formatBlock( + block: SPEC.BLOCK_WITH_RECEIPTS | SPEC.BLOCK_WITH_TX_HASHES, +): Omit & { + transactions: StarknetTransactionRaw[]; +} { return { blockHash: block.block_hash, parentHash: block.parent_hash, @@ -42,7 +47,7 @@ export function formatBlock(block: any): StarknetBlock { status: block.status, logs: [], // Filled in at starknetBlockWrapped constructor transactions: block.transactions, // Transaction still raw here, will format in fetchBlock - } as StarknetBlock; + }; } export function formatBlockUtil< @@ -56,31 +61,27 @@ export function formatBlockUtil< export function formatLog( log: StarknetLogRaw, - block: StarknetBlock, + logIndex: number, + tx: StarknetTransaction, + block: Omit & { + transactions: StarknetTransactionRaw[]; + }, ): StarknetLog { const formattedLog = { - block, address: log.from_address, topics: log.keys, blockNumber: block.blockNumber, blockHash: block.blockHash, - transactionHash: log.transaction_hash, + transactionHash: tx.hash, data: log.data, + logIndex: logIndex, + block: block, + transaction: tx, + transactionIndex: tx.transactionIndex, toJSON(): string { return JSON.stringify(omit(this, ['transaction', 'block', 'toJSON'])); }, }; - - // Define this afterwards as the spread on `...log` breaks defining a getter - Object.defineProperty(formattedLog, 'transaction', { - get: () => { - const rawTransaction = block.transactions?.find( - (tx) => tx.hash === log.transaction_hash, - ); - - return rawTransaction; - }, - }); return formattedLog as unknown as StarknetLog; } @@ -110,9 +111,13 @@ export function formatLog( */ export function formatTransaction( tx: Record, - block: StarknetBlock, + block: + | StarknetBlock + | (Omit & { + transactions: StarknetTransactionRaw[]; + }), txIndex: number, -): Omit { +): StarknetTransaction { const transaction = { ...tx, hash: tx.transaction_hash, @@ -128,6 +133,7 @@ export function formatTransaction( transactionIndex: txIndex, entryPointSelector: tx.entry_point_selector, contractAddress: tx.contract_address, + receipt: formatReceipt(tx.receipt), parseCallData(): StarknetContractCall[] | undefined { if (this.decodedCalls) { return this.decodedCalls; @@ -159,7 +165,7 @@ export function formatTransaction( toJSON(): string { return JSON.stringify(omit(this, ['receipt', 'toJSON'])); }, - } as Omit; + } as StarknetTransaction; return transaction; } @@ -187,7 +193,13 @@ export function formatReceipt( } as unknown as TransactionReceipt; } -export function starknetBlockToHeader(block: BlockContent): Header { +export function starknetBlockToHeader( + block: + | BlockContent + | (Omit & { + transactions: StarknetTransactionRaw[]; + }), +): Header { return { blockHeight: block.blockNumber, blockHash: block.blockHash, @@ -195,16 +207,18 @@ export function starknetBlockToHeader(block: BlockContent): Header { }; } -export function starknetBlockHeaderToHeader(block: SPEC.BLOCK_HEADER): Header { +export function starknetBlockHeaderToHeader( + block: Partial, +): Header { return { - blockHeight: block.block_number, - blockHash: block.block_hash, + blockHeight: block.block_number!, + blockHash: block.block_hash!, parentHash: block.parent_hash, }; } //TODO, only used to phrase abi event -export function reverseToRawLog(log: StarknetLog): StarknetLogRaw { +export function reverseToRawLog(log: StarknetLog): SPEC.EMITTED_EVENT { return { block_hash: log.blockHash, keys: [...log.topics], diff --git a/packages/types/src/interfaces.ts b/packages/types/src/interfaces.ts index becf1ce..a2e6226 100644 --- a/packages/types/src/interfaces.ts +++ b/packages/types/src/interfaces.ts @@ -1,7 +1,7 @@ // Copyright 2020-2024 SubQuery Pte Ltd authors & contributors // SPDX-License-Identifier: GPL-3.0 -import {BlockWithTxs} from '@starknet-io/types-js'; +import {SPEC} from 'starknet-types-07'; export interface ApiWrapper { init: () => Promise; @@ -9,5 +9,5 @@ export interface ApiWrapper { getChainId: () => string; getSpecVersion: () => string; getFinalizedBlockHeight: () => Promise; - getBlockByHeightOrHash: (hashOrHeight: number | string) => Promise; + getBlockByHeightOrHash: (hashOrHeight: number | string) => Promise; } diff --git a/packages/types/src/starknet/index.ts b/packages/types/src/starknet/index.ts index 203b0d7..37c1001 100644 --- a/packages/types/src/starknet/index.ts +++ b/packages/types/src/starknet/index.ts @@ -2,3 +2,4 @@ // SPDX-License-Identifier: GPL-3.0 export * from './interfaces'; +export * from './utils'; diff --git a/packages/types/src/starknet/interfaces.ts b/packages/types/src/starknet/interfaces.ts index b0dae41..9e3a2cc 100644 --- a/packages/types/src/starknet/interfaces.ts +++ b/packages/types/src/starknet/interfaces.ts @@ -5,7 +5,14 @@ import {BlockHash, Felt, SPEC} from '@starknet-io/types-js'; import {BlockFilter} from '@subql/types-core'; import {ParsedEvent, TransactionReceipt} from 'starknet'; -export type StarknetLogRaw = SPEC.EMITTED_EVENT; +export type StarknetLogRaw = SPEC.EVENT; + +export type StarknetFullTx = { + transaction: SPEC.TXN; + receipt: SPEC.TXN_RECEIPT; +}; + +export type StarknetTransactionRaw = StarknetFullTx | SPEC.TXN_HASH; export type StarknetBlockFilter = BlockFilter; @@ -61,7 +68,7 @@ export interface StarknetLogFilter { export type StarknetResult = ParsedEvent; -export type StarknetBlock = LightStarknetBlock & { +export type StarknetBlock = Omit & { transactions: StarknetTransaction[]; logs: StarknetLog[]; }; @@ -78,6 +85,7 @@ export type LightStarknetBlock = { starknetVersion: string; status: SPEC.BLOCK_STATUS; logs: StarknetLog[]; + transactions: SPEC.TXN_HASH[]; }; export interface StarknetContractCall> { @@ -90,6 +98,8 @@ export interface StarknetContractCall> { export type StarknetTransaction = { type: SPEC.TXN_TYPE; hash: string; + nonce: number; + maxFee: number; // This is sender_address or contract_address from: string; blockHash: string; @@ -104,8 +114,8 @@ export type StarknetTransaction = { // Store decoded calls, also store abi parsed data/args decodedCalls?: StarknetContractCall[]; // Parse the calldata also save into local decodedCalls - parseCallData: () => StarknetContractCall[]; - receipt?: () => Promise; + parseCallData: () => StarknetContractCall[] | undefined; + receipt: TransactionReceipt; logs?: StarknetLog[]; }; @@ -117,6 +127,7 @@ export type StarknetLog = { blockNumber: number; transactionHash: string; transactionIndex: number; + logIndex: number; args?: T; block: StarknetBlock; transaction: StarknetTransaction; diff --git a/packages/types/src/starknet/utils.ts b/packages/types/src/starknet/utils.ts new file mode 100644 index 0000000..327b452 --- /dev/null +++ b/packages/types/src/starknet/utils.ts @@ -0,0 +1,10 @@ +// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors +// SPDX-License-Identifier: GPL-3.0 + +import {SPEC} from 'starknet-types-07'; + +export function isFulfilledBlock( + block: SPEC.BLOCK_WITH_RECEIPTS | SPEC.PENDING_BLOCK_WITH_RECEIPTS +): block is SPEC.BLOCK_WITH_RECEIPTS { + return 'status' in block && block.status !== 'PENDING' && block.status !== 'REJECTED'; +} From d7c8031237966aac4373ce55a1d69680c36e20a5 Mon Sep 17 00:00:00 2001 From: JQQQ Date: Wed, 22 Jan 2025 17:18:27 +1300 Subject: [PATCH 2/5] =?UTF-8?q?Fix=202=EF=BC=8C=20remove=20non-null=20asse?= =?UTF-8?q?rtion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/node/src/starknet/block.starknet.ts | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/node/src/starknet/block.starknet.ts b/packages/node/src/starknet/block.starknet.ts index 7a9d581..b64f3c3 100644 --- a/packages/node/src/starknet/block.starknet.ts +++ b/packages/node/src/starknet/block.starknet.ts @@ -86,8 +86,9 @@ export function filterTransactionsProcessor( if (filter.function) { const index = decodedCalls?.findIndex( (call) => - hexEq(call.selector, filter.function!) || - hexEq(call.selector, encodeSelectorToHex(filter.function!)), + typeof filter.function === 'string' && + (hexEq(call.selector, filter.function) || + hexEq(call.selector, encodeSelectorToHex(filter.function))), ); if (index === -1) { return false; @@ -100,8 +101,8 @@ export function filterTransactionsProcessor( if (filter.to || address) { // if filter.to is not provided, we use address as filter const filterAddress = filter.to ?? address; - const index = decodedCalls?.findIndex((call) => - hexEq(call.to, filterAddress!), + const index = decodedCalls?.findIndex( + (call) => filterAddress && hexEq(call.to, filterAddress), ); if (index === -1) { return false; @@ -115,16 +116,17 @@ export function filterTransactionsProcessor( if (filter.function) { const index = transaction.calldata?.findIndex( (call) => - call === filter.function || - call === encodeSelectorToHex(filter.function!), + typeof filter.function === 'string' && + (call === filter.function || + call === encodeSelectorToHex(filter.function)), ); if (index === -1) { return false; } } if (filter.to) { - const index = transaction.calldata?.findIndex((call) => - hexEq(call, filter.to!), + const index = transaction.calldata?.findIndex( + (call) => typeof filter.to === 'string' && hexEq(call, filter.to), ); if (index === -1) { return false; @@ -146,7 +148,7 @@ export function filterLogsProcessor( if ( filter.topics?.length && log.topics?.length && - topicsHaveNoCommonElements(filter.topics!, log.topics) + topicsHaveNoCommonElements(filter.topics, log.topics) ) { return false; } From 7d9246859424e3e7f20d7fcecded85c6ccb5937b Mon Sep 17 00:00:00 2001 From: JQQQ Date: Wed, 22 Jan 2025 17:25:50 +1300 Subject: [PATCH 3/5] remove unused --- .../src/indexer/blockDispatcher/block-dispatcher.service.ts | 2 -- packages/node/src/starknet/block.starknet.ts | 1 - packages/node/src/utils/project.ts | 1 - packages/types/src/modular.ts | 1 - 4 files changed, 5 deletions(-) diff --git a/packages/node/src/indexer/blockDispatcher/block-dispatcher.service.ts b/packages/node/src/indexer/blockDispatcher/block-dispatcher.service.ts index efb95b1..07cd8ae 100644 --- a/packages/node/src/indexer/blockDispatcher/block-dispatcher.service.ts +++ b/packages/node/src/indexer/blockDispatcher/block-dispatcher.service.ts @@ -15,12 +15,10 @@ import { IBlock, IStoreModelProvider, } from '@subql/node-core'; -import { StarknetBlock } from '@subql/types-starknet'; import { StarknetProjectDs, SubqueryProject, } from '../../configure/SubqueryProject'; -import { isFullBlock } from '../../starknet/block.starknet'; import { IndexerManager } from '../indexer.manager'; import { BlockContent, getBlockSize } from '../types'; diff --git a/packages/node/src/starknet/block.starknet.ts b/packages/node/src/starknet/block.starknet.ts index b64f3c3..990103d 100644 --- a/packages/node/src/starknet/block.starknet.ts +++ b/packages/node/src/starknet/block.starknet.ts @@ -17,7 +17,6 @@ import { hexEq, encodeSelectorToHex, encodeEventKey } from './utils.starknet'; export function filterBlocksProcessor( block: StarknetBlock, filter: StarknetBlockFilter, - address?: string, ): boolean { if (filter?.modulo && block.blockNumber % filter.modulo !== 0) { return false; diff --git a/packages/node/src/utils/project.ts b/packages/node/src/utils/project.ts index c9b06a7..a819bd9 100644 --- a/packages/node/src/utils/project.ts +++ b/packages/node/src/utils/project.ts @@ -10,7 +10,6 @@ import { isCustomDs, isRuntimeDs, } from '@subql/common-starknet'; -import { retryOnFail } from '@subql/node-core'; import { StarknetProjectDs, SubqueryProject, diff --git a/packages/types/src/modular.ts b/packages/types/src/modular.ts index 5585319..d25afbc 100644 --- a/packages/types/src/modular.ts +++ b/packages/types/src/modular.ts @@ -2,7 +2,6 @@ // SPDX-License-Identifier: GPL-3.0 import {INetworkCommonModule} from '@subql/types-core'; -import {Data} from 'ejs'; import {AbiInterfaces} from 'starknet'; import {StarknetCustomDatasource, SubqlDatasource, StarknetRuntimeDatasource} from './project'; From d74bf864069fb0938254fb77fe2e792270812f2a Mon Sep 17 00:00:00 2001 From: JQQQ Date: Wed, 22 Jan 2025 17:30:18 +1300 Subject: [PATCH 4/5] fix removed lead type error --- packages/node/src/starknet/block.starknet.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/node/src/starknet/block.starknet.ts b/packages/node/src/starknet/block.starknet.ts index 990103d..b64f3c3 100644 --- a/packages/node/src/starknet/block.starknet.ts +++ b/packages/node/src/starknet/block.starknet.ts @@ -17,6 +17,7 @@ import { hexEq, encodeSelectorToHex, encodeEventKey } from './utils.starknet'; export function filterBlocksProcessor( block: StarknetBlock, filter: StarknetBlockFilter, + address?: string, ): boolean { if (filter?.modulo && block.blockNumber % filter.modulo !== 0) { return false; From 9dbee4cda88015f9af9f2001565cf7d7d7b934f2 Mon Sep 17 00:00:00 2001 From: JQQQ Date: Wed, 22 Jan 2025 18:05:07 +1300 Subject: [PATCH 5/5] fix missing receipt issue --- packages/node/src/starknet/api.starknet.ts | 2 +- packages/node/src/starknet/utils.starknet.ts | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/node/src/starknet/api.starknet.ts b/packages/node/src/starknet/api.starknet.ts index 52b40cf..bbfcbb1 100644 --- a/packages/node/src/starknet/api.starknet.ts +++ b/packages/node/src/starknet/api.starknet.ts @@ -214,7 +214,7 @@ export class StarknetApi implements ApiWrapper { const formattedTransactions = rawBlock.transactions.map((tx, index) => { const formattedTransaction = formatTransaction( - tx.transaction, + tx, formattedBlock, index, ); diff --git a/packages/node/src/starknet/utils.starknet.ts b/packages/node/src/starknet/utils.starknet.ts index 899d79e..330472e 100644 --- a/packages/node/src/starknet/utils.starknet.ts +++ b/packages/node/src/starknet/utils.starknet.ts @@ -119,20 +119,20 @@ export function formatTransaction( txIndex: number, ): StarknetTransaction { const transaction = { - ...tx, - hash: tx.transaction_hash, - type: tx.type, - version: tx.version, - nonce: tx.nonce, - maxFee: tx.max_fee, - from: getTxContractAddress(tx), - calldata: tx.calldata, + ...tx.transaction, + hash: tx.transaction.transaction_hash, + type: tx.transaction.type, + version: tx.transaction.version, + nonce: tx.transaction.nonce, + maxFee: tx.transaction.max_fee, + from: getTxContractAddress(tx.transaction), + calldata: tx.transaction.calldata, blockHash: block.blockHash, blockNumber: block.blockNumber, blockTimestamp: block.timestamp, transactionIndex: txIndex, - entryPointSelector: tx.entry_point_selector, - contractAddress: tx.contract_address, + entryPointSelector: tx.transaction.entry_point_selector, + contractAddress: tx.transaction.contract_address, receipt: formatReceipt(tx.receipt), parseCallData(): StarknetContractCall[] | undefined { if (this.decodedCalls) {