ethereum.shanghai.fork

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

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

Introduction

Entry point for the Ethereum specification.

BASE_FEE_MAX_CHANGE_DENOMINATOR

58
BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8)

ELASTICITY_MULTIPLIER

59
ELASTICITY_MULTIPLIER = Uint(2)

GAS_LIMIT_ADJUSTMENT_FACTOR

60
GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024)

GAS_LIMIT_MINIMUM

61
GAS_LIMIT_MINIMUM = Uint(5000)

EMPTY_OMMER_HASH

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

BlockChain

History and current state of the block chain.

65
@dataclass
class BlockChain:

blocks

71
    blocks: List[Block]

state

72
    state: State

chain_id

73
    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:
77
    """
78
    Transforms the state from the previous hard fork (`old`) into the block
79
    chain object for this hard fork and returns it.
80
81
    When forks need to implement an irregular state transition, this function
82
    is used to handle the irregularity. See the :ref:`DAO Fork <dao-fork>` for
83
    an example.
84
85
    Parameters
86
    ----------
87
    old :
88
        Previous block chain object.
89
90
    Returns
91
    -------
92
    new : `BlockChain`
93
        Upgraded block chain object for this hard fork.
94
    """
95
    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]:
99
    """
100
    Obtain the list of hashes of the previous 256 blocks in order of
101
    increasing block number.
102
103
    This function will return less hashes for the first 256 blocks.
104
105
    The ``BLOCKHASH`` opcode needs to access the latest hashes on the chain,
106
    therefore this function retrieves them.
107
108
    Parameters
109
    ----------
110
    chain :
111
        History and current state.
112
113
    Returns
114
    -------
115
    recent_block_hashes : `List[Hash32]`
116
        Hashes of the recent 256 blocks in order of increasing block number.
117
    """
118
    recent_blocks = chain.blocks[-255:]
119
    # TODO: This function has not been tested rigorously
120
    if len(recent_blocks) == 0:
121
        return []
122
123
    recent_block_hashes = []
124
125
    for block in recent_blocks:
126
        prev_block_hash = block.header.parent_hash
127
        recent_block_hashes.append(prev_block_hash)
128
129
    # We are computing the hash only for the most recent block and not for
130
    # the rest of the blocks as they have successors which have the hash of
131
    # the current block as parent hash.
132
    most_recent_block_hash = keccak256(rlp.encode(recent_blocks[-1].header))
133
    recent_block_hashes.append(most_recent_block_hash)
134
135
    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:
139
    """
140
    Attempts to apply a block to an existing block chain.
141
142
    All parts of the block's contents need to be verified before being added
143
    to the chain. Blocks are verified by ensuring that the contents of the
144
    block make logical sense with the contents of the parent block. The
145
    information in the block's header must also match the corresponding
146
    information in the block.
147
148
    To implement Ethereum, in theory clients are only required to store the
149
    most recent 255 blocks of the chain since as far as execution is
150
    concerned, only those blocks are accessed. Practically, however, clients
151
    should store more blocks to handle reorgs.
152
153
    Parameters
154
    ----------
155
    chain :
156
        History and current state.
157
    block :
158
        Block to apply to `chain`.
159
    """
160
    parent_header = chain.blocks[-1].header
161
    validate_header(block.header, parent_header)
162
    if block.ommers != ():
163
        raise InvalidBlock
164
    apply_body_output = apply_body(
165
        chain.state,
166
        get_last_256_block_hashes(chain),
167
        block.header.coinbase,
168
        block.header.number,
169
        block.header.base_fee_per_gas,
170
        block.header.gas_limit,
171
        block.header.timestamp,
172
        block.header.prev_randao,
173
        block.transactions,
174
        chain.chain_id,
175
        block.withdrawals,
176
    )
177
    if apply_body_output.block_gas_used != block.header.gas_used:
178
        raise InvalidBlock(
179
            f"{apply_body_output.block_gas_used} != {block.header.gas_used}"
180
        )
181
    if apply_body_output.transactions_root != block.header.transactions_root:
182
        raise InvalidBlock
183
    if apply_body_output.state_root != block.header.state_root:
184
        raise InvalidBlock
185
    if apply_body_output.receipt_root != block.header.receipt_root:
186
        raise InvalidBlock
187
    if apply_body_output.block_logs_bloom != block.header.bloom:
188
        raise InvalidBlock
189
    if apply_body_output.withdrawals_root != block.header.withdrawals_root:
190
        raise InvalidBlock
191
192
    chain.blocks.append(block)
193
    if len(chain.blocks) > 255:
194
        # Real clients have to store more blocks to deal with reorgs, but the
195
        # protocol only requires the last 255
196
        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:
205
    """
206
    Calculates the base fee per gas for the block.
207
208
    Parameters
209
    ----------
210
    block_gas_limit :
211
        Gas limit of the block for which the base fee is being calculated.
212
    parent_gas_limit :
213
        Gas limit of the parent block.
214
    parent_gas_used :
215
        Gas used in the parent block.
216
    parent_base_fee_per_gas :
217
        Base fee per gas of the parent block.
218
219
    Returns
220
    -------
221
    base_fee_per_gas : `Uint`
222
        Base fee per gas for the block.
223
    """
224
    parent_gas_target = parent_gas_limit // ELASTICITY_MULTIPLIER
225
    if not check_gas_limit(block_gas_limit, parent_gas_limit):
226
        raise InvalidBlock
227
228
    if parent_gas_used == parent_gas_target:
229
        expected_base_fee_per_gas = parent_base_fee_per_gas
230
    elif parent_gas_used > parent_gas_target:
231
        gas_used_delta = parent_gas_used - parent_gas_target
232
233
        parent_fee_gas_delta = parent_base_fee_per_gas * gas_used_delta
234
        target_fee_gas_delta = parent_fee_gas_delta // parent_gas_target
235
236
        base_fee_per_gas_delta = max(
237
            target_fee_gas_delta // BASE_FEE_MAX_CHANGE_DENOMINATOR,
238
            Uint(1),
239
        )
240
241
        expected_base_fee_per_gas = (
242
            parent_base_fee_per_gas + base_fee_per_gas_delta
243
        )
244
    else:
245
        gas_used_delta = parent_gas_target - parent_gas_used
246
247
        parent_fee_gas_delta = parent_base_fee_per_gas * gas_used_delta
248
        target_fee_gas_delta = parent_fee_gas_delta // parent_gas_target
249
250
        base_fee_per_gas_delta = (
251
            target_fee_gas_delta // BASE_FEE_MAX_CHANGE_DENOMINATOR
252
        )
253
254
        expected_base_fee_per_gas = (
255
            parent_base_fee_per_gas - base_fee_per_gas_delta
256
        )
257
258
    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:
262
    """
263
    Verifies a block header.
264
265
    In order to consider a block's header valid, the logic for the
266
    quantities in the header should match the logic for the block itself.
267
    For example the header timestamp should be greater than the block's parent
268
    timestamp because the block was created *after* the parent block.
269
    Additionally, the block's number should be directly following the parent
270
    block's number since it is the next block in the sequence.
271
272
    Parameters
273
    ----------
274
    header :
275
        Header to check for correctness.
276
    parent_header :
277
        Parent Header of the header to check for correctness
278
    """
279
    if header.gas_used > header.gas_limit:
280
        raise InvalidBlock
281
282
    expected_base_fee_per_gas = calculate_base_fee_per_gas(
283
        header.gas_limit,
284
        parent_header.gas_limit,
285
        parent_header.gas_used,
286
        parent_header.base_fee_per_gas,
287
    )
288
    if expected_base_fee_per_gas != header.base_fee_per_gas:
289
        raise InvalidBlock
290
    if header.timestamp <= parent_header.timestamp:
291
        raise InvalidBlock
292
    if header.number != parent_header.number + Uint(1):
293
        raise InvalidBlock
294
    if len(header.extra_data) > 32:
295
        raise InvalidBlock
296
    if header.difficulty != 0:
297
        raise InvalidBlock
298
    if header.nonce != b"\x00\x00\x00\x00\x00\x00\x00\x00":
299
        raise InvalidBlock
300
    if header.ommers_hash != EMPTY_OMMER_HASH:
301
        raise InvalidBlock
302
303
    block_parent_hash = keccak256(rlp.encode(parent_header))
304
    if header.parent_hash != block_parent_hash:
305
        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]:
314
    """
315
    Check if the transaction is includable in the block.
316
317
    Parameters
318
    ----------
319
    tx :
320
        The transaction.
321
    base_fee_per_gas :
322
        The block base fee.
323
    gas_available :
324
        The gas remaining in the block.
325
    chain_id :
326
        The ID of the current chain.
327
328
    Returns
329
    -------
330
    sender_address :
331
        The sender of the transaction.
332
    effective_gas_price :
333
        The price to charge for gas when the transaction is executed.
334
335
    Raises
336
    ------
337
    InvalidBlock :
338
        If the transaction is not includable.
339
    """
340
    if tx.gas > gas_available:
341
        raise InvalidBlock
342
    sender_address = recover_sender(chain_id, tx)
343
344
    if isinstance(tx, FeeMarketTransaction):
345
        if tx.max_fee_per_gas < tx.max_priority_fee_per_gas:
346
            raise InvalidBlock
347
        if tx.max_fee_per_gas < base_fee_per_gas:
348
            raise InvalidBlock
349
350
        priority_fee_per_gas = min(
351
            tx.max_priority_fee_per_gas,
352
            tx.max_fee_per_gas - base_fee_per_gas,
353
        )
354
        effective_gas_price = priority_fee_per_gas + base_fee_per_gas
355
    else:
356
        if tx.gas_price < base_fee_per_gas:
357
            raise InvalidBlock
358
        effective_gas_price = tx.gas_price
359
360
    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[EthereumException], ​​cumulative_gas_used: Uint, ​​logs: Tuple[Log, ...]) -> Union[Bytes, Receipt]:
369
    """
370
    Make the receipt for a transaction that was executed.
371
372
    Parameters
373
    ----------
374
    tx :
375
        The executed transaction.
376
    error :
377
        Error in the top level frame of the transaction, if any.
378
    cumulative_gas_used :
379
        The total gas used so far in the block after the transaction was
380
        executed.
381
    logs :
382
        The logs produced by the transaction.
383
384
    Returns
385
    -------
386
    receipt :
387
        The receipt for the transaction.
388
    """
389
    receipt = Receipt(
390
        succeeded=error is None,
391
        cumulative_gas_used=cumulative_gas_used,
392
        bloom=logs_bloom(logs),
393
        logs=logs,
394
    )
395
396
    if isinstance(tx, AccessListTransaction):
397
        return b"\x01" + rlp.encode(receipt)
398
    elif isinstance(tx, FeeMarketTransaction):
399
        return b"\x02" + rlp.encode(receipt)
400
    else:
401
        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.

404
@dataclass
class ApplyBodyOutput:

block_gas_used

426
    block_gas_used: Uint

transactions_root

427
    transactions_root: Root

receipt_root

428
    receipt_root: Root

block_logs_bloom

429
    block_logs_bloom: Bloom

state_root

430
    state_root: Root

withdrawals_root

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

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[EthereumException]]:
568
    """
569
    Execute a transaction against the provided environment.
570
571
    This function processes the actions needed to execute a transaction.
572
    It decrements the sender's account after calculating the gas fee and
573
    refunds them the proper amount after execution. Calling contracts,
574
    deploying code, and incrementing nonces are all examples of actions that
575
    happen within this function or from a call made within this function.
576
577
    Accounts that are marked for deletion are processed and destroyed after
578
    execution.
579
580
    Parameters
581
    ----------
582
    env :
583
        Environment for the Ethereum Virtual Machine.
584
    tx :
585
        Transaction to execute.
586
587
    Returns
588
    -------
589
    gas_left : `ethereum.base_types.U256`
590
        Remaining gas after execution.
591
    logs : `Tuple[ethereum.blocks.Log, ...]`
592
        Logs generated during execution.
593
    """
594
    if not validate_transaction(tx):
595
        raise InvalidBlock
596
597
    sender = env.origin
598
    sender_account = get_account(env.state, sender)
599
600
    if isinstance(tx, FeeMarketTransaction):
601
        max_gas_fee = tx.gas * tx.max_fee_per_gas
602
    else:
603
        max_gas_fee = tx.gas * tx.gas_price
604
    if sender_account.nonce != tx.nonce:
605
        raise InvalidBlock
606
    if Uint(sender_account.balance) < max_gas_fee + Uint(tx.value):
607
        raise InvalidBlock
608
    if sender_account.code != bytearray():
609
        raise InvalidSenderError("not EOA")
610
611
    effective_gas_fee = tx.gas * env.gas_price
612
613
    gas = tx.gas - calculate_intrinsic_cost(tx)
614
    increment_nonce(env.state, sender)
615
616
    sender_balance_after_gas_fee = (
617
        Uint(sender_account.balance) - effective_gas_fee
618
    )
619
    set_account_balance(env.state, sender, U256(sender_balance_after_gas_fee))
620
621
    preaccessed_addresses = set()
622
    preaccessed_storage_keys = set()
623
    preaccessed_addresses.add(env.coinbase)
624
    if isinstance(tx, (AccessListTransaction, FeeMarketTransaction)):
625
        for address, keys in tx.access_list:
626
            preaccessed_addresses.add(address)
627
            for key in keys:
628
                preaccessed_storage_keys.add((address, key))
629
630
    message = prepare_message(
631
        sender,
632
        tx.to,
633
        tx.value,
634
        tx.data,
635
        gas,
636
        env,
637
        preaccessed_addresses=frozenset(preaccessed_addresses),
638
        preaccessed_storage_keys=frozenset(preaccessed_storage_keys),
639
    )
640
641
    output = process_message_call(message, env)
642
643
    gas_used = tx.gas - output.gas_left
644
    gas_refund = min(gas_used // Uint(5), Uint(output.refund_counter))
645
    gas_refund_amount = (output.gas_left + gas_refund) * env.gas_price
646
647
    # For non-1559 transactions env.gas_price == tx.gas_price
648
    priority_fee_per_gas = env.gas_price - env.base_fee_per_gas
649
    transaction_fee = (
650
        tx.gas - output.gas_left - gas_refund
651
    ) * priority_fee_per_gas
652
653
    total_gas_used = gas_used - gas_refund
654
655
    # refund gas
656
    sender_balance_after_refund = get_account(
657
        env.state, sender
658
    ).balance + U256(gas_refund_amount)
659
    set_account_balance(env.state, sender, sender_balance_after_refund)
660
661
    # transfer miner fees
662
    coinbase_balance_after_mining_fee = get_account(
663
        env.state, env.coinbase
664
    ).balance + U256(transaction_fee)
665
    if coinbase_balance_after_mining_fee != 0:
666
        set_account_balance(
667
            env.state, env.coinbase, coinbase_balance_after_mining_fee
668
        )
669
    elif account_exists_and_is_empty(env.state, env.coinbase):
670
        destroy_account(env.state, env.coinbase)
671
672
    for address in output.accounts_to_delete:
673
        destroy_account(env.state, address)
674
675
    for address in output.touched_accounts:
676
        if account_exists_and_is_empty(env.state, address):
677
            destroy_account(env.state, address)
678
679
    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:
683
    """
684
    Computes the hash of a block header.
685
686
    The header hash of a block is the canonical hash that is used to refer
687
    to a specific block and completely distinguishes a block from another.
688
689
    ``keccak256`` is a function that produces a 256 bit hash of any input.
690
    It also takes in any number of bytes as an input and produces a single
691
    hash for them. A hash is a completely unique output for a single input.
692
    So an input corresponds to one unique hash that can be used to identify
693
    the input exactly.
694
695
    Prior to using the ``keccak256`` hash function, the header must be
696
    encoded using the Recursive-Length Prefix. See :ref:`rlp`.
697
    RLP encoding the header converts it into a space-efficient format that
698
    allows for easy transfer of data between nodes. The purpose of RLP is to
699
    encode arbitrarily nested arrays of binary data, and RLP is the primary
700
    encoding method used to serialize objects in Ethereum's execution layer.
701
    The only purpose of RLP is to encode structure; encoding specific data
702
    types (e.g. strings, floats) is left up to higher-order protocols.
703
704
    Parameters
705
    ----------
706
    header :
707
        Header of interest.
708
709
    Returns
710
    -------
711
    hash : `ethereum.crypto.hash.Hash32`
712
        Hash of the header.
713
    """
714
    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:
718
    """
719
    Validates the gas limit for a block.
720
721
    The bounds of the gas limit, ``max_adjustment_delta``, is set as the
722
    quotient of the parent block's gas limit and the
723
    ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is
724
    passed through as a parameter is greater than or equal to the *sum* of
725
    the parent's gas and the adjustment delta then the limit for gas is too
726
    high and fails this function's check. Similarly, if the limit is less
727
    than or equal to the *difference* of the parent's gas and the adjustment
728
    delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's
729
    check fails because the gas limit doesn't allow for a sufficient or
730
    reasonable amount of gas to be used on a block.
731
732
    Parameters
733
    ----------
734
    gas_limit :
735
        Gas limit to validate.
736
737
    parent_gas_limit :
738
        Gas limit of the parent block.
739
740
    Returns
741
    -------
742
    check : `bool`
743
        True if gas limit constraints are satisfied, False otherwise.
744
    """
745
    max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR
746
    if gas_limit >= parent_gas_limit + max_adjustment_delta:
747
        return False
748
    if gas_limit <= parent_gas_limit - max_adjustment_delta:
749
        return False
750
    if gas_limit < GAS_LIMIT_MINIMUM:
751
        return False
752
753
    return True