Skip to content

Commit b5b590c

Browse files
committed
chore(fw): raise an exception if an opcode recieves an invalid keyword argument
* Add kwargs validation in Opcode.__call__ method in opcode.py * Add test coverage in test_vm.py for validation behavior
1 parent 0c70094 commit b5b590c

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

docs/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Users can select any of the artifacts depending on their testing needs for their
2626
#### 🔀 Refactoring
2727

2828
- 🔀 Move `TransactionType` enum from test file to proper module location in `ethereum_test_types.transaction_types` for better code organization and reusability.
29+
- ✨ Opcode classes now validate keyword arguments and raise `ValueError` with clear error messages
2930

3031
#### `fill`
3132

src/ethereum_test_vm/opcode.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,16 @@ def __call__(
254254

255255
if self.kwargs is not None and len(kwargs) > 0:
256256
assert len(args) == 0, f"Cannot mix positional and keyword arguments {args} {kwargs}"
257+
258+
# Validate that all provided kwargs are valid
259+
invalid_kwargs = set(kwargs.keys()) - set(self.kwargs)
260+
if invalid_kwargs:
261+
raise ValueError(
262+
f"Invalid keyword argument(s) {list(invalid_kwargs)} for opcode "
263+
f"{self._name_}. Valid arguments are: {self.kwargs}"
264+
f"Valid arguments are: {self.kwargs}"
265+
)
266+
257267
for kw in self.kwargs:
258268
args.append(kwargs[kw] if kw in kwargs else self.kwargs_defaults.get(kw, 0))
259269

src/ethereum_test_vm/tests/test_vm.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,3 +431,30 @@ def test_bytecode_concatenation_with_bytes():
431431
assert code.max_stack_height == base.max_stack_height
432432
assert code.min_stack_height == base.min_stack_height
433433
assert code.terminating == base.terminating
434+
435+
436+
def test_opcode_kwargs_validation():
437+
"""Test that invalid keyword arguments raise ValueError."""
438+
# Test valid kwargs work
439+
Op.MSTORE(offset=0, value=1)
440+
Op.CALL(gas=1, address=2, value=3, args_offset=4, args_size=5, ret_offset=6, ret_size=7)
441+
442+
# Test invalid kwargs raise ValueError
443+
with pytest.raises(
444+
ValueError, match=r"Invalid keyword argument\(s\) \['offest'\] for opcode MSTORE"
445+
):
446+
Op.MSTORE(offest=0, value=1) # codespell:ignore offest
447+
448+
with pytest.raises(
449+
ValueError, match=r"Invalid keyword argument\(s\) \['wrong_arg'\] for opcode MSTORE"
450+
):
451+
Op.MSTORE(offset=0, value=1, wrong_arg=2)
452+
453+
with pytest.raises(
454+
ValueError, match=r"Invalid keyword argument\(s\) \['addres'\] for opcode CALL"
455+
):
456+
Op.CALL(gas=1, address=2, value=3, args_offset=4, args_size=5, ret_offset=6, ret_size=7)
457+
458+
# Test multiple invalid kwargs
459+
with pytest.raises(ValueError, match=r"Invalid keyword argument\(s\).*for opcode MSTORE"):
460+
Op.MSTORE(offest=0, valu=1, extra=2) # codespell:ignore offest,valu

0 commit comments

Comments
 (0)