forked from ethereumjs/ethereumjs-monorepo
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement EIP5656 MCOPY (ethereumjs#2808)
* common/evm: implement EIP5656 MCOPY * evm: add tests 5656 * evm: add comment 5656 tests * evm: update correct 5656 gas * evm: lint * evm: fix test
- Loading branch information
1 parent
c51d81e
commit d3055ae
Showing
7 changed files
with
167 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"name": "EIP-5656", | ||
"number": 5656, | ||
"comment": "MCOPY - Memory copying instruction", | ||
"url": "https://eips.ethereum.org/EIPS/eip-5656", | ||
"status": "Draft", | ||
"minimumHardfork": "shanghai", | ||
"gasConfig": {}, | ||
"gasPrices": { | ||
"mcopy": { | ||
"v": 3, | ||
"d": "Base fee of the MCOPY opcode" | ||
} | ||
}, | ||
"vm": {}, | ||
"pow": {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import { Chain, Common, Hardfork } from '@ethereumjs/common' | ||
import { DefaultStateManager } from '@ethereumjs/statemanager' | ||
import { bytesToHex, hexStringToBytes } from '@ethereumjs/util' | ||
import { assert, describe, it } from 'vitest' | ||
|
||
import { EVM } from '../../src' | ||
|
||
type Situation = { | ||
pre: string | ||
post: string | ||
dst: number | ||
src: number | ||
length: number | ||
} | ||
|
||
// Taken from EIP | ||
|
||
const situations: Situation[] = [ | ||
{ | ||
pre: '0000000000000000000000000000000000000000000000000000000000000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', | ||
post: '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', | ||
dst: 0, | ||
src: 32, | ||
length: 32, | ||
}, | ||
{ | ||
pre: '0101010101010101010101010101010101010101010101010101010101010101', | ||
post: '0101010101010101010101010101010101010101010101010101010101010101', | ||
dst: 0, | ||
src: 0, | ||
length: 32, | ||
}, | ||
// For the situation below, pre/post have 1 byte less than in the current state of the EIP | ||
{ | ||
pre: '0001020304050607080000000000000000000000000000000000000000000000', | ||
post: '0102030405060708080000000000000000000000000000000000000000000000', | ||
dst: 0, | ||
src: 1, | ||
length: 8, | ||
}, | ||
// For the situation below, pre/post have 1 byte less than in the current state of the EIP | ||
{ | ||
pre: '0001020304050607080000000000000000000000000000000000000000000000', | ||
post: '0000010203040506070000000000000000000000000000000000000000000000', | ||
dst: 1, | ||
src: 0, | ||
length: 8, | ||
}, | ||
] | ||
|
||
function numToOpcode(num: number) { | ||
return num.toString(16).padStart(2, '0') | ||
} | ||
|
||
const PUSH1 = '60' | ||
const MSTORE8 = '53' | ||
const MCOPY = '5E' | ||
const STOP = '00' | ||
|
||
describe('should test mcopy', () => { | ||
for (const situation of situations) { | ||
it('should produce correct output', async () => { | ||
// create bytecode | ||
let bytecode = '' | ||
// prepare the memory | ||
for (let i = 0; i < situation.pre.length / 2; i++) { | ||
const start = i * 2 | ||
const hexNum = situation.pre.slice(start, start + 2) | ||
bytecode += PUSH1 + hexNum + PUSH1 + numToOpcode(i) + MSTORE8 | ||
} | ||
// mcopy | ||
bytecode += | ||
PUSH1 + | ||
numToOpcode(situation.length) + | ||
PUSH1 + | ||
numToOpcode(situation.src) + | ||
PUSH1 + | ||
numToOpcode(situation.dst) | ||
bytecode += MCOPY + STOP | ||
|
||
const common = new Common({ | ||
chain: Chain.Mainnet, | ||
hardfork: Hardfork.Shanghai, | ||
eips: [5656], | ||
}) | ||
|
||
const evm = await EVM.create({ | ||
common, | ||
stateManager: new DefaultStateManager(), | ||
}) | ||
|
||
let currentMem = '' | ||
|
||
evm.events.on('step', (e) => { | ||
if (e.opcode.name === 'STOP') { | ||
currentMem = bytesToHex(e.memory) | ||
} | ||
}) | ||
|
||
await evm.runCall({ | ||
data: hexStringToBytes(bytecode), | ||
gasLimit: BigInt(0xffffff), | ||
}) | ||
|
||
assert.equal(currentMem, situation.post, 'post-memory correct') | ||
}) | ||
} | ||
}) |