ethereum.dao_fork.fork

.. _dao-fork:

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

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

Introduction

Entry point for the Ethereum specification.

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

The DAO-Fork occurred as a result of the 2016 DAO Hacks <https://www.gemini.com/cryptopedia/the-dao-hack-makerdao>_ in which an unknown entity managed to drain more than 3.6 million ether causing the price of ether to drop by nearly 35%. This fork was the solution to the hacks and manually reset the affected parties' accounts to their state prior to the attack. This fork essentially rewrote the history of the Ethereum network.

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]:
108def get_last_256_block_hashes(chain: BlockChain) -> List[Hash32]:
109    """
110    Obtain the list of hashes of the previous 256 blocks in order of
111    increasing block number.
112
113    This function will return less hashes for the first 256 blocks.
114
115    The ``BLOCKHASH`` opcode needs to access the latest hashes on the chain,
116    therefore this function retrieves them.
117
118    Parameters
119    ----------
120    chain :
121        History and current state.
122
123    Returns
124    -------
125    recent_block_hashes : `List[Hash32]`
126        Hashes of the recent 256 blocks in order of increasing block number.
127    """
128    recent_blocks = chain.blocks[-255:]
129    # TODO: This function has not been tested rigorously
130    if len(recent_blocks) == 0:
131        return []
132
133    recent_block_hashes = []
134
135    for block in recent_blocks:
136        prev_block_hash = block.header.parent_hash
137        recent_block_hashes.append(prev_block_hash)
138
139    # We are computing the hash only for the most recent block and not for
140    # the rest of the blocks as they have successors which have the hash of
141    # the current block as parent hash.
142    most_recent_block_hash = keccak256(rlp.encode(recent_blocks[-1].header))
143    recent_block_hashes.append(most_recent_block_hash)
144
145    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.dao_fork.fork_types.Block) -> None:
148def state_transition(chain: BlockChain, block: Block) -> None:
149    """
150    Attempts to apply a block to an existing block chain.
151
152    All parts of the block's contents need to be verified before being added
153    to the chain. Blocks are verified by ensuring that the contents of the
154    block make logical sense with the contents of the parent block. The
155    information in the block's header must also match the corresponding
156    information in the block.
157
158    To implement Ethereum, in theory clients are only required to store the
159    most recent 255 blocks of the chain since as far as execution is
160    concerned, only those blocks are accessed. Practically, however, clients
161    should store more blocks to handle reorgs.
162
163    Parameters
164    ----------
165    chain :
166        History and current state.
167    block :
168        Block to apply to `chain`.
169    """
170    parent_header = chain.blocks[-1].header
171    validate_header(block.header, parent_header)
172    validate_ommers(block.ommers, block.header, chain)
173    (
174        gas_used,
175        transactions_root,
176        receipt_root,
177        block_logs_bloom,
178        state,
179    ) = apply_body(
180        chain.state,
181        get_last_256_block_hashes(chain),
182        block.header.coinbase,
183        block.header.number,
184        block.header.gas_limit,
185        block.header.timestamp,
186        block.header.difficulty,
187        block.transactions,
188        block.ommers,
189    )
190    ensure(gas_used == block.header.gas_used, InvalidBlock)
191    ensure(transactions_root == block.header.transactions_root, InvalidBlock)
192    ensure(state_root(state) == block.header.state_root, InvalidBlock)
193    ensure(receipt_root == block.header.receipt_root, InvalidBlock)
194    ensure(block_logs_bloom == block.header.bloom, InvalidBlock)
195
196    chain.blocks.append(block)
197    if len(chain.blocks) > 255:
198        # Real clients have to store more blocks to deal with reorgs, but the
199        # protocol only requires the last 255
200        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.dao_fork.fork_types.Header, parent_header: ethereum.dao_fork.fork_types.Header) -> None:
203def validate_header(header: Header, parent_header: Header) -> None:
204    """
205    Verifies a block header.
206
207    In order to consider a block's header valid, the logic for the
208    quantities in the header should match the logic for the block itself.
209    For example the header timestamp should be greater than the block's parent
210    timestamp because the block was created *after* the parent block.
211    Additionally, the block's number should be directly following the parent
212    block's number since it is the next block in the sequence.
213
214    Parameters
215    ----------
216    header :
217        Header to check for correctness.
218    parent_header :
219        Parent Header of the header to check for correctness
220    """
221    ensure(header.timestamp > parent_header.timestamp, InvalidBlock)
222    ensure(header.number == parent_header.number + 1, InvalidBlock)
223    ensure(
224        check_gas_limit(header.gas_limit, parent_header.gas_limit),
225        InvalidBlock,
226    )
227    ensure(len(header.extra_data) <= 32, InvalidBlock)
228
229    block_difficulty = calculate_block_difficulty(
230        header.number,
231        header.timestamp,
232        parent_header.timestamp,
233        parent_header.difficulty,
234    )
235    ensure(header.difficulty == block_difficulty, InvalidBlock)
236
237    block_parent_hash = keccak256(rlp.encode(parent_header))
238    ensure(header.parent_hash == block_parent_hash, InvalidBlock)
239
240    if (
241        header.number >= FORK_CRITERIA.block_number
242        and header.number < FORK_CRITERIA.block_number + 10
243    ):
244        ensure(header.extra_data == b"dao-hard-fork", InvalidBlock)
245
246    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.dao_fork.fork_types.Header) -> ethereum.base_types.Bytes32:
249def generate_header_hash_for_pow(header: Header) -> Hash32:
250    """
251    Generate rlp hash of the header which is to be used for Proof-of-Work
252    verification.
253
254    In other words, the PoW artefacts `mix_digest` and `nonce` are ignored
255    while calculating this hash.
256
257    A particular PoW is valid for a single hash, that hash is computed by
258    this function. The `nonce` and `mix_digest` are omitted from this hash
259    because they are being changed by miners in their search for a sufficient
260    proof-of-work.
261
262    Parameters
263    ----------
264    header :
265        The header object for which the hash is to be generated.
266
267    Returns
268    -------
269    hash : `Hash32`
270        The PoW valid rlp hash of the passed in header.
271    """
272    header_data_without_pow_artefacts = [
273        header.parent_hash,
274        header.ommers_hash,
275        header.coinbase,
276        header.state_root,
277        header.transactions_root,
278        header.receipt_root,
279        header.bloom,
280        header.difficulty,
281        header.number,
282        header.gas_limit,
283        header.gas_used,
284        header.timestamp,
285        header.extra_data,
286    ]
287
288    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.dao_fork.fork_types.Header) -> None:
291def validate_proof_of_work(header: Header) -> None:
292    """
293    Validates the Proof of Work constraints.
294
295    In order to verify that a miner's proof-of-work is valid for a block, a
296    ``mix-digest`` and ``result`` are calculated using the ``hashimoto_light``
297    hash function. The mix digest is a hash of the header and the nonce that
298    is passed through and it confirms whether or not proof-of-work was done
299    on the correct block. The result is the actual hash value of the block.
300
301    Parameters
302    ----------
303    header :
304        Header of interest.
305    """
306    header_hash = generate_header_hash_for_pow(header)
307    # TODO: Memoize this somewhere and read from that data instead of
308    # calculating cache for every block validation.
309    cache = generate_cache(header.number)
310    mix_digest, result = hashimoto_light(
311        header_hash, header.nonce, cache, dataset_size(header.number)
312    )
313
314    ensure(mix_digest == header.mix_digest, InvalidBlock)
315    ensure(
316        Uint.from_be_bytes(result) <= (U256_CEIL_VALUE // header.difficulty),
317        InvalidBlock,
318    )

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.

def check_transaction( tx: ethereum.dao_fork.fork_types.Transaction, gas_available: ethereum.base_types.Uint) -> ethereum.base_types.Bytes20:
321def check_transaction(
322    tx: Transaction,
323    gas_available: Uint,
324) -> Address:
325    """
326    Check if the transaction is includable in the block.
327
328    Parameters
329    ----------
330    tx :
331        The transaction.
332    gas_available :
333        The gas remaining in the block.
334
335    Returns
336    -------
337    sender_address :
338        The sender of the transaction.
339
340    Raises
341    ------
342    InvalidBlock :
343        If the transaction is not includable.
344    """
345    ensure(tx.gas <= gas_available, InvalidBlock)
346    sender_address = recover_sender(tx)
347
348    return sender_address

Check if the transaction is includable in the block.

Parameters

tx : The transaction. gas_available : The gas remaining in the block.

Returns

sender_address : The sender of the transaction.

Raises

InvalidBlock : If the transaction is not includable.

351def make_receipt(
352    tx: Transaction,
353    post_state: Bytes32,
354    cumulative_gas_used: Uint,
355    logs: Tuple[Log, ...],
356) -> Receipt:
357    """
358    Make the receipt for a transaction that was executed.
359
360    Parameters
361    ----------
362    tx :
363        The executed transaction.
364    post_state :
365        The state root immediately after this transaction.
366    cumulative_gas_used :
367        The total gas used so far in the block after the transaction was
368        executed.
369    logs :
370        The logs produced by the transaction.
371
372    Returns
373    -------
374    receipt :
375        The receipt for the transaction.
376    """
377    receipt = Receipt(
378        post_state=post_state,
379        cumulative_gas_used=cumulative_gas_used,
380        bloom=logs_bloom(logs),
381        logs=logs,
382    )
383
384    return receipt

Make the receipt for a transaction that was executed.

Parameters

tx : The executed transaction. post_state : The state root immediately after this transaction. 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.

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

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

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.dao_fork.fork_types.Header, ...], block_header: ethereum.dao_fork.fork_types.Header, chain: BlockChain) -> None:
503def validate_ommers(
504    ommers: Tuple[Header, ...], block_header: Header, chain: BlockChain
505) -> None:
506    """
507    Validates the ommers mentioned in the block.
508
509    An ommer block is a block that wasn't canonically added to the
510    blockchain because it wasn't validated as fast as the canonical block
511    but was mined at the same time.
512
513    To be considered valid, the ommers must adhere to the rules defined in
514    the Ethereum protocol. The maximum amount of ommers is 2 per block and
515    there cannot be duplicate ommers in a block. Many of the other ommer
516    constraints are listed in the in-line comments of this function.
517
518    Parameters
519    ----------
520    ommers :
521        List of ommers mentioned in the current block.
522    block_header:
523        The header of current block.
524    chain :
525        History and current state.
526    """
527    block_hash = rlp.rlp_hash(block_header)
528
529    ensure(rlp.rlp_hash(ommers) == block_header.ommers_hash, InvalidBlock)
530
531    if len(ommers) == 0:
532        # Nothing to validate
533        return
534
535    # Check that each ommer satisfies the constraints of a header
536    for ommer in ommers:
537        ensure(1 <= ommer.number < block_header.number, InvalidBlock)
538        ommer_parent_header = chain.blocks[
539            -(block_header.number - ommer.number) - 1
540        ].header
541        validate_header(ommer, ommer_parent_header)
542
543    # Check that there can be only at most 2 ommers for a block.
544    ensure(len(ommers) <= 2, InvalidBlock)
545
546    ommers_hashes = [rlp.rlp_hash(ommer) for ommer in ommers]
547    # Check that there are no duplicates in the ommers of current block
548    ensure(len(ommers_hashes) == len(set(ommers_hashes)), InvalidBlock)
549
550    recent_canonical_blocks = chain.blocks[-(MAX_OMMER_DEPTH + 1) :]
551    recent_canonical_block_hashes = {
552        rlp.rlp_hash(block.header) for block in recent_canonical_blocks
553    }
554    recent_ommers_hashes: Set[Hash32] = set()
555    for block in recent_canonical_blocks:
556        recent_ommers_hashes = recent_ommers_hashes.union(
557            {rlp.rlp_hash(ommer) for ommer in block.ommers}
558        )
559
560    for ommer_index, ommer in enumerate(ommers):
561        ommer_hash = ommers_hashes[ommer_index]
562        # The current block shouldn't be the ommer
563        ensure(ommer_hash != block_hash, InvalidBlock)
564
565        # Ommer shouldn't be one of the recent canonical blocks
566        ensure(ommer_hash not in recent_canonical_block_hashes, InvalidBlock)
567
568        # Ommer shouldn't be one of the uncles mentioned in the recent
569        # canonical blocks
570        ensure(ommer_hash not in recent_ommers_hashes, InvalidBlock)
571
572        # Ommer age with respect to the current block. For example, an age of
573        # 1 indicates that the ommer is a sibling of previous block.
574        ommer_age = block_header.number - ommer.number
575        ensure(1 <= ommer_age <= MAX_OMMER_DEPTH, InvalidBlock)
576
577        ensure(
578            ommer.parent_hash in recent_canonical_block_hashes, InvalidBlock
579        )
580        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.dao_fork.state.State, block_number: ethereum.base_types.Uint, coinbase: ethereum.base_types.Bytes20, ommers: Tuple[ethereum.dao_fork.fork_types.Header, ...]) -> None:
583def pay_rewards(
584    state: State,
585    block_number: Uint,
586    coinbase: Address,
587    ommers: Tuple[Header, ...],
588) -> None:
589    """
590    Pay rewards to the block miner as well as the ommers miners.
591
592    The miner of the canonical block is rewarded with the predetermined
593    block reward, ``BLOCK_REWARD``, plus a variable award based off of the
594    number of ommer blocks that were mined around the same time, and included
595    in the canonical block's header. An ommer block is a block that wasn't
596    added to the canonical blockchain because it wasn't validated as fast as
597    the accepted block but was mined at the same time. Although not all blocks
598    that are mined are added to the canonical chain, miners are still paid a
599    reward for their efforts. This reward is called an ommer reward and is
600    calculated based on the number associated with the ommer block that they
601    mined.
602
603    Parameters
604    ----------
605    state :
606        Current account state.
607    block_number :
608        Position of the block within the chain.
609    coinbase :
610        Address of account which receives block reward and transaction fees.
611    ommers :
612        List of ommers mentioned in the current block.
613    """
614    miner_reward = BLOCK_REWARD + (len(ommers) * (BLOCK_REWARD // 32))
615    create_ether(state, coinbase, miner_reward)
616
617    for ommer in ommers:
618        # Ommer age with respect to the current block.
619        ommer_age = U256(block_number - ommer.number)
620        ommer_miner_reward = ((8 - ommer_age) * BLOCK_REWARD) // 8
621        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.

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

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.dao_fork.fork_types.Transaction) -> bool:
704def validate_transaction(tx: Transaction) -> bool:
705    """
706    Verifies a transaction.
707
708    The gas in a transaction gets used to pay for the intrinsic cost of
709    operations, therefore if there is insufficient gas then it would not
710    be possible to execute a transaction and it will be declared invalid.
711
712    Additionally, the nonce of a transaction must not equal or exceed the
713    limit defined in `EIP-2681 <https://eips.ethereum.org/EIPS/eip-2681>`_.
714    In practice, defining the limit as ``2**64-1`` has no impact because
715    sending ``2**64-1`` transactions is improbable. It's not strictly
716    impossible though, ``2**64-1`` transactions is the entire capacity of the
717    Ethereum blockchain at 2022 gas limits for a little over 22 years.
718
719    Parameters
720    ----------
721    tx :
722        Transaction to validate.
723
724    Returns
725    -------
726    verified : `bool`
727        True if the transaction can be executed, or False otherwise.
728    """
729    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.dao_fork.fork_types.Transaction) -> ethereum.base_types.Uint:
732def calculate_intrinsic_cost(tx: Transaction) -> Uint:
733    """
734    Calculates the gas that is charged before execution is started.
735
736    The intrinsic cost of the transaction is charged before execution has
737    begun. Functions/operations in the EVM cost money to execute so this
738    intrinsic cost is for the operations that need to be paid for as part of
739    the transaction. Data transfer, for example, is part of this intrinsic
740    cost. It costs ether to send data over the wire and that ether is
741    accounted for in the intrinsic cost calculated in this function. This
742    intrinsic cost must be calculated and paid for before execution in order
743    for all operations to be implemented.
744
745    Parameters
746    ----------
747    tx :
748        Transaction to compute the intrinsic cost of.
749
750    Returns
751    -------
752    verified : `ethereum.base_types.Uint`
753        The intrinsic cost of the transaction.
754    """
755    data_cost = 0
756
757    for byte in tx.data:
758        if byte == 0:
759            data_cost += TX_DATA_COST_PER_ZERO
760        else:
761            data_cost += TX_DATA_COST_PER_NON_ZERO
762
763    if tx.to == Bytes0(b""):
764        create_cost = TX_CREATE_COST
765    else:
766        create_cost = 0
767
768    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.

771def recover_sender(tx: Transaction) -> Address:
772    """
773    Extracts the sender address from a transaction.
774
775    The v, r, and s values are the three parts that make up the signature
776    of a transaction. In order to recover the sender of a transaction the two
777    components needed are the signature (``v``, ``r``, and ``s``) and the
778    signing hash of the transaction. The sender's public key can be obtained
779    with these two values and therefore the sender address can be retrieved.
780
781    Parameters
782    ----------
783    tx :
784        Transaction of interest.
785
786    Returns
787    -------
788    sender : `ethereum.fork_types.Address`
789        The address of the account that signed the transaction.
790    """
791    v, r, s = tx.v, tx.r, tx.s
792
793    #  if v > 28:
794    #      v = v - (chain_id*2+8)
795
796    ensure(v == 27 or v == 28, InvalidBlock)
797    ensure(0 < r and r < SECP256K1N, InvalidBlock)
798    ensure(0 < s and s <= SECP256K1N // 2, InvalidBlock)
799
800    public_key = secp256k1_recover(r, s, v - 27, signing_hash(tx))
801    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.

Returns

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

804def signing_hash(tx: Transaction) -> Hash32:
805    """
806    Compute the hash of a transaction used in the signature.
807
808    The values that are used to compute the signing hash set the rules for a
809    transaction. For example, signing over the gas sets a limit for the
810    amount of money that is allowed to be pulled out of the sender's account.
811
812    Parameters
813    ----------
814    tx :
815        Transaction of interest.
816
817    Returns
818    -------
819    hash : `ethereum.crypto.hash.Hash32`
820        Hash of the transaction.
821    """
822    return keccak256(
823        rlp.encode(
824            (
825                tx.nonce,
826                tx.gas_price,
827                tx.gas,
828                tx.to,
829                tx.value,
830                tx.data,
831            )
832        )
833    )

Compute the hash of a transaction used in the signature.

The values that are used to compute the signing hash set the rules for a transaction. For example, signing over the gas sets a limit for the amount of money that is allowed to be pulled out of the sender's account.

Parameters

tx : Transaction of interest.

Returns

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

def compute_header_hash( header: ethereum.dao_fork.fork_types.Header) -> ethereum.base_types.Bytes32:
836def compute_header_hash(header: Header) -> Hash32:
837    """
838    Computes the hash of a block header.
839
840    The header hash of a block is the canonical hash that is used to refer
841    to a specific block and completely distinguishes a block from another.
842
843    ``keccak256`` is a function that produces a 256 bit hash of any input.
844    It also takes in any number of bytes as an input and produces a single
845    hash for them. A hash is a completely unique output for a single input.
846    So an input corresponds to one unique hash that can be used to identify
847    the input exactly.
848
849    Prior to using the ``keccak256`` hash function, the header must be
850    encoded using the Recursive-Length Prefix. See :ref:`rlp`.
851    RLP encoding the header converts it into a space-efficient format that
852    allows for easy transfer of data between nodes. The purpose of RLP is to
853    encode arbitrarily nested arrays of binary data, and RLP is the primary
854    encoding method used to serialize objects in Ethereum's execution layer.
855    The only purpose of RLP is to encode structure; encoding specific data
856    types (e.g. strings, floats) is left up to higher-order protocols.
857
858    Parameters
859    ----------
860    header :
861        Header of interest.
862
863    Returns
864    -------
865    hash : `ethereum.crypto.hash.Hash32`
866        Hash of the header.
867    """
868    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:
871def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool:
872    """
873    Validates the gas limit for a block.
874
875    The bounds of the gas limit, ``max_adjustment_delta``, is set as the
876    quotient of the parent block's gas limit and the
877    ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is
878    passed through as a parameter is greater than or equal to the *sum* of
879    the parent's gas and the adjustment delta then the limit for gas is too
880    high and fails this function's check. Similarly, if the limit is less
881    than or equal to the *difference* of the parent's gas and the adjustment
882    delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's
883    check fails because the gas limit doesn't allow for a sufficient or
884    reasonable amount of gas to be used on a block.
885
886    Parameters
887    ----------
888    gas_limit :
889        Gas limit to validate.
890
891    parent_gas_limit :
892        Gas limit of the parent block.
893
894    Returns
895    -------
896    check : `bool`
897        True if gas limit constraints are satisfied, False otherwise.
898    """
899    max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR
900    if gas_limit >= parent_gas_limit + max_adjustment_delta:
901        return False
902    if gas_limit <= parent_gas_limit - max_adjustment_delta:
903        return False
904    if gas_limit < GAS_LIMIT_MINIMUM:
905        return False
906
907    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) -> ethereum.base_types.Uint:
910def calculate_block_difficulty(
911    block_number: Uint,
912    block_timestamp: U256,
913    parent_timestamp: U256,
914    parent_difficulty: Uint,
915) -> Uint:
916    """
917    Computes difficulty of a block using its header and parent header.
918
919    The difficulty is determined by the time the block was created after its
920    parent. The ``offset`` is calculated using the parent block's difficulty,
921    ``parent_difficulty``, and the timestamp between blocks. This offset is
922    then added to the parent difficulty and is stored as the ``difficulty``
923    variable. If the time between the block and its parent is too short, the
924    offset will result in a positive number thus making the sum of
925    ``parent_difficulty`` and ``offset`` to be a greater value in order to
926    avoid mass forking. But, if the time is long enough, then the offset
927    results in a negative value making the block less difficult than
928    its parent.
929
930    The base standard for a block's difficulty is the predefined value
931    set for the genesis block since it has no parent. So, a block
932    can't be less difficult than the genesis block, therefore each block's
933    difficulty is set to the maximum value between the calculated
934    difficulty and the ``GENESIS_DIFFICULTY``.
935
936    Parameters
937    ----------
938    block_number :
939        Block number of the block.
940    block_timestamp :
941        Timestamp of the block.
942    parent_timestamp :
943        Timestamp of the parent block.
944    parent_difficulty :
945        difficulty of the parent block.
946
947    Returns
948    -------
949    difficulty : `ethereum.base_types.Uint`
950        Computed difficulty for a block.
951    """
952    offset = (
953        int(parent_difficulty)
954        // 2048
955        * max(1 - int(block_timestamp - parent_timestamp) // 10, -99)
956    )
957    difficulty = int(parent_difficulty) + offset
958    # Historical Note: The difficulty bomb was not present in Ethereum at the
959    # start of Frontier, but was added shortly after launch. However since the
960    # bomb has no effect prior to block 200000 we pretend it existed from
961    # genesis.
962    # See https://github.com/ethereum/go-ethereum/pull/1588
963    num_bomb_periods = (int(block_number) // 100000) - 2
964    if num_bomb_periods >= 0:
965        difficulty += 2**num_bomb_periods
966
967    # Some clients raise the difficulty to `MINIMUM_DIFFICULTY` prior to adding
968    # the bomb. This bug does not matter because the difficulty is always much
969    # greater than `MINIMUM_DIFFICULTY` on Mainnet.
970    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.

Returns

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