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 src/ethereum_test_base_types/base_types.py
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
class Address(FixedSizeBytes[20]):  # type: ignore
    """
    Class that helps represent Ethereum addresses in tests.
    """

    label: str | None = None

    def __new__(cls, input: "FixedSizeBytesConvertible | Address", *, label: str | None = None):
        """
        Creates a new Address object with an optional label.
        """
        instance = super(Address, cls).__new__(cls, input)
        if isinstance(input, Address) and label is None:
            instance.label = input.label
        else:
            instance.label = label
        return instance

__new__(input, *, label=None)

Creates a new Address object with an optional label.

Source code in src/ethereum_test_base_types/base_types.py
355
356
357
358
359
360
361
362
363
364
def __new__(cls, input: "FixedSizeBytesConvertible | Address", *, label: str | None = None):
    """
    Creates a new Address object with an optional label.
    """
    instance = super(Address, cls).__new__(cls, input)
    if isinstance(input, Address) and label is None:
        instance.label = input.label
    else:
        instance.label = label
    return instance

Bloom

Bases: FixedSizeBytes[256]

Class that helps represent blooms in tests.

Source code in src/ethereum_test_base_types/base_types.py
375
376
377
378
379
380
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 src/ethereum_test_base_types/base_types.py
391
392
393
394
395
396
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 src/ethereum_test_base_types/base_types.py
399
400
401
402
403
404
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 src/ethereum_test_base_types/base_types.py
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
class Bytes(bytes, ToStringSchema):
    """
    Class that helps represent bytes of variable length in tests.
    """

    def __new__(cls, input: BytesConvertible = b""):
        """
        Creates a new Bytes object.
        """
        if type(input) is cls:
            return input
        return super(Bytes, cls).__new__(cls, to_bytes(input))

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

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

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

    @classmethod
    def or_none(cls, input: "Bytes | BytesConvertible | None") -> "Bytes | None":
        """
        Converts the input to a Bytes while accepting None.
        """
        if input is None:
            return input
        return cls(input)

    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())

__new__(input=b'')

Creates a new Bytes object.

Source code in src/ethereum_test_base_types/base_types.py
166
167
168
169
170
171
172
def __new__(cls, input: BytesConvertible = b""):
    """
    Creates a new Bytes object.
    """
    if type(input) is cls:
        return input
    return super(Bytes, cls).__new__(cls, to_bytes(input))

__hash__()

Returns the hash of the bytes.

Source code in src/ethereum_test_base_types/base_types.py
174
175
176
177
178
def __hash__(self) -> int:
    """
    Returns the hash of the bytes.
    """
    return super(Bytes, self).__hash__()

__str__()

Returns the hexadecimal representation of the bytes.

Source code in src/ethereum_test_base_types/base_types.py
180
181
182
183
184
def __str__(self) -> str:
    """
    Returns the hexadecimal representation of the bytes.
    """
    return self.hex()

hex(*args, **kwargs)

Returns the hexadecimal representation of the bytes.

Source code in src/ethereum_test_base_types/base_types.py
186
187
188
189
190
def hex(self, *args, **kwargs) -> str:
    """
    Returns the hexadecimal representation of the bytes.
    """
    return "0x" + super().hex(*args, **kwargs)

or_none(input) classmethod

Converts the input to a Bytes while accepting None.

Source code in src/ethereum_test_base_types/base_types.py
192
193
194
195
196
197
198
199
@classmethod
def or_none(cls, input: "Bytes | BytesConvertible | None") -> "Bytes | None":
    """
    Converts the input to a Bytes while accepting None.
    """
    if input is None:
        return input
    return cls(input)

keccak256()

Return the keccak256 hash of the opcode byte representation.

Source code in src/ethereum_test_base_types/base_types.py
201
202
203
204
205
206
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 src/ethereum_test_base_types/base_types.py
208
209
210
211
212
def sha256(self) -> "Hash":
    """
    Return the sha256 hash of the opcode byte representation.
    """
    return Hash(sha256(self).digest())

FixedSizeBytes

Bases: Bytes

Class that helps represent bytes of fixed length in tests.

Source code in src/ethereum_test_base_types/base_types.py
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
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"]:
        """
        Creates 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: FixedSizeBytesConvertible | T):
        """
        Creates a new FixedSizeBytes object.
        """
        if type(input) is cls:
            return input
        return super(FixedSizeBytes, cls).__new__(cls, to_fixed_size_bytes(input, cls.byte_length))

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

    @classmethod
    def or_none(cls: Type[T], input: T | FixedSizeBytesConvertible | None) -> T | None:
        """
        Converts the input to a Fixed Size Bytes while accepting None.
        """
        if input is None:
            return input
        return cls(input)

    def __eq__(self, other: object) -> bool:
        """
        Compares 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:
        """
        Compares two FixedSizeBytes objects to be not equal.
        """
        return not self.__eq__(other)

__class_getitem__(length)

Creates a new FixedSizeBytes class with the given length.

Source code in src/ethereum_test_base_types/base_types.py
291
292
293
294
295
296
297
298
299
300
def __class_getitem__(cls, length: int) -> Type["FixedSizeBytes"]:
    """
    Creates a new FixedSizeBytes class with the given length.
    """

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

    Sized._sized_ = Sized
    return Sized

__new__(input)

Creates a new FixedSizeBytes object.

Source code in src/ethereum_test_base_types/base_types.py
302
303
304
305
306
307
308
def __new__(cls, input: FixedSizeBytesConvertible | T):
    """
    Creates a new FixedSizeBytes object.
    """
    if type(input) is cls:
        return input
    return super(FixedSizeBytes, cls).__new__(cls, to_fixed_size_bytes(input, cls.byte_length))

__hash__()

Returns the hash of the bytes.

Source code in src/ethereum_test_base_types/base_types.py
310
311
312
313
314
def __hash__(self) -> int:
    """
    Returns the hash of the bytes.
    """
    return super(FixedSizeBytes, self).__hash__()

or_none(input) classmethod

Converts the input to a Fixed Size Bytes while accepting None.

Source code in src/ethereum_test_base_types/base_types.py
316
317
318
319
320
321
322
323
@classmethod
def or_none(cls: Type[T], input: T | FixedSizeBytesConvertible | None) -> T | None:
    """
    Converts the input to a Fixed Size Bytes while accepting None.
    """
    if input is None:
        return input
    return cls(input)

__eq__(other)

Compares two FixedSizeBytes objects to be equal.

Source code in src/ethereum_test_base_types/base_types.py
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
def __eq__(self, other: object) -> bool:
    """
    Compares 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)

Compares two FixedSizeBytes objects to be not equal.

Source code in src/ethereum_test_base_types/base_types.py
341
342
343
344
345
def __ne__(self, other: object) -> bool:
    """
    Compares two FixedSizeBytes objects to be not equal.
    """
    return not self.__eq__(other)

Hash

Bases: FixedSizeBytes[32]

Class that helps represent hashes in tests.

Source code in src/ethereum_test_base_types/base_types.py
367
368
369
370
371
372
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 src/ethereum_test_base_types/base_types.py
272
273
274
275
276
277
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 src/ethereum_test_base_types/base_types.py
383
384
385
386
387
388
class HeaderNonce(FixedSizeBytes[8]):  # type: ignore
    """
    Class that helps represent the header nonce in tests.
    """

    pass

HexNumber

Bases: Number

Class that helps represent an hexadecimal numbers in tests.

Source code in src/ethereum_test_base_types/base_types.py
129
130
131
132
133
134
135
136
137
138
class HexNumber(Number):
    """
    Class that helps represent an hexadecimal numbers in tests.
    """

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

__str__()

Returns the string representation of the number.

Source code in src/ethereum_test_base_types/base_types.py
134
135
136
137
138
def __str__(self) -> str:
    """
    Returns the string representation of the number.
    """
    return self.hex()

Number

Bases: int, ToStringSchema

Class that helps represent numbers in tests.

Source code in src/ethereum_test_base_types/base_types.py
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
class Number(int, ToStringSchema):
    """
    Class that helps represent numbers in tests.
    """

    def __new__(cls, input: NumberConvertible | N):
        """
        Creates a new Number object.
        """
        return super(Number, cls).__new__(cls, to_number(input))

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

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

    @classmethod
    def or_none(cls: Type[N], input: N | NumberConvertible | None) -> N | None:
        """
        Converts the input to a Number while accepting None.
        """
        if input is None:
            return input
        return cls(input)

__new__(input)

Creates a new Number object.

Source code in src/ethereum_test_base_types/base_types.py
51
52
53
54
55
def __new__(cls, input: NumberConvertible | N):
    """
    Creates a new Number object.
    """
    return super(Number, cls).__new__(cls, to_number(input))

__str__()

Returns the string representation of the number.

Source code in src/ethereum_test_base_types/base_types.py
57
58
59
60
61
def __str__(self) -> str:
    """
    Returns the string representation of the number.
    """
    return str(int(self))

hex()

Returns the hexadecimal representation of the number.

Source code in src/ethereum_test_base_types/base_types.py
63
64
65
66
67
def hex(self) -> str:
    """
    Returns the hexadecimal representation of the number.
    """
    return hex(self)

or_none(input) classmethod

Converts the input to a Number while accepting None.

Source code in src/ethereum_test_base_types/base_types.py
69
70
71
72
73
74
75
76
@classmethod
def or_none(cls: Type[N], input: N | NumberConvertible | None) -> N | None:
    """
    Converts the input to a Number while accepting None.
    """
    if input is None:
        return input
    return cls(input)

Wei

Bases: Number

Class that helps represent wei that can be parsed from strings

Source code in src/ethereum_test_base_types/base_types.py
 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
class Wei(Number):
    """
    Class that helps represent wei that can be parsed from strings
    """

    def __new__(cls, input: NumberConvertible | N):
        """
        Creates a new Number object.
        """
        if isinstance(input, str):
            words = input.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 = float(value_str)
            return super(Number, cls).__new__(cls, value * multiplier)
        return super(Number, cls).__new__(cls, to_number(input))

    @staticmethod
    def _get_multiplier(unit: str) -> int:
        """
        Returns 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)

Creates a new Number object.

Source code in src/ethereum_test_base_types/base_types.py
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
def __new__(cls, input: NumberConvertible | N):
    """
    Creates a new Number object.
    """
    if isinstance(input, str):
        words = input.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 = float(value_str)
        return super(Number, cls).__new__(cls, value * multiplier)
    return super(Number, cls).__new__(cls, to_number(input))

ZeroPaddedHexNumber

Bases: HexNumber

Class that helps represent zero padded hexadecimal numbers in tests.

Source code in src/ethereum_test_base_types/base_types.py
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
class ZeroPaddedHexNumber(HexNumber):
    """
    Class that helps represent zero padded hexadecimal numbers in tests.
    """

    def hex(self) -> str:
        """
        Returns 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

hex()

Returns the hexadecimal representation of the number.

Source code in src/ethereum_test_base_types/base_types.py
146
147
148
149
150
151
152
153
154
155
def hex(self) -> str:
    """
    Returns 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

AccessList

Bases: CamelModel

Access List for transactions.

Source code in src/ethereum_test_base_types/composite_types.py
479
480
481
482
483
484
485
486
487
488
489
490
491
class AccessList(CamelModel):
    """
    Access List for transactions.
    """

    address: Address
    storage_keys: List[Hash]

    def to_list(self) -> List[Address | List[Hash]]:
        """
        Returns the access list as a list of serializable elements.
        """
        return [self.address, self.storage_keys]

to_list()

Returns the access list as a list of serializable elements.

Source code in src/ethereum_test_base_types/composite_types.py
487
488
489
490
491
def to_list(self) -> List[Address | List[Hash]]:
    """
    Returns the access list as a list of serializable elements.
    """
    return [self.address, self.storage_keys]

Account

Bases: CamelModel

State associated with an address.

Source code in src/ethereum_test_base_types/composite_types.py
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
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
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
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.
    """

    @dataclass(kw_only=True)
    class NonceMismatch(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):
            super().__init__(args)
            self.address = address
            self.want = want
            self.got = got

        def __str__(self):
            """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 BalanceMismatch(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):
            super().__init__(args)
            self.address = address
            self.want = want
            self.got = got

        def __str__(self):
            """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 CodeMismatch(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):
            super().__init__(args)
            self.address = address
            self.want = want
            self.got = got

        def __str__(self):
            """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}, got {self.got}"
            )

    def check_alloc(self: "Account", address: Address, account: "Account"):
        """
        Checks 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.NonceMismatch(
                    address=address,
                    want=self.nonce,
                    got=account.nonce,
                )

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

        if "code" in self.model_fields_set:
            if self.code != account.code:
                raise Account.CodeMismatch(
                    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:
        """
        Returns True on a non-empty account.
        """
        return any((self.nonce, self.balance, self.code, self.storage))

    @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 = 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 = ZeroPaddedHexNumber(0) class-attribute instance-attribute

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

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

Bytecode contained by the account.

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

Storage within a contract.

NONEXISTENT: None = None class-attribute

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

NonceMismatch dataclass

Bases: Exception

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

Source code in src/ethereum_test_base_types/composite_types.py
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
@dataclass(kw_only=True)
class NonceMismatch(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):
        super().__init__(args)
        self.address = address
        self.want = want
        self.got = got

    def __str__(self):
        """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}"
        )

__str__()

Print exception string

Source code in src/ethereum_test_base_types/composite_types.py
339
340
341
342
343
344
345
346
347
def __str__(self):
    """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}"
    )

BalanceMismatch dataclass

Bases: Exception

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

Source code in src/ethereum_test_base_types/composite_types.py
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
@dataclass(kw_only=True)
class BalanceMismatch(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):
        super().__init__(args)
        self.address = address
        self.want = want
        self.got = got

    def __str__(self):
        """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}"
        )

__str__()

Print exception string

Source code in src/ethereum_test_base_types/composite_types.py
366
367
368
369
370
371
372
373
374
def __str__(self):
    """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}"
    )

CodeMismatch dataclass

Bases: Exception

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

Source code in src/ethereum_test_base_types/composite_types.py
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
@dataclass(kw_only=True)
class CodeMismatch(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):
        super().__init__(args)
        self.address = address
        self.want = want
        self.got = got

    def __str__(self):
        """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}, got {self.got}"
        )

__str__()

Print exception string

Source code in src/ethereum_test_base_types/composite_types.py
393
394
395
396
397
398
399
400
401
def __str__(self):
    """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}, got {self.got}"
    )

check_alloc(address, account)

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

Source code in src/ethereum_test_base_types/composite_types.py
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
def check_alloc(self: "Account", address: Address, account: "Account"):
    """
    Checks 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.NonceMismatch(
                address=address,
                want=self.nonce,
                got=account.nonce,
            )

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

    if "code" in self.model_fields_set:
        if self.code != account.code:
            raise Account.CodeMismatch(
                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__()

Returns True on a non-empty account.

Source code in src/ethereum_test_base_types/composite_types.py
435
436
437
438
439
def __bool__(self: "Account") -> bool:
    """
    Returns True on a non-empty account.
    """
    return any((self.nonce, self.balance, self.code, self.storage))

with_code(code) classmethod

Create account with provided code and nonce of 1.

Source code in src/ethereum_test_base_types/composite_types.py
441
442
443
444
445
446
@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 src/ethereum_test_base_types/composite_types.py
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
@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 src/ethereum_test_base_types/composite_types.py
471
472
473
474
475
476
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)

Storage

Bases: EthereumTestRootModel[Dict[StorageKeyValueType, StorageKeyValueType]]

Definition of a storage in pre or post state of a test

Source code in src/ethereum_test_base_types/composite_types.py
 20
 21
 22
 23
 24
 25
 26
 27
 28
 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
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
class Storage(EthereumTestRootModel[Dict[StorageKeyValueType, StorageKeyValueType]]):
    """
    Definition of a storage in pre or post state of a test
    """

    root: Dict[StorageKeyValueType, StorageKeyValueType] = Field(default_factory=dict)

    _current_slot: int = PrivateAttr(0)
    _hint_map: Dict[StorageKeyValueType, str] = 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 InvalidType(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):
            super().__init__(args)
            self.key_or_value = key_or_value

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

    @dataclass(kw_only=True)
    class InvalidValue(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):
            super().__init__(args)
            self.key_or_value = key_or_value

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

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

        key: int

        def __init__(self, key: int, *args):
            super().__init__(args)
            self.key = key

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

    @dataclass(kw_only=True)
    class KeyValueMismatch(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):
            super().__init__(args)
            self.address = address
            self.key = key
            self.want = want
            self.got = got
            self.hint = hint

        def __str__(self):
            """Print exception string"""
            label_str = ""
            if self.address.label is not None:
                label_str = f" ({self.address.label})"
            return (
                f"incorrect value in address {self.address}{label_str} for "
                + f"key {Hash(self.key)}{f' ({self.hint})' if self.hint else ''}:"
                + 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:
        """Checks for an item in the storage"""
        return StorageKeyValueTypeAdapter.validate_python(key) in self.root

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

    def __setitem__(
        self,
        key: StorageKeyValueTypeConvertible | StorageKeyValueType,
        value: StorageKeyValueTypeConvertible | StorageKeyValueType,
    ):  # noqa: SC200
        """Sets an item in the storage"""
        self.root[
            StorageKeyValueTypeAdapter.validate_python(key)
        ] = StorageKeyValueTypeAdapter.validate_python(value)

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

    def __iter__(self):
        """Returns an iterator over the storage"""
        return iter(self.root)

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

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

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

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

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

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

    def items(self):
        """Returns the items of the storage"""
        return self.root.items()

    def store_next(
        self, value: StorageKeyValueTypeConvertible | StorageKeyValueType | bool, hint: str = ""
    ) -> StorageKeyValueType:
        """
        Stores a value in the storage and returns 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:
        """
        Peeks the next slot that will be used by `store_next`.
        """
        return self._current_slot

    def contains(self, other: "Storage") -> bool:
        """
        Returns 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"):
        """
        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.MissingKey(key=key)
            elif self[key] != other[key]:
                raise Storage.KeyValueMismatch(
                    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"):
        """
        Succeeds 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.KeyValueMismatch(
                    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.KeyValueMismatch(
                        address=address,
                        key=key,
                        want=self[key],
                        got=0,
                        hint=self._hint_map.get(key, ""),
                    )

            elif other[key] != 0:
                raise Storage.KeyValueMismatch(
                    address=address,
                    key=key,
                    want=0,
                    got=other[key],
                    hint=self._hint_map.get(key, ""),
                )

    def canary(self) -> "Storage":
        """
        Returns 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: TypeAlias = Dict[str | int | bytes | SupportsBytes, str | int | bytes | SupportsBytes] class-attribute

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

InvalidType dataclass

Bases: Exception

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

Source code in src/ethereum_test_base_types/composite_types.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
@dataclass(kw_only=True)
class InvalidType(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):
        super().__init__(args)
        self.key_or_value = key_or_value

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

__str__()

Print exception string

Source code in src/ethereum_test_base_types/composite_types.py
49
50
51
def __str__(self):
    """Print exception string"""
    return f"invalid type for key/value: {self.key_or_value}"

InvalidValue dataclass

Bases: Exception

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

Source code in src/ethereum_test_base_types/composite_types.py
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
@dataclass(kw_only=True)
class InvalidValue(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):
        super().__init__(args)
        self.key_or_value = key_or_value

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

__str__()

Print exception string

Source code in src/ethereum_test_base_types/composite_types.py
66
67
68
def __str__(self):
    """Print exception string"""
    return f"invalid value for key/value: {self.key_or_value}"

MissingKey dataclass

Bases: Exception

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

Source code in src/ethereum_test_base_types/composite_types.py
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
@dataclass(kw_only=True)
class MissingKey(Exception):
    """
    Test expected to find a storage key set but key was missing.
    """

    key: int

    def __init__(self, key: int, *args):
        super().__init__(args)
        self.key = key

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

__str__()

Print exception string

Source code in src/ethereum_test_base_types/composite_types.py
82
83
84
def __str__(self):
    """Print exception string"""
    return "key {0} not found in storage".format(Hash(self.key))

KeyValueMismatch dataclass

Bases: Exception

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

Source code in src/ethereum_test_base_types/composite_types.py
 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
@dataclass(kw_only=True)
class KeyValueMismatch(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):
        super().__init__(args)
        self.address = address
        self.key = key
        self.want = want
        self.got = got
        self.hint = hint

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

__str__()

Print exception string

Source code in src/ethereum_test_base_types/composite_types.py
107
108
109
110
111
112
113
114
115
116
117
def __str__(self):
    """Print exception string"""
    label_str = ""
    if self.address.label is not None:
        label_str = f" ({self.address.label})"
    return (
        f"incorrect value in address {self.address}{label_str} for "
        + f"key {Hash(self.key)}{f' ({self.hint})' if self.hint else ''}:"
        + f" want {HexNumber(self.want)} (dec:{int(self.want)}),"
        + f" got {HexNumber(self.got)} (dec:{int(self.got)})"
    )

__contains__(key)

Checks for an item in the storage

Source code in src/ethereum_test_base_types/composite_types.py
119
120
121
def __contains__(self, key: StorageKeyValueTypeConvertible | StorageKeyValueType) -> bool:
    """Checks for an item in the storage"""
    return StorageKeyValueTypeAdapter.validate_python(key) in self.root

__getitem__(key)

Returns an item from the storage

Source code in src/ethereum_test_base_types/composite_types.py
123
124
125
126
127
def __getitem__(
    self, key: StorageKeyValueTypeConvertible | StorageKeyValueType
) -> StorageKeyValueType:
    """Returns an item from the storage"""
    return self.root[StorageKeyValueTypeAdapter.validate_python(key)]

__setitem__(key, value)

Sets an item in the storage

Source code in src/ethereum_test_base_types/composite_types.py
129
130
131
132
133
134
135
136
137
def __setitem__(
    self,
    key: StorageKeyValueTypeConvertible | StorageKeyValueType,
    value: StorageKeyValueTypeConvertible | StorageKeyValueType,
):  # noqa: SC200
    """Sets an item in the storage"""
    self.root[
        StorageKeyValueTypeAdapter.validate_python(key)
    ] = StorageKeyValueTypeAdapter.validate_python(value)

__delitem__(key)

Deletes an item from the storage

Source code in src/ethereum_test_base_types/composite_types.py
139
140
141
def __delitem__(self, key: StorageKeyValueTypeConvertible | StorageKeyValueType):
    """Deletes an item from the storage"""
    del self.root[StorageKeyValueTypeAdapter.validate_python(key)]

__iter__()

Returns an iterator over the storage

Source code in src/ethereum_test_base_types/composite_types.py
143
144
145
def __iter__(self):
    """Returns an iterator over the storage"""
    return iter(self.root)

__eq__(other)

Returns True if both storages are equal.

Source code in src/ethereum_test_base_types/composite_types.py
147
148
149
150
151
152
153
def __eq__(self, other) -> bool:
    """
    Returns True if both storages are equal.
    """
    if not isinstance(other, Storage):
        return False
    return self.root == other.root

__ne__(other)

Returns True if both storages are not equal.

Source code in src/ethereum_test_base_types/composite_types.py
155
156
157
158
159
160
161
def __ne__(self, other) -> bool:
    """
    Returns True if both storages are not equal.
    """
    if not isinstance(other, Storage):
        return False
    return self.root != other.root

__bool__()

Returns True if the storage is not empty

Source code in src/ethereum_test_base_types/composite_types.py
163
164
165
def __bool__(self) -> bool:
    """Returns True if the storage is not empty"""
    return any(v for v in self.root.values())

__add__(other)

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

Source code in src/ethereum_test_base_types/composite_types.py
167
168
169
170
171
def __add__(self, other: "Storage") -> "Storage":
    """
    Returns a new storage that is the sum of two storages.
    """
    return Storage({**self.root, **other.root})

keys()

Returns the keys of the storage

Source code in src/ethereum_test_base_types/composite_types.py
173
174
175
def keys(self) -> set[StorageKeyValueType]:
    """Returns the keys of the storage"""
    return set(self.root.keys())

set_next_slot(slot)

Sets the next slot to be used by store_next.

Source code in src/ethereum_test_base_types/composite_types.py
177
178
179
180
181
182
def set_next_slot(self, slot: int) -> "Storage":
    """
    Sets the next slot to be used by `store_next`.
    """
    self._current_slot = slot
    return self

items()

Returns the items of the storage

Source code in src/ethereum_test_base_types/composite_types.py
184
185
186
def items(self):
    """Returns the items of the storage"""
    return self.root.items()

store_next(value, hint='')

Stores a value in the storage and returns 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 src/ethereum_test_base_types/composite_types.py
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
def store_next(
    self, value: StorageKeyValueTypeConvertible | StorageKeyValueType | bool, hint: str = ""
) -> StorageKeyValueType:
    """
    Stores a value in the storage and returns 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()

Peeks the next slot that will be used by store_next.

Source code in src/ethereum_test_base_types/composite_types.py
204
205
206
207
208
def peek_slot(self) -> int:
    """
    Peeks the next slot that will be used by `store_next`.
    """
    return self._current_slot

contains(other)

Returns 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 src/ethereum_test_base_types/composite_types.py
210
211
212
213
214
215
216
217
218
219
220
221
222
def contains(self, other: "Storage") -> bool:
    """
    Returns 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 src/ethereum_test_base_types/composite_types.py
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
def must_contain(self, address: Address, other: "Storage"):
    """
    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.MissingKey(key=key)
        elif self[key] != other[key]:
            raise Storage.KeyValueMismatch(
                address=address,
                key=key,
                want=self[key],
                got=other[key],
                hint=self._hint_map.get(key, ""),
            )

must_be_equal(address, other)

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

Source code in src/ethereum_test_base_types/composite_types.py
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
def must_be_equal(self, address: Address, other: "Storage | None"):
    """
    Succeeds 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.KeyValueMismatch(
                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.KeyValueMismatch(
                    address=address,
                    key=key,
                    want=self[key],
                    got=0,
                    hint=self._hint_map.get(key, ""),
                )

        elif other[key] != 0:
            raise Storage.KeyValueMismatch(
                address=address,
                key=key,
                want=0,
                got=other[key],
                hint=self._hint_map.get(key, ""),
            )

canary()

Returns 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 src/ethereum_test_base_types/composite_types.py
284
285
286
287
288
289
def canary(self) -> "Storage":
    """
    Returns 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)

Converts multiple types into bytes.

Source code in src/ethereum_test_base_types/conversions.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def to_bytes(input: BytesConvertible) -> bytes:
    """
    Converts multiple types into bytes.
    """
    if input is None:
        raise Exception("Cannot convert `None` input to bytes")

    if isinstance(input, SupportsBytes) or isinstance(input, bytes) or isinstance(input, list):
        return bytes(input)

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

    raise Exception("invalid type for `bytes`")

to_hex(input)

Converts multiple types into a bytes hex string.

Source code in src/ethereum_test_base_types/conversions.py
69
70
71
72
73
def to_hex(input: BytesConvertible) -> str:
    """
    Converts multiple types into a bytes hex string.
    """
    return "0x" + to_bytes(input).hex()

to_json(input)

Converts a model to its json data representation.

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

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 src/ethereum_test_base_types/pydantic.py
45
46
47
48
49
50
51
52
53
54
55
56
57
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,
    )

EthereumTestBaseModel

Bases: BaseModel, ModelCustomizationsMixin

Base model for all models for Ethereum tests.

Source code in src/ethereum_test_base_types/pydantic.py
17
18
19
20
21
22
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 src/ethereum_test_base_types/pydantic.py
25
26
27
28
29
30
class EthereumTestRootModel(RootModel[RootModelRootType], ModelCustomizationsMixin):
    """
    Base model for all models for Ethereum tests.
    """

    root: Any

ReferenceSpec

Reference Specification Description Abstract Class.

Source code in src/ethereum_test_base_types/reference_spec/reference_spec.py
 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
class ReferenceSpec:
    """
    Reference Specification Description Abstract Class.
    """

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

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

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

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

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

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

    @abstractmethod
    def write_info(self, info: Dict[str, str]):
        """
        Writes info about the reference specification used into the output
        fixture.
        """
        pass

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

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

name() abstractmethod

Returns the name of the spec.

Source code in src/ethereum_test_base_types/reference_spec/reference_spec.py
35
36
37
38
39
40
@abstractmethod
def name(self) -> str:
    """
    Returns the name of the spec.
    """
    pass

has_known_version() abstractmethod

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

Source code in src/ethereum_test_base_types/reference_spec/reference_spec.py
42
43
44
45
46
47
48
@abstractmethod
def has_known_version(self) -> bool:
    """
    Returns true if the reference spec object is hard-coded with a latest
    known version.
    """
    pass

known_version() abstractmethod

Returns the latest known version in the reference.

Source code in src/ethereum_test_base_types/reference_spec/reference_spec.py
50
51
52
53
54
55
@abstractmethod
def known_version(self) -> str:
    """
    Returns the latest known version in the reference.
    """
    pass

api_url() abstractmethod

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

Source code in src/ethereum_test_base_types/reference_spec/reference_spec.py
57
58
59
60
61
62
@abstractmethod
def api_url(self) -> str:
    """
    Returns the URL required to poll the version from an API, if needed.
    """
    pass

latest_version() abstractmethod

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

Source code in src/ethereum_test_base_types/reference_spec/reference_spec.py
64
65
66
67
68
69
@abstractmethod
def latest_version(self) -> str:
    """
    Returns a digest that points to the latest version of the spec.
    """
    pass

is_outdated() abstractmethod

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

Source code in src/ethereum_test_base_types/reference_spec/reference_spec.py
71
72
73
74
75
76
77
@abstractmethod
def is_outdated(self) -> bool:
    """
    Checks whether the reference specification has been updated since the
    test was last updated.
    """
    pass

write_info(info) abstractmethod

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

Source code in src/ethereum_test_base_types/reference_spec/reference_spec.py
79
80
81
82
83
84
85
@abstractmethod
def write_info(self, info: Dict[str, str]):
    """
    Writes info about the reference specification used into the output
    fixture.
    """
    pass

parseable_from_module(module_dict) abstractmethod staticmethod

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

Source code in src/ethereum_test_base_types/reference_spec/reference_spec.py
87
88
89
90
91
92
93
94
@staticmethod
@abstractmethod
def parseable_from_module(module_dict: Dict[str, Any]) -> bool:
    """
    Checks whether the module's dict contains required reference spec
    information.
    """
    pass

parse_from_module(module_dict) abstractmethod staticmethod

Parses the module's dict into a reference spec.

Source code in src/ethereum_test_base_types/reference_spec/reference_spec.py
 96
 97
 98
 99
100
101
102
@staticmethod
@abstractmethod
def parse_from_module(module_dict: Dict[str, Any]) -> "ReferenceSpec":
    """
    Parses the module's dict into a reference spec.
    """
    pass