ethereum.muir_glacier.fork

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

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

Introduction

Entry point for the Ethereum specification.

   1"""
   2Ethereum Specification
   3^^^^^^^^^^^^^^^^^^^^^^
   4
   5.. contents:: Table of Contents
   6    :backlinks: none
   7    :local:
   8
   9Introduction
  10------------
  11
  12Entry point for the Ethereum specification.
  13"""
  14
  15from dataclasses import dataclass
  16from typing import List, Optional, Set, Tuple
  17
  18from ethereum.base_types import Bytes0
  19from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
  20from ethereum.crypto.hash import Hash32, keccak256
  21from ethereum.ethash import dataset_size, generate_cache, hashimoto_light
  22from ethereum.exceptions import InvalidBlock
  23from ethereum.utils.ensure import ensure
  24
  25from .. import rlp
  26from ..base_types import U64, U256, U256_CEIL_VALUE, Bytes, Uint
  27from . import vm
  28from .bloom import logs_bloom
  29from .fork_types import (
  30    TX_BASE_COST,
  31    TX_CREATE_COST,
  32    TX_DATA_COST_PER_NON_ZERO,
  33    TX_DATA_COST_PER_ZERO,
  34    Address,
  35    Block,
  36    Bloom,
  37    Header,
  38    Log,
  39    Receipt,
  40    Root,
  41    Transaction,
  42)
  43from .state import (
  44    State,
  45    account_exists_and_is_empty,
  46    create_ether,
  47    destroy_account,
  48    get_account,
  49    increment_nonce,
  50    set_account_balance,
  51    state_root,
  52)
  53from .trie import Trie, root, trie_set
  54from .utils.message import prepare_message
  55from .vm.interpreter import process_message_call
  56
  57BLOCK_REWARD = U256(2 * 10**18)
  58GAS_LIMIT_ADJUSTMENT_FACTOR = 1024
  59GAS_LIMIT_MINIMUM = 5000
  60MINIMUM_DIFFICULTY = Uint(131072)
  61MAX_OMMER_DEPTH = 6
  62BOMB_DELAY_BLOCKS = 9000000
  63EMPTY_OMMER_HASH = keccak256(rlp.encode([]))
  64
  65
  66@dataclass
  67class BlockChain:
  68    """
  69    History and current state of the block chain.
  70    """
  71
  72    blocks: List[Block]
  73    state: State
  74    chain_id: U64
  75
  76
  77def apply_fork(old: BlockChain) -> BlockChain:
  78    """
  79    Transforms the state from the previous hard fork (`old`) into the block
  80    chain object for this hard fork and returns it.
  81
  82    When forks need to implement an irregular state transition, this function
  83    is used to handle the irregularity. See the :ref:`DAO Fork <dao-fork>` for
  84    an example.
  85
  86    Parameters
  87    ----------
  88    old :
  89        Previous block chain object.
  90
  91    Returns
  92    -------
  93    new : `BlockChain`
  94        Upgraded block chain object for this hard fork.
  95    """
  96    return old
  97
  98
  99def get_last_256_block_hashes(chain: BlockChain) -> List[Hash32]:
 100    """
 101    Obtain the list of hashes of the previous 256 blocks in order of
 102    increasing block number.
 103
 104    This function will return less hashes for the first 256 blocks.
 105
 106    The ``BLOCKHASH`` opcode needs to access the latest hashes on the chain,
 107    therefore this function retrieves them.
 108
 109    Parameters
 110    ----------
 111    chain :
 112        History and current state.
 113
 114    Returns
 115    -------
 116    recent_block_hashes : `List[Hash32]`
 117        Hashes of the recent 256 blocks in order of increasing block number.
 118    """
 119    recent_blocks = chain.blocks[-255:]
 120    # TODO: This function has not been tested rigorously
 121    if len(recent_blocks) == 0:
 122        return []
 123
 124    recent_block_hashes = []
 125
 126    for block in recent_blocks:
 127        prev_block_hash = block.header.parent_hash
 128        recent_block_hashes.append(prev_block_hash)
 129
 130    # We are computing the hash only for the most recent block and not for
 131    # the rest of the blocks as they have successors which have the hash of
 132    # the current block as parent hash.
 133    most_recent_block_hash = keccak256(rlp.encode(recent_blocks[-1].header))
 134    recent_block_hashes.append(most_recent_block_hash)
 135
 136    return recent_block_hashes
 137
 138
 139def state_transition(chain: BlockChain, block: Block) -> None:
 140    """
 141    Attempts to apply a block to an existing block chain.
 142
 143    All parts of the block's contents need to be verified before being added
 144    to the chain. Blocks are verified by ensuring that the contents of the
 145    block make logical sense with the contents of the parent block. The
 146    information in the block's header must also match the corresponding
 147    information in the block.
 148
 149    To implement Ethereum, in theory clients are only required to store the
 150    most recent 255 blocks of the chain since as far as execution is
 151    concerned, only those blocks are accessed. Practically, however, clients
 152    should store more blocks to handle reorgs.
 153
 154    Parameters
 155    ----------
 156    chain :
 157        History and current state.
 158    block :
 159        Block to apply to `chain`.
 160    """
 161    parent_header = chain.blocks[-1].header
 162    validate_header(block.header, parent_header)
 163    validate_ommers(block.ommers, block.header, chain)
 164    (
 165        gas_used,
 166        transactions_root,
 167        receipt_root,
 168        block_logs_bloom,
 169        state,
 170    ) = apply_body(
 171        chain.state,
 172        get_last_256_block_hashes(chain),
 173        block.header.coinbase,
 174        block.header.number,
 175        block.header.gas_limit,
 176        block.header.timestamp,
 177        block.header.difficulty,
 178        block.transactions,
 179        block.ommers,
 180        chain.chain_id,
 181    )
 182    ensure(gas_used == block.header.gas_used, InvalidBlock)
 183    ensure(transactions_root == block.header.transactions_root, InvalidBlock)
 184    ensure(state_root(state) == block.header.state_root, InvalidBlock)
 185    ensure(receipt_root == block.header.receipt_root, InvalidBlock)
 186    ensure(block_logs_bloom == block.header.bloom, 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:]
 193
 194
 195def validate_header(header: Header, parent_header: Header) -> None:
 196    """
 197    Verifies a block header.
 198
 199    In order to consider a block's header valid, the logic for the
 200    quantities in the header should match the logic for the block itself.
 201    For example the header timestamp should be greater than the block's parent
 202    timestamp because the block was created *after* the parent block.
 203    Additionally, the block's number should be directly following the parent
 204    block's number since it is the next block in the sequence.
 205
 206    Parameters
 207    ----------
 208    header :
 209        Header to check for correctness.
 210    parent_header :
 211        Parent Header of the header to check for correctness
 212    """
 213    parent_has_ommers = parent_header.ommers_hash != EMPTY_OMMER_HASH
 214    ensure(header.timestamp > parent_header.timestamp, InvalidBlock)
 215    ensure(header.number == parent_header.number + 1, InvalidBlock)
 216    ensure(
 217        check_gas_limit(header.gas_limit, parent_header.gas_limit),
 218        InvalidBlock,
 219    )
 220    ensure(len(header.extra_data) <= 32, InvalidBlock)
 221
 222    block_difficulty = calculate_block_difficulty(
 223        header.number,
 224        header.timestamp,
 225        parent_header.timestamp,
 226        parent_header.difficulty,
 227        parent_has_ommers,
 228    )
 229    ensure(header.difficulty == block_difficulty, InvalidBlock)
 230
 231    block_parent_hash = keccak256(rlp.encode(parent_header))
 232    ensure(header.parent_hash == block_parent_hash, InvalidBlock)
 233
 234    validate_proof_of_work(header)
 235
 236
 237def generate_header_hash_for_pow(header: Header) -> Hash32:
 238    """
 239    Generate rlp hash of the header which is to be used for Proof-of-Work
 240    verification.
 241
 242    In other words, the PoW artefacts `mix_digest` and `nonce` are ignored
 243    while calculating this hash.
 244
 245    A particular PoW is valid for a single hash, that hash is computed by
 246    this function. The `nonce` and `mix_digest` are omitted from this hash
 247    because they are being changed by miners in their search for a sufficient
 248    proof-of-work.
 249
 250    Parameters
 251    ----------
 252    header :
 253        The header object for which the hash is to be generated.
 254
 255    Returns
 256    -------
 257    hash : `Hash32`
 258        The PoW valid rlp hash of the passed in header.
 259    """
 260    header_data_without_pow_artefacts = [
 261        header.parent_hash,
 262        header.ommers_hash,
 263        header.coinbase,
 264        header.state_root,
 265        header.transactions_root,
 266        header.receipt_root,
 267        header.bloom,
 268        header.difficulty,
 269        header.number,
 270        header.gas_limit,
 271        header.gas_used,
 272        header.timestamp,
 273        header.extra_data,
 274    ]
 275
 276    return rlp.rlp_hash(header_data_without_pow_artefacts)
 277
 278
 279def validate_proof_of_work(header: Header) -> None:
 280    """
 281    Validates the Proof of Work constraints.
 282
 283    In order to verify that a miner's proof-of-work is valid for a block, a
 284    ``mix-digest`` and ``result`` are calculated using the ``hashimoto_light``
 285    hash function. The mix digest is a hash of the header and the nonce that
 286    is passed through and it confirms whether or not proof-of-work was done
 287    on the correct block. The result is the actual hash value of the block.
 288
 289    Parameters
 290    ----------
 291    header :
 292        Header of interest.
 293    """
 294    header_hash = generate_header_hash_for_pow(header)
 295    # TODO: Memoize this somewhere and read from that data instead of
 296    # calculating cache for every block validation.
 297    cache = generate_cache(header.number)
 298    mix_digest, result = hashimoto_light(
 299        header_hash, header.nonce, cache, dataset_size(header.number)
 300    )
 301
 302    ensure(mix_digest == header.mix_digest, InvalidBlock)
 303    ensure(
 304        Uint.from_be_bytes(result) <= (U256_CEIL_VALUE // header.difficulty),
 305        InvalidBlock,
 306    )
 307
 308
 309def check_transaction(
 310    tx: Transaction,
 311    gas_available: Uint,
 312    chain_id: U64,
 313) -> Address:
 314    """
 315    Check if the transaction is includable in the block.
 316
 317    Parameters
 318    ----------
 319    tx :
 320        The transaction.
 321    gas_available :
 322        The gas remaining in the block.
 323    chain_id :
 324        The ID of the current chain.
 325
 326    Returns
 327    -------
 328    sender_address :
 329        The sender of the transaction.
 330
 331    Raises
 332    ------
 333    InvalidBlock :
 334        If the transaction is not includable.
 335    """
 336    ensure(tx.gas <= gas_available, InvalidBlock)
 337    sender_address = recover_sender(chain_id, tx)
 338
 339    return sender_address
 340
 341
 342def make_receipt(
 343    tx: Transaction,
 344    error: Optional[Exception],
 345    cumulative_gas_used: Uint,
 346    logs: Tuple[Log, ...],
 347) -> Receipt:
 348    """
 349    Make the receipt for a transaction that was executed.
 350
 351    Parameters
 352    ----------
 353    tx :
 354        The executed transaction.
 355    error :
 356        Error in the top level frame of the transaction, if any.
 357    cumulative_gas_used :
 358        The total gas used so far in the block after the transaction was
 359        executed.
 360    logs :
 361        The logs produced by the transaction.
 362
 363    Returns
 364    -------
 365    receipt :
 366        The receipt for the transaction.
 367    """
 368    receipt = Receipt(
 369        succeeded=error is None,
 370        cumulative_gas_used=cumulative_gas_used,
 371        bloom=logs_bloom(logs),
 372        logs=logs,
 373    )
 374
 375    return receipt
 376
 377
 378def apply_body(
 379    state: State,
 380    block_hashes: List[Hash32],
 381    coinbase: Address,
 382    block_number: Uint,
 383    block_gas_limit: Uint,
 384    block_time: U256,
 385    block_difficulty: Uint,
 386    transactions: Tuple[Transaction, ...],
 387    ommers: Tuple[Header, ...],
 388    chain_id: U64,
 389) -> Tuple[Uint, Root, Root, Bloom, State]:
 390    """
 391    Executes a block.
 392
 393    Many of the contents of a block are stored in data structures called
 394    tries. There is a transactions trie which is similar to a ledger of the
 395    transactions stored in the current block. There is also a receipts trie
 396    which stores the results of executing a transaction, like the post state
 397    and gas used. This function creates and executes the block that is to be
 398    added to the chain.
 399
 400    Parameters
 401    ----------
 402    state :
 403        Current account state.
 404    block_hashes :
 405        List of hashes of the previous 256 blocks in the order of
 406        increasing block number.
 407    coinbase :
 408        Address of account which receives block reward and transaction fees.
 409    block_number :
 410        Position of the block within the chain.
 411    block_gas_limit :
 412        Initial amount of gas available for execution in this block.
 413    block_time :
 414        Time the block was produced, measured in seconds since the epoch.
 415    block_difficulty :
 416        Difficulty of the block.
 417    transactions :
 418        Transactions included in the block.
 419    ommers :
 420        Headers of ancestor blocks which are not direct parents (formerly
 421        uncles.)
 422    chain_id :
 423        ID of the executing chain.
 424
 425    Returns
 426    -------
 427    block_gas_used : `ethereum.base_types.Uint`
 428        Gas used for executing all transactions.
 429    transactions_root : `ethereum.fork_types.Root`
 430        Trie root of all the transactions in the block.
 431    receipt_root : `ethereum.fork_types.Root`
 432        Trie root of all the receipts in the block.
 433    block_logs_bloom : `Bloom`
 434        Logs bloom of all the logs included in all the transactions of the
 435        block.
 436    state : `ethereum.fork_types.State`
 437        State after all transactions have been executed.
 438    """
 439    gas_available = block_gas_limit
 440    transactions_trie: Trie[Bytes, Optional[Transaction]] = Trie(
 441        secured=False, default=None
 442    )
 443    receipts_trie: Trie[Bytes, Optional[Receipt]] = Trie(
 444        secured=False, default=None
 445    )
 446    block_logs: Tuple[Log, ...] = ()
 447
 448    for i, tx in enumerate(transactions):
 449        trie_set(transactions_trie, rlp.encode(Uint(i)), tx)
 450
 451        sender_address = check_transaction(tx, gas_available, chain_id)
 452
 453        env = vm.Environment(
 454            caller=sender_address,
 455            origin=sender_address,
 456            block_hashes=block_hashes,
 457            coinbase=coinbase,
 458            number=block_number,
 459            gas_limit=block_gas_limit,
 460            gas_price=tx.gas_price,
 461            time=block_time,
 462            difficulty=block_difficulty,
 463            state=state,
 464            chain_id=chain_id,
 465            traces=[],
 466        )
 467
 468        gas_used, logs, error = process_transaction(env, tx)
 469        gas_available -= gas_used
 470
 471        receipt = make_receipt(
 472            tx, error, (block_gas_limit - gas_available), logs
 473        )
 474
 475        trie_set(
 476            receipts_trie,
 477            rlp.encode(Uint(i)),
 478            receipt,
 479        )
 480
 481        block_logs += logs
 482
 483    pay_rewards(state, block_number, coinbase, ommers)
 484
 485    block_gas_used = block_gas_limit - gas_available
 486
 487    block_logs_bloom = logs_bloom(block_logs)
 488
 489    return (
 490        block_gas_used,
 491        root(transactions_trie),
 492        root(receipts_trie),
 493        block_logs_bloom,
 494        state,
 495    )
 496
 497
 498def validate_ommers(
 499    ommers: Tuple[Header, ...], block_header: Header, chain: BlockChain
 500) -> None:
 501    """
 502    Validates the ommers mentioned in the block.
 503
 504    An ommer block is a block that wasn't canonically added to the
 505    blockchain because it wasn't validated as fast as the canonical block
 506    but was mined at the same time.
 507
 508    To be considered valid, the ommers must adhere to the rules defined in
 509    the Ethereum protocol. The maximum amount of ommers is 2 per block and
 510    there cannot be duplicate ommers in a block. Many of the other ommer
 511    constraints are listed in the in-line comments of this function.
 512
 513    Parameters
 514    ----------
 515    ommers :
 516        List of ommers mentioned in the current block.
 517    block_header:
 518        The header of current block.
 519    chain :
 520        History and current state.
 521    """
 522    block_hash = rlp.rlp_hash(block_header)
 523
 524    ensure(rlp.rlp_hash(ommers) == block_header.ommers_hash, InvalidBlock)
 525
 526    if len(ommers) == 0:
 527        # Nothing to validate
 528        return
 529
 530    # Check that each ommer satisfies the constraints of a header
 531    for ommer in ommers:
 532        ensure(1 <= ommer.number < block_header.number, InvalidBlock)
 533        ommer_parent_header = chain.blocks[
 534            -(block_header.number - ommer.number) - 1
 535        ].header
 536        validate_header(ommer, ommer_parent_header)
 537
 538    # Check that there can be only at most 2 ommers for a block.
 539    ensure(len(ommers) <= 2, InvalidBlock)
 540
 541    ommers_hashes = [rlp.rlp_hash(ommer) for ommer in ommers]
 542    # Check that there are no duplicates in the ommers of current block
 543    ensure(len(ommers_hashes) == len(set(ommers_hashes)), InvalidBlock)
 544
 545    recent_canonical_blocks = chain.blocks[-(MAX_OMMER_DEPTH + 1) :]
 546    recent_canonical_block_hashes = {
 547        rlp.rlp_hash(block.header) for block in recent_canonical_blocks
 548    }
 549    recent_ommers_hashes: Set[Hash32] = set()
 550    for block in recent_canonical_blocks:
 551        recent_ommers_hashes = recent_ommers_hashes.union(
 552            {rlp.rlp_hash(ommer) for ommer in block.ommers}
 553        )
 554
 555    for ommer_index, ommer in enumerate(ommers):
 556        ommer_hash = ommers_hashes[ommer_index]
 557        # The current block shouldn't be the ommer
 558        ensure(ommer_hash != block_hash, InvalidBlock)
 559
 560        # Ommer shouldn't be one of the recent canonical blocks
 561        ensure(ommer_hash not in recent_canonical_block_hashes, InvalidBlock)
 562
 563        # Ommer shouldn't be one of the uncles mentioned in the recent
 564        # canonical blocks
 565        ensure(ommer_hash not in recent_ommers_hashes, InvalidBlock)
 566
 567        # Ommer age with respect to the current block. For example, an age of
 568        # 1 indicates that the ommer is a sibling of previous block.
 569        ommer_age = block_header.number - ommer.number
 570        ensure(1 <= ommer_age <= MAX_OMMER_DEPTH, InvalidBlock)
 571
 572        ensure(
 573            ommer.parent_hash in recent_canonical_block_hashes, InvalidBlock
 574        )
 575        ensure(ommer.parent_hash != block_header.parent_hash, InvalidBlock)
 576
 577
 578def pay_rewards(
 579    state: State,
 580    block_number: Uint,
 581    coinbase: Address,
 582    ommers: Tuple[Header, ...],
 583) -> None:
 584    """
 585    Pay rewards to the block miner as well as the ommers miners.
 586
 587    The miner of the canonical block is rewarded with the predetermined
 588    block reward, ``BLOCK_REWARD``, plus a variable award based off of the
 589    number of ommer blocks that were mined around the same time, and included
 590    in the canonical block's header. An ommer block is a block that wasn't
 591    added to the canonical blockchain because it wasn't validated as fast as
 592    the accepted block but was mined at the same time. Although not all blocks
 593    that are mined are added to the canonical chain, miners are still paid a
 594    reward for their efforts. This reward is called an ommer reward and is
 595    calculated based on the number associated with the ommer block that they
 596    mined.
 597
 598    Parameters
 599    ----------
 600    state :
 601        Current account state.
 602    block_number :
 603        Position of the block within the chain.
 604    coinbase :
 605        Address of account which receives block reward and transaction fees.
 606    ommers :
 607        List of ommers mentioned in the current block.
 608    """
 609    miner_reward = BLOCK_REWARD + (len(ommers) * (BLOCK_REWARD // 32))
 610    create_ether(state, coinbase, miner_reward)
 611
 612    for ommer in ommers:
 613        # Ommer age with respect to the current block.
 614        ommer_age = U256(block_number - ommer.number)
 615        ommer_miner_reward = ((8 - ommer_age) * BLOCK_REWARD) // 8
 616        create_ether(state, ommer.coinbase, ommer_miner_reward)
 617
 618
 619def process_transaction(
 620    env: vm.Environment, tx: Transaction
 621) -> Tuple[Uint, Tuple[Log, ...], Optional[Exception]]:
 622    """
 623    Execute a transaction against the provided environment.
 624
 625    This function processes the actions needed to execute a transaction.
 626    It decrements the sender's account after calculating the gas fee and
 627    refunds them the proper amount after execution. Calling contracts,
 628    deploying code, and incrementing nonces are all examples of actions that
 629    happen within this function or from a call made within this function.
 630
 631    Accounts that are marked for deletion are processed and destroyed after
 632    execution.
 633
 634    Parameters
 635    ----------
 636    env :
 637        Environment for the Ethereum Virtual Machine.
 638    tx :
 639        Transaction to execute.
 640
 641    Returns
 642    -------
 643    gas_left : `ethereum.base_types.U256`
 644        Remaining gas after execution.
 645    logs : `Tuple[ethereum.fork_types.Log, ...]`
 646        Logs generated during execution.
 647    """
 648    ensure(validate_transaction(tx), InvalidBlock)
 649
 650    sender = env.origin
 651    sender_account = get_account(env.state, sender)
 652    gas_fee = tx.gas * tx.gas_price
 653    ensure(sender_account.nonce == tx.nonce, InvalidBlock)
 654    ensure(sender_account.balance >= gas_fee + tx.value, InvalidBlock)
 655    ensure(sender_account.code == bytearray(), InvalidBlock)
 656
 657    gas = tx.gas - calculate_intrinsic_cost(tx)
 658    increment_nonce(env.state, sender)
 659    sender_balance_after_gas_fee = sender_account.balance - gas_fee
 660    set_account_balance(env.state, sender, sender_balance_after_gas_fee)
 661
 662    message = prepare_message(
 663        sender,
 664        tx.to,
 665        tx.value,
 666        tx.data,
 667        gas,
 668        env,
 669    )
 670
 671    output = process_message_call(message, env)
 672
 673    gas_used = tx.gas - output.gas_left
 674    gas_refund = min(gas_used // 2, output.refund_counter)
 675    gas_refund_amount = (output.gas_left + gas_refund) * tx.gas_price
 676    transaction_fee = (tx.gas - output.gas_left - gas_refund) * tx.gas_price
 677    total_gas_used = gas_used - gas_refund
 678
 679    # refund gas
 680    sender_balance_after_refund = (
 681        get_account(env.state, sender).balance + gas_refund_amount
 682    )
 683    set_account_balance(env.state, sender, sender_balance_after_refund)
 684
 685    # transfer miner fees
 686    coinbase_balance_after_mining_fee = (
 687        get_account(env.state, env.coinbase).balance + transaction_fee
 688    )
 689    if coinbase_balance_after_mining_fee != 0:
 690        set_account_balance(
 691            env.state, env.coinbase, coinbase_balance_after_mining_fee
 692        )
 693    elif account_exists_and_is_empty(env.state, env.coinbase):
 694        destroy_account(env.state, env.coinbase)
 695
 696    for address in output.accounts_to_delete:
 697        destroy_account(env.state, address)
 698
 699    for address in output.touched_accounts:
 700        if account_exists_and_is_empty(env.state, address):
 701            destroy_account(env.state, address)
 702
 703    return total_gas_used, output.logs, output.error
 704
 705
 706def validate_transaction(tx: Transaction) -> bool:
 707    """
 708    Verifies a transaction.
 709
 710    The gas in a transaction gets used to pay for the intrinsic cost of
 711    operations, therefore if there is insufficient gas then it would not
 712    be possible to execute a transaction and it will be declared invalid.
 713
 714    Additionally, the nonce of a transaction must not equal or exceed the
 715    limit defined in `EIP-2681 <https://eips.ethereum.org/EIPS/eip-2681>`_.
 716    In practice, defining the limit as ``2**64-1`` has no impact because
 717    sending ``2**64-1`` transactions is improbable. It's not strictly
 718    impossible though, ``2**64-1`` transactions is the entire capacity of the
 719    Ethereum blockchain at 2022 gas limits for a little over 22 years.
 720
 721    Parameters
 722    ----------
 723    tx :
 724        Transaction to validate.
 725
 726    Returns
 727    -------
 728    verified : `bool`
 729        True if the transaction can be executed, or False otherwise.
 730    """
 731    return calculate_intrinsic_cost(tx) <= tx.gas and tx.nonce < 2**64 - 1
 732
 733
 734def calculate_intrinsic_cost(tx: Transaction) -> Uint:
 735    """
 736    Calculates the gas that is charged before execution is started.
 737
 738    The intrinsic cost of the transaction is charged before execution has
 739    begun. Functions/operations in the EVM cost money to execute so this
 740    intrinsic cost is for the operations that need to be paid for as part of
 741    the transaction. Data transfer, for example, is part of this intrinsic
 742    cost. It costs ether to send data over the wire and that ether is
 743    accounted for in the intrinsic cost calculated in this function. This
 744    intrinsic cost must be calculated and paid for before execution in order
 745    for all operations to be implemented.
 746
 747    Parameters
 748    ----------
 749    tx :
 750        Transaction to compute the intrinsic cost of.
 751
 752    Returns
 753    -------
 754    verified : `ethereum.base_types.Uint`
 755        The intrinsic cost of the transaction.
 756    """
 757    data_cost = 0
 758
 759    for byte in tx.data:
 760        if byte == 0:
 761            data_cost += TX_DATA_COST_PER_ZERO
 762        else:
 763            data_cost += TX_DATA_COST_PER_NON_ZERO
 764
 765    if tx.to == Bytes0(b""):
 766        create_cost = TX_CREATE_COST
 767    else:
 768        create_cost = 0
 769
 770    return Uint(TX_BASE_COST + data_cost + create_cost)
 771
 772
 773def recover_sender(chain_id: U64, tx: Transaction) -> Address:
 774    """
 775    Extracts the sender address from a transaction.
 776
 777    The v, r, and s values are the three parts that make up the signature
 778    of a transaction. In order to recover the sender of a transaction the two
 779    components needed are the signature (``v``, ``r``, and ``s``) and the
 780    signing hash of the transaction. The sender's public key can be obtained
 781    with these two values and therefore the sender address can be retrieved.
 782
 783    Parameters
 784    ----------
 785    tx :
 786        Transaction of interest.
 787    chain_id :
 788        ID of the executing chain.
 789
 790    Returns
 791    -------
 792    sender : `ethereum.fork_types.Address`
 793        The address of the account that signed the transaction.
 794    """
 795    v, r, s = tx.v, tx.r, tx.s
 796
 797    ensure(0 < r and r < SECP256K1N, InvalidBlock)
 798    ensure(0 < s and s <= SECP256K1N // 2, InvalidBlock)
 799
 800    if v == 27 or v == 28:
 801        public_key = secp256k1_recover(r, s, v - 27, signing_hash_pre155(tx))
 802    else:
 803        ensure(v == 35 + chain_id * 2 or v == 36 + chain_id * 2, InvalidBlock)
 804        public_key = secp256k1_recover(
 805            r, s, v - 35 - chain_id * 2, signing_hash_155(tx, chain_id)
 806        )
 807    return Address(keccak256(public_key)[12:32])
 808
 809
 810def signing_hash_pre155(tx: Transaction) -> Hash32:
 811    """
 812    Compute the hash of a transaction used in a legacy (pre EIP 155) signature.
 813
 814    Parameters
 815    ----------
 816    tx :
 817        Transaction of interest.
 818
 819    Returns
 820    -------
 821    hash : `ethereum.crypto.hash.Hash32`
 822        Hash of the transaction.
 823    """
 824    return keccak256(
 825        rlp.encode(
 826            (
 827                tx.nonce,
 828                tx.gas_price,
 829                tx.gas,
 830                tx.to,
 831                tx.value,
 832                tx.data,
 833            )
 834        )
 835    )
 836
 837
 838def signing_hash_155(tx: Transaction, chain_id: U64) -> Hash32:
 839    """
 840    Compute the hash of a transaction used in a EIP 155 signature.
 841
 842    Parameters
 843    ----------
 844    tx :
 845        Transaction of interest.
 846    chain_id :
 847        The id of the current chain.
 848
 849    Returns
 850    -------
 851    hash : `ethereum.crypto.hash.Hash32`
 852        Hash of the transaction.
 853    """
 854    return keccak256(
 855        rlp.encode(
 856            (
 857                tx.nonce,
 858                tx.gas_price,
 859                tx.gas,
 860                tx.to,
 861                tx.value,
 862                tx.data,
 863                chain_id,
 864                Uint(0),
 865                Uint(0),
 866            )
 867        )
 868    )
 869
 870
 871def compute_header_hash(header: Header) -> Hash32:
 872    """
 873    Computes the hash of a block header.
 874
 875    The header hash of a block is the canonical hash that is used to refer
 876    to a specific block and completely distinguishes a block from another.
 877
 878    ``keccak256`` is a function that produces a 256 bit hash of any input.
 879    It also takes in any number of bytes as an input and produces a single
 880    hash for them. A hash is a completely unique output for a single input.
 881    So an input corresponds to one unique hash that can be used to identify
 882    the input exactly.
 883
 884    Prior to using the ``keccak256`` hash function, the header must be
 885    encoded using the Recursive-Length Prefix. See :ref:`rlp`.
 886    RLP encoding the header converts it into a space-efficient format that
 887    allows for easy transfer of data between nodes. The purpose of RLP is to
 888    encode arbitrarily nested arrays of binary data, and RLP is the primary
 889    encoding method used to serialize objects in Ethereum's execution layer.
 890    The only purpose of RLP is to encode structure; encoding specific data
 891    types (e.g. strings, floats) is left up to higher-order protocols.
 892
 893    Parameters
 894    ----------
 895    header :
 896        Header of interest.
 897
 898    Returns
 899    -------
 900    hash : `ethereum.crypto.hash.Hash32`
 901        Hash of the header.
 902    """
 903    return keccak256(rlp.encode(header))
 904
 905
 906def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool:
 907    """
 908    Validates the gas limit for a block.
 909
 910    The bounds of the gas limit, ``max_adjustment_delta``, is set as the
 911    quotient of the parent block's gas limit and the
 912    ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is
 913    passed through as a parameter is greater than or equal to the *sum* of
 914    the parent's gas and the adjustment delta then the limit for gas is too
 915    high and fails this function's check. Similarly, if the limit is less
 916    than or equal to the *difference* of the parent's gas and the adjustment
 917    delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's
 918    check fails because the gas limit doesn't allow for a sufficient or
 919    reasonable amount of gas to be used on a block.
 920
 921    Parameters
 922    ----------
 923    gas_limit :
 924        Gas limit to validate.
 925
 926    parent_gas_limit :
 927        Gas limit of the parent block.
 928
 929    Returns
 930    -------
 931    check : `bool`
 932        True if gas limit constraints are satisfied, False otherwise.
 933    """
 934    max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR
 935    if gas_limit >= parent_gas_limit + max_adjustment_delta:
 936        return False
 937    if gas_limit <= parent_gas_limit - max_adjustment_delta:
 938        return False
 939    if gas_limit < GAS_LIMIT_MINIMUM:
 940        return False
 941
 942    return True
 943
 944
 945def calculate_block_difficulty(
 946    block_number: Uint,
 947    block_timestamp: U256,
 948    parent_timestamp: U256,
 949    parent_difficulty: Uint,
 950    parent_has_ommers: bool,
 951) -> Uint:
 952    """
 953    Computes difficulty of a block using its header and parent header.
 954
 955    The difficulty is determined by the time the block was created after its
 956    parent. The ``offset`` is calculated using the parent block's difficulty,
 957    ``parent_difficulty``, and the timestamp between blocks. This offset is
 958    then added to the parent difficulty and is stored as the ``difficulty``
 959    variable. If the time between the block and its parent is too short, the
 960    offset will result in a positive number thus making the sum of
 961    ``parent_difficulty`` and ``offset`` to be a greater value in order to
 962    avoid mass forking. But, if the time is long enough, then the offset
 963    results in a negative value making the block less difficult than
 964    its parent.
 965
 966    The base standard for a block's difficulty is the predefined value
 967    set for the genesis block since it has no parent. So, a block
 968    can't be less difficult than the genesis block, therefore each block's
 969    difficulty is set to the maximum value between the calculated
 970    difficulty and the ``GENESIS_DIFFICULTY``.
 971
 972    Parameters
 973    ----------
 974    block_number :
 975        Block number of the block.
 976    block_timestamp :
 977        Timestamp of the block.
 978    parent_timestamp :
 979        Timestamp of the parent block.
 980    parent_difficulty :
 981        difficulty of the parent block.
 982    parent_has_ommers:
 983        does the parent have ommers.
 984
 985    Returns
 986    -------
 987    difficulty : `ethereum.base_types.Uint`
 988        Computed difficulty for a block.
 989    """
 990    offset = (
 991        int(parent_difficulty)
 992        // 2048
 993        * max(
 994            (2 if parent_has_ommers else 1)
 995            - int(block_timestamp - parent_timestamp) // 9,
 996            -99,
 997        )
 998    )
 999    difficulty = int(parent_difficulty) + offset
1000    # Historical Note: The difficulty bomb was not present in Ethereum at the
1001    # start of Frontier, but was added shortly after launch. However since the
1002    # bomb has no effect prior to block 200000 we pretend it existed from
1003    # genesis.
1004    # See https://github.com/ethereum/go-ethereum/pull/1588
1005    num_bomb_periods = ((int(block_number) - BOMB_DELAY_BLOCKS) // 100000) - 2
1006    if num_bomb_periods >= 0:
1007        difficulty += 2**num_bomb_periods
1008
1009    # Some clients raise the difficulty to `MINIMUM_DIFFICULTY` prior to adding
1010    # the bomb. This bug does not matter because the difficulty is always much
1011    # greater than `MINIMUM_DIFFICULTY` on Mainnet.
1012    return Uint(max(difficulty, MINIMUM_DIFFICULTY))
@dataclass
class BlockChain:
67@dataclass
68class BlockChain:
69    """
70    History and current state of the block chain.
71    """
72
73    blocks: List[Block]
74    state: State
75    chain_id: U64

History and current state of the block chain.

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

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 get_last_256_block_hashes( chain: BlockChain) -> List[ethereum.base_types.Bytes32]:
100def get_last_256_block_hashes(chain: BlockChain) -> List[Hash32]:
101    """
102    Obtain the list of hashes of the previous 256 blocks in order of
103    increasing block number.
104
105    This function will return less hashes for the first 256 blocks.
106
107    The ``BLOCKHASH`` opcode needs to access the latest hashes on the chain,
108    therefore this function retrieves them.
109
110    Parameters
111    ----------
112    chain :
113        History and current state.
114
115    Returns
116    -------
117    recent_block_hashes : `List[Hash32]`
118        Hashes of the recent 256 blocks in order of increasing block number.
119    """
120    recent_blocks = chain.blocks[-255:]
121    # TODO: This function has not been tested rigorously
122    if len(recent_blocks) == 0:
123        return []
124
125    recent_block_hashes = []
126
127    for block in recent_blocks:
128        prev_block_hash = block.header.parent_hash
129        recent_block_hashes.append(prev_block_hash)
130
131    # We are computing the hash only for the most recent block and not for
132    # the rest of the blocks as they have successors which have the hash of
133    # the current block as parent hash.
134    most_recent_block_hash = keccak256(rlp.encode(recent_blocks[-1].header))
135    recent_block_hashes.append(most_recent_block_hash)
136
137    return recent_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 state_transition( chain: BlockChain, block: ethereum.muir_glacier.fork_types.Block) -> None:
140def state_transition(chain: BlockChain, block: Block) -> None:
141    """
142    Attempts to apply a block to an existing block chain.
143
144    All parts of the block's contents need to be verified before being added
145    to the chain. Blocks are verified by ensuring that the contents of the
146    block make logical sense with the contents of the parent block. The
147    information in the block's header must also match the corresponding
148    information in the block.
149
150    To implement Ethereum, in theory clients are only required to store the
151    most recent 255 blocks of the chain since as far as execution is
152    concerned, only those blocks are accessed. Practically, however, clients
153    should store more blocks to handle reorgs.
154
155    Parameters
156    ----------
157    chain :
158        History and current state.
159    block :
160        Block to apply to `chain`.
161    """
162    parent_header = chain.blocks[-1].header
163    validate_header(block.header, parent_header)
164    validate_ommers(block.ommers, block.header, chain)
165    (
166        gas_used,
167        transactions_root,
168        receipt_root,
169        block_logs_bloom,
170        state,
171    ) = apply_body(
172        chain.state,
173        get_last_256_block_hashes(chain),
174        block.header.coinbase,
175        block.header.number,
176        block.header.gas_limit,
177        block.header.timestamp,
178        block.header.difficulty,
179        block.transactions,
180        block.ommers,
181        chain.chain_id,
182    )
183    ensure(gas_used == block.header.gas_used, InvalidBlock)
184    ensure(transactions_root == block.header.transactions_root, InvalidBlock)
185    ensure(state_root(state) == block.header.state_root, InvalidBlock)
186    ensure(receipt_root == block.header.receipt_root, InvalidBlock)
187    ensure(block_logs_bloom == block.header.bloom, InvalidBlock)
188
189    chain.blocks.append(block)
190    if len(chain.blocks) > 255:
191        # Real clients have to store more blocks to deal with reorgs, but the
192        # protocol only requires the last 255
193        chain.blocks = chain.blocks[-255:]

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 validate_header( header: ethereum.muir_glacier.fork_types.Header, parent_header: ethereum.muir_glacier.fork_types.Header) -> None:
196def validate_header(header: Header, parent_header: Header) -> None:
197    """
198    Verifies a block header.
199
200    In order to consider a block's header valid, the logic for the
201    quantities in the header should match the logic for the block itself.
202    For example the header timestamp should be greater than the block's parent
203    timestamp because the block was created *after* the parent block.
204    Additionally, the block's number should be directly following the parent
205    block's number since it is the next block in the sequence.
206
207    Parameters
208    ----------
209    header :
210        Header to check for correctness.
211    parent_header :
212        Parent Header of the header to check for correctness
213    """
214    parent_has_ommers = parent_header.ommers_hash != EMPTY_OMMER_HASH
215    ensure(header.timestamp > parent_header.timestamp, InvalidBlock)
216    ensure(header.number == parent_header.number + 1, InvalidBlock)
217    ensure(
218        check_gas_limit(header.gas_limit, parent_header.gas_limit),
219        InvalidBlock,
220    )
221    ensure(len(header.extra_data) <= 32, InvalidBlock)
222
223    block_difficulty = calculate_block_difficulty(
224        header.number,
225        header.timestamp,
226        parent_header.timestamp,
227        parent_header.difficulty,
228        parent_has_ommers,
229    )
230    ensure(header.difficulty == block_difficulty, InvalidBlock)
231
232    block_parent_hash = keccak256(rlp.encode(parent_header))
233    ensure(header.parent_hash == block_parent_hash, InvalidBlock)
234
235    validate_proof_of_work(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 generate_header_hash_for_pow( header: ethereum.muir_glacier.fork_types.Header) -> ethereum.base_types.Bytes32:
238def generate_header_hash_for_pow(header: Header) -> Hash32:
239    """
240    Generate rlp hash of the header which is to be used for Proof-of-Work
241    verification.
242
243    In other words, the PoW artefacts `mix_digest` and `nonce` are ignored
244    while calculating this hash.
245
246    A particular PoW is valid for a single hash, that hash is computed by
247    this function. The `nonce` and `mix_digest` are omitted from this hash
248    because they are being changed by miners in their search for a sufficient
249    proof-of-work.
250
251    Parameters
252    ----------
253    header :
254        The header object for which the hash is to be generated.
255
256    Returns
257    -------
258    hash : `Hash32`
259        The PoW valid rlp hash of the passed in header.
260    """
261    header_data_without_pow_artefacts = [
262        header.parent_hash,
263        header.ommers_hash,
264        header.coinbase,
265        header.state_root,
266        header.transactions_root,
267        header.receipt_root,
268        header.bloom,
269        header.difficulty,
270        header.number,
271        header.gas_limit,
272        header.gas_used,
273        header.timestamp,
274        header.extra_data,
275    ]
276
277    return rlp.rlp_hash(header_data_without_pow_artefacts)

Generate rlp hash of the header which is to be used for Proof-of-Work verification.

In other words, the PoW artefacts mix_digest and nonce are ignored while calculating this hash.

A particular PoW is valid for a single hash, that hash is computed by this function. The nonce and mix_digest are omitted from this hash because they are being changed by miners in their search for a sufficient proof-of-work.

Parameters

header : The header object for which the hash is to be generated.

Returns

hash : Hash32 The PoW valid rlp hash of the passed in header.

def validate_proof_of_work(header: ethereum.muir_glacier.fork_types.Header) -> None:
280def validate_proof_of_work(header: Header) -> None:
281    """
282    Validates the Proof of Work constraints.
283
284    In order to verify that a miner's proof-of-work is valid for a block, a
285    ``mix-digest`` and ``result`` are calculated using the ``hashimoto_light``
286    hash function. The mix digest is a hash of the header and the nonce that
287    is passed through and it confirms whether or not proof-of-work was done
288    on the correct block. The result is the actual hash value of the block.
289
290    Parameters
291    ----------
292    header :
293        Header of interest.
294    """
295    header_hash = generate_header_hash_for_pow(header)
296    # TODO: Memoize this somewhere and read from that data instead of
297    # calculating cache for every block validation.
298    cache = generate_cache(header.number)
299    mix_digest, result = hashimoto_light(
300        header_hash, header.nonce, cache, dataset_size(header.number)
301    )
302
303    ensure(mix_digest == header.mix_digest, InvalidBlock)
304    ensure(
305        Uint.from_be_bytes(result) <= (U256_CEIL_VALUE // header.difficulty),
306        InvalidBlock,
307    )

Validates the Proof of Work constraints.

In order to verify that a miner's proof-of-work is valid for a block, a mix-digest and result are calculated using the hashimoto_light hash function. The mix digest is a hash of the header and the nonce that is passed through and it confirms whether or not proof-of-work was done on the correct block. The result is the actual hash value of the block.

Parameters

header : Header of interest.

310def check_transaction(
311    tx: Transaction,
312    gas_available: Uint,
313    chain_id: U64,
314) -> Address:
315    """
316    Check if the transaction is includable in the block.
317
318    Parameters
319    ----------
320    tx :
321        The transaction.
322    gas_available :
323        The gas remaining in the block.
324    chain_id :
325        The ID of the current chain.
326
327    Returns
328    -------
329    sender_address :
330        The sender of the transaction.
331
332    Raises
333    ------
334    InvalidBlock :
335        If the transaction is not includable.
336    """
337    ensure(tx.gas <= gas_available, InvalidBlock)
338    sender_address = recover_sender(chain_id, tx)
339
340    return sender_address

Check if the transaction is includable in the block.

Parameters

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

Returns

sender_address : The sender of the transaction.

Raises

InvalidBlock : If the transaction is not includable.

def make_receipt( tx: ethereum.muir_glacier.fork_types.Transaction, error: Optional[Exception], cumulative_gas_used: ethereum.base_types.Uint, logs: Tuple[ethereum.muir_glacier.fork_types.Log, ...]) -> ethereum.muir_glacier.fork_types.Receipt:
343def make_receipt(
344    tx: Transaction,
345    error: Optional[Exception],
346    cumulative_gas_used: Uint,
347    logs: Tuple[Log, ...],
348) -> Receipt:
349    """
350    Make the receipt for a transaction that was executed.
351
352    Parameters
353    ----------
354    tx :
355        The executed transaction.
356    error :
357        Error in the top level frame of the transaction, if any.
358    cumulative_gas_used :
359        The total gas used so far in the block after the transaction was
360        executed.
361    logs :
362        The logs produced by the transaction.
363
364    Returns
365    -------
366    receipt :
367        The receipt for the transaction.
368    """
369    receipt = Receipt(
370        succeeded=error is None,
371        cumulative_gas_used=cumulative_gas_used,
372        bloom=logs_bloom(logs),
373        logs=logs,
374    )
375
376    return 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.

379def apply_body(
380    state: State,
381    block_hashes: List[Hash32],
382    coinbase: Address,
383    block_number: Uint,
384    block_gas_limit: Uint,
385    block_time: U256,
386    block_difficulty: Uint,
387    transactions: Tuple[Transaction, ...],
388    ommers: Tuple[Header, ...],
389    chain_id: U64,
390) -> Tuple[Uint, Root, Root, Bloom, State]:
391    """
392    Executes a block.
393
394    Many of the contents of a block are stored in data structures called
395    tries. There is a transactions trie which is similar to a ledger of the
396    transactions stored in the current block. There is also a receipts trie
397    which stores the results of executing a transaction, like the post state
398    and gas used. This function creates and executes the block that is to be
399    added to the chain.
400
401    Parameters
402    ----------
403    state :
404        Current account state.
405    block_hashes :
406        List of hashes of the previous 256 blocks in the order of
407        increasing block number.
408    coinbase :
409        Address of account which receives block reward and transaction fees.
410    block_number :
411        Position of the block within the chain.
412    block_gas_limit :
413        Initial amount of gas available for execution in this block.
414    block_time :
415        Time the block was produced, measured in seconds since the epoch.
416    block_difficulty :
417        Difficulty of the block.
418    transactions :
419        Transactions included in the block.
420    ommers :
421        Headers of ancestor blocks which are not direct parents (formerly
422        uncles.)
423    chain_id :
424        ID of the executing chain.
425
426    Returns
427    -------
428    block_gas_used : `ethereum.base_types.Uint`
429        Gas used for executing all transactions.
430    transactions_root : `ethereum.fork_types.Root`
431        Trie root of all the transactions in the block.
432    receipt_root : `ethereum.fork_types.Root`
433        Trie root of all the receipts in the block.
434    block_logs_bloom : `Bloom`
435        Logs bloom of all the logs included in all the transactions of the
436        block.
437    state : `ethereum.fork_types.State`
438        State after all transactions have been executed.
439    """
440    gas_available = block_gas_limit
441    transactions_trie: Trie[Bytes, Optional[Transaction]] = Trie(
442        secured=False, default=None
443    )
444    receipts_trie: Trie[Bytes, Optional[Receipt]] = Trie(
445        secured=False, default=None
446    )
447    block_logs: Tuple[Log, ...] = ()
448
449    for i, tx in enumerate(transactions):
450        trie_set(transactions_trie, rlp.encode(Uint(i)), tx)
451
452        sender_address = check_transaction(tx, gas_available, chain_id)
453
454        env = vm.Environment(
455            caller=sender_address,
456            origin=sender_address,
457            block_hashes=block_hashes,
458            coinbase=coinbase,
459            number=block_number,
460            gas_limit=block_gas_limit,
461            gas_price=tx.gas_price,
462            time=block_time,
463            difficulty=block_difficulty,
464            state=state,
465            chain_id=chain_id,
466            traces=[],
467        )
468
469        gas_used, logs, error = process_transaction(env, tx)
470        gas_available -= gas_used
471
472        receipt = make_receipt(
473            tx, error, (block_gas_limit - gas_available), logs
474        )
475
476        trie_set(
477            receipts_trie,
478            rlp.encode(Uint(i)),
479            receipt,
480        )
481
482        block_logs += logs
483
484    pay_rewards(state, block_number, coinbase, ommers)
485
486    block_gas_used = block_gas_limit - gas_available
487
488    block_logs_bloom = logs_bloom(block_logs)
489
490    return (
491        block_gas_used,
492        root(transactions_trie),
493        root(receipts_trie),
494        block_logs_bloom,
495        state,
496    )

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. 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. block_difficulty : Difficulty of the block. 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.

Returns

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 : ethereum.fork_types.State State after all transactions have been executed.

def validate_ommers( ommers: Tuple[ethereum.muir_glacier.fork_types.Header, ...], block_header: ethereum.muir_glacier.fork_types.Header, chain: BlockChain) -> None:
499def validate_ommers(
500    ommers: Tuple[Header, ...], block_header: Header, chain: BlockChain
501) -> None:
502    """
503    Validates the ommers mentioned in the block.
504
505    An ommer block is a block that wasn't canonically added to the
506    blockchain because it wasn't validated as fast as the canonical block
507    but was mined at the same time.
508
509    To be considered valid, the ommers must adhere to the rules defined in
510    the Ethereum protocol. The maximum amount of ommers is 2 per block and
511    there cannot be duplicate ommers in a block. Many of the other ommer
512    constraints are listed in the in-line comments of this function.
513
514    Parameters
515    ----------
516    ommers :
517        List of ommers mentioned in the current block.
518    block_header:
519        The header of current block.
520    chain :
521        History and current state.
522    """
523    block_hash = rlp.rlp_hash(block_header)
524
525    ensure(rlp.rlp_hash(ommers) == block_header.ommers_hash, InvalidBlock)
526
527    if len(ommers) == 0:
528        # Nothing to validate
529        return
530
531    # Check that each ommer satisfies the constraints of a header
532    for ommer in ommers:
533        ensure(1 <= ommer.number < block_header.number, InvalidBlock)
534        ommer_parent_header = chain.blocks[
535            -(block_header.number - ommer.number) - 1
536        ].header
537        validate_header(ommer, ommer_parent_header)
538
539    # Check that there can be only at most 2 ommers for a block.
540    ensure(len(ommers) <= 2, InvalidBlock)
541
542    ommers_hashes = [rlp.rlp_hash(ommer) for ommer in ommers]
543    # Check that there are no duplicates in the ommers of current block
544    ensure(len(ommers_hashes) == len(set(ommers_hashes)), InvalidBlock)
545
546    recent_canonical_blocks = chain.blocks[-(MAX_OMMER_DEPTH + 1) :]
547    recent_canonical_block_hashes = {
548        rlp.rlp_hash(block.header) for block in recent_canonical_blocks
549    }
550    recent_ommers_hashes: Set[Hash32] = set()
551    for block in recent_canonical_blocks:
552        recent_ommers_hashes = recent_ommers_hashes.union(
553            {rlp.rlp_hash(ommer) for ommer in block.ommers}
554        )
555
556    for ommer_index, ommer in enumerate(ommers):
557        ommer_hash = ommers_hashes[ommer_index]
558        # The current block shouldn't be the ommer
559        ensure(ommer_hash != block_hash, InvalidBlock)
560
561        # Ommer shouldn't be one of the recent canonical blocks
562        ensure(ommer_hash not in recent_canonical_block_hashes, InvalidBlock)
563
564        # Ommer shouldn't be one of the uncles mentioned in the recent
565        # canonical blocks
566        ensure(ommer_hash not in recent_ommers_hashes, InvalidBlock)
567
568        # Ommer age with respect to the current block. For example, an age of
569        # 1 indicates that the ommer is a sibling of previous block.
570        ommer_age = block_header.number - ommer.number
571        ensure(1 <= ommer_age <= MAX_OMMER_DEPTH, InvalidBlock)
572
573        ensure(
574            ommer.parent_hash in recent_canonical_block_hashes, InvalidBlock
575        )
576        ensure(ommer.parent_hash != block_header.parent_hash, InvalidBlock)

Validates the ommers mentioned in the block.

An ommer block is a block that wasn't canonically added to the blockchain because it wasn't validated as fast as the canonical block but was mined at the same time.

To be considered valid, the ommers must adhere to the rules defined in the Ethereum protocol. The maximum amount of ommers is 2 per block and there cannot be duplicate ommers in a block. Many of the other ommer constraints are listed in the in-line comments of this function.

Parameters

ommers : List of ommers mentioned in the current block. block_header: The header of current block. chain : History and current state.

def pay_rewards( state: ethereum.muir_glacier.state.State, block_number: ethereum.base_types.Uint, coinbase: ethereum.base_types.Bytes20, ommers: Tuple[ethereum.muir_glacier.fork_types.Header, ...]) -> None:
579def pay_rewards(
580    state: State,
581    block_number: Uint,
582    coinbase: Address,
583    ommers: Tuple[Header, ...],
584) -> None:
585    """
586    Pay rewards to the block miner as well as the ommers miners.
587
588    The miner of the canonical block is rewarded with the predetermined
589    block reward, ``BLOCK_REWARD``, plus a variable award based off of the
590    number of ommer blocks that were mined around the same time, and included
591    in the canonical block's header. An ommer block is a block that wasn't
592    added to the canonical blockchain because it wasn't validated as fast as
593    the accepted block but was mined at the same time. Although not all blocks
594    that are mined are added to the canonical chain, miners are still paid a
595    reward for their efforts. This reward is called an ommer reward and is
596    calculated based on the number associated with the ommer block that they
597    mined.
598
599    Parameters
600    ----------
601    state :
602        Current account state.
603    block_number :
604        Position of the block within the chain.
605    coinbase :
606        Address of account which receives block reward and transaction fees.
607    ommers :
608        List of ommers mentioned in the current block.
609    """
610    miner_reward = BLOCK_REWARD + (len(ommers) * (BLOCK_REWARD // 32))
611    create_ether(state, coinbase, miner_reward)
612
613    for ommer in ommers:
614        # Ommer age with respect to the current block.
615        ommer_age = U256(block_number - ommer.number)
616        ommer_miner_reward = ((8 - ommer_age) * BLOCK_REWARD) // 8
617        create_ether(state, ommer.coinbase, ommer_miner_reward)

Pay rewards to the block miner as well as the ommers miners.

The miner of the canonical block is rewarded with the predetermined block reward, BLOCK_REWARD, plus a variable award based off of the number of ommer blocks that were mined around the same time, and included in the canonical block's header. An ommer block is a block that wasn't added to the canonical blockchain because it wasn't validated as fast as the accepted block but was mined at the same time. Although not all blocks that are mined are added to the canonical chain, miners are still paid a reward for their efforts. This reward is called an ommer reward and is calculated based on the number associated with the ommer block that they mined.

Parameters

state : Current account state. block_number : Position of the block within the chain. coinbase : Address of account which receives block reward and transaction fees. ommers : List of ommers mentioned in the current block.

def process_transaction( env: ethereum.muir_glacier.vm.Environment, tx: ethereum.muir_glacier.fork_types.Transaction) -> Tuple[ethereum.base_types.Uint, Tuple[ethereum.muir_glacier.fork_types.Log, ...], Optional[Exception]]:
620def process_transaction(
621    env: vm.Environment, tx: Transaction
622) -> Tuple[Uint, Tuple[Log, ...], Optional[Exception]]:
623    """
624    Execute a transaction against the provided environment.
625
626    This function processes the actions needed to execute a transaction.
627    It decrements the sender's account after calculating the gas fee and
628    refunds them the proper amount after execution. Calling contracts,
629    deploying code, and incrementing nonces are all examples of actions that
630    happen within this function or from a call made within this function.
631
632    Accounts that are marked for deletion are processed and destroyed after
633    execution.
634
635    Parameters
636    ----------
637    env :
638        Environment for the Ethereum Virtual Machine.
639    tx :
640        Transaction to execute.
641
642    Returns
643    -------
644    gas_left : `ethereum.base_types.U256`
645        Remaining gas after execution.
646    logs : `Tuple[ethereum.fork_types.Log, ...]`
647        Logs generated during execution.
648    """
649    ensure(validate_transaction(tx), InvalidBlock)
650
651    sender = env.origin
652    sender_account = get_account(env.state, sender)
653    gas_fee = tx.gas * tx.gas_price
654    ensure(sender_account.nonce == tx.nonce, InvalidBlock)
655    ensure(sender_account.balance >= gas_fee + tx.value, InvalidBlock)
656    ensure(sender_account.code == bytearray(), InvalidBlock)
657
658    gas = tx.gas - calculate_intrinsic_cost(tx)
659    increment_nonce(env.state, sender)
660    sender_balance_after_gas_fee = sender_account.balance - gas_fee
661    set_account_balance(env.state, sender, sender_balance_after_gas_fee)
662
663    message = prepare_message(
664        sender,
665        tx.to,
666        tx.value,
667        tx.data,
668        gas,
669        env,
670    )
671
672    output = process_message_call(message, env)
673
674    gas_used = tx.gas - output.gas_left
675    gas_refund = min(gas_used // 2, output.refund_counter)
676    gas_refund_amount = (output.gas_left + gas_refund) * tx.gas_price
677    transaction_fee = (tx.gas - output.gas_left - gas_refund) * tx.gas_price
678    total_gas_used = gas_used - gas_refund
679
680    # refund gas
681    sender_balance_after_refund = (
682        get_account(env.state, sender).balance + gas_refund_amount
683    )
684    set_account_balance(env.state, sender, sender_balance_after_refund)
685
686    # transfer miner fees
687    coinbase_balance_after_mining_fee = (
688        get_account(env.state, env.coinbase).balance + transaction_fee
689    )
690    if coinbase_balance_after_mining_fee != 0:
691        set_account_balance(
692            env.state, env.coinbase, coinbase_balance_after_mining_fee
693        )
694    elif account_exists_and_is_empty(env.state, env.coinbase):
695        destroy_account(env.state, env.coinbase)
696
697    for address in output.accounts_to_delete:
698        destroy_account(env.state, address)
699
700    for address in output.touched_accounts:
701        if account_exists_and_is_empty(env.state, address):
702            destroy_account(env.state, address)
703
704    return total_gas_used, output.logs, output.error

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.fork_types.Log, ...] Logs generated during execution.

def validate_transaction(tx: ethereum.muir_glacier.fork_types.Transaction) -> bool:
707def validate_transaction(tx: Transaction) -> bool:
708    """
709    Verifies a transaction.
710
711    The gas in a transaction gets used to pay for the intrinsic cost of
712    operations, therefore if there is insufficient gas then it would not
713    be possible to execute a transaction and it will be declared invalid.
714
715    Additionally, the nonce of a transaction must not equal or exceed the
716    limit defined in `EIP-2681 <https://eips.ethereum.org/EIPS/eip-2681>`_.
717    In practice, defining the limit as ``2**64-1`` has no impact because
718    sending ``2**64-1`` transactions is improbable. It's not strictly
719    impossible though, ``2**64-1`` transactions is the entire capacity of the
720    Ethereum blockchain at 2022 gas limits for a little over 22 years.
721
722    Parameters
723    ----------
724    tx :
725        Transaction to validate.
726
727    Returns
728    -------
729    verified : `bool`
730        True if the transaction can be executed, or False otherwise.
731    """
732    return calculate_intrinsic_cost(tx) <= tx.gas and tx.nonce < 2**64 - 1

Verifies a transaction.

The gas in a transaction gets used to pay for the intrinsic cost of operations, therefore if there is insufficient gas then it would not be possible to execute a transaction and it will be declared invalid.

Additionally, the nonce of a transaction must not equal or exceed the limit defined in EIP-2681 <https://eips.ethereum.org/EIPS/eip-2681>_. In practice, defining the limit as 2**64-1 has no impact because sending 2**64-1 transactions is improbable. It's not strictly impossible though, 2**64-1 transactions is the entire capacity of the Ethereum blockchain at 2022 gas limits for a little over 22 years.

Parameters

tx : Transaction to validate.

Returns

verified : bool True if the transaction can be executed, or False otherwise.

def calculate_intrinsic_cost( tx: ethereum.muir_glacier.fork_types.Transaction) -> ethereum.base_types.Uint:
735def calculate_intrinsic_cost(tx: Transaction) -> Uint:
736    """
737    Calculates the gas that is charged before execution is started.
738
739    The intrinsic cost of the transaction is charged before execution has
740    begun. Functions/operations in the EVM cost money to execute so this
741    intrinsic cost is for the operations that need to be paid for as part of
742    the transaction. Data transfer, for example, is part of this intrinsic
743    cost. It costs ether to send data over the wire and that ether is
744    accounted for in the intrinsic cost calculated in this function. This
745    intrinsic cost must be calculated and paid for before execution in order
746    for all operations to be implemented.
747
748    Parameters
749    ----------
750    tx :
751        Transaction to compute the intrinsic cost of.
752
753    Returns
754    -------
755    verified : `ethereum.base_types.Uint`
756        The intrinsic cost of the transaction.
757    """
758    data_cost = 0
759
760    for byte in tx.data:
761        if byte == 0:
762            data_cost += TX_DATA_COST_PER_ZERO
763        else:
764            data_cost += TX_DATA_COST_PER_NON_ZERO
765
766    if tx.to == Bytes0(b""):
767        create_cost = TX_CREATE_COST
768    else:
769        create_cost = 0
770
771    return Uint(TX_BASE_COST + data_cost + create_cost)

Calculates the gas that is charged before execution is started.

The intrinsic cost of the transaction is charged before execution has begun. Functions/operations in the EVM cost money to execute so this intrinsic cost is for the operations that need to be paid for as part of the transaction. Data transfer, for example, is part of this intrinsic cost. It costs ether to send data over the wire and that ether is accounted for in the intrinsic cost calculated in this function. This intrinsic cost must be calculated and paid for before execution in order for all operations to be implemented.

Parameters

tx : Transaction to compute the intrinsic cost of.

Returns

verified : ethereum.base_types.Uint The intrinsic cost of the transaction.

774def recover_sender(chain_id: U64, tx: Transaction) -> Address:
775    """
776    Extracts the sender address from a transaction.
777
778    The v, r, and s values are the three parts that make up the signature
779    of a transaction. In order to recover the sender of a transaction the two
780    components needed are the signature (``v``, ``r``, and ``s``) and the
781    signing hash of the transaction. The sender's public key can be obtained
782    with these two values and therefore the sender address can be retrieved.
783
784    Parameters
785    ----------
786    tx :
787        Transaction of interest.
788    chain_id :
789        ID of the executing chain.
790
791    Returns
792    -------
793    sender : `ethereum.fork_types.Address`
794        The address of the account that signed the transaction.
795    """
796    v, r, s = tx.v, tx.r, tx.s
797
798    ensure(0 < r and r < SECP256K1N, InvalidBlock)
799    ensure(0 < s and s <= SECP256K1N // 2, InvalidBlock)
800
801    if v == 27 or v == 28:
802        public_key = secp256k1_recover(r, s, v - 27, signing_hash_pre155(tx))
803    else:
804        ensure(v == 35 + chain_id * 2 or v == 36 + chain_id * 2, InvalidBlock)
805        public_key = secp256k1_recover(
806            r, s, v - 35 - chain_id * 2, signing_hash_155(tx, chain_id)
807        )
808    return Address(keccak256(public_key)[12:32])

Extracts the sender address from a transaction.

The v, r, and s values are the three parts that make up the signature of a transaction. In order to recover the sender of a transaction the two components needed are the signature (v, r, and s) and the signing hash of the transaction. The sender's public key can be obtained with these two values and therefore the sender address can be retrieved.

Parameters

tx : Transaction of interest. chain_id : ID of the executing chain.

Returns

sender : ethereum.fork_types.Address The address of the account that signed the transaction.

def signing_hash_pre155( tx: ethereum.muir_glacier.fork_types.Transaction) -> ethereum.base_types.Bytes32:
811def signing_hash_pre155(tx: Transaction) -> Hash32:
812    """
813    Compute the hash of a transaction used in a legacy (pre EIP 155) signature.
814
815    Parameters
816    ----------
817    tx :
818        Transaction of interest.
819
820    Returns
821    -------
822    hash : `ethereum.crypto.hash.Hash32`
823        Hash of the transaction.
824    """
825    return keccak256(
826        rlp.encode(
827            (
828                tx.nonce,
829                tx.gas_price,
830                tx.gas,
831                tx.to,
832                tx.value,
833                tx.data,
834            )
835        )
836    )

Compute the hash of a transaction used in a legacy (pre EIP 155) signature.

Parameters

tx : Transaction of interest.

Returns

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

839def signing_hash_155(tx: Transaction, chain_id: U64) -> Hash32:
840    """
841    Compute the hash of a transaction used in a EIP 155 signature.
842
843    Parameters
844    ----------
845    tx :
846        Transaction of interest.
847    chain_id :
848        The id of the current chain.
849
850    Returns
851    -------
852    hash : `ethereum.crypto.hash.Hash32`
853        Hash of the transaction.
854    """
855    return keccak256(
856        rlp.encode(
857            (
858                tx.nonce,
859                tx.gas_price,
860                tx.gas,
861                tx.to,
862                tx.value,
863                tx.data,
864                chain_id,
865                Uint(0),
866                Uint(0),
867            )
868        )
869    )

Compute the hash of a transaction used in a EIP 155 signature.

Parameters

tx : Transaction of interest. chain_id : The id of the current chain.

Returns

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

def compute_header_hash( header: ethereum.muir_glacier.fork_types.Header) -> ethereum.base_types.Bytes32:
872def compute_header_hash(header: Header) -> Hash32:
873    """
874    Computes the hash of a block header.
875
876    The header hash of a block is the canonical hash that is used to refer
877    to a specific block and completely distinguishes a block from another.
878
879    ``keccak256`` is a function that produces a 256 bit hash of any input.
880    It also takes in any number of bytes as an input and produces a single
881    hash for them. A hash is a completely unique output for a single input.
882    So an input corresponds to one unique hash that can be used to identify
883    the input exactly.
884
885    Prior to using the ``keccak256`` hash function, the header must be
886    encoded using the Recursive-Length Prefix. See :ref:`rlp`.
887    RLP encoding the header converts it into a space-efficient format that
888    allows for easy transfer of data between nodes. The purpose of RLP is to
889    encode arbitrarily nested arrays of binary data, and RLP is the primary
890    encoding method used to serialize objects in Ethereum's execution layer.
891    The only purpose of RLP is to encode structure; encoding specific data
892    types (e.g. strings, floats) is left up to higher-order protocols.
893
894    Parameters
895    ----------
896    header :
897        Header of interest.
898
899    Returns
900    -------
901    hash : `ethereum.crypto.hash.Hash32`
902        Hash of the header.
903    """
904    return keccak256(rlp.encode(header))

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 check_gas_limit( gas_limit: ethereum.base_types.Uint, parent_gas_limit: ethereum.base_types.Uint) -> bool:
907def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool:
908    """
909    Validates the gas limit for a block.
910
911    The bounds of the gas limit, ``max_adjustment_delta``, is set as the
912    quotient of the parent block's gas limit and the
913    ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is
914    passed through as a parameter is greater than or equal to the *sum* of
915    the parent's gas and the adjustment delta then the limit for gas is too
916    high and fails this function's check. Similarly, if the limit is less
917    than or equal to the *difference* of the parent's gas and the adjustment
918    delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's
919    check fails because the gas limit doesn't allow for a sufficient or
920    reasonable amount of gas to be used on a block.
921
922    Parameters
923    ----------
924    gas_limit :
925        Gas limit to validate.
926
927    parent_gas_limit :
928        Gas limit of the parent block.
929
930    Returns
931    -------
932    check : `bool`
933        True if gas limit constraints are satisfied, False otherwise.
934    """
935    max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR
936    if gas_limit >= parent_gas_limit + max_adjustment_delta:
937        return False
938    if gas_limit <= parent_gas_limit - max_adjustment_delta:
939        return False
940    if gas_limit < GAS_LIMIT_MINIMUM:
941        return False
942
943    return True

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 calculate_block_difficulty( block_number: ethereum.base_types.Uint, block_timestamp: ethereum.base_types.U256, parent_timestamp: ethereum.base_types.U256, parent_difficulty: ethereum.base_types.Uint, parent_has_ommers: bool) -> ethereum.base_types.Uint:
 946def calculate_block_difficulty(
 947    block_number: Uint,
 948    block_timestamp: U256,
 949    parent_timestamp: U256,
 950    parent_difficulty: Uint,
 951    parent_has_ommers: bool,
 952) -> Uint:
 953    """
 954    Computes difficulty of a block using its header and parent header.
 955
 956    The difficulty is determined by the time the block was created after its
 957    parent. The ``offset`` is calculated using the parent block's difficulty,
 958    ``parent_difficulty``, and the timestamp between blocks. This offset is
 959    then added to the parent difficulty and is stored as the ``difficulty``
 960    variable. If the time between the block and its parent is too short, the
 961    offset will result in a positive number thus making the sum of
 962    ``parent_difficulty`` and ``offset`` to be a greater value in order to
 963    avoid mass forking. But, if the time is long enough, then the offset
 964    results in a negative value making the block less difficult than
 965    its parent.
 966
 967    The base standard for a block's difficulty is the predefined value
 968    set for the genesis block since it has no parent. So, a block
 969    can't be less difficult than the genesis block, therefore each block's
 970    difficulty is set to the maximum value between the calculated
 971    difficulty and the ``GENESIS_DIFFICULTY``.
 972
 973    Parameters
 974    ----------
 975    block_number :
 976        Block number of the block.
 977    block_timestamp :
 978        Timestamp of the block.
 979    parent_timestamp :
 980        Timestamp of the parent block.
 981    parent_difficulty :
 982        difficulty of the parent block.
 983    parent_has_ommers:
 984        does the parent have ommers.
 985
 986    Returns
 987    -------
 988    difficulty : `ethereum.base_types.Uint`
 989        Computed difficulty for a block.
 990    """
 991    offset = (
 992        int(parent_difficulty)
 993        // 2048
 994        * max(
 995            (2 if parent_has_ommers else 1)
 996            - int(block_timestamp - parent_timestamp) // 9,
 997            -99,
 998        )
 999    )
1000    difficulty = int(parent_difficulty) + offset
1001    # Historical Note: The difficulty bomb was not present in Ethereum at the
1002    # start of Frontier, but was added shortly after launch. However since the
1003    # bomb has no effect prior to block 200000 we pretend it existed from
1004    # genesis.
1005    # See https://github.com/ethereum/go-ethereum/pull/1588
1006    num_bomb_periods = ((int(block_number) - BOMB_DELAY_BLOCKS) // 100000) - 2
1007    if num_bomb_periods >= 0:
1008        difficulty += 2**num_bomb_periods
1009
1010    # Some clients raise the difficulty to `MINIMUM_DIFFICULTY` prior to adding
1011    # the bomb. This bug does not matter because the difficulty is always much
1012    # greater than `MINIMUM_DIFFICULTY` on Mainnet.
1013    return Uint(max(difficulty, MINIMUM_DIFFICULTY))

Computes difficulty of a block using its header and parent header.

The difficulty is determined by the time the block was created after its parent. The offset is calculated using the parent block's difficulty, parent_difficulty, and the timestamp between blocks. This offset is then added to the parent difficulty and is stored as the difficulty variable. If the time between the block and its parent is too short, the offset will result in a positive number thus making the sum of parent_difficulty and offset to be a greater value in order to avoid mass forking. But, if the time is long enough, then the offset results in a negative value making the block less difficult than its parent.

The base standard for a block's difficulty is the predefined value set for the genesis block since it has no parent. So, a block can't be less difficult than the genesis block, therefore each block's difficulty is set to the maximum value between the calculated difficulty and the GENESIS_DIFFICULTY.

Parameters

block_number : Block number of the block. block_timestamp : Timestamp of the block. parent_timestamp : Timestamp of the parent block. parent_difficulty : difficulty of the parent block. parent_has_ommers: does the parent have ommers.

Returns

difficulty : ethereum.base_types.Uint Computed difficulty for a block.