Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.

Commit 4ef015f

Browse files
committed
Preliminary check for test breaks
1 parent 8841a69 commit 4ef015f

File tree

3 files changed

+134
-56
lines changed

3 files changed

+134
-56
lines changed

eth/vm/computation.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,15 @@
1919
)
2020
from eth_utils import (
2121
encode_hex,
22+
int_to_big_endian,
2223
)
2324

2425
from eth.constants import (
26+
ANY,
27+
BYTES,
2528
GAS_MEMORY,
2629
GAS_MEMORY_QUADRATIC_DENOMINATOR,
30+
UINT256,
2731
)
2832
from eth.exceptions import (
2933
Halt,
@@ -319,7 +323,41 @@ def stack_pop(self, num_items: int=1, type_hint: str=None) -> Any:
319323
Raise `eth.exceptions.InsufficientStack` if there are not enough items on
320324
the stack.
321325
"""
322-
return self._stack.pop(num_items, type_hint)
326+
if num_items == 1:
327+
stack_item = self._stack.pop()
328+
if type_hint == UINT256 or type_hint == ANY:
329+
return stack_item
330+
elif type_hint == BYTES:
331+
return int_to_big_endian(stack_item)
332+
333+
else:
334+
popped_items = tuple(self._stack.pop_n(num_items))
335+
if type_hint == UINT256 or type_hint == ANY:
336+
return popped_items
337+
elif type_hint == BYTES:
338+
return tuple(int_to_big_endian(item) for item in popped_items)
339+
# for item in popped_items:
340+
# yield int_to_big_endian(item)
341+
342+
# elif num_items == 2:
343+
# stack_item1, stack_item2 = self._stack.pop2()
344+
# if type_hint == UINT256 or type_hint == ANY:
345+
# return stack_item1, stack_item2
346+
# elif type_hint == BYTES:
347+
# return (int_to_big_endian(stack_item1), int_to_big_endian(stack_item2))
348+
# elif num_items == 3:
349+
# stack_item1, stack_item2, stack_item3 = self._stack.pop3()
350+
# if type_hint == UINT256 or type_hint == ANY:
351+
# return stack_item1, stack_item2, stack_item3
352+
# elif type_hint == BYTES:
353+
# return (
354+
# int_to_big_endian(stack_item1),
355+
# int_to_big_endian(stack_item2),
356+
# int_to_big_endian(stack_item3),
357+
# )
358+
# else:
359+
# # TODO: Replace with suitable customized Exception
360+
# raise Exception("Cannot pop more than 3 elements from stack")
323361

324362
def stack_push(self, value: Union[int, bytes]) -> None:
325363
"""

eth/vm/stack.py

Lines changed: 68 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class Stack(object):
3030
logger = logging.getLogger('eth.vm.stack.Stack')
3131

3232
def __init__(self) -> None:
33-
self.values = [] # type: List[Union[int, bytes]]
33+
self.values = [] # type: List[int]
3434

3535
def __len__(self) -> int:
3636
return len(self.values)
@@ -44,47 +44,81 @@ def push(self, value: Union[int, bytes]) -> None:
4444

4545
validate_stack_item(value)
4646

47-
self.values.append(value)
47+
if isinstance(value, int):
48+
stack_value = value
49+
elif isinstance(value, bytes):
50+
stack_value = big_endian_to_int(value)
51+
else:
52+
raise Exception(
53+
"Stack supports only Int or Byte objects, got {} type object".format(type(value))
54+
)
4855

49-
def pop(self,
50-
num_items: int,
51-
type_hint: str) -> Union[int, bytes, Tuple[Union[int, bytes], ...]]:
52-
"""
53-
Pop an item off the stack.
56+
self.values.append(stack_value)
5457

55-
Note: This function is optimized for speed over readability.
56-
"""
58+
# def pop(self,
59+
# num_items: int,
60+
# type_hint: str) -> Union[int, bytes, Tuple[Union[int, bytes], ...]]:
61+
# """
62+
# Pop an item off the stack.
63+
#
64+
# Note: This function is optimized for speed over readability.
65+
# """
66+
# try:
67+
# if num_items == 1:
68+
# return next(self._pop(num_items, type_hint))
69+
# else:
70+
# return tuple(self._pop(num_items, type_hint))
71+
# except IndexError:
72+
# raise InsufficientStack("No stack items")
73+
#
74+
# def _pop(self, num_items: int, type_hint: str) -> Generator[Union[int, bytes], None, None]:
75+
# for _ in range(num_items):
76+
# if type_hint == constants.UINT256:
77+
# value = self.values.pop()
78+
# if isinstance(value, int):
79+
# yield value
80+
# else:
81+
# yield big_endian_to_int(value)
82+
# elif type_hint == constants.BYTES:
83+
# value = self.values.pop()
84+
# if isinstance(value, bytes):
85+
# yield value
86+
# else:
87+
# yield int_to_big_endian(value)
88+
# elif type_hint == constants.ANY:
89+
# yield self.values.pop()
90+
# else:
91+
# raise TypeError(
92+
# "Unknown type_hint: {0}. Must be one of {1}".format(
93+
# type_hint,
94+
# ", ".join((constants.UINT256, constants.BYTES)),
95+
# )
96+
# )
97+
98+
def pop(self) -> int:
5799
try:
58-
if num_items == 1:
59-
return next(self._pop(num_items, type_hint))
60-
else:
61-
return tuple(self._pop(num_items, type_hint))
100+
return self.values.pop()
62101
except IndexError:
63102
raise InsufficientStack("No stack items")
64103

65-
def _pop(self, num_items: int, type_hint: str) -> Generator[Union[int, bytes], None, None]:
104+
def pop_n(self, num_items: int) -> Tuple[int, ...]:
66105
for _ in range(num_items):
67-
if type_hint == constants.UINT256:
68-
value = self.values.pop()
69-
if isinstance(value, int):
70-
yield value
71-
else:
72-
yield big_endian_to_int(value)
73-
elif type_hint == constants.BYTES:
74-
value = self.values.pop()
75-
if isinstance(value, bytes):
76-
yield value
77-
else:
78-
yield int_to_big_endian(value)
79-
elif type_hint == constants.ANY:
106+
try:
80107
yield self.values.pop()
81-
else:
82-
raise TypeError(
83-
"Unknown type_hint: {0}. Must be one of {1}".format(
84-
type_hint,
85-
", ".join((constants.UINT256, constants.BYTES)),
86-
)
87-
)
108+
except IndexError:
109+
raise InsufficientStack("No stack items")
110+
111+
def pop2(self) -> Tuple[int, int]:
112+
try:
113+
return (self.values.pop(), self.values.pop())
114+
except IndexError:
115+
raise InsufficientStack("No stack items")
116+
117+
def pop3(self) -> Tuple[int, int, int]:
118+
try:
119+
return (self.values.pop(), self.values.pop(), self.values.pop())
120+
except IndexError:
121+
raise InsufficientStack("No stack items")
88122

89123
def swap(self, position: int) -> None:
90124
"""

tests/core/stack/test_stack.py

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import pytest
22

33
from eth_utils import (
4+
big_endian_to_int,
45
ValidationError,
56
)
67

@@ -39,7 +40,10 @@ def stack():
3940
def test_push_only_pushes_valid_stack_items(stack, value, is_valid):
4041
if is_valid:
4142
stack.push(value)
42-
assert stack.values == [value]
43+
if isinstance(value, int):
44+
assert stack.values == [value]
45+
else:
46+
assert stack.values == [big_endian_to_int(value)]
4347
else:
4448
with pytest.raises(ValidationError):
4549
stack.push(value)
@@ -67,30 +71,30 @@ def test_dup_does_not_allow_stack_to_exceed_1024_items(stack):
6771
(
6872
([1], UINT256),
6973
([1, 2, 3], UINT256),
70-
([b'1', b'10', b'101', b'1010'], BYTES)
74+
# ([b'1', b'10', b'101', b'1010'], BYTES)
7175
)
7276
)
7377
def test_pop_returns_latest_stack_item(stack, items, type_hint):
7478
for each in items:
7579
stack.push(each)
76-
assert stack.pop(num_items=1, type_hint=type_hint) == items[-1]
77-
78-
79-
@pytest.mark.parametrize(
80-
("value,type_hint,type,is_valid"),
81-
(
82-
(1, UINT256, int, True),
83-
(b'101', BYTES, bytes, True),
84-
(1, SECPK1_N, int, False)
85-
)
86-
)
87-
def test_pop_typecasts_correctly_based_off_type_hint(stack, value, type_hint, type, is_valid):
88-
stack.push(value)
89-
if is_valid:
90-
assert isinstance(stack.pop(num_items=1, type_hint=type_hint), type)
91-
else:
92-
with pytest.raises(TypeError):
93-
stack.pop(type_hint=type_hint)
80+
assert stack.pop() == items[-1]
81+
82+
83+
# @pytest.mark.parametrize(
84+
# ("value,type_hint,type,is_valid"),
85+
# (
86+
# (1, UINT256, int, True),
87+
# (b'101', BYTES, bytes, True),
88+
# (1, SECPK1_N, int, False)
89+
# )
90+
# )
91+
# def test_pop_typecasts_correctly_based_off_type_hint(stack, value, type_hint, type, is_valid):
92+
# stack.push(value)
93+
# if is_valid:
94+
# assert isinstance(stack.pop(num_items=1, type_hint=type_hint), type)
95+
# else:
96+
# with pytest.raises(TypeError):
97+
# stack.pop(type_hint=type_hint)
9498

9599

96100
def test_swap_operates_correctly(stack):
@@ -115,7 +119,9 @@ def test_dup_operates_correctly(stack):
115119

116120
def test_pop_raises_InsufficientStack_appropriately(stack):
117121
with pytest.raises(InsufficientStack):
118-
stack.pop(num_items=1, type_hint=UINT256)
122+
stack.pop()
123+
stack.pop_n(2)
124+
stack.pop_n(5)
119125

120126

121127
def test_swap_raises_InsufficientStack_appropriately(stack):

0 commit comments

Comments
 (0)