diff --git a/contracts/BlockInfo.sol b/contracts/BlockInfo.sol new file mode 100644 index 0000000..39a245c --- /dev/null +++ b/contracts/BlockInfo.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +contract BlockInfo { + function blockInfo() external view returns (uint256 timestamp, uint256 blockNumber) { + return (block.timestamp, block.number); + } +} \ No newline at end of file diff --git a/src/all-tests.ts b/src/all-tests.ts index 4317a49..84a3c1e 100644 --- a/src/all-tests.ts +++ b/src/all-tests.ts @@ -8,6 +8,7 @@ await import('./gas.test.ts') await import('./others.test.ts') await import('./tracing-call-trace.test.ts') await import('./tracing-prestate.test.ts') +await import('./block-info.test.ts') globalThis.addEventListener('unload', () => { cleanupTests() diff --git a/src/block-info.test.ts b/src/block-info.test.ts new file mode 100644 index 0000000..6abe256 --- /dev/null +++ b/src/block-info.test.ts @@ -0,0 +1,71 @@ +import { CallReturnType, decodeFunctionResult, encodeFunctionData } from 'viem' +import { + getByteCode, + getEnv, + memoizedTx, + sanitizeOpts as opts, +} from './util.ts' +import { expect } from '@std/expect' +import { BlockInfoAbi } from '../codegen/abi/BlockInfo.ts' + +// Initialize test environment +const env = await getEnv() + +const getBlockInfoReceipt = memoizedTx( + env, + () => + env.serverWallet.deployContract({ + abi: BlockInfoAbi, + bytecode: getByteCode('BlockInfo', env.evm), + }), +) + +const getBlockInfoAddr = () => + getBlockInfoReceipt().then((r) => r.contractAddress!) + +Deno.test('eth_call with latest block tag', opts, async () => { + const address = await getBlockInfoAddr() + + const latestBlock = await env.serverWallet.getBlock({ blockTag: 'latest' }) + + const callReturn: CallReturnType = await env.serverWallet.call({ + to: address, + data: encodeFunctionData({ + abi: BlockInfoAbi, + functionName: 'blockInfo', + }), + blockTag: 'latest', + }) + + const [blockTimestamp, blockNumber] = decodeFunctionResult({ + abi: BlockInfoAbi, + functionName: 'blockInfo', + data: callReturn?.data!, + }) + expect(blockNumber).toEqual(latestBlock.number) + expect(blockTimestamp).toEqual(latestBlock.timestamp) +}) + +Deno.test('eth_call with pending block tag', opts, async () => { + const address = await getBlockInfoAddr() + + const latestBlock = await env.serverWallet.getBlock({ blockTag: 'latest' }) + + const callReturn: CallReturnType = await env.serverWallet.call({ + to: address, + data: encodeFunctionData({ + abi: BlockInfoAbi, + functionName: 'blockInfo', + }), + blockTag: 'pending', + }) + + const [blockTimestamp, blockNumber] = decodeFunctionResult({ + abi: BlockInfoAbi, + functionName: 'blockInfo', + data: callReturn?.data!, + }) + + expect(blockNumber).toEqual(latestBlock.number + 1n) + expect(blockTimestamp).toBeGreaterThan(Number(latestBlock.timestamp)) +})