Skip to content

Commit

Permalink
common: update eip 2935 as per latest devnet1 spec and add related ei…
Browse files Browse the repository at this point in the history
…p 7709 (#3475)

* common: update eip 2935 as per latest devnet1 spec and add related eip 7709

* typo

* fix 2935 test

* fix casing typo

* lint

* apply feedback

* empty

---------

Co-authored-by: acolytec3 <17355484+acolytec3@users.noreply.github.com>
  • Loading branch information
g11tech and acolytec3 authored Jun 29, 2024
1 parent 81cd86d commit 669925f
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 21 deletions.
4 changes: 2 additions & 2 deletions packages/block/src/from-beacon-payload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type BeaconDepositRequest = {

type BeaconWithdrawalRequest = {
source_address: PrefixedHexString
validator_pub_key: PrefixedHexString
validator_pubkey: PrefixedHexString
amount: PrefixedHexString
}

Expand Down Expand Up @@ -160,7 +160,7 @@ export function executionPayloadFromBeaconPayload(payload: BeaconPayloadJson): E
if (payload.withdrawal_requests !== undefined && payload.withdrawal_requests !== null) {
executionPayload.withdrawalRequests = payload.withdrawal_requests.map((breq) => ({
sourceAddress: breq.source_address,
validatorPubkey: breq.validator_pub_key,
validatorPubkey: breq.validator_pubkey,
amount: breq.amount,
}))
}
Expand Down
22 changes: 13 additions & 9 deletions packages/client/test/rpc/engine/newPayloadV4.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ const [blockData] = blocks

const parentBeaconBlockRoot = '0x42942949c4ed512cd85c2cb54ca88591338cbb0564d3a2bea7961a639ef29d64'
const validForkChoiceState = {
headBlockHash: '0x586b459d3fa589fa0e30477ef0e9d11794629b8b914e00b2703c0615a33ab9ed',
safeBlockHash: '0x586b459d3fa589fa0e30477ef0e9d11794629b8b914e00b2703c0615a33ab9ed',
finalizedBlockHash: '0x586b459d3fa589fa0e30477ef0e9d11794629b8b914e00b2703c0615a33ab9ed',
headBlockHash: '0x3ff9144b3f0818580798b0a9ff5cedc1350ff62f46ec99b098344e2864be1e47',
safeBlockHash: '0x3ff9144b3f0818580798b0a9ff5cedc1350ff62f46ec99b098344e2864be1e47',
finalizedBlockHash: '0x3ff9144b3f0818580798b0a9ff5cedc1350ff62f46ec99b098344e2864be1e47',
}
const validPayloadAttributes = {
timestamp: '0x64ba84fd',
Expand Down Expand Up @@ -50,6 +50,11 @@ describe(`${method}: call with executionPayloadV4`, () => {
const { pragueJson, pragueTime } = readyPragueGenesis(genesisJSON)
const { service, server } = await setupChain(pragueJson, 'post-merge', { engine: true })
const rpc = getRpcClient(server)
let res

res = await rpc.request(`eth_getBlockByNumber`, ['0x0', false])
assert.equal(res.result.hash, validForkChoiceState.headBlockHash)

const validBlock = {
...blockData,
timestamp: bigIntToHex(BigInt(pragueTime)),
Expand All @@ -58,11 +63,10 @@ describe(`${method}: call with executionPayloadV4`, () => {
excessBlobGas: '0x0',
depositRequests: [],
withdrawalRequests: [],
parentHash: '0x586b459d3fa589fa0e30477ef0e9d11794629b8b914e00b2703c0615a33ab9ed',
stateRoot: '0x76869ec89f1bc786e10a03ecf4a3f9815ec9dddecb372bd0eff51fe75d0d921e',
blockHash: '0x34ec8335d47f4ba04a4c1f75f414b85b5e5200d60a6a639b6fc71ce90bcaaee2',
parentHash: '0x3ff9144b3f0818580798b0a9ff5cedc1350ff62f46ec99b098344e2864be1e47',
stateRoot: '0xd207043769091b6cdc91621f12bf2800b0b4643aeff09118fca52543c7a8ff03',
blockHash: '0xf9b4285204630ca183fec0a9a282cb68021af1aa9f3ab5f10d6b9ea8a7a3d4b6',
}
let res

const oldMethods = ['engine_newPayloadV1', 'engine_newPayloadV2', 'engine_newPayloadV3']
const expectedErrors = [
Expand Down Expand Up @@ -129,10 +133,10 @@ describe(`${method}: call with executionPayloadV4`, () => {
const electraGenesisContracts = {
// sender corresponding to the priv key 0x9c9996335451aab4fc4eac58e31a8c300e095cdbcee532d53d09280e83360355
'0x610adc49ecd66cbf176a8247ebd59096c031bd9f': { balance: '0x6d6172697573766477000000' },
'0x25a219378dad9b3503c8268c9ca836a52427a4fb': {
'0x0aae40965e6800cd9b1f4b05ff21581047e3f91e': {
balance: '0',
nonce: '1',
code: '0x60203611603157600143035f35116029575f356120000143116029576120005f3506545f5260205ff35b5f5f5260205ff35b5f5ffd00',
code: '0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500',
},
'0x00A3ca265EBcb825B45F985A16CEFB49958cE017': {
balance: '0',
Expand Down
9 changes: 8 additions & 1 deletion packages/common/src/eips.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ export const EIPs: EIPsDict = {
requiredEIPs: [],
vm: {
historyStorageAddress: {
v: BigInt('0x25a219378dad9b3503c8268c9ca836a52427a4fb'),
v: BigInt('0x0aae40965e6800cd9b1f4b05ff21581047e3f91e'),
d: 'The address where the historical blockhashes are stored',
},
historyServeWindow: {
Expand Down Expand Up @@ -623,4 +623,11 @@ export const EIPs: EIPsDict = {
requiredEIPs: [3675],
gasPrices: {},
},
7709: {
comment: 'Use historical block hashes saved in state for BLOCKHASH',
url: 'https://eips.ethereum.org/EIPS/eip-7709',
status: Status.Draft,
minimumHardfork: Hardfork.Chainstart,
requiredEIPs: [2935],
},
}
1 change: 1 addition & 0 deletions packages/evm/src/evm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ export class EVM implements EVMInterface {
const supportedEIPs = [
1153, 1559, 2537, 2565, 2718, 2929, 2930, 2935, 3074, 3198, 3529, 3540, 3541, 3607, 3651,
3670, 3855, 3860, 4399, 4895, 4788, 4844, 5133, 5656, 6110, 6780, 6800, 7002, 7516, 7685,
7709,
]

for (const eip of this.common.eips()) {
Expand Down
9 changes: 5 additions & 4 deletions packages/evm/src/opcodes/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -608,23 +608,24 @@ export const handlers: Map<number, OpHandler> = new Map([
async function (runState, common) {
const number = runState.stack.pop()

if (common.isActivatedEIP(2935)) {
if (common.isActivatedEIP(7709)) {
if (number >= runState.interpreter.getBlockNumber()) {
runState.stack.push(BIGINT_0)
return
}

const diff = runState.interpreter.getBlockNumber() - number
const historyServeWindow = common.param('vm', 'historyServeWindow')
// block lookups must be within the `historyServeWindow`
if (diff > historyServeWindow || diff <= BIGINT_0) {
// block lookups must be within the original window even if historyStorageAddress's
// historyServeWindow is much greater than 256
if (diff > BIGINT_256 || diff <= BIGINT_0) {
runState.stack.push(BIGINT_0)
return
}

const historyAddress = new Address(
bigIntToAddressBytes(common.param('vm', 'historyStorageAddress'))
)
const historyServeWindow = common.param('vm', 'historyServeWindow')
const key = setLengthLeft(bigIntToBytes(number % historyServeWindow), 32)

if (common.isActivatedEIP(6800)) {
Expand Down
23 changes: 18 additions & 5 deletions packages/vm/test/api/EIPs/eip-2935-historical-block-hashes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ function eip2935ActiveAtCommon(timestamp: number) {
comment: 'Start of the Ethereum main chain',
url: '',
status: 'final',
eips: [2935],
eips: [2935, 7709],
},
},
hardforks,
Expand Down Expand Up @@ -248,8 +248,17 @@ describe('EIP 2935: historical block hashes', () => {
})
}

for (let i = 0; i <= blocksToBuild; i++) {
const block = await vm.blockchain.getBlock(i)
// swap out the blockchain to test from storage
const blockchainEmpty = await Blockchain.create({
common,
validateBlocks: false,
validateConsensus: false,
})
;(vm as any).blockchain = blockchainEmpty
;(vm.evm as any).blockchain = blockchainEmpty

for (let i = 1; i <= blocksToBuild; i++) {
const block = await blockchain.getBlock(i)
const storage = await vm.stateManager.getContractStorage(
historyAddress,
setLengthLeft(bigIntToBytes(BigInt(i) % historyServeWindow), 32)
Expand All @@ -263,7 +272,11 @@ describe('EIP 2935: historical block hashes', () => {
})
if (i <= blocksToBuild - 1 && i >= blocksToBuild - Number(historyServeWindow)) {
assert.ok(equalsBytes(setLengthLeft(storage, 32), block.hash()))
assert.ok(equalsBytes(ret.execResult.returnValue, setLengthLeft(block.hash(), 64)))
if (i >= blocksToBuild - 256) {
assert.ok(equalsBytes(ret.execResult.returnValue, setLengthLeft(block.hash(), 64)))
} else {
assert.ok(equalsBytes(ret.execResult.returnValue, zeros(64)))
}
} else {
assert.ok(equalsBytes(ret.execResult.returnValue, zeros(64)))
}
Expand All @@ -284,7 +297,7 @@ describe('EIP 2935: historical block hashes', () => {
// should be able to resolve blockhash via contract code
for (const i of [0, 1, blocksActivation, blocksToBuild - 1]) {
const blockHashi = await testBlockhashContract(vm, block, BigInt(i))
const blocki = await vm.blockchain.getBlock(i)
const blocki = await blockchain.getBlock(i)
assert.ok(equalsBytes(blockHashi, blocki.hash()))
}

Expand Down

0 comments on commit 669925f

Please sign in to comment.