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

History and current state of the block chain.

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

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

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

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

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

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

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

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

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

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

The difficulty of a block is determined by the time the block was created after its parent. If a block's timestamp is more than 13 seconds after its parent block then its difficulty is set as the difference between the parent's difficulty and the max_adjustment_delta. Otherwise, if the time between parent and child blocks is too small (under 13 seconds) then, to avoid mass forking, the block's difficulty is set to the sum of the delta and the parent's 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.