ethereum.constantinople.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 = 5000000
  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            traces=[],
 465        )
 466
 467        gas_used, logs, error = process_transaction(env, tx)
 468        gas_available -= gas_used
 469
 470        receipt = make_receipt(
 471            tx, error, (block_gas_limit - gas_available), logs
 472        )
 473
 474        trie_set(
 475            receipts_trie,
 476            rlp.encode(Uint(i)),
 477            receipt,
 478        )
 479
 480        block_logs += logs
 481
 482    pay_rewards(state, block_number, coinbase, ommers)
 483
 484    block_gas_used = block_gas_limit - gas_available
 485
 486    block_logs_bloom = logs_bloom(block_logs)
 487
 488    return (
 489        block_gas_used,
 490        root(transactions_trie),
 491        root(receipts_trie),
 492        block_logs_bloom,
 493        state,
 494    )
 495
 496
 497def validate_ommers(
 498    ommers: Tuple[Header, ...], block_header: Header, chain: BlockChain
 499) -> None:
 500    """
 501    Validates the ommers mentioned in the block.
 502
 503    An ommer block is a block that wasn't canonically added to the
 504    blockchain because it wasn't validated as fast as the canonical block
 505    but was mined at the same time.
 506
 507    To be considered valid, the ommers must adhere to the rules defined in
 508    the Ethereum protocol. The maximum amount of ommers is 2 per block and
 509    there cannot be duplicate ommers in a block. Many of the other ommer
 510    constraints are listed in the in-line comments of this function.
 511
 512    Parameters
 513    ----------
 514    ommers :
 515        List of ommers mentioned in the current block.
 516    block_header:
 517        The header of current block.
 518    chain :
 519        History and current state.
 520    """
 521    block_hash = rlp.rlp_hash(block_header)
 522
 523    ensure(rlp.rlp_hash(ommers) == block_header.ommers_hash, InvalidBlock)
 524
 525    if len(ommers) == 0:
 526        # Nothing to validate
 527        return
 528
 529    # Check that each ommer satisfies the constraints of a header
 530    for ommer in ommers:
 531        ensure(1 <= ommer.number < block_header.number, InvalidBlock)
 532        ommer_parent_header = chain.blocks[
 533            -(block_header.number - ommer.number) - 1
 534        ].header
 535        validate_header(ommer, ommer_parent_header)
 536
 537    # Check that there can be only at most 2 ommers for a block.
 538    ensure(len(ommers) <= 2, InvalidBlock)
 539
 540    ommers_hashes = [rlp.rlp_hash(ommer) for ommer in ommers]
 541    # Check that there are no duplicates in the ommers of current block
 542    ensure(len(ommers_hashes) == len(set(ommers_hashes)), InvalidBlock)
 543
 544    recent_canonical_blocks = chain.blocks[-(MAX_OMMER_DEPTH + 1) :]
 545    recent_canonical_block_hashes = {
 546        rlp.rlp_hash(block.header) for block in recent_canonical_blocks
 547    }
 548    recent_ommers_hashes: Set[Hash32] = set()
 549    for block in recent_canonical_blocks:
 550        recent_ommers_hashes = recent_ommers_hashes.union(
 551            {rlp.rlp_hash(ommer) for ommer in block.ommers}
 552        )
 553
 554    for ommer_index, ommer in enumerate(ommers):
 555        ommer_hash = ommers_hashes[ommer_index]
 556        # The current block shouldn't be the ommer
 557        ensure(ommer_hash != block_hash, InvalidBlock)
 558
 559        # Ommer shouldn't be one of the recent canonical blocks
 560        ensure(ommer_hash not in recent_canonical_block_hashes, InvalidBlock)
 561
 562        # Ommer shouldn't be one of the uncles mentioned in the recent
 563        # canonical blocks
 564        ensure(ommer_hash not in recent_ommers_hashes, InvalidBlock)
 565
 566        # Ommer age with respect to the current block. For example, an age of
 567        # 1 indicates that the ommer is a sibling of previous block.
 568        ommer_age = block_header.number - ommer.number
 569        ensure(1 <= ommer_age <= MAX_OMMER_DEPTH, InvalidBlock)
 570
 571        ensure(
 572            ommer.parent_hash in recent_canonical_block_hashes, InvalidBlock
 573        )
 574        ensure(ommer.parent_hash != block_header.parent_hash, InvalidBlock)
 575
 576
 577def pay_rewards(
 578    state: State,
 579    block_number: Uint,
 580    coinbase: Address,
 581    ommers: Tuple[Header, ...],
 582) -> None:
 583    """
 584    Pay rewards to the block miner as well as the ommers miners.
 585
 586    The miner of the canonical block is rewarded with the predetermined
 587    block reward, ``BLOCK_REWARD``, plus a variable award based off of the
 588    number of ommer blocks that were mined around the same time, and included
 589    in the canonical block's header. An ommer block is a block that wasn't
 590    added to the canonical blockchain because it wasn't validated as fast as
 591    the accepted block but was mined at the same time. Although not all blocks
 592    that are mined are added to the canonical chain, miners are still paid a
 593    reward for their efforts. This reward is called an ommer reward and is
 594    calculated based on the number associated with the ommer block that they
 595    mined.
 596
 597    Parameters
 598    ----------
 599    state :
 600        Current account state.
 601    block_number :
 602        Position of the block within the chain.
 603    coinbase :
 604        Address of account which receives block reward and transaction fees.
 605    ommers :
 606        List of ommers mentioned in the current block.
 607    """
 608    miner_reward = BLOCK_REWARD + (len(ommers) * (BLOCK_REWARD // 32))
 609    create_ether(state, coinbase, miner_reward)
 610
 611    for ommer in ommers:
 612        # Ommer age with respect to the current block.
 613        ommer_age = U256(block_number - ommer.number)
 614        ommer_miner_reward = ((8 - ommer_age) * BLOCK_REWARD) // 8
 615        create_ether(state, ommer.coinbase, ommer_miner_reward)
 616
 617
 618def process_transaction(
 619    env: vm.Environment, tx: Transaction
 620) -> Tuple[Uint, Tuple[Log, ...], Optional[Exception]]:
 621    """
 622    Execute a transaction against the provided environment.
 623
 624    This function processes the actions needed to execute a transaction.
 625    It decrements the sender's account after calculating the gas fee and
 626    refunds them the proper amount after execution. Calling contracts,
 627    deploying code, and incrementing nonces are all examples of actions that
 628    happen within this function or from a call made within this function.
 629
 630    Accounts that are marked for deletion are processed and destroyed after
 631    execution.
 632
 633    Parameters
 634    ----------
 635    env :
 636        Environment for the Ethereum Virtual Machine.
 637    tx :
 638        Transaction to execute.
 639
 640    Returns
 641    -------
 642    gas_left : `ethereum.base_types.U256`
 643        Remaining gas after execution.
 644    logs : `Tuple[ethereum.fork_types.Log, ...]`
 645        Logs generated during execution.
 646    """
 647    ensure(validate_transaction(tx), InvalidBlock)
 648
 649    sender = env.origin
 650    sender_account = get_account(env.state, sender)
 651    gas_fee = tx.gas * tx.gas_price
 652    ensure(sender_account.nonce == tx.nonce, InvalidBlock)
 653    ensure(sender_account.balance >= gas_fee + tx.value, InvalidBlock)
 654    ensure(sender_account.code == bytearray(), InvalidBlock)
 655
 656    gas = tx.gas - calculate_intrinsic_cost(tx)
 657    increment_nonce(env.state, sender)
 658    sender_balance_after_gas_fee = sender_account.balance - gas_fee
 659    set_account_balance(env.state, sender, sender_balance_after_gas_fee)
 660
 661    message = prepare_message(
 662        sender,
 663        tx.to,
 664        tx.value,
 665        tx.data,
 666        gas,
 667        env,
 668    )
 669
 670    output = process_message_call(message, env)
 671
 672    gas_used = tx.gas - output.gas_left
 673    gas_refund = min(gas_used // 2, output.refund_counter)
 674    gas_refund_amount = (output.gas_left + gas_refund) * tx.gas_price
 675    transaction_fee = (tx.gas - output.gas_left - gas_refund) * tx.gas_price
 676    total_gas_used = gas_used - gas_refund
 677
 678    # refund gas
 679    sender_balance_after_refund = (
 680        get_account(env.state, sender).balance + gas_refund_amount
 681    )
 682    set_account_balance(env.state, sender, sender_balance_after_refund)
 683
 684    # transfer miner fees
 685    coinbase_balance_after_mining_fee = (
 686        get_account(env.state, env.coinbase).balance + transaction_fee
 687    )
 688    if coinbase_balance_after_mining_fee != 0:
 689        set_account_balance(
 690            env.state, env.coinbase, coinbase_balance_after_mining_fee
 691        )
 692    elif account_exists_and_is_empty(env.state, env.coinbase):
 693        destroy_account(env.state, env.coinbase)
 694
 695    for address in output.accounts_to_delete:
 696        destroy_account(env.state, address)
 697
 698    for address in output.touched_accounts:
 699        if account_exists_and_is_empty(env.state, address):
 700            destroy_account(env.state, address)
 701
 702    return total_gas_used, output.logs, output.error
 703
 704
 705def validate_transaction(tx: Transaction) -> bool:
 706    """
 707    Verifies a transaction.
 708
 709    The gas in a transaction gets used to pay for the intrinsic cost of
 710    operations, therefore if there is insufficient gas then it would not
 711    be possible to execute a transaction and it will be declared invalid.
 712
 713    Additionally, the nonce of a transaction must not equal or exceed the
 714    limit defined in `EIP-2681 <https://eips.ethereum.org/EIPS/eip-2681>`_.
 715    In practice, defining the limit as ``2**64-1`` has no impact because
 716    sending ``2**64-1`` transactions is improbable. It's not strictly
 717    impossible though, ``2**64-1`` transactions is the entire capacity of the
 718    Ethereum blockchain at 2022 gas limits for a little over 22 years.
 719
 720    Parameters
 721    ----------
 722    tx :
 723        Transaction to validate.
 724
 725    Returns
 726    -------
 727    verified : `bool`
 728        True if the transaction can be executed, or False otherwise.
 729    """
 730    return calculate_intrinsic_cost(tx) <= tx.gas and tx.nonce < 2**64 - 1
 731
 732
 733def calculate_intrinsic_cost(tx: Transaction) -> Uint:
 734    """
 735    Calculates the gas that is charged before execution is started.
 736
 737    The intrinsic cost of the transaction is charged before execution has
 738    begun. Functions/operations in the EVM cost money to execute so this
 739    intrinsic cost is for the operations that need to be paid for as part of
 740    the transaction. Data transfer, for example, is part of this intrinsic
 741    cost. It costs ether to send data over the wire and that ether is
 742    accounted for in the intrinsic cost calculated in this function. This
 743    intrinsic cost must be calculated and paid for before execution in order
 744    for all operations to be implemented.
 745
 746    Parameters
 747    ----------
 748    tx :
 749        Transaction to compute the intrinsic cost of.
 750
 751    Returns
 752    -------
 753    verified : `ethereum.base_types.Uint`
 754        The intrinsic cost of the transaction.
 755    """
 756    data_cost = 0
 757
 758    for byte in tx.data:
 759        if byte == 0:
 760            data_cost += TX_DATA_COST_PER_ZERO
 761        else:
 762            data_cost += TX_DATA_COST_PER_NON_ZERO
 763
 764    if tx.to == Bytes0(b""):
 765        create_cost = TX_CREATE_COST
 766    else:
 767        create_cost = 0
 768
 769    return Uint(TX_BASE_COST + data_cost + create_cost)
 770
 771
 772def recover_sender(chain_id: U64, tx: Transaction) -> Address:
 773    """
 774    Extracts the sender address from a transaction.
 775
 776    The v, r, and s values are the three parts that make up the signature
 777    of a transaction. In order to recover the sender of a transaction the two
 778    components needed are the signature (``v``, ``r``, and ``s``) and the
 779    signing hash of the transaction. The sender's public key can be obtained
 780    with these two values and therefore the sender address can be retrieved.
 781
 782    Parameters
 783    ----------
 784    tx :
 785        Transaction of interest.
 786    chain_id :
 787        ID of the executing chain.
 788
 789    Returns
 790    -------
 791    sender : `ethereum.fork_types.Address`
 792        The address of the account that signed the transaction.
 793    """
 794    v, r, s = tx.v, tx.r, tx.s
 795
 796    ensure(0 < r and r < SECP256K1N, InvalidBlock)
 797    ensure(0 < s and s <= SECP256K1N // 2, InvalidBlock)
 798
 799    if v == 27 or v == 28:
 800        public_key = secp256k1_recover(r, s, v - 27, signing_hash_pre155(tx))
 801    else:
 802        ensure(v == 35 + chain_id * 2 or v == 36 + chain_id * 2, InvalidBlock)
 803        public_key = secp256k1_recover(
 804            r, s, v - 35 - chain_id * 2, signing_hash_155(tx, chain_id)
 805        )
 806    return Address(keccak256(public_key)[12:32])
 807
 808
 809def signing_hash_pre155(tx: Transaction) -> Hash32:
 810    """
 811    Compute the hash of a transaction used in a legacy (pre EIP 155) signature.
 812
 813    Parameters
 814    ----------
 815    tx :
 816        Transaction of interest.
 817
 818    Returns
 819    -------
 820    hash : `ethereum.crypto.hash.Hash32`
 821        Hash of the transaction.
 822    """
 823    return keccak256(
 824        rlp.encode(
 825            (
 826                tx.nonce,
 827                tx.gas_price,
 828                tx.gas,
 829                tx.to,
 830                tx.value,
 831                tx.data,
 832            )
 833        )
 834    )
 835
 836
 837def signing_hash_155(tx: Transaction, chain_id: U64) -> Hash32:
 838    """
 839    Compute the hash of a transaction used in a EIP 155 signature.
 840
 841    Parameters
 842    ----------
 843    tx :
 844        Transaction of interest.
 845    chain_id :
 846        The id of the current chain.
 847
 848    Returns
 849    -------
 850    hash : `ethereum.crypto.hash.Hash32`
 851        Hash of the transaction.
 852    """
 853    return keccak256(
 854        rlp.encode(
 855            (
 856                tx.nonce,
 857                tx.gas_price,
 858                tx.gas,
 859                tx.to,
 860                tx.value,
 861                tx.data,
 862                chain_id,
 863                Uint(0),
 864                Uint(0),
 865            )
 866        )
 867    )
 868
 869
 870def compute_header_hash(header: Header) -> Hash32:
 871    """
 872    Computes the hash of a block header.
 873
 874    The header hash of a block is the canonical hash that is used to refer
 875    to a specific block and completely distinguishes a block from another.
 876
 877    ``keccak256`` is a function that produces a 256 bit hash of any input.
 878    It also takes in any number of bytes as an input and produces a single
 879    hash for them. A hash is a completely unique output for a single input.
 880    So an input corresponds to one unique hash that can be used to identify
 881    the input exactly.
 882
 883    Prior to using the ``keccak256`` hash function, the header must be
 884    encoded using the Recursive-Length Prefix. See :ref:`rlp`.
 885    RLP encoding the header converts it into a space-efficient format that
 886    allows for easy transfer of data between nodes. The purpose of RLP is to
 887    encode arbitrarily nested arrays of binary data, and RLP is the primary
 888    encoding method used to serialize objects in Ethereum's execution layer.
 889    The only purpose of RLP is to encode structure; encoding specific data
 890    types (e.g. strings, floats) is left up to higher-order protocols.
 891
 892    Parameters
 893    ----------
 894    header :
 895        Header of interest.
 896
 897    Returns
 898    -------
 899    hash : `ethereum.crypto.hash.Hash32`
 900        Hash of the header.
 901    """
 902    return keccak256(rlp.encode(header))
 903
 904
 905def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool:
 906    """
 907    Validates the gas limit for a block.
 908
 909    The bounds of the gas limit, ``max_adjustment_delta``, is set as the
 910    quotient of the parent block's gas limit and the
 911    ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is
 912    passed through as a parameter is greater than or equal to the *sum* of
 913    the parent's gas and the adjustment delta then the limit for gas is too
 914    high and fails this function's check. Similarly, if the limit is less
 915    than or equal to the *difference* of the parent's gas and the adjustment
 916    delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's
 917    check fails because the gas limit doesn't allow for a sufficient or
 918    reasonable amount of gas to be used on a block.
 919
 920    Parameters
 921    ----------
 922    gas_limit :
 923        Gas limit to validate.
 924
 925    parent_gas_limit :
 926        Gas limit of the parent block.
 927
 928    Returns
 929    -------
 930    check : `bool`
 931        True if gas limit constraints are satisfied, False otherwise.
 932    """
 933    max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR
 934    if gas_limit >= parent_gas_limit + max_adjustment_delta:
 935        return False
 936    if gas_limit <= parent_gas_limit - max_adjustment_delta:
 937        return False
 938    if gas_limit < GAS_LIMIT_MINIMUM:
 939        return False
 940
 941    return True
 942
 943
 944def calculate_block_difficulty(
 945    block_number: Uint,
 946    block_timestamp: U256,
 947    parent_timestamp: U256,
 948    parent_difficulty: Uint,
 949    parent_has_ommers: bool,
 950) -> Uint:
 951    """
 952    Computes difficulty of a block using its header and parent header.
 953
 954    The difficulty is determined by the time the block was created after its
 955    parent. The ``offset`` is calculated using the parent block's difficulty,
 956    ``parent_difficulty``, and the timestamp between blocks. This offset is
 957    then added to the parent difficulty and is stored as the ``difficulty``
 958    variable. If the time between the block and its parent is too short, the
 959    offset will result in a positive number thus making the sum of
 960    ``parent_difficulty`` and ``offset`` to be a greater value in order to
 961    avoid mass forking. But, if the time is long enough, then the offset
 962    results in a negative value making the block less difficult than
 963    its parent.
 964
 965    The base standard for a block's difficulty is the predefined value
 966    set for the genesis block since it has no parent. So, a block
 967    can't be less difficult than the genesis block, therefore each block's
 968    difficulty is set to the maximum value between the calculated
 969    difficulty and the ``GENESIS_DIFFICULTY``.
 970
 971    Parameters
 972    ----------
 973    block_number :
 974        Block number of the block.
 975    block_timestamp :
 976        Timestamp of the block.
 977    parent_timestamp :
 978        Timestamp of the parent block.
 979    parent_difficulty :
 980        difficulty of the parent block.
 981    parent_has_ommers:
 982        does the parent have ommers.
 983
 984    Returns
 985    -------
 986    difficulty : `ethereum.base_types.Uint`
 987        Computed difficulty for a block.
 988    """
 989    offset = (
 990        int(parent_difficulty)
 991        // 2048
 992        * max(
 993            (2 if parent_has_ommers else 1)
 994            - int(block_timestamp - parent_timestamp) // 9,
 995            -99,
 996        )
 997    )
 998    difficulty = int(parent_difficulty) + offset
 999    # Historical Note: The difficulty bomb was not present in Ethereum at the
1000    # start of Frontier, but was added shortly after launch. However since the
1001    # bomb has no effect prior to block 200000 we pretend it existed from
1002    # genesis.
1003    # See https://github.com/ethereum/go-ethereum/pull/1588
1004    num_bomb_periods = ((int(block_number) - BOMB_DELAY_BLOCKS) // 100000) - 2
1005    if num_bomb_periods >= 0:
1006        difficulty += 2**num_bomb_periods
1007
1008    # Some clients raise the difficulty to `MINIMUM_DIFFICULTY` prior to adding
1009    # the bomb. This bug does not matter because the difficulty is always much
1010    # greater than `MINIMUM_DIFFICULTY` on Mainnet.
1011    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.constantinople.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.constantinople.fork_types.Header, parent_header: ethereum.constantinople.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.constantinople.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.constantinople.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.constantinople.fork_types.Transaction, error: Optional[Exception], cumulative_gas_used: ethereum.base_types.Uint, logs: Tuple[ethereum.constantinople.fork_types.Log, ...]) -> ethereum.constantinople.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            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    )

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.constantinople.fork_types.Header, ...], block_header: ethereum.constantinople.fork_types.Header, chain: BlockChain) -> None:
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)

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.constantinople.state.State, block_number: ethereum.base_types.Uint, coinbase: ethereum.base_types.Bytes20, ommers: Tuple[ethereum.constantinople.fork_types.Header, ...]) -> None:
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)

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.constantinople.vm.Environment, tx: ethereum.constantinople.fork_types.Transaction) -> Tuple[ethereum.base_types.Uint, Tuple[ethereum.constantinople.fork_types.Log, ...], Optional[Exception]]:
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

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.constantinople.fork_types.Transaction) -> bool:
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

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.constantinople.fork_types.Transaction) -> ethereum.base_types.Uint:
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)

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.

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])

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.constantinople.fork_types.Transaction) -> ethereum.base_types.Bytes32:
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    )

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.

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    )

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.constantinople.fork_types.Header) -> ethereum.base_types.Bytes32:
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))

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:
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

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:
 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))

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.