From adc7a0f83d2da429fee3c06afc0574d47377524c Mon Sep 17 00:00:00 2001 From: Shunji Zhan Date: Sat, 2 Nov 2024 00:38:17 +0800 Subject: [PATCH] fix --- packages/eth-providers/src/base-provider.ts | 114 ++++++++++-------- .../eth_getBlockByNumber.test.ts | 11 +- .../src/__tests__/utils/eth-rpc-apis.ts | 1 + 3 files changed, 71 insertions(+), 55 deletions(-) diff --git a/packages/eth-providers/src/base-provider.ts b/packages/eth-providers/src/base-provider.ts index 7e620eb50..020aa453a 100644 --- a/packages/eth-providers/src/base-provider.ts +++ b/packages/eth-providers/src/base-provider.ts @@ -619,67 +619,75 @@ export abstract class BaseProvider extends AbstractProvider { const blockHash = header.hash.toHex(); const blockNumber = header.number.toNumber(); + let blockDataFull: BlockData; + const cacheKey = `block-${blockHash}`; const cached = this.queryCache.get(cacheKey); - if (cached) return cached; - - const [block, headerExtended, timestamp, receiptsFromSubql] = await Promise.all([ - this.api.rpc.chain.getBlock(blockHash), - this.api.derive.chain.getHeader(blockHash), - getTimestamp(this.api, blockHash), - this.subql?.getAllReceiptsAtBlock(blockHash), - ]); + if (cached) { + blockDataFull = cached; + } else { + const [block, headerExtended, timestamp, receiptsFromSubql] = await Promise.all([ + this.api.rpc.chain.getBlock(blockHash), + this.api.derive.chain.getHeader(blockHash), + getTimestamp(this.api, blockHash), + this.subql?.getAllReceiptsAtBlock(blockHash), + ]); - // blockscout need `toLowerCase` - const author = (await this.getEvmAddress(headerExtended.author.toString(), blockHash)).toLowerCase(); + // blockscout need `toLowerCase` + const author = (await this.getEvmAddress(headerExtended.author.toString(), blockHash)).toLowerCase(); - let receipts: TransactionReceipt[]; - if (receiptsFromSubql?.length) { - receipts = receiptsFromSubql.map(subqlReceiptAdapter); - } else { - /* ---------- - if nothing is returned from subql, either no tx exists in this block, - or the block not finalized. So we still need to ask block cache. - ---------- */ - receipts = this.blockCache.getAllReceiptsAtBlock(blockHash); - } + let receipts: TransactionReceipt[]; + if (receiptsFromSubql?.length) { + receipts = receiptsFromSubql.map(subqlReceiptAdapter); + } else { + /* ---------- + if nothing is returned from subql, either no tx exists in this block, + or the block not finalized. So we still need to ask block cache. + ---------- */ + receipts = this.blockCache.getAllReceiptsAtBlock(blockHash); + } - const transactions = full - ? receipts.map(tx => receiptToTransaction(tx, block)) - : receipts.map(tx => tx.transactionHash as `0x${string}`); - - const gasUsed = receipts.reduce((totalGas, tx) => totalGas.add(tx.gasUsed), BIGNUMBER_ZERO); - - const blockData: BlockData = { - hash: blockHash, - parentHash: headerExtended.parentHash.toHex(), - number: blockNumber, - stateRoot: headerExtended.stateRoot.toHex(), - transactionsRoot: headerExtended.extrinsicsRoot.toHex(), - timestamp: Math.floor(timestamp / 1000), - nonce: DUMMY_BLOCK_NONCE, - mixHash: ZERO_BLOCK_HASH, - difficulty: ZERO, - totalDifficulty: ZERO, - gasLimit: BigNumber.from(BLOCK_GAS_LIMIT), - gasUsed, - - miner: author, - extraData: EMPTY_HEX_STRING, - sha3Uncles: EMTPY_UNCLE_HASH, - receiptsRoot: headerExtended.extrinsicsRoot.toHex(), - logsBloom: DUMMY_LOGS_BLOOM, // TODO: ??? - size: block.encodedLength, - uncles: EMTPY_UNCLES, - - transactions, - }; + const transactions = receipts.map(tx => receiptToTransaction(tx, block)); + const gasUsed = receipts.reduce((totalGas, tx) => totalGas.add(tx.gasUsed), BIGNUMBER_ZERO); + + const blockDataFull: BlockData = { + hash: blockHash, + parentHash: headerExtended.parentHash.toHex(), + number: blockNumber, + stateRoot: headerExtended.stateRoot.toHex(), + transactionsRoot: headerExtended.extrinsicsRoot.toHex(), + timestamp: Math.floor(timestamp / 1000), + nonce: DUMMY_BLOCK_NONCE, + mixHash: ZERO_BLOCK_HASH, + difficulty: ZERO, + totalDifficulty: ZERO, + gasLimit: BigNumber.from(BLOCK_GAS_LIMIT), + gasUsed, + + miner: author, + extraData: EMPTY_HEX_STRING, + sha3Uncles: EMTPY_UNCLE_HASH, + receiptsRoot: headerExtended.extrinsicsRoot.toHex(), + logsBloom: DUMMY_LOGS_BLOOM, // TODO: ??? + size: block.encodedLength, + uncles: EMTPY_UNCLES, + + transactions, + }; - const isFinalized = blockNumber <= await this.finalizedBlockNumber; - if (isFinalized) { - this.queryCache.set(cacheKey, blockData); + const isFinalized = blockNumber <= await this.finalizedBlockNumber; + if (isFinalized) { + this.queryCache.set(cacheKey, blockDataFull); + } } + const blockData = full + ? blockDataFull + : { + ...blockDataFull, + transactions: blockDataFull.transactions.map(tx => (tx as TX).hash as `0x${string}`), + }; + return blockData; }; diff --git a/packages/eth-rpc-adapter/src/__tests__/endpoint-tests/eth_getBlockByNumber.test.ts b/packages/eth-rpc-adapter/src/__tests__/endpoint-tests/eth_getBlockByNumber.test.ts index 2d649bc9b..87268db32 100644 --- a/packages/eth-rpc-adapter/src/__tests__/endpoint-tests/eth_getBlockByNumber.test.ts +++ b/packages/eth-rpc-adapter/src/__tests__/endpoint-tests/eth_getBlockByNumber.test.ts @@ -1,10 +1,10 @@ import { describe, expect, it } from 'vitest'; -import { deployErc20, eth_getBlockByNumber, testSetup } from '../utils'; +import { deployErc20, eth_getBlockByHash, eth_getBlockByNumber, testSetup } from '../utils'; const { wallet, provider } = testSetup; -describe('eth_getBlockByNumber', () => { +describe('eth_getBlockByNumber and eth_getBlockByHash', () => { it('get correct block info', async () => { const token = await deployErc20(wallet); const txHash = token.deployTransaction.hash; @@ -24,6 +24,13 @@ describe('eth_getBlockByNumber', () => { to: null, value: '0x0', }); + + // getblockbyhash should return the same result + const resHash = (await eth_getBlockByHash([resFull.hash, false])).data.result; + const resHashFull = (await eth_getBlockByHash([resFull.hash, true])).data.result; + + expect(resHash).to.deep.equal(res); + expect(resHashFull).to.deep.equal(resFull); }); it('returns null when block not found', async () => { diff --git a/packages/eth-rpc-adapter/src/__tests__/utils/eth-rpc-apis.ts b/packages/eth-rpc-adapter/src/__tests__/utils/eth-rpc-apis.ts index dd89153b2..0bb8f1e7f 100644 --- a/packages/eth-rpc-adapter/src/__tests__/utils/eth-rpc-apis.ts +++ b/packages/eth-rpc-adapter/src/__tests__/utils/eth-rpc-apis.ts @@ -21,6 +21,7 @@ export const rpcGet = export const eth_call = rpcGet('eth_call'); export const eth_blockNumber = rpcGet('eth_blockNumber'); export const eth_getBlockByNumber = rpcGet('eth_getBlockByNumber'); +export const eth_getBlockByHash = rpcGet('eth_getBlockByHash'); export const eth_getTransactionReceipt = rpcGet('eth_getTransactionReceipt'); export const eth_getLogs = rpcGet<{ data: { result: LogHexified[]; error?: JsonRpcError } }>('eth_getLogs'); export const eth_getTransactionByHash = rpcGet('eth_getTransactionByHash');