Skip to content

Commit ea1a927

Browse files
feat(tests): extra stack operation test for CLZ opcode (#1821)
* feat(clz): add stack overflow test case * feat(clz): add push operation with same value test * refactor(clz): reduce test case * refactor(tests): optimize clz push operation
1 parent 5345c1a commit ea1a927

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

tests/osaka/eip7939_count_leading_zeros/test_count_leading_zeros.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,64 @@ def test_clz_stack_underflow(state_test: StateTestFiller, pre: Alloc):
202202
state_test(pre=pre, post=post, tx=tx)
203203

204204

205+
@pytest.mark.valid_from("Osaka")
206+
def test_clz_stack_not_overflow(state_test: StateTestFiller, pre: Alloc, fork: Fork):
207+
"""Test CLZ opcode never causes stack overflow."""
208+
max_stack_items = fork.max_stack_height()
209+
210+
code = Bytecode()
211+
post = {}
212+
213+
code += Op.PUSH0 * (max_stack_items - 2)
214+
215+
for i in range(256):
216+
code += Op.PUSH1(i) + Op.CLZ(1 << i) + Op.SWAP1 + Op.SSTORE
217+
218+
code_address = pre.deploy_contract(code=code)
219+
220+
post[code_address] = Account(storage={i: 255 - i for i in range(256)})
221+
222+
tx = Transaction(
223+
to=code_address,
224+
sender=pre.fund_eoa(),
225+
gas_limit=6_000_000,
226+
)
227+
228+
state_test(pre=pre, post=post, tx=tx)
229+
230+
231+
@pytest.mark.valid_from("Osaka")
232+
def test_clz_push_operation_same_value(state_test: StateTestFiller, pre: Alloc):
233+
"""Test CLZ opcode returns the same value via different push operations."""
234+
storage = {}
235+
236+
code = Op.SSTORE(0, Op.CLZ(Op.PUSH0))
237+
storage[0x00] = 256
238+
239+
for bit in range(1, 33): # PUSH value
240+
for push_n in range(bit, 33): # PUSHn opcode
241+
op = getattr(Op, f"PUSH{push_n}")
242+
key = 100 * bit + push_n
243+
code += Op.SSTORE(key, Op.CLZ(op[1 << bit]))
244+
storage[key] = 255 - bit
245+
246+
code_address = pre.deploy_contract(code=code)
247+
248+
tx = Transaction(
249+
to=code_address,
250+
sender=pre.fund_eoa(),
251+
gas_limit=12_000_000,
252+
)
253+
254+
post = {
255+
code_address: Account(
256+
storage=storage,
257+
)
258+
}
259+
260+
state_test(pre=pre, post=post, tx=tx)
261+
262+
205263
@pytest.mark.valid_at_transition_to("Osaka", subsequent_forks=True)
206264
def test_clz_fork_transition(blockchain_test: BlockchainTestFiller, pre: Alloc):
207265
"""Test CLZ opcode behavior at fork transition."""

0 commit comments

Comments
 (0)