ethereum.forks.amsterdam.vm.eoa_delegation

Set EOA account code.

SET_CODE_TX_MAGIC

33
SET_CODE_TX_MAGIC = b"\x05"

EOA_DELEGATION_MARKER

34
EOA_DELEGATION_MARKER = b"\xef\x01\x00"

EOA_DELEGATION_MARKER_LENGTH

35
EOA_DELEGATION_MARKER_LENGTH = len(EOA_DELEGATION_MARKER)

EOA_DELEGATED_CODE_LENGTH

36
EOA_DELEGATED_CODE_LENGTH = 23

NULL_ADDRESS

37
NULL_ADDRESS = hex_to_address("0x0000000000000000000000000000000000000000")

is_valid_delegation

Whether the code is a valid delegation designation.

Parameters

code: bytes The code to check.

Returns

valid : bool True if the code is a valid delegation designation, False otherwise.

def is_valid_delegation(code: bytes) -> bool:
41
    <snip>
56
    return (
57
        len(code) == EOA_DELEGATED_CODE_LENGTH
58
        and code[:EOA_DELEGATION_MARKER_LENGTH] == EOA_DELEGATION_MARKER
59
    )

get_delegated_code_address

Get the address to which the code delegates.

Parameters

code: bytes The code to get the address from.

Returns

address : Optional[Address] The address of the delegated code.

def get_delegated_code_address(code: bytes) -> Optional[Address]:
63
    <snip>
77
    if is_valid_delegation(code):
78
        return Address(code[EOA_DELEGATION_MARKER_LENGTH:])
79
    return None

recover_authority

Recover the authority address from the authorization.

Parameters

authorization The authorization to recover the authority from.

Raises

InvalidSignatureError If the signature is invalid.

Returns

authority : Address The recovered authority address.

def recover_authority(authorization: Authorization) -> Address:
83
    <snip>
102
    y_parity, r, s = authorization.y_parity, authorization.r, authorization.s
103
    if y_parity not in (0, 1):
104
        raise InvalidSignatureError("Invalid y_parity in authorization")
105
    if U256(0) >= r or r >= SECP256K1N:
106
        raise InvalidSignatureError("Invalid r value in authorization")
107
    if U256(0) >= s or s > SECP256K1N // U256(2):
108
        raise InvalidSignatureError("Invalid s value in authorization")
109
110
    signing_hash = keccak256(
111
        SET_CODE_TX_MAGIC
112
        + rlp.encode(
113
            (
114
                authorization.chain_id,
115
                authorization.address,
116
                authorization.nonce,
117
            )
118
        )
119
    )
120
121
    public_key = secp256k1_recover(r, s, U256(y_parity), signing_hash)
122
    return Address(keccak256(public_key)[12:32])

calculate_delegation_cost

Get the delegation address and the cost of access from the address.

Parameters

evm : Evm The execution frame. address : Address The address to check for delegation.

Returns

delegation : Tuple[bool, Address, Uint] The delegation address and access gas cost.

def calculate_delegation_cost(evm: Evm, ​​address: Address) -> Tuple[bool, Address, Uint]:
128
    <snip>
144
    tx_state = evm.message.tx_env.state
145
146
    code = get_code(tx_state, get_account(tx_state, address).code_hash)
147
148
    if not is_valid_delegation(code):
149
        return False, address, Uint(0)
150
151
    delegated_address = Address(code[EOA_DELEGATION_MARKER_LENGTH:])
152
153
    if delegated_address in evm.accessed_addresses:
154
        delegation_gas_cost = GasCosts.WARM_ACCESS
155
    else:
156
        delegation_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS
157
158
    return True, delegated_address, delegation_gas_cost

validate_authorization

Check if the given Authorization is valid against the current state.

Returns the authority address, or None if the validation was unsuccessful.

def validate_authorization(message: Message, ​​auth: Authorization) -> Optional[Address]:
164
    <snip>
170
    tx_state = message.tx_env.state
171
172
    if auth.chain_id not in (message.block_env.chain_id, U256(0)):
173
        return None
174
175
    if auth.nonce >= U64.MAX_VALUE:
176
        return None
177
178
    try:
179
        authority = recover_authority(auth)
180
    except InvalidSignatureError:
181
        return None
182
183
    message.accessed_addresses.add(authority)
184
185
    authority_account = get_account(tx_state, authority)
186
    authority_code = get_code(tx_state, authority_account.code_hash)
187
188
    if authority_code and not is_valid_delegation(authority_code):
189
        return None
190
191
    authority_nonce = authority_account.nonce
192
    if authority_nonce != auth.nonce:
193
        return None
194
195
    return authority

set_delegation

Apply the EIP-7702 authorizations and charge their state-dependent costs at the top frame.

Each valid authorization is charged, on top of the state-independent GasCosts.REGULAR_PER_AUTH_BASE_COST already paid in the intrinsic cost:

  • StateGasCosts.NEW_ACCOUNT (state) when the authority's account leaf does not yet exist.

  • GasCosts.ACCOUNT_WRITE (regular) when applying the authorization is the transaction's first write to the authority's leaf. Writes the transaction already prices elsewhere are exempt: the sender's, covered by TX_BASE, and, for a value-bearing transaction, the recipient's, covered by TX_VALUE_COST. Repeated authorizations on one authority pay it once.

  • StateGasCosts.AUTH_BASE (state) when a net-new delegation indicator is written: the authority held no delegation before the transaction, none was set for it earlier in the transaction, and this authorization sets one. It is charged at most once per authority and is never credited back -- a delegation set and then cleared in the same transaction keeps its charge.

These costs depend on the authority's current state and so cannot be charged in the intrinsic cost. Insufficient gas raises an OutOfGasError; the caller rolls back the authorizations applied so far and halts the top frame.

Parameters

evm : The top-level transaction frame.

def set_delegation(evm: Evm) -> None:
199
    <snip>
234
    message = evm.message
235
    tx_state = message.tx_env.state
236
    # Accounts whose write the transaction has already priced: the
237
    # sender's leaf was written at inclusion (nonce bump and fee
238
    # deduction), and a value-bearing transaction prepays the
239
    # recipient's balance write -- the transfer itself only happens at
240
    # frame entry, after these charges.
241
    written_accounts: Set[Address] = {message.tx_env.origin}
242
    if evm.message.tx_env.value > U256(0):
243
        written_accounts.add(evm.message.current_target)
244
    # Authorities a delegation was set for earlier in this transaction.
245
    delegation_set_for: Set[Address] = set()
246
    for auth in message.tx_env.authorizations:
247
        match validate_authorization(message, auth):
248
            case None:
249
                continue
250
            case authority:
251
                pass
252
253
        if not account_exists(tx_state, authority):
254
            charge_state_gas(evm, StateGasCosts.NEW_ACCOUNT)
255
256
        if authority not in written_accounts:
257
            charge_gas(evm, GasCosts.ACCOUNT_WRITE)
258
            written_accounts.add(authority)
259
260
        pre_state_authority_account = get_pre_state_account(
261
            tx_state, authority
262
        )
263
        pre_state_authority_code = get_code(
264
            tx_state, pre_state_authority_account.code_hash
265
        )
266
        delegated_before_tx = is_valid_delegation(pre_state_authority_code)
267
268
        if auth.address == NULL_ADDRESS:
269
            code_to_set = b""
270
        else:
271
            if not delegated_before_tx and authority not in delegation_set_for:
272
                charge_state_gas(evm, StateGasCosts.AUTH_BASE)
273
            delegation_set_for.add(authority)
274
            code_to_set = EOA_DELEGATION_MARKER + auth.address
275
276
        set_code(tx_state, authority, code_to_set)
277
        increment_nonce(tx_state, authority)