Skip to content

Ethereum Test Base Types package

Common definitions and types.

Address

Bases: FixedSizeBytes[20]

Class that helps represent Ethereum addresses in tests.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
class Address(FixedSizeBytes[20]):  # type: ignore
    """Class that helps represent Ethereum addresses in tests."""

    label: str | None = None

    def __new__(
        cls,
        input_bytes: "FixedSizeBytesConvertible | Address",
        *args: Any,
        label: str | None = None,
        **kwargs: Any,
    ) -> Self:
        """Create a new Address object with an optional label."""
        instance = super(Address, cls).__new__(
            cls, input_bytes, *args, **kwargs
        )
        if isinstance(input_bytes, Address) and label is None:
            instance.label = input_bytes.label
        else:
            instance.label = label
        return instance

__new__(input_bytes, *args, label=None, **kwargs)

Create a new Address object with an optional label.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
def __new__(
    cls,
    input_bytes: "FixedSizeBytesConvertible | Address",
    *args: Any,
    label: str | None = None,
    **kwargs: Any,
) -> Self:
    """Create a new Address object with an optional label."""
    instance = super(Address, cls).__new__(
        cls, input_bytes, *args, **kwargs
    )
    if isinstance(input_bytes, Address) and label is None:
        instance.label = input_bytes.label
    else:
        instance.label = label
    return instance

Bloom

Bases: FixedSizeBytes[256]

Class that helps represent blooms in tests.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
465
466
467
468
class Bloom(FixedSizeBytes[256]):  # type: ignore
    """Class that helps represent blooms in tests."""

    pass

BLSPublicKey

Bases: FixedSizeBytes[48]

Class that helps represent BLS public keys in tests.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
477
478
479
480
class BLSPublicKey(FixedSizeBytes[48]):  # type: ignore
    """Class that helps represent BLS public keys in tests."""

    pass

BLSSignature

Bases: FixedSizeBytes[96]

Class that helps represent BLS signatures in tests.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
483
484
485
486
class BLSSignature(FixedSizeBytes[96]):  # type: ignore
    """Class that helps represent BLS signatures in tests."""

    pass

Bytes

Bases: bytes, ToStringSchema

Class that helps represent bytes of variable length in tests.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
class Bytes(bytes, ToStringSchema):
    """Class that helps represent bytes of variable length in tests."""

    def __new__(cls, input_bytes: BytesConvertible = b"") -> Self:
        """Create a new Bytes object."""
        if type(input_bytes) is cls:
            return input_bytes
        return super(Bytes, cls).__new__(cls, to_bytes(input_bytes))

    def __hash__(self) -> int:
        """Return the hash of the bytes."""
        return super(Bytes, self).__hash__()

    def __str__(self) -> str:
        """Return the hexadecimal representation of the bytes."""
        return self.hex()

    def hex(self, *args: Any, **kwargs: Any) -> str:
        """Return the hexadecimal representation of the bytes."""
        return "0x" + super().hex(*args, **kwargs)

    def keccak256(self) -> "Hash":
        """Return the keccak256 hash of the opcode byte representation."""
        k = keccak.new(digest_bits=256)
        return Hash(k.update(bytes(self)).digest())

    def sha256(self) -> "Hash":
        """Return the sha256 hash of the opcode byte representation."""
        return Hash(sha256(self).digest())

    @staticmethod
    def __get_pydantic_core_schema__(
        source_type: Any, handler: GetCoreSchemaHandler
    ) -> PlainValidatorFunctionSchema:
        """
        Call the class constructor without info and appends the serialization
        schema.
        """
        return no_info_plain_validator_function(
            source_type,
            serialization=to_string_ser_schema(),
            json_schema_input_schema=handler(
                Annotated[
                    str, StringConstraints(pattern=r"^0x([0-9a-fA-F]{2})*$")
                ]
            ),
        )

__new__(input_bytes=b'')

Create a new Bytes object.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
184
185
186
187
188
def __new__(cls, input_bytes: BytesConvertible = b"") -> Self:
    """Create a new Bytes object."""
    if type(input_bytes) is cls:
        return input_bytes
    return super(Bytes, cls).__new__(cls, to_bytes(input_bytes))

__hash__()

Return the hash of the bytes.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
190
191
192
def __hash__(self) -> int:
    """Return the hash of the bytes."""
    return super(Bytes, self).__hash__()

__str__()

Return the hexadecimal representation of the bytes.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
194
195
196
def __str__(self) -> str:
    """Return the hexadecimal representation of the bytes."""
    return self.hex()

hex(*args, **kwargs)

Return the hexadecimal representation of the bytes.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
198
199
200
def hex(self, *args: Any, **kwargs: Any) -> str:
    """Return the hexadecimal representation of the bytes."""
    return "0x" + super().hex(*args, **kwargs)

keccak256()

Return the keccak256 hash of the opcode byte representation.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
202
203
204
205
def keccak256(self) -> "Hash":
    """Return the keccak256 hash of the opcode byte representation."""
    k = keccak.new(digest_bits=256)
    return Hash(k.update(bytes(self)).digest())

sha256()

Return the sha256 hash of the opcode byte representation.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
207
208
209
def sha256(self) -> "Hash":
    """Return the sha256 hash of the opcode byte representation."""
    return Hash(sha256(self).digest())

__get_pydantic_core_schema__(source_type, handler) staticmethod

Call the class constructor without info and appends the serialization schema.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
@staticmethod
def __get_pydantic_core_schema__(
    source_type: Any, handler: GetCoreSchemaHandler
) -> PlainValidatorFunctionSchema:
    """
    Call the class constructor without info and appends the serialization
    schema.
    """
    return no_info_plain_validator_function(
        source_type,
        serialization=to_string_ser_schema(),
        json_schema_input_schema=handler(
            Annotated[
                str, StringConstraints(pattern=r"^0x([0-9a-fA-F]{2})*$")
            ]
        ),
    )

BytesConcatenation

Bases: SupportsBytes, Sized

A class that can be concatenated with bytes.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
245
246
247
248
249
250
251
252
253
254
255
256
257
258
class BytesConcatenation(SupportsBytes, Sized, metaclass=ABCMeta):
    """A class that can be concatenated with bytes."""

    def __len__(self) -> int:
        """Return length of the object when converted to bytes."""
        return len(bytes(self))

    def __add__(self, other: bytes | SupportsBytes) -> bytes:
        """Concatenates the object with another bytes object."""
        return bytes(self) + bytes(other)

    def __radd__(self, other: bytes | SupportsBytes) -> bytes:
        """Concatenates the object with another bytes object."""
        return bytes(other) + bytes(self)

__len__()

Return length of the object when converted to bytes.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
248
249
250
def __len__(self) -> int:
    """Return length of the object when converted to bytes."""
    return len(bytes(self))

__add__(other)

Concatenates the object with another bytes object.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
252
253
254
def __add__(self, other: bytes | SupportsBytes) -> bytes:
    """Concatenates the object with another bytes object."""
    return bytes(self) + bytes(other)

__radd__(other)

Concatenates the object with another bytes object.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
256
257
258
def __radd__(self, other: bytes | SupportsBytes) -> bytes:
    """Concatenates the object with another bytes object."""
    return bytes(other) + bytes(self)

CoerceBytes

Bases: Bytes

Class that helps represent bytes of variable length in tests and supports removing white spaces anywhere in the string.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
230
231
232
233
234
235
236
237
238
239
240
241
242
class CoerceBytes(Bytes):
    """
    Class that helps represent bytes of variable length in tests and
    supports removing white spaces anywhere in the string.
    """

    def __new__(cls, input_bytes: BytesConvertible = b"") -> Self:
        """Create a new CoerceBytes object."""
        if type(input_bytes) is cls:
            return input_bytes
        if isinstance(input_bytes, str):
            input_bytes = sub(r"\s+", "", input_bytes)
        return super(Bytes, cls).__new__(cls, to_bytes(input_bytes))

__new__(input_bytes=b'')

Create a new CoerceBytes object.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
236
237
238
239
240
241
242
def __new__(cls, input_bytes: BytesConvertible = b"") -> Self:
    """Create a new CoerceBytes object."""
    if type(input_bytes) is cls:
        return input_bytes
    if isinstance(input_bytes, str):
        input_bytes = sub(r"\s+", "", input_bytes)
    return super(Bytes, cls).__new__(cls, to_bytes(input_bytes))

FixedSizeBytes

Bases: Bytes

Class that helps represent bytes of fixed length in tests.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
class FixedSizeBytes(Bytes):
    """Class that helps represent bytes of fixed length in tests."""

    byte_length: ClassVar[int]
    _sized_: ClassVar[Type["FixedSizeBytes"]]

    def __class_getitem__(cls, length: int) -> Type["FixedSizeBytes"]:
        """Create a new FixedSizeBytes class with the given length."""

        class Sized(cls):  # type: ignore
            byte_length = length

        Sized._sized_ = Sized
        return Sized

    def __new__(
        cls,
        input_bytes: FixedSizeBytesConvertible | Self,
        *,
        left_padding: bool = False,
        right_padding: bool = False,
    ) -> Self:
        """Create a new FixedSizeBytes object."""
        if type(input_bytes) is cls:
            return input_bytes
        return super(FixedSizeBytes, cls).__new__(
            cls,
            to_fixed_size_bytes(
                input_bytes,
                cls.byte_length,
                left_padding=left_padding,
                right_padding=right_padding,
            ),
        )

    def __hash__(self) -> int:
        """Return the hash of the bytes."""
        return super(FixedSizeBytes, self).__hash__()

    def __eq__(self, other: object) -> bool:
        """Compare two FixedSizeBytes objects to be equal."""
        if other is None:
            return False
        if not isinstance(other, FixedSizeBytes):
            assert (
                isinstance(other, str)
                or isinstance(other, int)
                or isinstance(other, bytes)
                or isinstance(other, SupportsBytes)
            )
            other = self._sized_(other)
        return super().__eq__(other)

    def __ne__(self, other: object) -> bool:
        """Compare two FixedSizeBytes objects to be not equal."""
        return not self.__eq__(other)

    @classmethod
    def __get_pydantic_core_schema__(
        cls: Type[Self], source_type: Any, handler: GetCoreSchemaHandler
    ) -> PlainValidatorFunctionSchema:
        """
        Call the class constructor without info and appends the serialization
        schema.
        """
        pattern = f"^0x([0-9a-fA-F]{{{cls.byte_length * 2}}})*$"
        return no_info_plain_validator_function(
            source_type,
            serialization=to_string_ser_schema(),
            json_schema_input_schema=handler(
                Annotated[str, StringConstraints(pattern=pattern)]
            ),
        )

__class_getitem__(length)

Create a new FixedSizeBytes class with the given length.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
340
341
342
343
344
345
346
347
def __class_getitem__(cls, length: int) -> Type["FixedSizeBytes"]:
    """Create a new FixedSizeBytes class with the given length."""

    class Sized(cls):  # type: ignore
        byte_length = length

    Sized._sized_ = Sized
    return Sized

__new__(input_bytes, *, left_padding=False, right_padding=False)

Create a new FixedSizeBytes object.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
def __new__(
    cls,
    input_bytes: FixedSizeBytesConvertible | Self,
    *,
    left_padding: bool = False,
    right_padding: bool = False,
) -> Self:
    """Create a new FixedSizeBytes object."""
    if type(input_bytes) is cls:
        return input_bytes
    return super(FixedSizeBytes, cls).__new__(
        cls,
        to_fixed_size_bytes(
            input_bytes,
            cls.byte_length,
            left_padding=left_padding,
            right_padding=right_padding,
        ),
    )

__hash__()

Return the hash of the bytes.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
369
370
371
def __hash__(self) -> int:
    """Return the hash of the bytes."""
    return super(FixedSizeBytes, self).__hash__()

__eq__(other)

Compare two FixedSizeBytes objects to be equal.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
373
374
375
376
377
378
379
380
381
382
383
384
385
def __eq__(self, other: object) -> bool:
    """Compare two FixedSizeBytes objects to be equal."""
    if other is None:
        return False
    if not isinstance(other, FixedSizeBytes):
        assert (
            isinstance(other, str)
            or isinstance(other, int)
            or isinstance(other, bytes)
            or isinstance(other, SupportsBytes)
        )
        other = self._sized_(other)
    return super().__eq__(other)

__ne__(other)

Compare two FixedSizeBytes objects to be not equal.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
387
388
389
def __ne__(self, other: object) -> bool:
    """Compare two FixedSizeBytes objects to be not equal."""
    return not self.__eq__(other)

__get_pydantic_core_schema__(source_type, handler) classmethod

Call the class constructor without info and appends the serialization schema.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
@classmethod
def __get_pydantic_core_schema__(
    cls: Type[Self], source_type: Any, handler: GetCoreSchemaHandler
) -> PlainValidatorFunctionSchema:
    """
    Call the class constructor without info and appends the serialization
    schema.
    """
    pattern = f"^0x([0-9a-fA-F]{{{cls.byte_length * 2}}})*$"
    return no_info_plain_validator_function(
        source_type,
        serialization=to_string_ser_schema(),
        json_schema_input_schema=handler(
            Annotated[str, StringConstraints(pattern=pattern)]
        ),
    )

ForkHash

Bases: FixedSizeBytes[4]

Class that helps represent the CRC config hashes and identifiers of a fork.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
409
410
411
412
413
414
class ForkHash(FixedSizeBytes[4]):  # type: ignore
    """
    Class that helps represent the CRC config hashes and identifiers of a fork.
    """

    pass

Hash

Bases: FixedSizeBytes[32]

Class that helps represent hashes in tests.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
440
441
442
443
class Hash(FixedSizeBytes[32]):  # type: ignore
    """Class that helps represent hashes in tests."""

    pass

HashInt

Bases: FixedSizeHexNumber[32]

Class that helps represent hashes in tests.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
328
329
330
331
class HashInt(FixedSizeHexNumber[32]):  # type: ignore
    """Class that helps represent hashes in tests."""

    pass

HeaderNonce

Bases: FixedSizeBytes[8]

Class that helps represent the header nonce in tests.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
471
472
473
474
class HeaderNonce(FixedSizeBytes[8]):  # type: ignore
    """Class that helps represent the header nonce in tests."""

    pass

HexNumber

Bases: Number

Class that helps represent hexadecimal numbers in tests.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
class HexNumber(Number):
    """Class that helps represent hexadecimal numbers in tests."""

    def __str__(self) -> str:
        """Return the string representation of the number."""
        return self.hex()

    @staticmethod
    def __get_pydantic_core_schema__(
        source_type: Any, handler: GetCoreSchemaHandler
    ) -> PlainValidatorFunctionSchema:
        """
        Call the class constructor without info and appends the serialization
        schema.
        """
        return no_info_plain_validator_function(
            source_type,
            serialization=to_string_ser_schema(),
            json_schema_input_schema=handler(
                Annotated[str, StringConstraints(pattern=r"^0x[0-9a-fA-F]*$")]
            ),
        )

__str__()

Return the string representation of the number.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
124
125
126
def __str__(self) -> str:
    """Return the string representation of the number."""
    return self.hex()

__get_pydantic_core_schema__(source_type, handler) staticmethod

Call the class constructor without info and appends the serialization schema.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
@staticmethod
def __get_pydantic_core_schema__(
    source_type: Any, handler: GetCoreSchemaHandler
) -> PlainValidatorFunctionSchema:
    """
    Call the class constructor without info and appends the serialization
    schema.
    """
    return no_info_plain_validator_function(
        source_type,
        serialization=to_string_ser_schema(),
        json_schema_input_schema=handler(
            Annotated[str, StringConstraints(pattern=r"^0x[0-9a-fA-F]*$")]
        ),
    )

Number

Bases: int, ToStringSchema

Class that helps represent numbers in tests.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class Number(int, ToStringSchema):
    """Class that helps represent numbers in tests."""

    def __new__(cls, input_number: NumberConvertible | Self) -> Self:
        """Create a new Number object."""
        return super(Number, cls).__new__(cls, to_number(input_number))

    def __str__(self) -> str:
        """Return the string representation of the number."""
        return str(int(self))

    def hex(self) -> str:
        """Return the hexadecimal representation of the number."""
        return hex(self)

__new__(input_number)

Create a new Number object.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
58
59
60
def __new__(cls, input_number: NumberConvertible | Self) -> Self:
    """Create a new Number object."""
    return super(Number, cls).__new__(cls, to_number(input_number))

__str__()

Return the string representation of the number.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
62
63
64
def __str__(self) -> str:
    """Return the string representation of the number."""
    return str(int(self))

hex()

Return the hexadecimal representation of the number.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
66
67
68
def hex(self) -> str:
    """Return the hexadecimal representation of the number."""
    return hex(self)

StorageKey

Bases: FixedSizeBytes[32]

Storage key type that automatically applies left padding for values shorter than 32 bytes.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
class StorageKey(FixedSizeBytes[32]):  # type: ignore
    """
    Storage key type that automatically applies left padding for values shorter
    than 32 bytes.
    """

    def __new__(
        cls,
        input_bytes: FixedSizeBytesConvertible | FixedSizeBytes,
        **kwargs: Any,
    ) -> Self:
        """Create a new StorageKey with automatic left padding."""
        # Always apply left_padding for storage keys unless explicitly set to
        # False
        if "left_padding" not in kwargs:
            kwargs["left_padding"] = True
        return super().__new__(cls, input_bytes, **kwargs)

__new__(input_bytes, **kwargs)

Create a new StorageKey with automatic left padding.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
452
453
454
455
456
457
458
459
460
461
462
def __new__(
    cls,
    input_bytes: FixedSizeBytesConvertible | FixedSizeBytes,
    **kwargs: Any,
) -> Self:
    """Create a new StorageKey with automatic left padding."""
    # Always apply left_padding for storage keys unless explicitly set to
    # False
    if "left_padding" not in kwargs:
        kwargs["left_padding"] = True
    return super().__new__(cls, input_bytes, **kwargs)

Wei

Bases: Number

Class that helps represent wei that can be parsed from strings.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
class Wei(Number):
    """Class that helps represent wei that can be parsed from strings."""

    def __new__(cls, input_number: NumberConvertible | Self) -> Self:
        """Create a new Number object."""
        if isinstance(input_number, str):
            words = input_number.split()
            multiplier = 1
            assert len(words) <= 2
            value_str = words[0]
            if len(words) > 1:
                unit = words[1].lower()
                multiplier = cls._get_multiplier(unit)
            value: float
            if "**" in value_str:
                base, exp = value_str.split("**")
                value = float(base) ** int(exp)
            else:
                value = (
                    int(value_str)
                    if value_str.isdecimal()
                    else float(value_str)
                )
            return super(Number, cls).__new__(cls, value * multiplier)
        return super(Number, cls).__new__(cls, to_number(input_number))

    @staticmethod
    def _get_multiplier(unit: str) -> int:
        """
        Return the multiplier for the given unit of wei, handling synonyms.
        """
        match unit:
            case "wei":
                return 1
            case "kwei" | "babbage" | "femtoether":
                return 10**3
            case "mwei" | "lovelace" | "picoether":
                return 10**6
            case "gwei" | "shannon" | "nanoether" | "nano":
                return 10**9
            case "szabo" | "microether" | "micro":
                return 10**12
            case "finney" | "milliether" | "milli":
                return 10**15
            case "ether" | "eth":
                return 10**18
            case _:
                raise ValueError(f"Invalid unit {unit}")

__new__(input_number)

Create a new Number object.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
def __new__(cls, input_number: NumberConvertible | Self) -> Self:
    """Create a new Number object."""
    if isinstance(input_number, str):
        words = input_number.split()
        multiplier = 1
        assert len(words) <= 2
        value_str = words[0]
        if len(words) > 1:
            unit = words[1].lower()
            multiplier = cls._get_multiplier(unit)
        value: float
        if "**" in value_str:
            base, exp = value_str.split("**")
            value = float(base) ** int(exp)
        else:
            value = (
                int(value_str)
                if value_str.isdecimal()
                else float(value_str)
            )
        return super(Number, cls).__new__(cls, value * multiplier)
    return super(Number, cls).__new__(cls, to_number(input_number))

ZeroPaddedHexNumber

Bases: HexNumber

Class that helps represent zero padded hexadecimal numbers in tests.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
class ZeroPaddedHexNumber(HexNumber):
    """Class that helps represent zero padded hexadecimal numbers in tests."""

    def hex(self) -> str:
        """Return the hexadecimal representation of the number."""
        if self == 0:
            return "0x00"
        hex_str = hex(self)[2:]
        if len(hex_str) % 2 == 1:
            return "0x0" + hex_str
        return "0x" + hex_str

    @staticmethod
    def __get_pydantic_core_schema__(
        source_type: Any, handler: GetCoreSchemaHandler
    ) -> PlainValidatorFunctionSchema:
        """
        Call the class constructor without info and appends the serialization
        schema.
        """
        return no_info_plain_validator_function(
            source_type,
            serialization=to_string_ser_schema(),
            json_schema_input_schema=handler(
                Annotated[
                    str, StringConstraints(pattern=r"^0x([0-9a-fA-F]{2})*$")
                ]
            ),
        )

hex()

Return the hexadecimal representation of the number.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
148
149
150
151
152
153
154
155
def hex(self) -> str:
    """Return the hexadecimal representation of the number."""
    if self == 0:
        return "0x00"
    hex_str = hex(self)[2:]
    if len(hex_str) % 2 == 1:
        return "0x0" + hex_str
    return "0x" + hex_str

__get_pydantic_core_schema__(source_type, handler) staticmethod

Call the class constructor without info and appends the serialization schema.

Source code in packages/testing/src/execution_testing/base_types/base_types.py
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
@staticmethod
def __get_pydantic_core_schema__(
    source_type: Any, handler: GetCoreSchemaHandler
) -> PlainValidatorFunctionSchema:
    """
    Call the class constructor without info and appends the serialization
    schema.
    """
    return no_info_plain_validator_function(
        source_type,
        serialization=to_string_ser_schema(),
        json_schema_input_schema=handler(
            Annotated[
                str, StringConstraints(pattern=r"^0x([0-9a-fA-F]{2})*$")
            ]
        ),
    )

to_json(input_model)

Convert a model to its json data representation.

Source code in packages/testing/src/execution_testing/base_types/base_types_json.py
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def to_json(
    input_model: (
        EthereumTestBaseModel
        | EthereumTestRootModel
        | AnyStr
        | List[EthereumTestBaseModel | EthereumTestRootModel | AnyStr]
    ),
) -> Any:
    """Convert a model to its json data representation."""
    if isinstance(input_model, list):
        return [to_json(item) for item in input_model]
    elif isinstance(
        input_model, (EthereumTestBaseModel, EthereumTestRootModel)
    ):
        return input_model.model_dump(
            mode="json", by_alias=True, exclude_none=True
        )
    else:
        return str(input_model)

AccessList

Bases: CamelModel, RLPSerializable

Access List for transactions.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
572
573
574
575
576
577
578
class AccessList(CamelModel, RLPSerializable):
    """Access List for transactions."""

    address: Address
    storage_keys: List[Hash]

    rlp_fields: ClassVar[List[str]] = ["address", "storage_keys"]

Account

Bases: CamelModel

State associated with an address.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
class Account(CamelModel):
    """State associated with an address."""

    nonce: ZeroPaddedHexNumber = ZeroPaddedHexNumber(0)
    """
    The scalar value equal to a) the number of transactions sent by an
    Externally Owned Account, b) the amount of contracts created by a contract.
    """
    balance: ZeroPaddedHexNumber = ZeroPaddedHexNumber(0)
    """The amount of Wei (10<sup>-18</sup> Eth) the account has."""
    code: Bytes = Bytes(b"")
    """Bytecode contained by the account."""
    storage: Storage = Field(default_factory=Storage)
    """Storage within a contract."""

    NONEXISTENT: ClassVar[None] = None
    """
    Sentinel object used to specify when an account should not exist in the
    state.
    """

    model_config = {
        **CamelModel.model_config,
        "frozen": True,
    }

    @dataclass(kw_only=True)
    class NonceMismatchError(Exception):
        """
        Test expected a certain nonce value for an account but a different
        value was found.
        """

        address: Address
        want: int | None
        got: int | None

        def __init__(
            self,
            address: Address,
            want: int | None,
            got: int | None,
            *args: Any,
        ) -> None:
            """
            Initialize the exception with the address, wanted and got values.
            """
            super().__init__(args)
            self.address = address
            self.want = want
            self.got = got

        def __str__(self) -> str:
            """Print exception string."""
            label_str = ""
            if self.address.label is not None:
                label_str = f" ({self.address.label})"
            return (
                f"unexpected nonce for account {self.address}{label_str}: "
                + f"want {self.want}, got {self.got}"
            )

    @dataclass(kw_only=True)
    class BalanceMismatchError(Exception):
        """
        Test expected a certain balance for an account but a different value
        was found.
        """

        address: Address
        want: int | None
        got: int | None

        def __init__(
            self,
            address: Address,
            want: int | None,
            got: int | None,
            *args: Any,
        ) -> None:
            """
            Initialize the exception with the address, wanted and got values.
            """
            super().__init__(args)
            self.address = address
            self.want = want
            self.got = got

        def __str__(self) -> str:
            """Print exception string."""
            label_str = ""
            if self.address.label is not None:
                label_str = f" ({self.address.label})"
            return (
                f"unexpected balance for account {self.address}{label_str}: "
                + f"want {self.want}, got {self.got}"
            )

    @dataclass(kw_only=True)
    class CodeMismatchError(Exception):
        """
        Test expected a certain bytecode for an account but a different one was
        found.
        """

        address: Address
        want: bytes | None
        got: bytes | None

        def __init__(
            self,
            address: Address,
            want: bytes | None,
            got: bytes | None,
            *args: Any,
        ) -> None:
            """
            Initialize the exception with the address, wanted and got values.
            """
            super().__init__(args)
            self.address = address
            self.want = want
            self.got = got

        def __str__(self) -> str:
            """Print exception string."""
            label_str = ""
            if self.address.label is not None:
                label_str = f" ({self.address.label})"
            return (
                f"unexpected code for account {self.address}{label_str}: "
                f"want {self.want.hex() if self.want else self.want}, "
                f"got {self.got.hex() if self.got else self.got}"
            )

    def check_alloc(
        self: "Account", address: Address, account: "Account"
    ) -> None:
        """
        Check the returned alloc against an expected account in post state.
        Raises exception on failure.
        """
        if "nonce" in self.model_fields_set:
            if self.nonce != account.nonce:
                raise Account.NonceMismatchError(
                    address=address,
                    want=self.nonce,
                    got=account.nonce,
                )

        if "balance" in self.model_fields_set:
            if self.balance != account.balance:
                raise Account.BalanceMismatchError(
                    address=address,
                    want=self.balance,
                    got=account.balance,
                )

        if "code" in self.model_fields_set:
            if self.code != account.code:
                raise Account.CodeMismatchError(
                    address=address,
                    want=self.code,
                    got=account.code,
                )

        if "storage" in self.model_fields_set:
            self.storage.must_be_equal(address=address, other=account.storage)

    def __bool__(self: "Account") -> bool:
        """Return True on a non-empty account."""
        return any((self.nonce, self.balance, self.code, self.storage))

    def hash(self) -> Hash:
        """Return the hash of the account given its properties."""
        data = self.model_dump(mode="json")
        blob = json.dumps(
            data,
            sort_keys=True,
            separators=(",", ":"),
        ).encode("utf-8")
        return Hash(hashlib.sha256(blob).digest())

    @classmethod
    def with_code(cls: Type, code: BytesConvertible) -> "Account":
        """Create account with provided `code` and nonce of `1`."""
        return Account(nonce=HexNumber(1), code=Bytes(code))

    @classmethod
    def merge(
        cls: Type,
        account_1: "Dict | Account | None",
        account_2: "Dict | Account | None",
    ) -> "Account":
        """Create a merged account from two sources."""

        def to_kwargs_dict(account: "Dict | Account | None") -> Dict:
            if account is None:
                return {}
            if isinstance(account, dict):
                return account
            elif isinstance(account, cls):
                return account.model_dump(exclude_unset=True)
            raise TypeError(
                f"Unexpected type for account merge: {type(account)}"
            )

        kwargs = to_kwargs_dict(account_1)
        kwargs.update(to_kwargs_dict(account_2))

        return cls(**kwargs)

nonce = ZeroPaddedHexNumber(0) class-attribute instance-attribute

The scalar value equal to a) the number of transactions sent by an Externally Owned Account, b) the amount of contracts created by a contract.

balance = ZeroPaddedHexNumber(0) class-attribute instance-attribute

The amount of Wei (10-18 Eth) the account has.

code = Bytes(b'') class-attribute instance-attribute

Bytecode contained by the account.

storage = Field(default_factory=Storage) class-attribute instance-attribute

Storage within a contract.

NONEXISTENT = None class-attribute

Sentinel object used to specify when an account should not exist in the state.

NonceMismatchError dataclass

Bases: Exception

Test expected a certain nonce value for an account but a different value was found.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
@dataclass(kw_only=True)
class NonceMismatchError(Exception):
    """
    Test expected a certain nonce value for an account but a different
    value was found.
    """

    address: Address
    want: int | None
    got: int | None

    def __init__(
        self,
        address: Address,
        want: int | None,
        got: int | None,
        *args: Any,
    ) -> None:
        """
        Initialize the exception with the address, wanted and got values.
        """
        super().__init__(args)
        self.address = address
        self.want = want
        self.got = got

    def __str__(self) -> str:
        """Print exception string."""
        label_str = ""
        if self.address.label is not None:
            label_str = f" ({self.address.label})"
        return (
            f"unexpected nonce for account {self.address}{label_str}: "
            + f"want {self.want}, got {self.got}"
        )

__init__(address, want, got, *args)

Initialize the exception with the address, wanted and got values.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
388
389
390
391
392
393
394
395
396
397
398
399
400
401
def __init__(
    self,
    address: Address,
    want: int | None,
    got: int | None,
    *args: Any,
) -> None:
    """
    Initialize the exception with the address, wanted and got values.
    """
    super().__init__(args)
    self.address = address
    self.want = want
    self.got = got

__str__()

Print exception string.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
403
404
405
406
407
408
409
410
411
def __str__(self) -> str:
    """Print exception string."""
    label_str = ""
    if self.address.label is not None:
        label_str = f" ({self.address.label})"
    return (
        f"unexpected nonce for account {self.address}{label_str}: "
        + f"want {self.want}, got {self.got}"
    )

BalanceMismatchError dataclass

Bases: Exception

Test expected a certain balance for an account but a different value was found.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
@dataclass(kw_only=True)
class BalanceMismatchError(Exception):
    """
    Test expected a certain balance for an account but a different value
    was found.
    """

    address: Address
    want: int | None
    got: int | None

    def __init__(
        self,
        address: Address,
        want: int | None,
        got: int | None,
        *args: Any,
    ) -> None:
        """
        Initialize the exception with the address, wanted and got values.
        """
        super().__init__(args)
        self.address = address
        self.want = want
        self.got = got

    def __str__(self) -> str:
        """Print exception string."""
        label_str = ""
        if self.address.label is not None:
            label_str = f" ({self.address.label})"
        return (
            f"unexpected balance for account {self.address}{label_str}: "
            + f"want {self.want}, got {self.got}"
        )

__init__(address, want, got, *args)

Initialize the exception with the address, wanted and got values.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
424
425
426
427
428
429
430
431
432
433
434
435
436
437
def __init__(
    self,
    address: Address,
    want: int | None,
    got: int | None,
    *args: Any,
) -> None:
    """
    Initialize the exception with the address, wanted and got values.
    """
    super().__init__(args)
    self.address = address
    self.want = want
    self.got = got

__str__()

Print exception string.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
439
440
441
442
443
444
445
446
447
def __str__(self) -> str:
    """Print exception string."""
    label_str = ""
    if self.address.label is not None:
        label_str = f" ({self.address.label})"
    return (
        f"unexpected balance for account {self.address}{label_str}: "
        + f"want {self.want}, got {self.got}"
    )

CodeMismatchError dataclass

Bases: Exception

Test expected a certain bytecode for an account but a different one was found.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
@dataclass(kw_only=True)
class CodeMismatchError(Exception):
    """
    Test expected a certain bytecode for an account but a different one was
    found.
    """

    address: Address
    want: bytes | None
    got: bytes | None

    def __init__(
        self,
        address: Address,
        want: bytes | None,
        got: bytes | None,
        *args: Any,
    ) -> None:
        """
        Initialize the exception with the address, wanted and got values.
        """
        super().__init__(args)
        self.address = address
        self.want = want
        self.got = got

    def __str__(self) -> str:
        """Print exception string."""
        label_str = ""
        if self.address.label is not None:
            label_str = f" ({self.address.label})"
        return (
            f"unexpected code for account {self.address}{label_str}: "
            f"want {self.want.hex() if self.want else self.want}, "
            f"got {self.got.hex() if self.got else self.got}"
        )

__init__(address, want, got, *args)

Initialize the exception with the address, wanted and got values.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
460
461
462
463
464
465
466
467
468
469
470
471
472
473
def __init__(
    self,
    address: Address,
    want: bytes | None,
    got: bytes | None,
    *args: Any,
) -> None:
    """
    Initialize the exception with the address, wanted and got values.
    """
    super().__init__(args)
    self.address = address
    self.want = want
    self.got = got

__str__()

Print exception string.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
475
476
477
478
479
480
481
482
483
484
def __str__(self) -> str:
    """Print exception string."""
    label_str = ""
    if self.address.label is not None:
        label_str = f" ({self.address.label})"
    return (
        f"unexpected code for account {self.address}{label_str}: "
        f"want {self.want.hex() if self.want else self.want}, "
        f"got {self.got.hex() if self.got else self.got}"
    )

check_alloc(address, account)

Check the returned alloc against an expected account in post state. Raises exception on failure.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
def check_alloc(
    self: "Account", address: Address, account: "Account"
) -> None:
    """
    Check the returned alloc against an expected account in post state.
    Raises exception on failure.
    """
    if "nonce" in self.model_fields_set:
        if self.nonce != account.nonce:
            raise Account.NonceMismatchError(
                address=address,
                want=self.nonce,
                got=account.nonce,
            )

    if "balance" in self.model_fields_set:
        if self.balance != account.balance:
            raise Account.BalanceMismatchError(
                address=address,
                want=self.balance,
                got=account.balance,
            )

    if "code" in self.model_fields_set:
        if self.code != account.code:
            raise Account.CodeMismatchError(
                address=address,
                want=self.code,
                got=account.code,
            )

    if "storage" in self.model_fields_set:
        self.storage.must_be_equal(address=address, other=account.storage)

__bool__()

Return True on a non-empty account.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
520
521
522
def __bool__(self: "Account") -> bool:
    """Return True on a non-empty account."""
    return any((self.nonce, self.balance, self.code, self.storage))

hash()

Return the hash of the account given its properties.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
524
525
526
527
528
529
530
531
532
def hash(self) -> Hash:
    """Return the hash of the account given its properties."""
    data = self.model_dump(mode="json")
    blob = json.dumps(
        data,
        sort_keys=True,
        separators=(",", ":"),
    ).encode("utf-8")
    return Hash(hashlib.sha256(blob).digest())

with_code(code) classmethod

Create account with provided code and nonce of 1.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
534
535
536
537
@classmethod
def with_code(cls: Type, code: BytesConvertible) -> "Account":
    """Create account with provided `code` and nonce of `1`."""
    return Account(nonce=HexNumber(1), code=Bytes(code))

merge(account_1, account_2) classmethod

Create a merged account from two sources.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
@classmethod
def merge(
    cls: Type,
    account_1: "Dict | Account | None",
    account_2: "Dict | Account | None",
) -> "Account":
    """Create a merged account from two sources."""

    def to_kwargs_dict(account: "Dict | Account | None") -> Dict:
        if account is None:
            return {}
        if isinstance(account, dict):
            return account
        elif isinstance(account, cls):
            return account.model_dump(exclude_unset=True)
        raise TypeError(
            f"Unexpected type for account merge: {type(account)}"
        )

    kwargs = to_kwargs_dict(account_1)
    kwargs.update(to_kwargs_dict(account_2))

    return cls(**kwargs)

Alloc

Bases: EthereumTestRootModel[Dict[Address, Account | None]]

Allocation of accounts in the state, pre and post test execution.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
564
565
566
567
568
569
class Alloc(EthereumTestRootModel[Dict[Address, Account | None]]):
    """Allocation of accounts in the state, pre and post test execution."""

    root: Dict[Address, Account | None] = Field(
        default_factory=dict, validate_default=True
    )

BlobSchedule

Bases: EthereumTestRootModel[Dict[str, ForkBlobSchedule]]

Blob schedule configuration dictionary.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
class BlobSchedule(EthereumTestRootModel[Dict[str, ForkBlobSchedule]]):
    """Blob schedule configuration dictionary."""

    root: Dict[str, ForkBlobSchedule] = Field(
        default_factory=dict, validate_default=True
    )

    def append(self, *, fork: str, schedule: Any) -> None:
        """Append a new fork schedule."""
        if not isinstance(schedule, ForkBlobSchedule):
            schedule = ForkBlobSchedule(**schedule)
        self.root[fork] = schedule

    def last(self) -> ForkBlobSchedule | None:
        """Return the last schedule."""
        if len(self.root) == 0:
            return None
        return list(self.root.values())[-1]

    def __getitem__(self, key: str) -> ForkBlobSchedule:
        """Return the schedule for a given fork."""
        return self.root[key]

append(*, fork, schedule)

Append a new fork schedule.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
596
597
598
599
600
def append(self, *, fork: str, schedule: Any) -> None:
    """Append a new fork schedule."""
    if not isinstance(schedule, ForkBlobSchedule):
        schedule = ForkBlobSchedule(**schedule)
    self.root[fork] = schedule

last()

Return the last schedule.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
602
603
604
605
606
def last(self) -> ForkBlobSchedule | None:
    """Return the last schedule."""
    if len(self.root) == 0:
        return None
    return list(self.root.values())[-1]

__getitem__(key)

Return the schedule for a given fork.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
608
609
610
def __getitem__(self, key: str) -> ForkBlobSchedule:
    """Return the schedule for a given fork."""
    return self.root[key]

ForkBlobSchedule

Bases: CamelModel

Representation of the blob schedule of a given fork.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
581
582
583
584
585
586
class ForkBlobSchedule(CamelModel):
    """Representation of the blob schedule of a given fork."""

    target_blobs_per_block: HexNumber = Field(..., alias="target")
    max_blobs_per_block: HexNumber = Field(..., alias="max")
    base_fee_update_fraction: HexNumber = Field(...)

Storage

Bases: EthereumTestRootModel[Dict[StorageKeyValueType, StorageKeyValueType]]

Definition of contract storage in the pre or post state of a test.

This model accepts a dictionary with keys and values as any of: str, int, bytes, or any type that supports conversion to bytes, and automatically casts them to HashInt.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
class Storage(
    EthereumTestRootModel[Dict[StorageKeyValueType, StorageKeyValueType]]
):
    """
    Definition of contract storage in the `pre` or `post` state of a test.

    This model accepts a dictionary with keys and values as any of: str, int,
    bytes, or any type that supports conversion to bytes, and automatically
    casts them to `HashInt`.
    """

    # internal storage is maintained as a dict with HashInt keys and values.
    root: Dict[StorageKeyValueType, StorageKeyValueType] = Field(
        default_factory=dict
    )

    _current_slot: int = PrivateAttr(0)
    _hint_map: Dict[StorageKeyValueType, str] = PrivateAttr(
        default_factory=dict
    )
    _any_map: Dict[StorageKeyValueType, bool] = PrivateAttr(
        default_factory=dict
    )

    StorageDictType: ClassVar[TypeAlias] = Dict[
        str | int | bytes | SupportsBytes, str | int | bytes | SupportsBytes
    ]
    """
    Dictionary type to be used when defining an input to initialize a storage.
    """

    @dataclass(kw_only=True)
    class InvalidTypeError(Exception):
        """
        Invalid type used when describing test's expected storage key or value.
        """

        key_or_value: Any

        def __init__(self, key_or_value: Any, *args: Any) -> None:
            """Initialize the exception with the invalid type."""
            super().__init__(args)
            self.key_or_value = key_or_value

        def __str__(self) -> str:
            """Print exception string."""
            return f"invalid type for key/value: {self.key_or_value}"

    @dataclass(kw_only=True)
    class InvalidValueError(Exception):
        """
        Invalid value used when describing test's expected storage key or
        value.
        """

        key_or_value: Any

        def __init__(self, key_or_value: Any, *args: Any) -> None:
            """Initialize the exception with the invalid value."""
            super().__init__(args)
            self.key_or_value = key_or_value

        def __str__(self) -> str:
            """Print exception string."""
            return f"invalid value for key/value: {self.key_or_value}"

    @dataclass(kw_only=True)
    class MissingKeyError(Exception):
        """Test expected to find a storage key set but key was missing."""

        key: int

        def __init__(self, key: int, *args: Any) -> None:
            """Initialize the exception with the missing key."""
            super().__init__(args)
            self.key = key

        def __str__(self) -> str:
            """Print exception string."""
            return "key {0} not found in storage".format(Hash(self.key))

    @dataclass(kw_only=True)
    class KeyValueMismatchError(Exception):
        """
        Test expected a certain value in a storage key but value found was
        different.
        """

        address: Address
        key: int
        want: int
        got: int
        hint: str

        def __init__(
            self,
            address: Address,
            key: int,
            want: int,
            got: int,
            hint: str = "",
            *args: Any,
        ) -> None:
            """
            Initialize the exception with the address, key, wanted and got
            values.
            """
            super().__init__(args)
            self.address = address
            self.key = key
            self.want = want
            self.got = got
            self.hint = hint

        def __str__(self) -> str:
            """Print exception string."""
            label_str = ""
            if self.address.label is not None:
                label_str = f" ({self.address.label})"
            hint_str = f" ({self.hint})" if self.hint else ""
            return (
                f"incorrect value in address {self.address}{label_str} for "
                + f"key {Hash(self.key)}{hint_str}:"
                + f" want {HexNumber(self.want)} (dec:{int(self.want)}),"
                + f" got {HexNumber(self.got)} (dec:{int(self.got)})"
            )

    def __contains__(
        self, key: StorageKeyValueTypeConvertible | StorageKeyValueType
    ) -> bool:
        """Check for an item in the storage."""
        return StorageKeyValueTypeAdapter.validate_python(key) in self.root

    def __getitem__(
        self, key: StorageKeyValueTypeConvertible | StorageKeyValueType
    ) -> StorageKeyValueType:
        """Return an item from the storage."""
        return self.root[StorageKeyValueTypeAdapter.validate_python(key)]

    def __setitem__(
        self,
        key: StorageKeyValueTypeConvertible | StorageKeyValueType,
        value: StorageKeyValueTypeConvertible | StorageKeyValueType,
    ) -> None:
        """Set an item in the storage."""
        self.root[StorageKeyValueTypeAdapter.validate_python(key)] = (
            StorageKeyValueTypeAdapter.validate_python(value)
        )

    def __delitem__(
        self, key: StorageKeyValueTypeConvertible | StorageKeyValueType
    ) -> None:
        """Delete an item from the storage."""
        del self.root[StorageKeyValueTypeAdapter.validate_python(key)]

    def __iter__(self) -> Iterator[StorageKeyValueType]:  # type: ignore [override]
        """Return an iterator over the storage."""
        return iter(self.root)

    def __eq__(self, other: object) -> bool:
        """Return True if both storages are equal."""
        if not isinstance(other, Storage):
            return False
        return self.root == other.root

    def __ne__(self, other: object) -> bool:
        """Return True if both storages are not equal."""
        if not isinstance(other, Storage):
            return False
        return self.root != other.root

    def __bool__(self) -> bool:
        """Return True if the storage is not empty."""
        return any(v for v in self.root.values())

    def __add__(self, other: "Storage") -> "Storage":
        """Return a new storage that is the sum of two storages."""
        return Storage({**self.root, **other.root})

    def __len__(self) -> int:
        """
        Return the number of keys that have been explicitly set in the storage.
        """
        return len(self.root)

    def keys(self) -> set[StorageKeyValueType]:
        """Return the keys of the storage."""
        return set(self.root.keys())

    def set_next_slot(self, slot: int) -> "Storage":
        """Set the next slot to be used by `store_next`."""
        self._current_slot = slot
        return self

    def items(self) -> ItemsView[StorageKeyValueType, StorageKeyValueType]:
        """Return the items of the storage."""
        return self.root.items()

    def set_expect_any(
        self, key: StorageKeyValueTypeConvertible | StorageKeyValueType
    ) -> None:
        """
        Mark key to be able to have any expected value when comparing storages.
        """
        self._any_map[StorageKeyValueTypeAdapter.validate_python(key)] = True

    def store_next(
        self,
        value: StorageKeyValueTypeConvertible | StorageKeyValueType | bool,
        hint: str = "",
    ) -> StorageKeyValueType:
        """
        Store a value in the storage and return the key where the value is
        stored.

        Increments the key counter so the next time this function is called,
        the next key is used.
        """
        slot = StorageKeyValueTypeAdapter.validate_python(self._current_slot)
        self._current_slot += 1
        if hint:
            self._hint_map[slot] = hint
        self[slot] = StorageKeyValueTypeAdapter.validate_python(value)
        return slot

    def peek_slot(self) -> int:
        """Peek the next slot that will be used by `store_next`."""
        return self._current_slot

    def contains(self, other: "Storage") -> bool:
        """
        Return True if self contains all keys with equal value as contained by
        second storage. Used for comparison with test expected post state and
        alloc returned by the transition tool.
        """
        for key in other.keys():
            if key not in self:
                return False
            if self[key] != other[key]:
                return False
        return True

    def must_contain(self, address: Address, other: "Storage") -> None:
        """
        Succeeds only if self contains all keys with equal value as contained
        by second storage. Used for comparison with test expected post state
        and alloc returned by the transition tool. Raises detailed exception
        when a difference is found.
        """
        for key in other.keys():
            if key not in self:
                # storage[key]==0 is equal to missing storage
                if other[key] != 0:
                    raise Storage.MissingKeyError(key=key)
            elif self[key] != other[key]:
                raise Storage.KeyValueMismatchError(
                    address=address,
                    key=key,
                    want=self[key],
                    got=other[key],
                    hint=self._hint_map.get(key, ""),
                )

    def must_be_equal(self, address: Address, other: "Storage | None") -> None:
        """Succeed only if "self" is equal to "other" storage."""
        # Test keys contained in both storage objects
        if other is None:
            other = Storage({})
        for key in self.keys() & other.keys():
            if self[key] != other[key]:
                raise Storage.KeyValueMismatchError(
                    address=address,
                    key=key,
                    want=self[key],
                    got=other[key],
                    hint=self._hint_map.get(key, ""),
                )

        # Test keys contained in either one of the storage objects
        for key in self.keys() ^ other.keys():
            if key in self:
                if self[key] != 0:
                    raise Storage.KeyValueMismatchError(
                        address=address,
                        key=key,
                        want=self[key],
                        got=0,
                        hint=self._hint_map.get(key, ""),
                    )

            elif other[key] != 0:
                # Skip key verification if we allow this key to be ANY
                if self._any_map.get(key) is True:
                    continue
                raise Storage.KeyValueMismatchError(
                    address=address,
                    key=key,
                    want=0,
                    got=other[key],
                    hint=self._hint_map.get(key, ""),
                )

    def canary(self) -> "Storage":
        """
        Return a canary storage filled with non-zero values where the current
        storage expects zero values, to guarantee that the test overwrites the
        storage.
        """
        return Storage(
            {key: HashInt(0xBA5E) for key in self.keys() if self[key] == 0}
        )

StorageDictType = Dict[str | int | bytes | SupportsBytes, str | int | bytes | SupportsBytes] class-attribute

Dictionary type to be used when defining an input to initialize a storage.

InvalidTypeError dataclass

Bases: Exception

Invalid type used when describing test's expected storage key or value.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
@dataclass(kw_only=True)
class InvalidTypeError(Exception):
    """
    Invalid type used when describing test's expected storage key or value.
    """

    key_or_value: Any

    def __init__(self, key_or_value: Any, *args: Any) -> None:
        """Initialize the exception with the invalid type."""
        super().__init__(args)
        self.key_or_value = key_or_value

    def __str__(self) -> str:
        """Print exception string."""
        return f"invalid type for key/value: {self.key_or_value}"

__init__(key_or_value, *args)

Initialize the exception with the invalid type.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
77
78
79
80
def __init__(self, key_or_value: Any, *args: Any) -> None:
    """Initialize the exception with the invalid type."""
    super().__init__(args)
    self.key_or_value = key_or_value

__str__()

Print exception string.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
82
83
84
def __str__(self) -> str:
    """Print exception string."""
    return f"invalid type for key/value: {self.key_or_value}"

InvalidValueError dataclass

Bases: Exception

Invalid value used when describing test's expected storage key or value.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
@dataclass(kw_only=True)
class InvalidValueError(Exception):
    """
    Invalid value used when describing test's expected storage key or
    value.
    """

    key_or_value: Any

    def __init__(self, key_or_value: Any, *args: Any) -> None:
        """Initialize the exception with the invalid value."""
        super().__init__(args)
        self.key_or_value = key_or_value

    def __str__(self) -> str:
        """Print exception string."""
        return f"invalid value for key/value: {self.key_or_value}"

__init__(key_or_value, *args)

Initialize the exception with the invalid value.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
95
96
97
98
def __init__(self, key_or_value: Any, *args: Any) -> None:
    """Initialize the exception with the invalid value."""
    super().__init__(args)
    self.key_or_value = key_or_value

__str__()

Print exception string.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
100
101
102
def __str__(self) -> str:
    """Print exception string."""
    return f"invalid value for key/value: {self.key_or_value}"

MissingKeyError dataclass

Bases: Exception

Test expected to find a storage key set but key was missing.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
104
105
106
107
108
109
110
111
112
113
114
115
116
117
@dataclass(kw_only=True)
class MissingKeyError(Exception):
    """Test expected to find a storage key set but key was missing."""

    key: int

    def __init__(self, key: int, *args: Any) -> None:
        """Initialize the exception with the missing key."""
        super().__init__(args)
        self.key = key

    def __str__(self) -> str:
        """Print exception string."""
        return "key {0} not found in storage".format(Hash(self.key))

__init__(key, *args)

Initialize the exception with the missing key.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
110
111
112
113
def __init__(self, key: int, *args: Any) -> None:
    """Initialize the exception with the missing key."""
    super().__init__(args)
    self.key = key

__str__()

Print exception string.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
115
116
117
def __str__(self) -> str:
    """Print exception string."""
    return "key {0} not found in storage".format(Hash(self.key))

KeyValueMismatchError dataclass

Bases: Exception

Test expected a certain value in a storage key but value found was different.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
@dataclass(kw_only=True)
class KeyValueMismatchError(Exception):
    """
    Test expected a certain value in a storage key but value found was
    different.
    """

    address: Address
    key: int
    want: int
    got: int
    hint: str

    def __init__(
        self,
        address: Address,
        key: int,
        want: int,
        got: int,
        hint: str = "",
        *args: Any,
    ) -> None:
        """
        Initialize the exception with the address, key, wanted and got
        values.
        """
        super().__init__(args)
        self.address = address
        self.key = key
        self.want = want
        self.got = got
        self.hint = hint

    def __str__(self) -> str:
        """Print exception string."""
        label_str = ""
        if self.address.label is not None:
            label_str = f" ({self.address.label})"
        hint_str = f" ({self.hint})" if self.hint else ""
        return (
            f"incorrect value in address {self.address}{label_str} for "
            + f"key {Hash(self.key)}{hint_str}:"
            + f" want {HexNumber(self.want)} (dec:{int(self.want)}),"
            + f" got {HexNumber(self.got)} (dec:{int(self.got)})"
        )

__init__(address, key, want, got, hint='', *args)

Initialize the exception with the address, key, wanted and got values.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
def __init__(
    self,
    address: Address,
    key: int,
    want: int,
    got: int,
    hint: str = "",
    *args: Any,
) -> None:
    """
    Initialize the exception with the address, key, wanted and got
    values.
    """
    super().__init__(args)
    self.address = address
    self.key = key
    self.want = want
    self.got = got
    self.hint = hint

__str__()

Print exception string.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
152
153
154
155
156
157
158
159
160
161
162
163
def __str__(self) -> str:
    """Print exception string."""
    label_str = ""
    if self.address.label is not None:
        label_str = f" ({self.address.label})"
    hint_str = f" ({self.hint})" if self.hint else ""
    return (
        f"incorrect value in address {self.address}{label_str} for "
        + f"key {Hash(self.key)}{hint_str}:"
        + f" want {HexNumber(self.want)} (dec:{int(self.want)}),"
        + f" got {HexNumber(self.got)} (dec:{int(self.got)})"
    )

__contains__(key)

Check for an item in the storage.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
165
166
167
168
169
def __contains__(
    self, key: StorageKeyValueTypeConvertible | StorageKeyValueType
) -> bool:
    """Check for an item in the storage."""
    return StorageKeyValueTypeAdapter.validate_python(key) in self.root

__getitem__(key)

Return an item from the storage.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
171
172
173
174
175
def __getitem__(
    self, key: StorageKeyValueTypeConvertible | StorageKeyValueType
) -> StorageKeyValueType:
    """Return an item from the storage."""
    return self.root[StorageKeyValueTypeAdapter.validate_python(key)]

__setitem__(key, value)

Set an item in the storage.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
177
178
179
180
181
182
183
184
185
def __setitem__(
    self,
    key: StorageKeyValueTypeConvertible | StorageKeyValueType,
    value: StorageKeyValueTypeConvertible | StorageKeyValueType,
) -> None:
    """Set an item in the storage."""
    self.root[StorageKeyValueTypeAdapter.validate_python(key)] = (
        StorageKeyValueTypeAdapter.validate_python(value)
    )

__delitem__(key)

Delete an item from the storage.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
187
188
189
190
191
def __delitem__(
    self, key: StorageKeyValueTypeConvertible | StorageKeyValueType
) -> None:
    """Delete an item from the storage."""
    del self.root[StorageKeyValueTypeAdapter.validate_python(key)]

__iter__()

Return an iterator over the storage.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
193
194
195
def __iter__(self) -> Iterator[StorageKeyValueType]:  # type: ignore [override]
    """Return an iterator over the storage."""
    return iter(self.root)

__eq__(other)

Return True if both storages are equal.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
197
198
199
200
201
def __eq__(self, other: object) -> bool:
    """Return True if both storages are equal."""
    if not isinstance(other, Storage):
        return False
    return self.root == other.root

__ne__(other)

Return True if both storages are not equal.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
203
204
205
206
207
def __ne__(self, other: object) -> bool:
    """Return True if both storages are not equal."""
    if not isinstance(other, Storage):
        return False
    return self.root != other.root

__bool__()

Return True if the storage is not empty.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
209
210
211
def __bool__(self) -> bool:
    """Return True if the storage is not empty."""
    return any(v for v in self.root.values())

__add__(other)

Return a new storage that is the sum of two storages.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
213
214
215
def __add__(self, other: "Storage") -> "Storage":
    """Return a new storage that is the sum of two storages."""
    return Storage({**self.root, **other.root})

__len__()

Return the number of keys that have been explicitly set in the storage.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
217
218
219
220
221
def __len__(self) -> int:
    """
    Return the number of keys that have been explicitly set in the storage.
    """
    return len(self.root)

keys()

Return the keys of the storage.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
223
224
225
def keys(self) -> set[StorageKeyValueType]:
    """Return the keys of the storage."""
    return set(self.root.keys())

set_next_slot(slot)

Set the next slot to be used by store_next.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
227
228
229
230
def set_next_slot(self, slot: int) -> "Storage":
    """Set the next slot to be used by `store_next`."""
    self._current_slot = slot
    return self

items()

Return the items of the storage.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
232
233
234
def items(self) -> ItemsView[StorageKeyValueType, StorageKeyValueType]:
    """Return the items of the storage."""
    return self.root.items()

set_expect_any(key)

Mark key to be able to have any expected value when comparing storages.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
236
237
238
239
240
241
242
def set_expect_any(
    self, key: StorageKeyValueTypeConvertible | StorageKeyValueType
) -> None:
    """
    Mark key to be able to have any expected value when comparing storages.
    """
    self._any_map[StorageKeyValueTypeAdapter.validate_python(key)] = True

store_next(value, hint='')

Store a value in the storage and return the key where the value is stored.

Increments the key counter so the next time this function is called, the next key is used.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
def store_next(
    self,
    value: StorageKeyValueTypeConvertible | StorageKeyValueType | bool,
    hint: str = "",
) -> StorageKeyValueType:
    """
    Store a value in the storage and return the key where the value is
    stored.

    Increments the key counter so the next time this function is called,
    the next key is used.
    """
    slot = StorageKeyValueTypeAdapter.validate_python(self._current_slot)
    self._current_slot += 1
    if hint:
        self._hint_map[slot] = hint
    self[slot] = StorageKeyValueTypeAdapter.validate_python(value)
    return slot

peek_slot()

Peek the next slot that will be used by store_next.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
263
264
265
def peek_slot(self) -> int:
    """Peek the next slot that will be used by `store_next`."""
    return self._current_slot

contains(other)

Return True if self contains all keys with equal value as contained by second storage. Used for comparison with test expected post state and alloc returned by the transition tool.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
267
268
269
270
271
272
273
274
275
276
277
278
def contains(self, other: "Storage") -> bool:
    """
    Return True if self contains all keys with equal value as contained by
    second storage. Used for comparison with test expected post state and
    alloc returned by the transition tool.
    """
    for key in other.keys():
        if key not in self:
            return False
        if self[key] != other[key]:
            return False
    return True

must_contain(address, other)

Succeeds only if self contains all keys with equal value as contained by second storage. Used for comparison with test expected post state and alloc returned by the transition tool. Raises detailed exception when a difference is found.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
def must_contain(self, address: Address, other: "Storage") -> None:
    """
    Succeeds only if self contains all keys with equal value as contained
    by second storage. Used for comparison with test expected post state
    and alloc returned by the transition tool. Raises detailed exception
    when a difference is found.
    """
    for key in other.keys():
        if key not in self:
            # storage[key]==0 is equal to missing storage
            if other[key] != 0:
                raise Storage.MissingKeyError(key=key)
        elif self[key] != other[key]:
            raise Storage.KeyValueMismatchError(
                address=address,
                key=key,
                want=self[key],
                got=other[key],
                hint=self._hint_map.get(key, ""),
            )

must_be_equal(address, other)

Succeed only if "self" is equal to "other" storage.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
def must_be_equal(self, address: Address, other: "Storage | None") -> None:
    """Succeed only if "self" is equal to "other" storage."""
    # Test keys contained in both storage objects
    if other is None:
        other = Storage({})
    for key in self.keys() & other.keys():
        if self[key] != other[key]:
            raise Storage.KeyValueMismatchError(
                address=address,
                key=key,
                want=self[key],
                got=other[key],
                hint=self._hint_map.get(key, ""),
            )

    # Test keys contained in either one of the storage objects
    for key in self.keys() ^ other.keys():
        if key in self:
            if self[key] != 0:
                raise Storage.KeyValueMismatchError(
                    address=address,
                    key=key,
                    want=self[key],
                    got=0,
                    hint=self._hint_map.get(key, ""),
                )

        elif other[key] != 0:
            # Skip key verification if we allow this key to be ANY
            if self._any_map.get(key) is True:
                continue
            raise Storage.KeyValueMismatchError(
                address=address,
                key=key,
                want=0,
                got=other[key],
                hint=self._hint_map.get(key, ""),
            )

canary()

Return a canary storage filled with non-zero values where the current storage expects zero values, to guarantee that the test overwrites the storage.

Source code in packages/testing/src/execution_testing/base_types/composite_types.py
340
341
342
343
344
345
346
347
348
def canary(self) -> "Storage":
    """
    Return a canary storage filled with non-zero values where the current
    storage expects zero values, to guarantee that the test overwrites the
    storage.
    """
    return Storage(
        {key: HashInt(0xBA5E) for key in self.keys() if self[key] == 0}
    )

to_bytes(input_bytes)

Convert multiple types into bytes.

Source code in packages/testing/src/execution_testing/base_types/conversions.py
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def to_bytes(input_bytes: BytesConvertible) -> bytes:
    """Convert multiple types into bytes."""
    if input_bytes is None:
        raise Exception("Cannot convert `None` input to bytes")

    if isinstance(input_bytes, str):
        # We can have a hex representation of bytes with spaces for readability
        if input_bytes.startswith("0x"):
            input_bytes = input_bytes[2:]
        if len(input_bytes) % 2 == 1:
            input_bytes = "0" + input_bytes
        return bytes.fromhex(input_bytes)

    return bytes(input_bytes)

to_hex(input_bytes)

Convert multiple types into a bytes hex string.

Source code in packages/testing/src/execution_testing/base_types/conversions.py
72
73
74
def to_hex(input_bytes: BytesConvertible) -> str:
    """Convert multiple types into a bytes hex string."""
    return "0x" + to_bytes(input_bytes).hex()

CamelModel

Bases: CopyValidateModel

A base model that converts field names to camel case when serializing.

For example, the field name current_timestamp in a Python model will be represented as currentTimestamp when it is serialized to json.

Source code in packages/testing/src/execution_testing/base_types/pydantic.py
45
46
47
48
49
50
51
52
53
54
55
56
57
58
class CamelModel(CopyValidateModel):
    """
    A base model that converts field names to camel case when serializing.

    For example, the field name `current_timestamp` in a Python model will be
    represented as `currentTimestamp` when it is serialized to json.
    """

    model_config = ConfigDict(
        alias_generator=to_camel,
        populate_by_name=True,
        validate_default=True,
        extra="forbid",
    )

EthereumTestBaseModel

Bases: BaseModel, ModelCustomizationsMixin

Base model for all models for Ethereum tests.

Source code in packages/testing/src/execution_testing/base_types/pydantic.py
14
15
16
17
class EthereumTestBaseModel(BaseModel, ModelCustomizationsMixin):
    """Base model for all models for Ethereum tests."""

    pass

EthereumTestRootModel

Bases: RootModel[RootModelRootType], ModelCustomizationsMixin

Base model for all models for Ethereum tests.

Source code in packages/testing/src/execution_testing/base_types/pydantic.py
20
21
22
23
24
25
class EthereumTestRootModel(
    RootModel[RootModelRootType], ModelCustomizationsMixin
):
    """Base model for all models for Ethereum tests."""

    root: Any

ReferenceSpec

Reference Specification Description Abstract Class.

Source code in packages/testing/src/execution_testing/base_types/reference_spec/reference_spec.py
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
class ReferenceSpec:
    """Reference Specification Description Abstract Class."""

    @abstractmethod
    def name(self) -> str:
        """Return the name of the spec."""
        pass

    @abstractmethod
    def has_known_version(self) -> bool:
        """
        Return true if the reference spec object is hard-coded with a latest
        known version.
        """
        pass

    @abstractmethod
    def known_version(self) -> str:
        """Return the latest known version in the reference."""
        pass

    @abstractmethod
    def api_url(self) -> str:
        """
        Return the URL required to poll the version from an API, if needed.
        """
        pass

    @abstractmethod
    def latest_version(self) -> str:
        """Return a digest that points to the latest version of the spec."""
        pass

    @abstractmethod
    def is_outdated(self) -> bool:
        """
        Check whether the reference specification has been updated since the
        test was last updated.
        """
        pass

    @abstractmethod
    def write_info(self, info: Dict[str, Dict[str, Any] | str]) -> None:
        """
        Write info about the reference specification used into the output
        fixture.
        """
        pass

    @staticmethod
    @abstractmethod
    def parseable_from_module(module_dict: Dict[str, Any]) -> bool:
        """
        Check whether the module's dict contains required reference spec
        information.
        """
        pass

    @staticmethod
    @abstractmethod
    def parse_from_module(
        module_dict: Dict[str, Any], github_token: Optional[str] = None
    ) -> "ReferenceSpec":
        """
        Parse the module's dict into a reference spec.

        Args:
            module_dict: Dictionary containing module information
            github_token: Optional GitHub token for API authentication

        """
        pass

name() abstractmethod

Return the name of the spec.

Source code in packages/testing/src/execution_testing/base_types/reference_spec/reference_spec.py
32
33
34
35
@abstractmethod
def name(self) -> str:
    """Return the name of the spec."""
    pass

has_known_version() abstractmethod

Return true if the reference spec object is hard-coded with a latest known version.

Source code in packages/testing/src/execution_testing/base_types/reference_spec/reference_spec.py
37
38
39
40
41
42
43
@abstractmethod
def has_known_version(self) -> bool:
    """
    Return true if the reference spec object is hard-coded with a latest
    known version.
    """
    pass

known_version() abstractmethod

Return the latest known version in the reference.

Source code in packages/testing/src/execution_testing/base_types/reference_spec/reference_spec.py
45
46
47
48
@abstractmethod
def known_version(self) -> str:
    """Return the latest known version in the reference."""
    pass

api_url() abstractmethod

Return the URL required to poll the version from an API, if needed.

Source code in packages/testing/src/execution_testing/base_types/reference_spec/reference_spec.py
50
51
52
53
54
55
@abstractmethod
def api_url(self) -> str:
    """
    Return the URL required to poll the version from an API, if needed.
    """
    pass

latest_version() abstractmethod

Return a digest that points to the latest version of the spec.

Source code in packages/testing/src/execution_testing/base_types/reference_spec/reference_spec.py
57
58
59
60
@abstractmethod
def latest_version(self) -> str:
    """Return a digest that points to the latest version of the spec."""
    pass

is_outdated() abstractmethod

Check whether the reference specification has been updated since the test was last updated.

Source code in packages/testing/src/execution_testing/base_types/reference_spec/reference_spec.py
62
63
64
65
66
67
68
@abstractmethod
def is_outdated(self) -> bool:
    """
    Check whether the reference specification has been updated since the
    test was last updated.
    """
    pass

write_info(info) abstractmethod

Write info about the reference specification used into the output fixture.

Source code in packages/testing/src/execution_testing/base_types/reference_spec/reference_spec.py
70
71
72
73
74
75
76
@abstractmethod
def write_info(self, info: Dict[str, Dict[str, Any] | str]) -> None:
    """
    Write info about the reference specification used into the output
    fixture.
    """
    pass

parseable_from_module(module_dict) abstractmethod staticmethod

Check whether the module's dict contains required reference spec information.

Source code in packages/testing/src/execution_testing/base_types/reference_spec/reference_spec.py
78
79
80
81
82
83
84
85
@staticmethod
@abstractmethod
def parseable_from_module(module_dict: Dict[str, Any]) -> bool:
    """
    Check whether the module's dict contains required reference spec
    information.
    """
    pass

parse_from_module(module_dict, github_token=None) abstractmethod staticmethod

Parse the module's dict into a reference spec.

Parameters:

Name Type Description Default
module_dict Dict[str, Any]

Dictionary containing module information

required
github_token Optional[str]

Optional GitHub token for API authentication

None
Source code in packages/testing/src/execution_testing/base_types/reference_spec/reference_spec.py
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
@staticmethod
@abstractmethod
def parse_from_module(
    module_dict: Dict[str, Any], github_token: Optional[str] = None
) -> "ReferenceSpec":
    """
    Parse the module's dict into a reference spec.

    Args:
        module_dict: Dictionary containing module information
        github_token: Optional GitHub token for API authentication

    """
    pass

RLPSerializable

Class that adds RLP serialization to another class.

Source code in packages/testing/src/execution_testing/base_types/serialization.py
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
class RLPSerializable:
    """Class that adds RLP serialization to another class."""

    rlp_override: Bytes | None = None

    signable: ClassVar[bool] = False
    rlp_fields: ClassVar[List[str]]
    rlp_signing_fields: ClassVar[List[str]]
    rlp_exclude_none: ClassVar[bool] = False

    def get_rlp_fields(self) -> List[str]:
        """
        Return an ordered list of field names to be included in RLP
        serialization.

        Function can be overridden to customize the logic to return the fields.

        By default, rlp_fields class variable is used.

        The list can be nested list up to one extra level to represent nested
        fields.
        """
        return self.rlp_fields

    def get_rlp_signing_fields(self) -> List[str]:
        """
        Return an ordered list of field names to be included in the RLP
        serialization of the object signature.

        Function can be overridden to customize the logic to return the fields.

        By default, rlp_signing_fields class variable is used.

        The list can be nested list up to one extra level to represent nested
        fields.
        """
        return self.rlp_signing_fields

    def get_rlp_prefix(self) -> bytes:
        """
        Return a prefix that has to be appended to the serialized object.

        By default, an empty string is returned.
        """
        return b""

    def get_rlp_signing_prefix(self) -> bytes:
        """
        Return a prefix that has to be appended to the serialized signing
        object.

        By default, an empty string is returned.
        """
        return b""

    def sign(self) -> None:
        """Sign the current object for further serialization."""
        raise NotImplementedError(
            f'Object "{self.__class__.__name__}" cannot be signed.'
        )

    def to_list_from_fields(self, fields: List[str]) -> List[Any]:
        """
        Return an RLP serializable list that can be passed to `eth_rlp.encode`.

        Can be for signing purposes or the entire object.
        """
        values_list: List[Any] = []
        for field in fields:
            assert isinstance(field, str), (
                f'Unable to rlp serialize field "{field}" '
                f'in object type "{self.__class__.__name__}"'
            )
            assert hasattr(self, field), (
                f'Unable to rlp serialize field "{field}" '
                f'in object type "{self.__class__.__name__}"'
            )
            try:
                value = getattr(self, field)
                if self.rlp_exclude_none and value is None:
                    continue
                values_list.append(to_serializable_element(value))
            except Exception as e:
                raise Exception(
                    f'Unable to rlp serialize field "{field}" '
                    f'in object type "{self.__class__.__name__}"'
                ) from e
        return values_list

    def to_list(self, signing: bool = False) -> List[Any]:
        """
        Return an RLP serializable list that can be passed to `eth_rlp.encode`.

        Can be for signing purposes or the entire object.
        """
        field_list: List[str]
        if signing:
            if not self.signable:
                raise Exception(
                    f'Object "{self.__class__.__name__}" '
                    "does not support signing"
                )
            field_list = self.get_rlp_signing_fields()
        else:
            if self.signable:
                # Automatically sign signable objects during full
                # serialization: Ensures nested objects have valid signatures
                # in the final RLP.
                self.sign()
            field_list = self.get_rlp_fields()

        return self.to_list_from_fields(field_list)

    def rlp_signing_bytes(self) -> Bytes:
        """Return the signing serialized envelope used for signing."""
        return Bytes(
            self.get_rlp_signing_prefix()
            + eth_rlp.encode(self.to_list(signing=True))
        )

    def rlp(self) -> Bytes:
        """Return the serialized object."""
        if self.rlp_override is not None:
            return self.rlp_override
        return Bytes(
            self.get_rlp_prefix() + eth_rlp.encode(self.to_list(signing=False))
        )

    @classmethod
    def list_root(cls, element_list: Sequence[Self]) -> bytes:
        """Return the root of a list of the given type."""
        t = HexaryTrie(db={})
        for i, e in enumerate(element_list):
            t.set(
                eth_rlp.encode(Uint(i)),
                e.rlp(),
            )
        return t.root_hash

get_rlp_fields()

Return an ordered list of field names to be included in RLP serialization.

Function can be overridden to customize the logic to return the fields.

By default, rlp_fields class variable is used.

The list can be nested list up to one extra level to represent nested fields.

Source code in packages/testing/src/execution_testing/base_types/serialization.py
39
40
41
42
43
44
45
46
47
48
49
50
51
def get_rlp_fields(self) -> List[str]:
    """
    Return an ordered list of field names to be included in RLP
    serialization.

    Function can be overridden to customize the logic to return the fields.

    By default, rlp_fields class variable is used.

    The list can be nested list up to one extra level to represent nested
    fields.
    """
    return self.rlp_fields

get_rlp_signing_fields()

Return an ordered list of field names to be included in the RLP serialization of the object signature.

Function can be overridden to customize the logic to return the fields.

By default, rlp_signing_fields class variable is used.

The list can be nested list up to one extra level to represent nested fields.

Source code in packages/testing/src/execution_testing/base_types/serialization.py
53
54
55
56
57
58
59
60
61
62
63
64
65
def get_rlp_signing_fields(self) -> List[str]:
    """
    Return an ordered list of field names to be included in the RLP
    serialization of the object signature.

    Function can be overridden to customize the logic to return the fields.

    By default, rlp_signing_fields class variable is used.

    The list can be nested list up to one extra level to represent nested
    fields.
    """
    return self.rlp_signing_fields

get_rlp_prefix()

Return a prefix that has to be appended to the serialized object.

By default, an empty string is returned.

Source code in packages/testing/src/execution_testing/base_types/serialization.py
67
68
69
70
71
72
73
def get_rlp_prefix(self) -> bytes:
    """
    Return a prefix that has to be appended to the serialized object.

    By default, an empty string is returned.
    """
    return b""

get_rlp_signing_prefix()

Return a prefix that has to be appended to the serialized signing object.

By default, an empty string is returned.

Source code in packages/testing/src/execution_testing/base_types/serialization.py
75
76
77
78
79
80
81
82
def get_rlp_signing_prefix(self) -> bytes:
    """
    Return a prefix that has to be appended to the serialized signing
    object.

    By default, an empty string is returned.
    """
    return b""

sign()

Sign the current object for further serialization.

Source code in packages/testing/src/execution_testing/base_types/serialization.py
84
85
86
87
88
def sign(self) -> None:
    """Sign the current object for further serialization."""
    raise NotImplementedError(
        f'Object "{self.__class__.__name__}" cannot be signed.'
    )

to_list_from_fields(fields)

Return an RLP serializable list that can be passed to eth_rlp.encode.

Can be for signing purposes or the entire object.

Source code in packages/testing/src/execution_testing/base_types/serialization.py
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
def to_list_from_fields(self, fields: List[str]) -> List[Any]:
    """
    Return an RLP serializable list that can be passed to `eth_rlp.encode`.

    Can be for signing purposes or the entire object.
    """
    values_list: List[Any] = []
    for field in fields:
        assert isinstance(field, str), (
            f'Unable to rlp serialize field "{field}" '
            f'in object type "{self.__class__.__name__}"'
        )
        assert hasattr(self, field), (
            f'Unable to rlp serialize field "{field}" '
            f'in object type "{self.__class__.__name__}"'
        )
        try:
            value = getattr(self, field)
            if self.rlp_exclude_none and value is None:
                continue
            values_list.append(to_serializable_element(value))
        except Exception as e:
            raise Exception(
                f'Unable to rlp serialize field "{field}" '
                f'in object type "{self.__class__.__name__}"'
            ) from e
    return values_list

to_list(signing=False)

Return an RLP serializable list that can be passed to eth_rlp.encode.

Can be for signing purposes or the entire object.

Source code in packages/testing/src/execution_testing/base_types/serialization.py
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
def to_list(self, signing: bool = False) -> List[Any]:
    """
    Return an RLP serializable list that can be passed to `eth_rlp.encode`.

    Can be for signing purposes or the entire object.
    """
    field_list: List[str]
    if signing:
        if not self.signable:
            raise Exception(
                f'Object "{self.__class__.__name__}" '
                "does not support signing"
            )
        field_list = self.get_rlp_signing_fields()
    else:
        if self.signable:
            # Automatically sign signable objects during full
            # serialization: Ensures nested objects have valid signatures
            # in the final RLP.
            self.sign()
        field_list = self.get_rlp_fields()

    return self.to_list_from_fields(field_list)

rlp_signing_bytes()

Return the signing serialized envelope used for signing.

Source code in packages/testing/src/execution_testing/base_types/serialization.py
142
143
144
145
146
147
def rlp_signing_bytes(self) -> Bytes:
    """Return the signing serialized envelope used for signing."""
    return Bytes(
        self.get_rlp_signing_prefix()
        + eth_rlp.encode(self.to_list(signing=True))
    )

rlp()

Return the serialized object.

Source code in packages/testing/src/execution_testing/base_types/serialization.py
149
150
151
152
153
154
155
def rlp(self) -> Bytes:
    """Return the serialized object."""
    if self.rlp_override is not None:
        return self.rlp_override
    return Bytes(
        self.get_rlp_prefix() + eth_rlp.encode(self.to_list(signing=False))
    )

list_root(element_list) classmethod

Return the root of a list of the given type.

Source code in packages/testing/src/execution_testing/base_types/serialization.py
157
158
159
160
161
162
163
164
165
166
@classmethod
def list_root(cls, element_list: Sequence[Self]) -> bytes:
    """Return the root of a list of the given type."""
    t = HexaryTrie(db={})
    for i, e in enumerate(element_list):
        t.set(
            eth_rlp.encode(Uint(i)),
            e.rlp(),
        )
    return t.root_hash

SignableRLPSerializable

Bases: RLPSerializable

Class that adds RLP serialization to another class with signing support.

Source code in packages/testing/src/execution_testing/base_types/serialization.py
169
170
171
172
173
174
175
176
177
178
179
180
class SignableRLPSerializable(RLPSerializable):
    """
    Class that adds RLP serialization to another class with signing support.
    """

    signable: ClassVar[bool] = True

    def sign(self) -> None:
        """Sign the current object for further serialization."""
        raise NotImplementedError(
            f'Object "{self.__class__.__name__}" needs to implement `sign`.'
        )

sign()

Sign the current object for further serialization.

Source code in packages/testing/src/execution_testing/base_types/serialization.py
176
177
178
179
180
def sign(self) -> None:
    """Sign the current object for further serialization."""
    raise NotImplementedError(
        f'Object "{self.__class__.__name__}" needs to implement `sign`.'
    )

unwrap_annotation(hint)

Recursively unwrap Annotated and Union types to find the actual type.

This function is useful for introspecting complex type annotations like: - Annotated[int, ...] -> int - int | None -> int - Annotated[int, ...] | None -> int

Parameters:

Name Type Description Default
hint Any

Type annotation to unwrap

required

Returns:

Type Description
Any

The unwrapped base type

Source code in packages/testing/src/execution_testing/base_types/typing_utils.py
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
def unwrap_annotation(hint: Any) -> Any:
    """
    Recursively unwrap Annotated and Union types to find the actual type.

    This function is useful for introspecting complex type annotations like:
    - `Annotated[int, ...]` -> `int`
    - `int | None` -> `int`
    - `Annotated[int, ...] | None` -> `int`

    Args:
        hint: Type annotation to unwrap

    Returns:
        The unwrapped base type

    """
    type_args = get_args(hint)
    if not type_args:
        # Base case: simple type with no parameters
        return hint

    # For Union types (including Optional), find the first non-None type
    for arg in type_args:
        if arg is not type(None):
            # Recursively unwrap (handles nested Annotated/Union)
            return unwrap_annotation(arg)

    # All args were None (shouldn't happen in practice)
    return hint