From 2a774e5d8475f8617a466be4675bd36d78386de7 Mon Sep 17 00:00:00 2001 From: g11tech Date: Sun, 30 Jun 2024 17:05:56 +0530 Subject: [PATCH] vm: remove backfill of block hashes on 2935 activation (#3478) --- packages/vm/src/runBlock.ts | 24 ------------- .../eip-2935-historical-block-hashes.spec.ts | 34 ++++++++++++------- 2 files changed, 22 insertions(+), 36 deletions(-) diff --git a/packages/vm/src/runBlock.ts b/packages/vm/src/runBlock.ts index 5c5a15343b..b2a4367788 100644 --- a/packages/vm/src/runBlock.ts +++ b/packages/vm/src/runBlock.ts @@ -493,8 +493,6 @@ export async function accumulateParentBlockHash( ) const historyServeWindow = this.common.param('vm', 'historyServeWindow') - const forkTime = this.common.eipTimestamp(2935) - // getAccount with historyAddress will throw error as witnesses are not bundeled // but we need to put account so as to query later for slot try { @@ -524,28 +522,6 @@ export async function accumulateParentBlockHash( } await putBlockHash(this, parentHash, currentBlockNumber - BIGINT_1) - // in stateless execution parentBlock is not in blockchain but in chain's blockCache - // need to move the blockCache to the blockchain, in any case we can ignore forkblock - // which is where we need this code segment - try { - const parentBlock = await this.blockchain.getBlock(parentHash) - - // If on the fork block, store the old block hashes as well - if (forkTime !== null && parentBlock.header.timestamp < forkTime) { - // forkTime could be null in test fixtures - let ancestor = parentBlock - for (let i = 0; i < Number(historyServeWindow) - 1; i++) { - if (ancestor.header.number === BIGINT_0) { - break - } - - ancestor = await this.blockchain.getBlock(ancestor.header.parentHash) - await putBlockHash(this, ancestor.hash(), ancestor.header.number) - } - } - // eslint-disable-next-line no-empty - } catch (_e) {} - // do cleanup if the code was not deployed await this.evm.journal.cleanup() } diff --git a/packages/vm/test/api/EIPs/eip-2935-historical-block-hashes.spec.ts b/packages/vm/test/api/EIPs/eip-2935-historical-block-hashes.spec.ts index c2e16b34b5..f6676ac6ea 100644 --- a/packages/vm/test/api/EIPs/eip-2935-historical-block-hashes.spec.ts +++ b/packages/vm/test/api/EIPs/eip-2935-historical-block-hashes.spec.ts @@ -211,9 +211,9 @@ describe('EIP 2935: historical block hashes', () => { }) it('should ensure blocks older than 256 blocks can be retrieved from the history contract', async () => { // Test: build a chain with 256+ blocks and then retrieve BLOCKHASH of the genesis block and block 1 - const blocksActivation = 256 // This ensures that block 0 - 255 all get stored into the hash contract + const blocksActivation = 256 // This ensures that only block 255 gets stored into the hash contract // More than blocks activation to build, so we can ensure that we can also retrieve block 0 or block 1 hash at block 300 - const blocksToBuild = 300 + const blocksToBuild = 500 const commonGetHistoryServeWindow = eip2935ActiveAtCommon(0) commonGetHistoryServeWindow.setEIPs([2935]) const common = eip2935ActiveAtCommon(blocksActivation) @@ -225,23 +225,23 @@ describe('EIP 2935: historical block hashes', () => { validateConsensus: false, }) const vm = await VM.create({ common, blockchain }) - let parentBlock = await vm.blockchain.getBlock(0) + let lastBlock = await vm.blockchain.getBlock(0) for (let i = 1; i <= blocksToBuild; i++) { - parentBlock = await ( + lastBlock = await ( await vm.buildBlock({ - parentBlock, + parentBlock: lastBlock, blockOpts: { putBlockIntoBlockchain: false, setHardfork: true, }, headerData: { - timestamp: parentBlock.header.number + BIGINT_1, + timestamp: lastBlock.header.number + BIGINT_1, }, }) ).build() - await vm.blockchain.putBlock(parentBlock) + await vm.blockchain.putBlock(lastBlock) await vm.runBlock({ - block: parentBlock, + block: lastBlock, generate: true, skipHeaderValidation: true, setHardfork: true, @@ -263,14 +263,24 @@ describe('EIP 2935: historical block hashes', () => { historyAddress, setLengthLeft(bigIntToBytes(BigInt(i) % historyServeWindow), 32) ) + + // we will evaluate on lastBlock where 7709 is active and BLOCKHASH + // will look from the state if within 256 window const ret = await vm.evm.runCall({ // Code: RETURN the BLOCKHASH of block i // PUSH(i) BLOCKHASH PUSH(32) MSTORE PUSH(64) PUSH(0) RETURN // Note: need to return a contract with starting zero bytes to avoid non-deployable contracts by EIP 3540 data: hexToBytes('0x61' + i.toString(16).padStart(4, '0') + '4060205260406000F3'), - block: parentBlock, + block: lastBlock, }) - if (i <= blocksToBuild - 1 && i >= blocksToBuild - Number(historyServeWindow)) { + + // contract will only have hashes between blocksActivation -1 and blocksToBuild -1 thresholded by + // historyServeWindow window + if ( + i >= blocksActivation - 1 && + i <= blocksToBuild - 1 && + i >= blocksToBuild - Number(historyServeWindow) + ) { assert.ok(equalsBytes(setLengthLeft(storage, 32), block.hash())) if (i >= blocksToBuild - 256) { assert.ok(equalsBytes(ret.execResult.returnValue, setLengthLeft(block.hash(), 64))) @@ -294,8 +304,8 @@ describe('EIP 2935: historical block hashes', () => { { common } ) - // should be able to resolve blockhash via contract code - for (const i of [0, 1, blocksActivation, blocksToBuild - 1]) { + // should be able to resolve blockhash via contract code but from the blocksActivation -1 onwards + for (const i of [blocksActivation - 1, blocksActivation, blocksToBuild - 1]) { const blockHashi = await testBlockhashContract(vm, block, BigInt(i)) const blocki = await blockchain.getBlock(i) assert.ok(equalsBytes(blockHashi, blocki.hash()))