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

Remove EIP-3074 #3582

Merged
merged 4 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
Loading