ethereum.forks.constantinople.vm.runtimeethereum.forks.istanbul.vm.runtime

Ethereum Virtual Machine (EVM) Runtime Operations.

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

Introduction

Runtime related operations used while executing EVM code.

get_valid_jump_destinations

Analyze the evm code to obtain the set of valid jump destinations.

Valid jump destinations are defined as follows: * The jump destination is less than the length of the code. * The jump destination should have the JUMPDEST opcode (0x5B). * The jump destination shouldn't be part of the data corresponding to PUSH-N opcodes.

Note - Jump destinations are 0-indexed.

Parameters

code : The EVM code which is to be executed.

Returns

valid_jump_destinations: Set[Uint] The set of valid jump destinations in the code.

def get_valid_jump_destinations(code: Bytes) -> Set[Uint]:
23
    """
24
    Analyze the evm code to obtain the set of valid jump destinations.
25
26
    Valid jump destinations are defined as follows:
27
        * The jump destination is less than the length of the code.
28
        * The jump destination should have the `JUMPDEST` opcode (0x5B).
29
        * The jump destination shouldn't be part of the data corresponding to
30
          `PUSH-N` opcodes.
31
32
    Note - Jump destinations are 0-indexed.
33
34
    Parameters
35
    ----------
36
    code :
37
        The EVM code which is to be executed.
38
39
    Returns
40
    -------
41
    valid_jump_destinations: `Set[Uint]`
42
        The set of valid jump destinations in the code.
43
44
    """
45
    valid_jump_destinations = set()
46
    pc = Uint(0)
47
48
    while pc < ulen(code):
49
        try:
50
            current_opcode = Ops(code[pc])
51
        except ValueError:
52
            # Skip invalid opcodes, as they don't affect the jumpdest
53
            # analysis. Nevertheless, such invalid opcodes would be caught
54
            # and raised when the interpreter runs.
55
            pc += Uint(1)
56
            continue
57
58
        if current_opcode == Ops.JUMPDEST:
59
            valid_jump_destinations.add(pc)
60
        elif Ops.PUSH1.value <= current_opcode.value <= Ops.PUSH32.value:
61
            # If PUSH-N opcodes are encountered, skip the current opcode along
62
            # with the trailing data segment corresponding to the PUSH-N
63
            # opcodes.
64
            push_data_size = current_opcode.value - Ops.PUSH1.value + 1
65
            pc += Uint(push_data_size)
66
67
        pc += Uint(1)
68
69
    return valid_jump_destinations