ethereum.berlin.vm.runtimeethereum.london.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 | valid_jump_destinations = set() |
45 | pc = Uint(0) |
46 | |
47 | while pc < ulen(code): |
48 | try: |
49 | current_opcode = Ops(code[pc]) |
50 | except ValueError: |
51 | # Skip invalid opcodes, as they don't affect the jumpdest |
52 | # analysis. Nevertheless, such invalid opcodes would be caught |
53 | # and raised when the interpreter runs. |
54 | pc += Uint(1) |
55 | continue |
56 |
|
57 | if current_opcode == Ops.JUMPDEST: |
58 | valid_jump_destinations.add(pc) |
59 | elif Ops.PUSH1.value <= current_opcode.value <= Ops.PUSH32.value: |
60 | # If PUSH-N opcodes are encountered, skip the current opcode along |
61 | # with the trailing data segment corresponding to the PUSH-N |
62 | # opcodes. |
63 | push_data_size = current_opcode.value - Ops.PUSH1.value + 1 |
64 | pc += Uint(push_data_size) |
65 |
|
66 | pc += Uint(1) |
67 | |
68 | return valid_jump_destinations |