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

History and current state of the block chain.

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

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.

304def check_transaction(
305    tx: Transaction,
306    gas_available: Uint,
307) -> Address:
308    """
309    Check if the transaction is includable in the block.
310
311    Parameters
312    ----------
313    tx :
314        The transaction.
315    gas_available :
316        The gas remaining in the block.
317
318    Returns
319    -------
320    sender_address :
321        The sender of the transaction.
322
323    Raises
324    ------
325    InvalidBlock :
326        If the transaction is not includable.
327    """
328    ensure(tx.gas <= gas_available, InvalidBlock)
329    sender_address = recover_sender(tx)
330
331    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.

334def make_receipt(
335    tx: Transaction,
336    post_state: Bytes32,
337    cumulative_gas_used: Uint,
338    logs: Tuple[Log, ...],
339) -> Receipt:
340    """
341    Make the receipt for a transaction that was executed.
342
343    Parameters
344    ----------
345    tx :
346        The executed transaction.
347    post_state :
348        The state root immediately after this transaction.
349    cumulative_gas_used :
350        The total gas used so far in the block after the transaction was
351        executed.
352    logs :
353        The logs produced by the transaction.
354
355    Returns
356    -------
357    receipt :
358        The receipt for the transaction.
359    """
360    receipt = Receipt(
361        post_state=post_state,
362        cumulative_gas_used=cumulative_gas_used,
363        bloom=logs_bloom(logs),
364        logs=logs,
365    )
366
367    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.

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

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

607def process_transaction(
608    env: vm.Environment, tx: Transaction
609) -> Tuple[Uint, Tuple[Log, ...]]:
610    """
611    Execute a transaction against the provided environment.
612
613    This function processes the actions needed to execute a transaction.
614    It decrements the sender's account after calculating the gas fee and
615    refunds them the proper amount after execution. Calling contracts,
616    deploying code, and incrementing nonces are all examples of actions that
617    happen within this function or from a call made within this function.
618
619    Accounts that are marked for deletion are processed and destroyed after
620    execution.
621
622    Parameters
623    ----------
624    env :
625        Environment for the Ethereum Virtual Machine.
626    tx :
627        Transaction to execute.
628
629    Returns
630    -------
631    gas_left : `ethereum.base_types.U256`
632        Remaining gas after execution.
633    logs : `Tuple[ethereum.fork_types.Log, ...]`
634        Logs generated during execution.
635    """
636    ensure(validate_transaction(tx), InvalidBlock)
637
638    sender = env.origin
639    sender_account = get_account(env.state, sender)
640    gas_fee = tx.gas * tx.gas_price
641    ensure(sender_account.nonce == tx.nonce, InvalidBlock)
642    ensure(sender_account.balance >= gas_fee + tx.value, InvalidBlock)
643    ensure(sender_account.code == bytearray(), InvalidBlock)
644
645    gas = tx.gas - calculate_intrinsic_cost(tx)
646    increment_nonce(env.state, sender)
647    sender_balance_after_gas_fee = sender_account.balance - gas_fee
648    set_account_balance(env.state, sender, sender_balance_after_gas_fee)
649
650    message = prepare_message(
651        sender,
652        tx.to,
653        tx.value,
654        tx.data,
655        gas,
656        env,
657    )
658
659    output = process_message_call(message, env)
660
661    gas_used = tx.gas - output.gas_left
662    gas_refund = min(gas_used // 2, output.refund_counter)
663    gas_refund_amount = (output.gas_left + gas_refund) * tx.gas_price
664    transaction_fee = (tx.gas - output.gas_left - gas_refund) * tx.gas_price
665    total_gas_used = gas_used - gas_refund
666
667    # refund gas
668    sender_balance_after_refund = (
669        get_account(env.state, sender).balance + gas_refund_amount
670    )
671    set_account_balance(env.state, sender, sender_balance_after_refund)
672
673    # transfer miner fees
674    coinbase_balance_after_mining_fee = (
675        get_account(env.state, env.coinbase).balance + transaction_fee
676    )
677    set_account_balance(
678        env.state, env.coinbase, coinbase_balance_after_mining_fee
679    )
680
681    for address in output.accounts_to_delete:
682        destroy_account(env.state, address)
683
684    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.tangerine_whistle.fork_types.Transaction) -> bool:
687def validate_transaction(tx: Transaction) -> bool:
688    """
689    Verifies a transaction.
690
691    The gas in a transaction gets used to pay for the intrinsic cost of
692    operations, therefore if there is insufficient gas then it would not
693    be possible to execute a transaction and it will be declared invalid.
694
695    Additionally, the nonce of a transaction must not equal or exceed the
696    limit defined in `EIP-2681 <https://eips.ethereum.org/EIPS/eip-2681>`_.
697    In practice, defining the limit as ``2**64-1`` has no impact because
698    sending ``2**64-1`` transactions is improbable. It's not strictly
699    impossible though, ``2**64-1`` transactions is the entire capacity of the
700    Ethereum blockchain at 2022 gas limits for a little over 22 years.
701
702    Parameters
703    ----------
704    tx :
705        Transaction to validate.
706
707    Returns
708    -------
709    verified : `bool`
710        True if the transaction can be executed, or False otherwise.
711    """
712    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.tangerine_whistle.fork_types.Transaction) -> ethereum.base_types.Uint:
715def calculate_intrinsic_cost(tx: Transaction) -> Uint:
716    """
717    Calculates the gas that is charged before execution is started.
718
719    The intrinsic cost of the transaction is charged before execution has
720    begun. Functions/operations in the EVM cost money to execute so this
721    intrinsic cost is for the operations that need to be paid for as part of
722    the transaction. Data transfer, for example, is part of this intrinsic
723    cost. It costs ether to send data over the wire and that ether is
724    accounted for in the intrinsic cost calculated in this function. This
725    intrinsic cost must be calculated and paid for before execution in order
726    for all operations to be implemented.
727
728    Parameters
729    ----------
730    tx :
731        Transaction to compute the intrinsic cost of.
732
733    Returns
734    -------
735    verified : `ethereum.base_types.Uint`
736        The intrinsic cost of the transaction.
737    """
738    data_cost = 0
739
740    for byte in tx.data:
741        if byte == 0:
742            data_cost += TX_DATA_COST_PER_ZERO
743        else:
744            data_cost += TX_DATA_COST_PER_NON_ZERO
745
746    if tx.to == Bytes0(b""):
747        create_cost = TX_CREATE_COST
748    else:
749        create_cost = 0
750
751    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.

754def recover_sender(tx: Transaction) -> Address:
755    """
756    Extracts the sender address from a transaction.
757
758    The v, r, and s values are the three parts that make up the signature
759    of a transaction. In order to recover the sender of a transaction the two
760    components needed are the signature (``v``, ``r``, and ``s``) and the
761    signing hash of the transaction. The sender's public key can be obtained
762    with these two values and therefore the sender address can be retrieved.
763
764    Parameters
765    ----------
766    tx :
767        Transaction of interest.
768
769    Returns
770    -------
771    sender : `ethereum.fork_types.Address`
772        The address of the account that signed the transaction.
773    """
774    v, r, s = tx.v, tx.r, tx.s
775
776    #  if v > 28:
777    #      v = v - (chain_id*2+8)
778
779    ensure(v == 27 or v == 28, InvalidBlock)
780    ensure(0 < r and r < SECP256K1N, InvalidBlock)
781    ensure(0 < s and s <= SECP256K1N // 2, InvalidBlock)
782
783    public_key = secp256k1_recover(r, s, v - 27, signing_hash(tx))
784    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.

787def signing_hash(tx: Transaction) -> Hash32:
788    """
789    Compute the hash of a transaction used in the signature.
790
791    The values that are used to compute the signing hash set the rules for a
792    transaction. For example, signing over the gas sets a limit for the
793    amount of money that is allowed to be pulled out of the sender's account.
794
795    Parameters
796    ----------
797    tx :
798        Transaction of interest.
799
800    Returns
801    -------
802    hash : `ethereum.crypto.hash.Hash32`
803        Hash of the transaction.
804    """
805    return keccak256(
806        rlp.encode(
807            (
808                tx.nonce,
809                tx.gas_price,
810                tx.gas,
811                tx.to,
812                tx.value,
813                tx.data,
814            )
815        )
816    )

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