ethereum.shanghai.fork

Ethereum Specification ^^^^^^^^^^^^^^^^^^^^^^

.. contents:: Table of Contents :backlinks: none :local:

Introduction

Entry point for the Ethereum specification.

BASE_FEE_MAX_CHANGE_DENOMINATOR

54
BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8)

ELASTICITY_MULTIPLIER

55
ELASTICITY_MULTIPLIER = Uint(2)

GAS_LIMIT_ADJUSTMENT_FACTOR

56
GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024)

GAS_LIMIT_MINIMUM

57
GAS_LIMIT_MINIMUM = Uint(5000)

EMPTY_OMMER_HASH

58
EMPTY_OMMER_HASH = keccak256(rlp.encode([]))

BlockChain

History and current state of the block chain.

61
@dataclass
class BlockChain:

blocks

67
    blocks: List[Block]

state

68
    state: State

chain_id

69
    chain_id: U64

apply_fork

Transforms the state from the previous hard fork (old) into the block chain object for this hard fork and returns it.

When forks need to implement an irregular state transition, this function is used to handle the irregularity. See the :ref:DAO Fork <dao-fork> for an example.

Parameters

old : Previous block chain object.

Returns

new : BlockChain Upgraded block chain object for this hard fork.

def apply_fork(old: BlockChain) -> BlockChain:
73
    """
74
    Transforms the state from the previous hard fork (`old`) into the block
75
    chain object for this hard fork and returns it.
76
77
    When forks need to implement an irregular state transition, this function
78
    is used to handle the irregularity. See the :ref:`DAO Fork <dao-fork>` for
79
    an example.
80
81
    Parameters
82
    ----------
83
    old :
84
        Previous block chain object.
85
86
    Returns
87
    -------
88
    new : `BlockChain`
89
        Upgraded block chain object for this hard fork.
90
    """
91
    return old

get_last_256_block_hashes

Obtain the list of hashes of the previous 256 blocks in order of increasing block number.

This function will return less hashes for the first 256 blocks.

The BLOCKHASH opcode needs to access the latest hashes on the chain, therefore this function retrieves them.

Parameters

chain : History and current state.

Returns

recent_block_hashes : List[Hash32] Hashes of the recent 256 blocks in order of increasing block number.

def get_last_256_block_hashes(chain: BlockChain) -> List[Hash32]:
95
    """
96
    Obtain the list of hashes of the previous 256 blocks in order of
97
    increasing block number.
98
99
    This function will return less hashes for the first 256 blocks.
100
101
    The ``BLOCKHASH`` opcode needs to access the latest hashes on the chain,
102
    therefore this function retrieves them.
103
104
    Parameters
105
    ----------
106
    chain :
107
        History and current state.
108
109
    Returns
110
    -------
111
    recent_block_hashes : `List[Hash32]`
112
        Hashes of the recent 256 blocks in order of increasing block number.
113
    """
114
    recent_blocks = chain.blocks[-255:]
115
    # TODO: This function has not been tested rigorously
116
    if len(recent_blocks) == 0:
117
        return []
118
119
    recent_block_hashes = []
120
121
    for block in recent_blocks:
122
        prev_block_hash = block.header.parent_hash
123
        recent_block_hashes.append(prev_block_hash)
124
125
    # We are computing the hash only for the most recent block and not for
126
    # the rest of the blocks as they have successors which have the hash of
127
    # the current block as parent hash.
128
    most_recent_block_hash = keccak256(rlp.encode(recent_blocks[-1].header))
129
    recent_block_hashes.append(most_recent_block_hash)
130
131
    return recent_block_hashes

state_transition

Attempts to apply a block to an existing block chain.

All parts of the block's contents need to be verified before being added to the chain. Blocks are verified by ensuring that the contents of the block make logical sense with the contents of the parent block. The information in the block's header must also match the corresponding information in the block.

To implement Ethereum, in theory clients are only required to store the most recent 255 blocks of the chain since as far as execution is concerned, only those blocks are accessed. Practically, however, clients should store more blocks to handle reorgs.

Parameters

chain : History and current state. block : Block to apply to chain.

def state_transition(chain: BlockChain, ​​block: Block) -> None:
135
    """
136
    Attempts to apply a block to an existing block chain.
137
138
    All parts of the block's contents need to be verified before being added
139
    to the chain. Blocks are verified by ensuring that the contents of the
140
    block make logical sense with the contents of the parent block. The
141
    information in the block's header must also match the corresponding
142
    information in the block.
143
144
    To implement Ethereum, in theory clients are only required to store the
145
    most recent 255 blocks of the chain since as far as execution is
146
    concerned, only those blocks are accessed. Practically, however, clients
147
    should store more blocks to handle reorgs.
148
149
    Parameters
150
    ----------
151
    chain :
152
        History and current state.
153
    block :
154
        Block to apply to `chain`.
155
    """
156
    parent_header = chain.blocks[-1].header
157
    validate_header(block.header, parent_header)
158
    if block.ommers != ():
159
        raise InvalidBlock
160
    apply_body_output = apply_body(
161
        chain.state,
162
        get_last_256_block_hashes(chain),
163
        block.header.coinbase,
164
        block.header.number,
165
        block.header.base_fee_per_gas,
166
        block.header.gas_limit,
167
        block.header.timestamp,
168
        block.header.prev_randao,
169
        block.transactions,
170
        chain.chain_id,
171
        block.withdrawals,
172
    )
173
    if apply_body_output.block_gas_used != block.header.gas_used:
174
        raise InvalidBlock(
175
            f"{apply_body_output.block_gas_used} != {block.header.gas_used}"
176
        )
177
    if apply_body_output.transactions_root != block.header.transactions_root:
178
        raise InvalidBlock
179
    if apply_body_output.state_root != block.header.state_root:
180
        raise InvalidBlock
181
    if apply_body_output.receipt_root != block.header.receipt_root:
182
        raise InvalidBlock
183
    if apply_body_output.block_logs_bloom != block.header.bloom:
184
        raise InvalidBlock
185
    if apply_body_output.withdrawals_root != block.header.withdrawals_root:
186
        raise InvalidBlock
187
188
    chain.blocks.append(block)
189
    if len(chain.blocks) > 255:
190
        # Real clients have to store more blocks to deal with reorgs, but the
191
        # protocol only requires the last 255
192
        chain.blocks = chain.blocks[-255:]

calculate_base_fee_per_gas

Calculates the base fee per gas for the block.

Parameters

block_gas_limit : Gas limit of the block for which the base fee is being calculated. parent_gas_limit : Gas limit of the parent block. parent_gas_used : Gas used in the parent block. parent_base_fee_per_gas : Base fee per gas of the parent block.

Returns

base_fee_per_gas : Uint Base fee per gas for the block.

def calculate_base_fee_per_gas(block_gas_limit: Uint, ​​parent_gas_limit: Uint, ​​parent_gas_used: Uint, ​​parent_base_fee_per_gas: Uint) -> Uint:
201
    """
202
    Calculates the base fee per gas for the block.
203
204
    Parameters
205
    ----------
206
    block_gas_limit :
207
        Gas limit of the block for which the base fee is being calculated.
208
    parent_gas_limit :
209
        Gas limit of the parent block.
210
    parent_gas_used :
211
        Gas used in the parent block.
212
    parent_base_fee_per_gas :
213
        Base fee per gas of the parent block.
214
215
    Returns
216
    -------
217
    base_fee_per_gas : `Uint`
218
        Base fee per gas for the block.
219
    """
220
    parent_gas_target = parent_gas_limit // ELASTICITY_MULTIPLIER
221
    if not check_gas_limit(block_gas_limit, parent_gas_limit):
222
        raise InvalidBlock
223
224
    if parent_gas_used == parent_gas_target:
225
        expected_base_fee_per_gas = parent_base_fee_per_gas
226
    elif parent_gas_used > parent_gas_target:
227
        gas_used_delta = parent_gas_used - parent_gas_target
228
229
        parent_fee_gas_delta = parent_base_fee_per_gas * gas_used_delta
230
        target_fee_gas_delta = parent_fee_gas_delta // parent_gas_target
231
232
        base_fee_per_gas_delta = max(
233
            target_fee_gas_delta // BASE_FEE_MAX_CHANGE_DENOMINATOR,
234
            Uint(1),
235
        )
236
237
        expected_base_fee_per_gas = (
238
            parent_base_fee_per_gas + base_fee_per_gas_delta
239
        )
240
    else:
241
        gas_used_delta = parent_gas_target - parent_gas_used
242
243
        parent_fee_gas_delta = parent_base_fee_per_gas * gas_used_delta
244
        target_fee_gas_delta = parent_fee_gas_delta // parent_gas_target
245
246
        base_fee_per_gas_delta = (
247
            target_fee_gas_delta // BASE_FEE_MAX_CHANGE_DENOMINATOR
248
        )
249
250
        expected_base_fee_per_gas = (
251
            parent_base_fee_per_gas - base_fee_per_gas_delta
252
        )
253
254
    return Uint(expected_base_fee_per_gas)

validate_header

Verifies a block header.

In order to consider a block's header valid, the logic for the quantities in the header should match the logic for the block itself. For example the header timestamp should be greater than the block's parent timestamp because the block was created after the parent block. Additionally, the block's number should be directly following the parent block's number since it is the next block in the sequence.

Parameters

header : Header to check for correctness. parent_header : Parent Header of the header to check for correctness

def validate_header(header: Header, ​​parent_header: Header) -> None:
258
    """
259
    Verifies a block header.
260
261
    In order to consider a block's header valid, the logic for the
262
    quantities in the header should match the logic for the block itself.
263
    For example the header timestamp should be greater than the block's parent
264
    timestamp because the block was created *after* the parent block.
265
    Additionally, the block's number should be directly following the parent
266
    block's number since it is the next block in the sequence.
267
268
    Parameters
269
    ----------
270
    header :
271
        Header to check for correctness.
272
    parent_header :
273
        Parent Header of the header to check for correctness
274
    """
275
    if header.gas_used > header.gas_limit:
276
        raise InvalidBlock
277
278
    expected_base_fee_per_gas = calculate_base_fee_per_gas(
279
        header.gas_limit,
280
        parent_header.gas_limit,
281
        parent_header.gas_used,
282
        parent_header.base_fee_per_gas,
283
    )
284
    if expected_base_fee_per_gas != header.base_fee_per_gas:
285
        raise InvalidBlock
286
    if header.timestamp <= parent_header.timestamp:
287
        raise InvalidBlock
288
    if header.number != parent_header.number + Uint(1):
289
        raise InvalidBlock
290
    if len(header.extra_data) > 32:
291
        raise InvalidBlock
292
    if header.difficulty != 0:
293
        raise InvalidBlock
294
    if header.nonce != b"\x00\x00\x00\x00\x00\x00\x00\x00":
295
        raise InvalidBlock
296
    if header.ommers_hash != EMPTY_OMMER_HASH:
297
        raise InvalidBlock
298
299
    block_parent_hash = keccak256(rlp.encode(parent_header))
300
    if header.parent_hash != block_parent_hash:
301
        raise InvalidBlock

check_transaction

Check if the transaction is includable in the block.

Parameters

tx : The transaction. base_fee_per_gas : The block base fee. gas_available : The gas remaining in the block. chain_id : The ID of the current chain.

Returns

sender_address : The sender of the transaction. effective_gas_price : The price to charge for gas when the transaction is executed.

Raises

InvalidBlock : If the transaction is not includable.

def check_transaction(tx: Transaction, ​​base_fee_per_gas: Uint, ​​gas_available: Uint, ​​chain_id: U64) -> Tuple[Address, Uint]:
310
    """
311
    Check if the transaction is includable in the block.
312
313
    Parameters
314
    ----------
315
    tx :
316
        The transaction.
317
    base_fee_per_gas :
318
        The block base fee.
319
    gas_available :
320
        The gas remaining in the block.
321
    chain_id :
322
        The ID of the current chain.
323
324
    Returns
325
    -------
326
    sender_address :
327
        The sender of the transaction.
328
    effective_gas_price :
329
        The price to charge for gas when the transaction is executed.
330
331
    Raises
332
    ------
333
    InvalidBlock :
334
        If the transaction is not includable.
335
    """
336
    if tx.gas > gas_available:
337
        raise InvalidBlock
338
    sender_address = recover_sender(chain_id, tx)
339
340
    if isinstance(tx, FeeMarketTransaction):
341
        if tx.max_fee_per_gas < tx.max_priority_fee_per_gas:
342
            raise InvalidBlock
343
        if tx.max_fee_per_gas < base_fee_per_gas:
344
            raise InvalidBlock
345
346
        priority_fee_per_gas = min(
347
            tx.max_priority_fee_per_gas,
348
            tx.max_fee_per_gas - base_fee_per_gas,
349
        )
350
        effective_gas_price = priority_fee_per_gas + base_fee_per_gas
351
    else:
352
        if tx.gas_price < base_fee_per_gas:
353
            raise InvalidBlock
354
        effective_gas_price = tx.gas_price
355
356
    return sender_address, effective_gas_price

make_receipt

Make the receipt for a transaction that was executed.

Parameters

tx : The executed transaction. error : Error in the top level frame of the transaction, if any. cumulative_gas_used : The total gas used so far in the block after the transaction was executed. logs : The logs produced by the transaction.

Returns

receipt : The receipt for the transaction.

def make_receipt(tx: Transaction, ​​error: Optional[Exception], ​​cumulative_gas_used: Uint, ​​logs: Tuple[Log, ...]) -> Union[Bytes, Receipt]:
365
    """
366
    Make the receipt for a transaction that was executed.
367
368
    Parameters
369
    ----------
370
    tx :
371
        The executed transaction.
372
    error :
373
        Error in the top level frame of the transaction, if any.
374
    cumulative_gas_used :
375
        The total gas used so far in the block after the transaction was
376
        executed.
377
    logs :
378
        The logs produced by the transaction.
379
380
    Returns
381
    -------
382
    receipt :
383
        The receipt for the transaction.
384
    """
385
    receipt = Receipt(
386
        succeeded=error is None,
387
        cumulative_gas_used=cumulative_gas_used,
388
        bloom=logs_bloom(logs),
389
        logs=logs,
390
    )
391
392
    if isinstance(tx, AccessListTransaction):
393
        return b"\x01" + rlp.encode(receipt)
394
    elif isinstance(tx, FeeMarketTransaction):
395
        return b"\x02" + rlp.encode(receipt)
396
    else:
397
        return receipt

ApplyBodyOutput

Output from applying the block body to the present state.

Contains the following:

block_gas_used : ethereum.base_types.Uint Gas used for executing all transactions. transactions_root : ethereum.fork_types.Root Trie root of all the transactions in the block. receipt_root : ethereum.fork_types.Root Trie root of all the receipts in the block. block_logs_bloom : Bloom Logs bloom of all the logs included in all the transactions of the block. state_root : ethereum.fork_types.Root State root after all transactions have been executed. withdrawals_root : ethereum.fork_types.Root Trie root of all the withdrawals in the block.

400
@dataclass
class ApplyBodyOutput:

block_gas_used

422
    block_gas_used: Uint

transactions_root

423
    transactions_root: Root

receipt_root

424
    receipt_root: Root

block_logs_bloom

425
    block_logs_bloom: Bloom

state_root

426
    state_root: Root

withdrawals_root

427
    withdrawals_root: Root

apply_body

Executes a block.

Many of the contents of a block are stored in data structures called tries. There is a transactions trie which is similar to a ledger of the transactions stored in the current block. There is also a receipts trie which stores the results of executing a transaction, like the post state and gas used. This function creates and executes the block that is to be added to the chain.

Parameters

state : Current account state. block_hashes : List of hashes of the previous 256 blocks in the order of increasing block number. coinbase : Address of account which receives block reward and transaction fees. block_number : Position of the block within the chain. base_fee_per_gas : Base fee per gas of within the block. block_gas_limit : Initial amount of gas available for execution in this block. block_time : Time the block was produced, measured in seconds since the epoch. prev_randao : The previous randao from the beacon chain. transactions : Transactions included in the block. ommers : Headers of ancestor blocks which are not direct parents (formerly uncles.) chain_id : ID of the executing chain. withdrawals : Withdrawals to be processed in the current block.

Returns

apply_body_output : ApplyBodyOutput Output of applying the block body to the state.

def apply_body(state: State, ​​block_hashes: List[Hash32], ​​coinbase: Address, ​​block_number: Uint, ​​base_fee_per_gas: Uint, ​​block_gas_limit: Uint, ​​block_time: U256, ​​prev_randao: Bytes32, ​​transactions: Tuple[Union[LegacyTransaction, Bytes], ...], ​​chain_id: U64, ​​withdrawals: Tuple[Withdrawal, ...]) -> ApplyBodyOutput:
443
    """
444
    Executes a block.
445
446
    Many of the contents of a block are stored in data structures called
447
    tries. There is a transactions trie which is similar to a ledger of the
448
    transactions stored in the current block. There is also a receipts trie
449
    which stores the results of executing a transaction, like the post state
450
    and gas used. This function creates and executes the block that is to be
451
    added to the chain.
452
453
    Parameters
454
    ----------
455
    state :
456
        Current account state.
457
    block_hashes :
458
        List of hashes of the previous 256 blocks in the order of
459
        increasing block number.
460
    coinbase :
461
        Address of account which receives block reward and transaction fees.
462
    block_number :
463
        Position of the block within the chain.
464
    base_fee_per_gas :
465
        Base fee per gas of within the block.
466
    block_gas_limit :
467
        Initial amount of gas available for execution in this block.
468
    block_time :
469
        Time the block was produced, measured in seconds since the epoch.
470
    prev_randao :
471
        The previous randao from the beacon chain.
472
    transactions :
473
        Transactions included in the block.
474
    ommers :
475
        Headers of ancestor blocks which are not direct parents (formerly
476
        uncles.)
477
    chain_id :
478
        ID of the executing chain.
479
    withdrawals :
480
        Withdrawals to be processed in the current block.
481
482
    Returns
483
    -------
484
    apply_body_output : `ApplyBodyOutput`
485
        Output of applying the block body to the state.
486
    """
487
    gas_available = block_gas_limit
488
    transactions_trie: Trie[
489
        Bytes, Optional[Union[Bytes, LegacyTransaction]]
490
    ] = Trie(secured=False, default=None)
491
    receipts_trie: Trie[Bytes, Optional[Union[Bytes, Receipt]]] = Trie(
492
        secured=False, default=None
493
    )
494
    withdrawals_trie: Trie[Bytes, Optional[Union[Bytes, Withdrawal]]] = Trie(
495
        secured=False, default=None
496
    )
497
    block_logs: Tuple[Log, ...] = ()
498
499
    for i, tx in enumerate(map(decode_transaction, transactions)):
500
        trie_set(
501
            transactions_trie, rlp.encode(Uint(i)), encode_transaction(tx)
502
        )
503
504
        sender_address, effective_gas_price = check_transaction(
505
            tx, base_fee_per_gas, gas_available, chain_id
506
        )
507
508
        env = vm.Environment(
509
            caller=sender_address,
510
            origin=sender_address,
511
            block_hashes=block_hashes,
512
            coinbase=coinbase,
513
            number=block_number,
514
            gas_limit=block_gas_limit,
515
            base_fee_per_gas=base_fee_per_gas,
516
            gas_price=effective_gas_price,
517
            time=block_time,
518
            prev_randao=prev_randao,
519
            state=state,
520
            chain_id=chain_id,
521
            traces=[],
522
        )
523
524
        gas_used, logs, error = process_transaction(env, tx)
525
        gas_available -= gas_used
526
527
        receipt = make_receipt(
528
            tx, error, (block_gas_limit - gas_available), logs
529
        )
530
531
        trie_set(
532
            receipts_trie,
533
            rlp.encode(Uint(i)),
534
            receipt,
535
        )
536
537
        block_logs += logs
538
539
    block_gas_used = block_gas_limit - gas_available
540
541
    block_logs_bloom = logs_bloom(block_logs)
542
543
    for i, wd in enumerate(withdrawals):
544
        trie_set(withdrawals_trie, rlp.encode(Uint(i)), rlp.encode(wd))
545
546
        process_withdrawal(state, wd)
547
548
        if account_exists_and_is_empty(state, wd.address):
549
            destroy_account(state, wd.address)
550
551
    return ApplyBodyOutput(
552
        block_gas_used,
553
        root(transactions_trie),
554
        root(receipts_trie),
555
        block_logs_bloom,
556
        state_root(state),
557
        root(withdrawals_trie),
558
    )

process_transaction

Execute a transaction against the provided environment.

This function processes the actions needed to execute a transaction. It decrements the sender's account after calculating the gas fee and refunds them the proper amount after execution. Calling contracts, deploying code, and incrementing nonces are all examples of actions that happen within this function or from a call made within this function.

Accounts that are marked for deletion are processed and destroyed after execution.

Parameters

env : Environment for the Ethereum Virtual Machine. tx : Transaction to execute.

Returns

gas_left : ethereum.base_types.U256 Remaining gas after execution. logs : Tuple[ethereum.blocks.Log, ...] Logs generated during execution.

def process_transaction(env: ethereum.shanghai.vm.Environment, ​​tx: Transaction) -> Tuple[Uint, Tuple[Log, ...], Optional[Exception]]:
564
    """
565
    Execute a transaction against the provided environment.
566
567
    This function processes the actions needed to execute a transaction.
568
    It decrements the sender's account after calculating the gas fee and
569
    refunds them the proper amount after execution. Calling contracts,
570
    deploying code, and incrementing nonces are all examples of actions that
571
    happen within this function or from a call made within this function.
572
573
    Accounts that are marked for deletion are processed and destroyed after
574
    execution.
575
576
    Parameters
577
    ----------
578
    env :
579
        Environment for the Ethereum Virtual Machine.
580
    tx :
581
        Transaction to execute.
582
583
    Returns
584
    -------
585
    gas_left : `ethereum.base_types.U256`
586
        Remaining gas after execution.
587
    logs : `Tuple[ethereum.blocks.Log, ...]`
588
        Logs generated during execution.
589
    """
590
    if not validate_transaction(tx):
591
        raise InvalidBlock
592
593
    sender = env.origin
594
    sender_account = get_account(env.state, sender)
595
596
    if isinstance(tx, FeeMarketTransaction):
597
        max_gas_fee = tx.gas * tx.max_fee_per_gas
598
    else:
599
        max_gas_fee = tx.gas * tx.gas_price
600
    if sender_account.nonce != tx.nonce:
601
        raise InvalidBlock
602
    if Uint(sender_account.balance) < max_gas_fee + Uint(tx.value):
603
        raise InvalidBlock
604
    if sender_account.code != bytearray():
605
        raise InvalidSenderError("not EOA")
606
607
    effective_gas_fee = tx.gas * env.gas_price
608
609
    gas = tx.gas - calculate_intrinsic_cost(tx)
610
    increment_nonce(env.state, sender)
611
612
    sender_balance_after_gas_fee = (
613
        Uint(sender_account.balance) - effective_gas_fee
614
    )
615
    set_account_balance(env.state, sender, U256(sender_balance_after_gas_fee))
616
617
    preaccessed_addresses = set()
618
    preaccessed_storage_keys = set()
619
    preaccessed_addresses.add(env.coinbase)
620
    if isinstance(tx, (AccessListTransaction, FeeMarketTransaction)):
621
        for address, keys in tx.access_list:
622
            preaccessed_addresses.add(address)
623
            for key in keys:
624
                preaccessed_storage_keys.add((address, key))
625
626
    message = prepare_message(
627
        sender,
628
        tx.to,
629
        tx.value,
630
        tx.data,
631
        gas,
632
        env,
633
        preaccessed_addresses=frozenset(preaccessed_addresses),
634
        preaccessed_storage_keys=frozenset(preaccessed_storage_keys),
635
    )
636
637
    output = process_message_call(message, env)
638
639
    gas_used = tx.gas - output.gas_left
640
    gas_refund = min(gas_used // Uint(5), Uint(output.refund_counter))
641
    gas_refund_amount = (output.gas_left + gas_refund) * env.gas_price
642
643
    # For non-1559 transactions env.gas_price == tx.gas_price
644
    priority_fee_per_gas = env.gas_price - env.base_fee_per_gas
645
    transaction_fee = (
646
        tx.gas - output.gas_left - gas_refund
647
    ) * priority_fee_per_gas
648
649
    total_gas_used = gas_used - gas_refund
650
651
    # refund gas
652
    sender_balance_after_refund = get_account(
653
        env.state, sender
654
    ).balance + U256(gas_refund_amount)
655
    set_account_balance(env.state, sender, sender_balance_after_refund)
656
657
    # transfer miner fees
658
    coinbase_balance_after_mining_fee = get_account(
659
        env.state, env.coinbase
660
    ).balance + U256(transaction_fee)
661
    if coinbase_balance_after_mining_fee != 0:
662
        set_account_balance(
663
            env.state, env.coinbase, coinbase_balance_after_mining_fee
664
        )
665
    elif account_exists_and_is_empty(env.state, env.coinbase):
666
        destroy_account(env.state, env.coinbase)
667
668
    for address in output.accounts_to_delete:
669
        destroy_account(env.state, address)
670
671
    for address in output.touched_accounts:
672
        if account_exists_and_is_empty(env.state, address):
673
            destroy_account(env.state, address)
674
675
    return total_gas_used, output.logs, output.error

compute_header_hash

Computes the hash of a block header.

The header hash of a block is the canonical hash that is used to refer to a specific block and completely distinguishes a block from another.

keccak256 is a function that produces a 256 bit hash of any input. It also takes in any number of bytes as an input and produces a single hash for them. A hash is a completely unique output for a single input. So an input corresponds to one unique hash that can be used to identify the input exactly.

Prior to using the keccak256 hash function, the header must be encoded using the Recursive-Length Prefix. See :ref:rlp. RLP encoding the header converts it into a space-efficient format that allows for easy transfer of data between nodes. The purpose of RLP is to encode arbitrarily nested arrays of binary data, and RLP is the primary encoding method used to serialize objects in Ethereum's execution layer. The only purpose of RLP is to encode structure; encoding specific data types (e.g. strings, floats) is left up to higher-order protocols.

Parameters

header : Header of interest.

Returns

hash : ethereum.crypto.hash.Hash32 Hash of the header.

def compute_header_hash(header: Header) -> Hash32:
679
    """
680
    Computes the hash of a block header.
681
682
    The header hash of a block is the canonical hash that is used to refer
683
    to a specific block and completely distinguishes a block from another.
684
685
    ``keccak256`` is a function that produces a 256 bit hash of any input.
686
    It also takes in any number of bytes as an input and produces a single
687
    hash for them. A hash is a completely unique output for a single input.
688
    So an input corresponds to one unique hash that can be used to identify
689
    the input exactly.
690
691
    Prior to using the ``keccak256`` hash function, the header must be
692
    encoded using the Recursive-Length Prefix. See :ref:`rlp`.
693
    RLP encoding the header converts it into a space-efficient format that
694
    allows for easy transfer of data between nodes. The purpose of RLP is to
695
    encode arbitrarily nested arrays of binary data, and RLP is the primary
696
    encoding method used to serialize objects in Ethereum's execution layer.
697
    The only purpose of RLP is to encode structure; encoding specific data
698
    types (e.g. strings, floats) is left up to higher-order protocols.
699
700
    Parameters
701
    ----------
702
    header :
703
        Header of interest.
704
705
    Returns
706
    -------
707
    hash : `ethereum.crypto.hash.Hash32`
708
        Hash of the header.
709
    """
710
    return keccak256(rlp.encode(header))

check_gas_limit

Validates the gas limit for a block.

The bounds of the gas limit, max_adjustment_delta, is set as the quotient of the parent block's gas limit and the GAS_LIMIT_ADJUSTMENT_FACTOR. Therefore, if the gas limit that is passed through as a parameter is greater than or equal to the sum of the parent's gas and the adjustment delta then the limit for gas is too high and fails this function's check. Similarly, if the limit is less than or equal to the difference of the parent's gas and the adjustment delta or the predefined GAS_LIMIT_MINIMUM then this function's check fails because the gas limit doesn't allow for a sufficient or reasonable amount of gas to be used on a block.

Parameters

gas_limit : Gas limit to validate.

parent_gas_limit : Gas limit of the parent block.

Returns

check : bool True if gas limit constraints are satisfied, False otherwise.

def check_gas_limit(gas_limit: Uint, ​​parent_gas_limit: Uint) -> bool:
714
    """
715
    Validates the gas limit for a block.
716
717
    The bounds of the gas limit, ``max_adjustment_delta``, is set as the
718
    quotient of the parent block's gas limit and the
719
    ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is
720
    passed through as a parameter is greater than or equal to the *sum* of
721
    the parent's gas and the adjustment delta then the limit for gas is too
722
    high and fails this function's check. Similarly, if the limit is less
723
    than or equal to the *difference* of the parent's gas and the adjustment
724
    delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's
725
    check fails because the gas limit doesn't allow for a sufficient or
726
    reasonable amount of gas to be used on a block.
727
728
    Parameters
729
    ----------
730
    gas_limit :
731
        Gas limit to validate.
732
733
    parent_gas_limit :
734
        Gas limit of the parent block.
735
736
    Returns
737
    -------
738
    check : `bool`
739
        True if gas limit constraints are satisfied, False otherwise.
740
    """
741
    max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR
742
    if gas_limit >= parent_gas_limit + max_adjustment_delta:
743
        return False
744
    if gas_limit <= parent_gas_limit - max_adjustment_delta:
745
        return False
746
    if gas_limit < GAS_LIMIT_MINIMUM:
747
        return False
748
749
    return True