Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement pectra devnet-5 spec #3807

Draft
wants to merge 27 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f290abe
evm: add devnet-5 EIP-7702 changes
jochem-brouwer Nov 25, 2024
85e937a
vm: add devnet-5 EIP-7685 changes
jochem-brouwer Nov 25, 2024
3525a19
monorepo: make cspell happy
jochem-brouwer Nov 25, 2024
4800a9f
vm/client: fix tests
jochem-brouwer Nov 26, 2024
d4e9496
evm: remove redundant test
jochem-brouwer Nov 26, 2024
caa9e1c
remove accidental console.log
jochem-brouwer Nov 27, 2024
74a2123
remove 7742 and add 7691 independently
g11tech Dec 16, 2024
7f5c4c5
fix t8ntool empty requests reporting
jochem-brouwer Dec 16, 2024
13aafd6
client: fix engine reporting empty requests
jochem-brouwer Dec 19, 2024
fc3c150
t8n: fix requests reporting
jochem-brouwer Dec 19, 2024
fb7e67f
Implement EIP 7623: calldata cost increase (#3813)
jochem-brouwer Dec 19, 2024
98806ff
client: fix requests contract address (devnet-5) (#3818)
lucassaldanha Dec 19, 2024
5079664
update chainid to uint256
jochem-brouwer Dec 22, 2024
c827859
evm: update bls gas (eips PR 9097)
jochem-brouwer Dec 22, 2024
e4adff7
evm: bls update msm gas (eips PR 9116)
jochem-brouwer Dec 22, 2024
34a4882
evm: bls update pairing gas (eips PR 9098)
jochem-brouwer Dec 22, 2024
3938e7f
evm: rename bls files and remove g1mul, g2mul (eips PR 8945)
jochem-brouwer Dec 22, 2024
b665335
Merge branch 'master' into devnet-5
jochem-brouwer Dec 22, 2024
eadbf2c
evm: update 2537 addresses in test
jochem-brouwer Jan 5, 2025
e2b355a
tx: add eip-7691 param
jochem-brouwer Jan 5, 2025
4b863bf
tx: add required params to common
jochem-brouwer Jan 6, 2025
a178857
vm/tests: update 7002 test: correctly deploy withdrawal contract
jochem-brouwer Jan 6, 2025
4a9b0c2
client: update genesis contracts
jochem-brouwer Jan 6, 2025
b195bbb
evm: update bls test files
jochem-brouwer Jan 6, 2025
df63978
vm: 2935 update history serve window
jochem-brouwer Jan 6, 2025
90fc63a
evm: EXTCODE* do not follow 7702 delegations for gas calculations
jochem-brouwer Jan 6, 2025
3d1a61f
vm: t8n fix: exit early on non-existent 2935 code
jochem-brouwer Jan 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/block/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,10 @@ export function genRequestsRoot(

let flatRequests = new Uint8Array()
for (const req of requests) {
flatRequests = concatBytes(flatRequests, sha256Function(req.bytes))
if (req.bytes.length > 1) {
// Only append requests if they have content
flatRequests = concatBytes(flatRequests, sha256Function(req.bytes))
}
}

return sha256Function(flatRequests)
Expand Down
3 changes: 2 additions & 1 deletion packages/client/test/rpc/engine/newPayloadV4.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ describe(`${method}: call with executionPayloadV4`, () => {
excessBlobGas: '0x0',
parentHash: '0x6abe4c2777a6a1e994d83920cfb95229b071174b95c89343f54b926f733789f2',
stateRoot: '0x7aa6e46df1f78988a3141b5e7da8abee78d1daca175f43fe8866b2d1bf8d8ef8',
blockHash: '0x9a5903d803e6e7c3631cd76cb7279f93d7facc995c53eaffadf4e225504b18eb',
blockHash: '0xece8d273a76238c4c9e4e28cbd301d40b04cb21242e83960ca688324e0483fd8',
}

const oldMethods = ['engine_newPayloadV1', 'engine_newPayloadV2', 'engine_newPayloadV3']
Expand All @@ -181,6 +181,7 @@ describe(`${method}: call with executionPayloadV4`, () => {
}

res = await rpc.request(method, [validBlock, [], parentBeaconBlockRoot, ['0x', '0x', '0x']])
console.log(res)
jochem-brouwer marked this conversation as resolved.
Show resolved Hide resolved
assert.equal(res.result.status, 'VALID')

res = await rpc.request('engine_forkchoiceUpdatedV3', validPayload)
Expand Down
42 changes: 31 additions & 11 deletions packages/evm/src/opcodes/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
concatBytes,
equalsBytes,
getVerkleTreeIndicesForStorageSlot,
hexToBytes,
setLengthLeft,
} from '@ethereumjs/util'
import { keccak256 } from 'ethereum-cryptography/keccak.js'
Expand Down Expand Up @@ -61,16 +62,40 @@

export type OpHandler = SyncOpHandler | AsyncOpHandler

// TODO: verify that this is the correct designator
// The PR https://github.com/ethereum/EIPs/pull/8969 has two definitions of the
// designator: the original (0xef0100) and the designator added in the changes (0xef01)
const eip7702Designator = hexToBytes('0xef01')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just confirming my thinking. These only get computed once at run time, right? They aren't recomputed every single time we access this code are they?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only computed once! Can also move it somewhere else like types.ts.

const eip7702HashBigInt = bytesToBigInt(keccak256(eip7702Designator))

function getEIP7702DelegatedAddress(code: Uint8Array) {
if (equalsBytes(code.slice(0, 3), DELEGATION_7702_FLAG)) {
return new Address(code.slice(3, 24))
}
}

async function eip7702CodeCheck(runState: RunState, code: Uint8Array) {
/**
* This method performs checks to transform the code which the EVM observes regarding EIP-7702.
* If the code is 7702-delegated code, it will retrieve the code of the designated address
* in case of an executable operation (`isReadOperation` == false), or the 7702 designator
* code in case of a read operation
* @param runState
* @param code
* @param isReadOperation Boolean to determine if the target code is meant to be read or executed (default: `false`)
* @returns
*/
async function eip7702CodeCheck(
runState: RunState,
code: Uint8Array,
isReadOperation: boolean = false,
) {

Check warning on line 91 in packages/evm/src/opcodes/functions.ts

View check run for this annotation

Codecov / codecov/patch

packages/evm/src/opcodes/functions.ts#L87-L91

Added lines #L87 - L91 were not covered by tests
const address = getEIP7702DelegatedAddress(code)
if (address !== undefined) {
return runState.stateManager.getCode(address)
if (isReadOperation) {
return eip7702Designator
} else {
return runState.stateManager.getCode(address)
}

Check warning on line 98 in packages/evm/src/opcodes/functions.ts

View check run for this annotation

Codecov / codecov/patch

packages/evm/src/opcodes/functions.ts#L94-L98

Added lines #L94 - L98 were not covered by tests
}

return code
Expand Down Expand Up @@ -538,7 +563,7 @@
runState.stack.push(BigInt(EOFBYTES.length))
return
} else if (common.isActivatedEIP(7702)) {
code = await eip7702CodeCheck(runState, code)
code = await eip7702CodeCheck(runState, code, true)

Check warning on line 566 in packages/evm/src/opcodes/functions.ts

View check run for this annotation

Codecov / codecov/patch

packages/evm/src/opcodes/functions.ts#L566

Added line #L566 was not covered by tests
}

const size = BigInt(code.length)
Expand All @@ -560,7 +585,7 @@
// In legacy code, the target code is treated as to be "EOFBYTES" code
code = EOFBYTES
} else if (common.isActivatedEIP(7702)) {
code = await eip7702CodeCheck(runState, code)
code = await eip7702CodeCheck(runState, code, true)

Check warning on line 588 in packages/evm/src/opcodes/functions.ts

View check run for this annotation

Codecov / codecov/patch

packages/evm/src/opcodes/functions.ts#L588

Added line #L588 was not covered by tests
}

const data = getDataSlice(code, codeOffset, dataLength)
Expand All @@ -587,13 +612,8 @@
} else if (common.isActivatedEIP(7702)) {
const possibleDelegatedAddress = getEIP7702DelegatedAddress(code)
if (possibleDelegatedAddress !== undefined) {
const account = await runState.stateManager.getAccount(possibleDelegatedAddress)
if (!account || account.isEmpty()) {
runState.stack.push(BIGINT_0)
return
}

runState.stack.push(BigInt(bytesToHex(account.codeHash)))
// The account is delegated by an EIP-7702 tx. Push the EIP-7702 designator hash to the stack
runState.stack.push(eip7702HashBigInt)

Check warning on line 616 in packages/evm/src/opcodes/functions.ts

View check run for this annotation

Codecov / codecov/patch

packages/evm/src/opcodes/functions.ts#L616

Added line #L616 was not covered by tests
return
} else {
runState.stack.push(bytesToBigInt(keccak256(code)))
Expand Down
5 changes: 4 additions & 1 deletion packages/vm/test/api/EIPs/eip-7685.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createBlock, genRequestsRoot } from '@ethereumjs/block'
import { createBlockchain } from '@ethereumjs/blockchain'
import { Common, Hardfork, Mainnet } from '@ethereumjs/common'
import { createCLRequest, hexToBytes } from '@ethereumjs/util'
import { createCLRequest, equalsBytes, hexToBytes } from '@ethereumjs/util'
import { sha256 } from 'ethereum-cryptography/sha256'
import { assert, describe, expect, it } from 'vitest'

Expand Down Expand Up @@ -31,6 +31,9 @@ describe('EIP-7685 runBlock tests', () => {
generate: true,
})
assert.equal(res.gasUsed, 0n)
// Verify that if the requests are empty, the byte-types are not appended to the to-be-hashed flat array
// I.e. the flat array to-be-hashed is not `0x 00 01 02`, but is now the empty bytes array, `0x`
assert.ok(equalsBytes(res.requestsHash!, sha256(new Uint8Array())))
})
it('should error when an invalid requestsHash is provided', async () => {
const vm = await setupVM({ common })
Expand Down
9 changes: 6 additions & 3 deletions packages/vm/test/api/EIPs/eip-7702.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ import type { VM } from '../../../src/index.js'
import type { AuthorizationListBytesItem } from '@ethereumjs/tx'
import type { PrefixedHexString } from '@ethereumjs/util'

// EIP-7702 code designator. If code starts with these bytes, it is a 7702-delegated address
const eip7702Designator = hexToBytes('0xef01')

const common = new Common({ chain: Mainnet, hardfork: Hardfork.Cancun, eips: [7702] })

const defaultAuthPkey = hexToBytes(`0x${'20'.repeat(32)}`)
Expand Down Expand Up @@ -248,21 +251,21 @@ describe('test EIP-7702 opcodes', () => {
{
// PUSH20 <defaultAuthAddr> EXTCODESIZE PUSH0 SSTORE STOP
code: `0x73${defaultAuthAddr.toString().slice(2)}3b5f5500`,
expectedStorage: bigIntToUnpaddedBytes(BigInt(randomCode.length)),
expectedStorage: bigIntToUnpaddedBytes(BigInt(eip7702Designator.length)),
name: 'EXTCODESIZE',
},
// EXTCODEHASH
{
// PUSH20 <defaultAuthAddr> EXTCODEHASH PUSH0 SSTORE STOP
code: `0x73${defaultAuthAddr.toString().slice(2)}3f5f5500`,
expectedStorage: keccak256(randomCode),
expectedStorage: keccak256(eip7702Designator),
name: 'EXTCODEHASH',
},
// EXTCODECOPY
{
// PUSH1 32 PUSH0 PUSH0 PUSH20 <defaultAuthAddr> EXTCODEHASH PUSH0 MLOAD PUSH0 SSTORE STOP
code: `0x60205f5f73${defaultAuthAddr.toString().slice(2)}3c5f515f5500`,
expectedStorage: setLengthRight(randomCode, 32),
expectedStorage: setLengthRight(eip7702Designator, 32),
name: 'EXTCODECOPY',
},
]
Expand Down
Loading