Skip to content

Commit

Permalink
Remove EIP-3074 (#3582)
Browse files Browse the repository at this point in the history
* Remove EIP-3074

* Fix EVM example

* vm/evm: remove more auth(call) references

---------

Co-authored-by: Holger Drewes <Holger.Drewes@gmail.com>
  • Loading branch information
jochem-brouwer and holgerd77 authored Aug 13, 2024
1 parent 699cde2 commit 0686310
Show file tree
Hide file tree
Showing 15 changed files with 15 additions and 1,134 deletions.
8 changes: 0 additions & 8 deletions packages/common/src/eips.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,6 @@ export const eipsDict: EIPsDict = {
2935: {
minimumHardfork: Hardfork.Chainstart,
},
/**
* Description : AUTH and AUTHCALL opcodes
* URL : https://github.com/ethereum/EIPs/commit/eca4416ff3c025fcb6ec8cd4eac481e74e108481
* Status : Review
*/
3074: {
minimumHardfork: Hardfork.London,
},
/**
* Description : BASEFEE opcode
* URL : https://eips.ethereum.org/EIPS/eip-3198
Expand Down
6 changes: 3 additions & 3 deletions packages/evm/examples/eips.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Chain, Common, Mainnet } from '@ethereumjs/common'
import { Common, Mainnet } from '@ethereumjs/common'
import { createEVM } from '@ethereumjs/evm'

const main = async () => {
const common = new Common({ chain: Mainnet, eips: [3074] })
const common = new Common({ chain: Mainnet, eips: [7702] })
const evm = await createEVM({ common })
console.log(`EIP 3074 is active - ${evm.common.isActivatedEIP(3074)}`)
console.log(`EIP 7702 is active - ${evm.common.isActivatedEIP(7702)}`)
}

void main()
15 changes: 7 additions & 8 deletions packages/evm/src/evm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,11 @@ export class EVM implements EVMInterface {

// Supported EIPs
const supportedEIPs = [
663, 1153, 1153, 1559, 1559, 2537, 2537, 2565, 2565, 2718, 2718, 2929, 2929, 2930, 2930, 2935,
2935, 3074, 3074, 3198, 3198, 3529, 3529, 3540, 3540, 3541, 3541, 3607, 3607, 3651, 3651,
3670, 3670, 3855, 3855, 3860, 3860, 4200, 4399, 4399, 4750, 4788, 4788, 4844, 4844, 4895,
4895, 5133, 5133, 5450, 5656, 5656, 6110, 6110, 6206, 6780, 6780, 6800, 6800, 7002, 7002,
7069, 7251, 7251, 7480, 7516, 7516, 7620, 7685, 7685, 7692, 7698, 7702, 7702, 7709, 7709,
663, 1153, 1559, 2537, 2565, 2718, 2929, 2930, 2935, 3198, 3529, 3540, 3541, 3607, 3651, 3670,
3855, 3860, 4200, 4399, 4750, 4788, 4844, 4895, 5133, 5450, 5656, 6110, 6206, 6780, 6800,
7002, 7069, 7251, 7480, 7516, 7620, 7685, 7692, 7698, 7702, 7709,
]

for (const eip of this.common.eips()) {
if (!supportedEIPs.includes(eip)) {
throw new Error(`EIP-${eip} is not supported by the EVM`)
Expand Down Expand Up @@ -248,7 +247,7 @@ export class EVM implements EVMInterface {

protected async _executeCall(message: MessageWithTo): Promise<EVMResult> {
let gasLimit = message.gasLimit
const fromAddress = message.authcallOrigin ?? message.caller
const fromAddress = message.caller

if (this.common.isActivatedEIP(6800)) {
const sendsValue = message.value !== BIGINT_0
Expand Down Expand Up @@ -394,7 +393,7 @@ export class EVM implements EVMInterface {

protected async _executeCreate(message: Message): Promise<EVMResult> {
let gasLimit = message.gasLimit
const fromAddress = message.authcallOrigin ?? message.caller
const fromAddress = message.caller

if (this.common.isActivatedEIP(6800)) {
if (message.depth === 0) {
Expand Down Expand Up @@ -1039,7 +1038,7 @@ export class EVM implements EVMInterface {
if (account.balance < BIGINT_0) {
throw new EvmError(ERROR.INSUFFICIENT_BALANCE)
}
const result = this.journal.putAccount(message.authcallOrigin ?? message.caller, account)
const result = this.journal.putAccount(message.caller, account)
if (this.DEBUG) {
debug(`Reduced sender (${message.caller}) balance (-> ${account.balance})`)
}
Expand Down
2 changes: 0 additions & 2 deletions packages/evm/src/exceptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ export enum ERROR {
INVALID_INPUT_LENGTH = 'invalid input length',
INVALID_EOF_FORMAT = 'invalid EOF format',

AUTHCALL_UNSET = 'attempting to AUTHCALL without AUTH set',

// BLS errors
BLS_12_381_INVALID_INPUT_LENGTH = 'invalid input length',
BLS_12_381_POINT_NOT_ON_CURVE = 'point not on curve',
Expand Down
26 changes: 0 additions & 26 deletions packages/evm/src/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ export interface RunState {
interpreter: Interpreter
gasRefund: bigint // Tracks the current refund
gasLeft: bigint // Current gas left
auth?: Address /** EIP-3074 AUTH parameter */
returnBytes: Uint8Array /* Current bytes in the return Uint8Array. Cleared each time a CALL/CREATE is made in the current frame. */
}

Expand Down Expand Up @@ -867,31 +866,6 @@ export class Interpreter {
return this._baseCall(msg)
}

/**
* Sends a message with arbitrary data to a given address path.
*/
async authcall(
gasLimit: bigint,
address: Address,
value: bigint,
data: Uint8Array,
): Promise<bigint> {
const msg = new Message({
caller: this._runState.auth,
gasLimit,
to: address,
value,
data,
isStatic: this._env.isStatic,
depth: this._env.depth + 1,
authcallOrigin: this._env.address,
blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
})

return this._baseCall(msg)
}

/**
* Message-call into this account with an alternative account's code.
*/
Expand Down
7 changes: 0 additions & 7 deletions packages/evm/src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ interface MessageOpts {
*/
createdAddresses?: Set<PrefixedHexString>
delegatecall?: boolean
authcallOrigin?: Address
gasRefund?: bigint
blobVersionedHashes?: Uint8Array[]
accessWitness?: AccessWitnessInterface
Expand Down Expand Up @@ -69,11 +68,6 @@ export class Message {
*/
createdAddresses?: Set<PrefixedHexString>
delegatecall: boolean
/**
* This is used to store the origin of the AUTHCALL,
* the purpose is to figure out where `value` should be taken from (not from `caller`)
*/
authcallOrigin?: Address
gasRefund: bigint // Keeps track of the gasRefund at the start of the frame (used for journaling purposes)
/**
* List of versioned hashes if message is a blob transaction in the outer VM
Expand All @@ -97,7 +91,6 @@ export class Message {
this.selfdestruct = opts.selfdestruct
this.createdAddresses = opts.createdAddresses
this.delegatecall = opts.delegatecall ?? defaults.delegatecall
this.authcallOrigin = opts.authcallOrigin
this.gasRefund = opts.gasRefund ?? defaults.gasRefund
this.blobVersionedHashes = opts.blobVersionedHashes
this.accessWitness = opts.accessWitness
Expand Down
4 changes: 2 additions & 2 deletions packages/evm/src/opcodes/EIP2929.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function accessAddressEIP2929(
address: Uint8Array,
common: Common,
chargeGas = true,
isSelfdestructOrAuthcall = false,
isSelfdestruct = false,
): bigint {
if (!common.isActivatedEIP(2929)) return BIGINT_0

Expand All @@ -33,7 +33,7 @@ export function accessAddressEIP2929(
return common.param('coldaccountaccessGas')
}
// Warm: (selfdestruct beneficiary address reads are not charged when warm)
} else if (chargeGas && !isSelfdestructOrAuthcall) {
} else if (chargeGas && !isSelfdestruct) {
return common.param('warmstoragereadGas')
}
return BIGINT_0
Expand Down
7 changes: 0 additions & 7 deletions packages/evm/src/opcodes/codes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,13 +294,6 @@ const eipOpcodes: { eip: number; opcodes: OpcodeEntry }[] = [
0x5f: { name: 'PUSH0', isAsync: false, dynamicGas: false },
},
},
{
eip: 3074,
opcodes: {
0xf6: { name: 'AUTH', isAsync: true, dynamicGas: true },
0xf7: { name: 'AUTHCALL', isAsync: true, dynamicGas: true },
},
},
{
eip: 4200,
opcodes: {
Expand Down
122 changes: 0 additions & 122 deletions packages/evm/src/opcodes/functions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
Account,
Address,
BIGINT_0,
BIGINT_1,
Expand All @@ -8,7 +7,6 @@ import {
BIGINT_224,
BIGINT_255,
BIGINT_256,
BIGINT_27,
BIGINT_2EXP160,
BIGINT_2EXP224,
BIGINT_2EXP96,
Expand All @@ -18,20 +16,15 @@ import {
BIGINT_8,
BIGINT_96,
MAX_INTEGER_BIGINT,
SECP256K1_ORDER_DIV_2,
TWO_POW256,
bigIntToAddressBytes,
bigIntToBytes,
bytesToBigInt,
bytesToHex,
bytesToInt,
concatBytes,
ecrecover,
getVerkleTreeIndexesForStorageSlot,
hexToBytes,
publicToAddress,
setLengthLeft,
setLengthRight,
} from '@ethereumjs/util'
import { keccak256 } from 'ethereum-cryptography/keccak.js'

Expand All @@ -56,8 +49,6 @@ import {
import type { RunState } from '../interpreter.js'
import type { Common } from '@ethereumjs/common'

const EIP3074MAGIC = hexToBytes('0x04')

export interface SyncOpHandler {
(runState: RunState, common: Common): void
}
Expand Down Expand Up @@ -1492,119 +1483,6 @@ export const handlers: Map<number, OpHandler> = new Map([
runState.stack.push(ret)
},
],
// 0xf6: AUTH
[
0xf6,
async function (runState) {
// eslint-disable-next-line prefer-const
let [authority, memOffset, memLength] = runState.stack.popN(3)

if (memLength > BigInt(97)) {
memLength = BigInt(97)
}

let mem = runState.memory.read(Number(memOffset), Number(memLength))
if (mem.length < 97) {
mem = setLengthRight(mem, 97)
}

const yParity = BigInt(mem[0])
const r = mem.subarray(1, 33)
const s = mem.subarray(33, 65)
const commit = mem.subarray(65, 97)

if (bytesToBigInt(s) > SECP256K1_ORDER_DIV_2) {
runState.stack.push(BIGINT_0)
runState.auth = undefined
return
}
if (yParity > BIGINT_1) {
runState.stack.push(BIGINT_0)
runState.auth = undefined
return
}

// we don't want strick check here on authority being in address range just last 20 bytes
const expectedAddress = new Address(bigIntToAddressBytes(authority, false))
const account = (await runState.stateManager.getAccount(expectedAddress)) ?? new Account()

if (account.isContract()) {
// EXTCODESIZE > 0
runState.stack.push(BIGINT_0)
runState.auth = undefined
return
}

const accountNonce = account.nonce

const invokedAddress = setLengthLeft(runState.interpreter._env.address.bytes, 32)
const chainId = setLengthLeft(bigIntToBytes(runState.interpreter.getChainId()), 32)
const nonce = setLengthLeft(bigIntToBytes(accountNonce), 32)
const message = concatBytes(EIP3074MAGIC, chainId, nonce, invokedAddress, commit)

const keccakFunction = runState.interpreter._evm.common.customCrypto.keccak256 ?? keccak256
const msgHash = keccakFunction(message)

let recover
const ecrecoverFunction = runState.interpreter._evm.common.customCrypto.ecrecover ?? ecrecover
try {
recover = ecrecoverFunction(msgHash, yParity + BIGINT_27, r, s)
} catch (e) {
// Malformed signature, push 0 on stack, clear auth variable
runState.stack.push(BIGINT_0)
runState.auth = undefined
return
}

const addressBuffer = publicToAddress(recover)
const address = new Address(addressBuffer)
runState.auth = address

if (!expectedAddress.equals(address)) {
// expected address does not equal the recovered address, clear auth variable
runState.stack.push(BIGINT_0)
runState.auth = undefined
return
}

runState.auth = address
runState.stack.push(BIGINT_1)
},
],
// 0xf7: AUTHCALL (3074) / RETURNDATALOAD (7069)
[
0xf7,
async function (runState, common) {
if (common.isActivatedEIP(3074) && runState.env.eof === undefined) {
// AUTHCALL logic
const [_currentGasLimit, addr, value, argsOffset, argsLength, retOffset, retLength] =
runState.stack.popN(7)

const toAddress = createAddressFromStackBigInt(addr)

const gasLimit = runState.messageGasLimit!
runState.messageGasLimit = undefined

let data = new Uint8Array(0)
if (argsLength !== BIGINT_0) {
data = runState.memory.read(Number(argsOffset), Number(argsLength))
}

const ret = await runState.interpreter.authcall(gasLimit, toAddress, value, data)
// Write return data to memory
writeCallOutput(runState, retOffset, retLength)
runState.stack.push(ret)
} else if (common.isActivatedEIP(7069)) {
// RETURNDATALOAD logic
const returnDataOffset = runState.stack.pop()
const data = getDataSlice(runState.interpreter.getReturnData(), returnDataOffset, BIGINT_32)
runState.stack.push(bytesToBigInt(data))
} else {
// This should be unreachable
trap(ERROR.INVALID_OPCODE)
}
},
],
// 0xf8: EXTCALL
[
0xf8,
Expand Down
Loading

0 comments on commit 0686310

Please sign in to comment.