From aab99e1d98f51f36eb557ac56604cbb8c7de0412 Mon Sep 17 00:00:00 2001 From: nikolay Date: Thu, 9 Oct 2025 16:04:54 +0300 Subject: [PATCH 1/3] chore: fix method Signed-off-by: nikolay --- .../ethService/blockService/BlockService.ts | 10 ++++---- .../lib/eth/eth_getBlockReceipts.spec.ts | 2 ++ .../tests/acceptance/rpc_batch1.spec.ts | 24 +++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/packages/relay/src/lib/services/ethService/blockService/BlockService.ts b/packages/relay/src/lib/services/ethService/blockService/BlockService.ts index 109a74515c..7e1400c68e 100644 --- a/packages/relay/src/lib/services/ethService/blockService/BlockService.ts +++ b/packages/relay/src/lib/services/ethService/blockService/BlockService.ts @@ -136,16 +136,18 @@ export class BlockService implements IBlockService { timestamp: [`lte:${block.timestamp.to}`, `gte:${block.timestamp.from}`], }; - const contractResults = await this.mirrorNodeClient.getContractResults(requestDetails, paramTimestamp); - if (!contractResults || contractResults.length === 0) { + const [contractResults, logs] = await Promise.all([ + this.mirrorNodeClient.getContractResults(requestDetails, paramTimestamp), + this.common.getLogsWithParams(null, paramTimestamp, requestDetails) + ]); + + if ((!contractResults || contractResults.length === 0) && logs.length == 0) { return []; } const receipts: ITransactionReceipt[] = []; const effectiveGas = numberTo0x(await this.common.getGasPriceInWeibars(block.timestamp.from.split('.')[0])); - const logs = await this.common.getLogsWithParams(null, paramTimestamp, requestDetails); - const logsByHash = new Map(); for (const log of logs) { const existingLogs = logsByHash.get(log.transactionHash) || []; diff --git a/packages/relay/tests/lib/eth/eth_getBlockReceipts.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockReceipts.spec.ts index 5de125d209..8ff6013e82 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockReceipts.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockReceipts.spec.ts @@ -170,6 +170,7 @@ describe('@ethGetBlockReceipts using MirrorNode', async function () { it('should return empty array for block with no transactions', async function () { restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL_2).reply(200, JSON.stringify({ results: [] })); + restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL_2).reply(200, JSON.stringify({ results: [] })); restMock.onGet(`blocks/${BLOCK_HASH}`).reply(200, JSON.stringify(DEFAULT_BLOCK)); const receipts = await ethImpl.getBlockReceipts(BLOCK_HASH, requestDetails); @@ -320,6 +321,7 @@ describe('@ethGetBlockReceipts using MirrorNode', async function () { describe('Error cases', () => { it('should handle transactions with no contract results', async function () { restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL_2).reply(200, JSON.stringify({ results: [] })); + restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL_2).reply(200, JSON.stringify({ results: [] })); restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, JSON.stringify({ blocks: [DEFAULT_BLOCK] })); restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(200, JSON.stringify(DEFAULT_BLOCK)); diff --git a/packages/server/tests/acceptance/rpc_batch1.spec.ts b/packages/server/tests/acceptance/rpc_batch1.spec.ts index 57c1da8376..af6d17400a 100644 --- a/packages/server/tests/acceptance/rpc_batch1.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch1.spec.ts @@ -643,6 +643,30 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { expect(blockResult.transactions.filter((tx) => tx.hash == txHash)[0].value).to.equal('0xffffffffffffff9c'); }); + it('should execute "eth_getBlockReceipts" for a block that contains synthetic transaction', async function() { + const tokenId = await servicesNode.createToken(1000); + await accounts[2].client.associateToken(tokenId); + const transaction = new TransferTransaction() + .addTokenTransfer(tokenId, servicesNode._thisAccountId(), -10) + .addTokenTransfer(tokenId, accounts[2].accountId, 10) + .setTransactionMemo('Relay test token transfer'); + const resp = await transaction.execute(servicesNode.client); + await resp.getRecord(servicesNode.client); + await Utils.wait(1000); + const logsRes = await mirrorNode.get(`/contracts/results/logs?limit=1`); + const blockNumber = logsRes.logs[0].block_number; + const formattedBlockNumber = prepend0x(blockNumber.toString(16)); + const contractId = logsRes.logs[0].contract_id; + const transactionHash = logsRes.logs[0].transaction_hash; + if (contractId !== tokenId.toString()) { + return; + } + + const receipts = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_RECEIPTS, [formattedBlockNumber]); + expect(receipts).to.not.be.empty; + expect(receipts.filter(receipt => receipt.transactionHash === transactionHash)).to.not.be.empty; + }); + it('should execute "eth_getBlockReceipts" with block hash successfully', async function () { const res = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_RECEIPTS, [ mirrorBlock.hash.substring(0, 66), From fdcddf86465f9bee4ca597f5edc6c954e44e197b Mon Sep 17 00:00:00 2001 From: nikolay Date: Thu, 9 Oct 2025 16:12:27 +0300 Subject: [PATCH 2/3] chore: add trailing comma Signed-off-by: nikolay --- .../src/lib/services/ethService/blockService/BlockService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/relay/src/lib/services/ethService/blockService/BlockService.ts b/packages/relay/src/lib/services/ethService/blockService/BlockService.ts index 7e1400c68e..b320ee94fb 100644 --- a/packages/relay/src/lib/services/ethService/blockService/BlockService.ts +++ b/packages/relay/src/lib/services/ethService/blockService/BlockService.ts @@ -138,7 +138,7 @@ export class BlockService implements IBlockService { const [contractResults, logs] = await Promise.all([ this.mirrorNodeClient.getContractResults(requestDetails, paramTimestamp), - this.common.getLogsWithParams(null, paramTimestamp, requestDetails) + this.common.getLogsWithParams(null, paramTimestamp, requestDetails), ]); if ((!contractResults || contractResults.length === 0) && logs.length == 0) { From 3c6187b43ad31859d146fe31bf8725102714e6e5 Mon Sep 17 00:00:00 2001 From: nikolay Date: Thu, 9 Oct 2025 16:35:36 +0300 Subject: [PATCH 3/3] chore: fix tests Signed-off-by: nikolay --- .../tests/acceptance/rpc_batch1.spec.ts | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/packages/server/tests/acceptance/rpc_batch1.spec.ts b/packages/server/tests/acceptance/rpc_batch1.spec.ts index af6d17400a..44f7b8237c 100644 --- a/packages/server/tests/acceptance/rpc_batch1.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch1.spec.ts @@ -643,30 +643,6 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { expect(blockResult.transactions.filter((tx) => tx.hash == txHash)[0].value).to.equal('0xffffffffffffff9c'); }); - it('should execute "eth_getBlockReceipts" for a block that contains synthetic transaction', async function() { - const tokenId = await servicesNode.createToken(1000); - await accounts[2].client.associateToken(tokenId); - const transaction = new TransferTransaction() - .addTokenTransfer(tokenId, servicesNode._thisAccountId(), -10) - .addTokenTransfer(tokenId, accounts[2].accountId, 10) - .setTransactionMemo('Relay test token transfer'); - const resp = await transaction.execute(servicesNode.client); - await resp.getRecord(servicesNode.client); - await Utils.wait(1000); - const logsRes = await mirrorNode.get(`/contracts/results/logs?limit=1`); - const blockNumber = logsRes.logs[0].block_number; - const formattedBlockNumber = prepend0x(blockNumber.toString(16)); - const contractId = logsRes.logs[0].contract_id; - const transactionHash = logsRes.logs[0].transaction_hash; - if (contractId !== tokenId.toString()) { - return; - } - - const receipts = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_RECEIPTS, [formattedBlockNumber]); - expect(receipts).to.not.be.empty; - expect(receipts.filter(receipt => receipt.transactionHash === transactionHash)).to.not.be.empty; - }); - it('should execute "eth_getBlockReceipts" with block hash successfully', async function () { const res = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_RECEIPTS, [ mirrorBlock.hash.substring(0, 66), @@ -756,6 +732,30 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { ]); expect(res).to.be.null; }); + + it('should execute "eth_getBlockReceipts" for a block that contains synthetic transaction', async function() { + const tokenId = await servicesNode.createToken(1000); + await accounts[2].client.associateToken(tokenId); + const transaction = new TransferTransaction() + .addTokenTransfer(tokenId, servicesNode._thisAccountId(), -10) + .addTokenTransfer(tokenId, accounts[2].accountId, 10) + .setTransactionMemo('Relay test token transfer'); + const resp = await transaction.execute(servicesNode.client); + await resp.getRecord(servicesNode.client); + await Utils.wait(1000); + const logsRes = await mirrorNode.get(`/contracts/results/logs?limit=1`); + const blockNumber = logsRes.logs[0].block_number; + const formattedBlockNumber = prepend0x(blockNumber.toString(16)); + const contractId = logsRes.logs[0].contract_id; + const transactionHash = logsRes.logs[0].transaction_hash; + if (contractId !== tokenId.toString()) { + return; + } + + const receipts = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_RECEIPTS, [formattedBlockNumber]); + expect(receipts).to.not.be.empty; + expect(receipts.filter(receipt => receipt.transactionHash === transactionHash)).to.not.be.empty; + }); }); describe('Transaction related RPC Calls', () => {