Skip to content

Commit 7a3510a

Browse files
committed
Add test_tx_revert_scenario_triples
Co-Authored-By: Claude claude-opus-4-6
1 parent d9b46fa commit 7a3510a

File tree

1 file changed

+88
-1
lines changed

1 file changed

+88
-1
lines changed

tests/monad_eight/staking_precompile/test_precompile_call.py

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1031,10 +1031,11 @@ def test_check_order(
10311031

10321032
def _pairwise_compatible(
10331033
scenarios: tuple[CallScenario, ...],
1034+
incompatible: set[frozenset[CallScenario]] = _INCOMPATIBLE_SCENARIOS,
10341035
) -> bool:
10351036
"""Check that no pair in the tuple is incompatible."""
10361037
return all(
1037-
frozenset({a, b}) not in _INCOMPATIBLE_SCENARIOS
1038+
frozenset({a, b}) not in incompatible
10381039
for i, a in enumerate(scenarios)
10391040
for b in scenarios[i + 1 :]
10401041
)
@@ -1325,6 +1326,92 @@ def test_tx_revert_scenario_pairs(
13251326
)
13261327

13271328

1329+
_TX_SCENARIO_TRIPLES = [
1330+
pytest.param(
1331+
s1,
1332+
s2,
1333+
s3,
1334+
id=f"{s1.name.lower()}__{s2.name.lower()}__{s3.name.lower()}",
1335+
)
1336+
for s1 in CallScenario
1337+
for s2 in CallScenario
1338+
for s3 in CallScenario
1339+
if CallScenario.SUCCESS not in {s1, s2, s3}
1340+
and CallScenario.NOT_CALL not in {s1, s2, s3}
1341+
and s1.check_priority < s2.check_priority < s3.check_priority
1342+
and _pairwise_compatible((s1, s2, s3), _TX_INCOMPATIBLE_SCENARIOS)
1343+
]
1344+
1345+
1346+
@pytest.mark.parametrize(
1347+
"func",
1348+
[pytest.param(f, id=f.name) for f in REPRESENTATIVE_FUNCTIONS],
1349+
)
1350+
@pytest.mark.parametrize("scenario1,scenario2,scenario3", _TX_SCENARIO_TRIPLES)
1351+
def test_tx_revert_scenario_triples(
1352+
state_test: StateTestFiller,
1353+
pre: Alloc,
1354+
fork: Fork,
1355+
func: FunctionInfo,
1356+
scenario1: CallScenario,
1357+
scenario2: CallScenario,
1358+
scenario3: CallScenario,
1359+
) -> None:
1360+
"""
1361+
Test when the precompile is called directly as transaction
1362+
`to` with 3 reasons to revert.
1363+
"""
1364+
normalized = {
1365+
_normalize(s, func) for s in (scenario1, scenario2, scenario3)
1366+
}
1367+
if not _pairwise_compatible(tuple(normalized), _TX_INCOMPATIBLE_SCENARIOS):
1368+
pytest.skip("normalized scenarios are incompatible")
1369+
1370+
gas_price = 10
1371+
1372+
calldata, value, to, gas_limit = _tx_params(
1373+
scenario1,
1374+
scenario2,
1375+
scenario3,
1376+
func=func,
1377+
pre=pre,
1378+
fork=fork,
1379+
)
1380+
gas_cost = gas_limit * gas_price
1381+
sender = pre.fund_eoa(gas_cost + value)
1382+
1383+
outcome1 = resolve_outcome(func, scenario1)
1384+
outcome2 = resolve_outcome(func, scenario2)
1385+
outcome3 = resolve_outcome(func, scenario3)
1386+
1387+
tx = Transaction(
1388+
gas_limit=gas_limit,
1389+
max_fee_per_gas=gas_price,
1390+
max_priority_fee_per_gas=gas_price,
1391+
to=to,
1392+
sender=sender,
1393+
data=calldata,
1394+
value=value,
1395+
expected_receipt=TransactionReceipt(
1396+
status=0x1
1397+
if outcome1.call_success
1398+
and outcome2.call_success
1399+
and outcome3.call_success
1400+
else 0x0
1401+
),
1402+
)
1403+
1404+
post: dict = {
1405+
sender: Account(balance=value),
1406+
}
1407+
1408+
state_test(
1409+
pre=pre,
1410+
post=post,
1411+
tx=tx,
1412+
)
1413+
1414+
13281415
@pytest.mark.parametrize(
13291416
"selector",
13301417
[

0 commit comments

Comments
 (0)