Skip to content

Commit 97fb35c

Browse files
authored
chore: revert simulate based ARC56 error message handling logic (#204)
1 parent 4db24ba commit 97fb35c

File tree

5 files changed

+50
-103
lines changed

5 files changed

+50
-103
lines changed

src/algokit_utils/errors/logic_error.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121

2222
LOGIC_ERROR = (
23-
".*transaction (?P<transaction_id>[A-Z0-9]+): (logic eval error: )?(?P<message>.*). Details: .*pc=(?P<pc>[0-9]+).*"
23+
".*transaction (?P<transaction_id>[A-Z0-9]+): logic eval error: (?P<message>.*). Details: .*pc=(?P<pc>[0-9]+).*"
2424
)
2525

2626

src/algokit_utils/transactions/transaction_composer.py

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from algosdk.transaction import OnComplete, SuggestedParams
2222
from algosdk.v2client.algod import AlgodClient
2323
from algosdk.v2client.models.simulate_request import SimulateRequest
24-
from typing_extensions import Never, deprecated
24+
from typing_extensions import deprecated
2525

2626
from algokit_utils.applications.abi import ABIReturn, ABIValue
2727
from algokit_utils.applications.app_manager import AppManager
@@ -667,7 +667,7 @@ def _encode_lease(lease: str | bytes | None) -> bytes | None:
667667
raise TypeError(f"Unknown lease type received of {type(lease)}")
668668

669669

670-
def _get_group_execution_info(
670+
def _get_group_execution_info( # noqa: C901
671671
atc: AtomicTransactionComposer,
672672
algod: AlgodClient,
673673
populate_app_call_resources: bool | None = None,
@@ -682,7 +682,6 @@ def _get_group_execution_info(
682682
txn_groups=[],
683683
allow_unnamed_resources=True,
684684
allow_empty_signatures=True,
685-
exec_trace_config=algosdk.v2client.models.SimulateTraceConfig(enable=True),
686685
)
687686

688687
# Clone ATC with null signers
@@ -717,8 +716,16 @@ def _get_group_execution_info(
717716
group_response = result.simulate_response["txn-groups"][0]
718717

719718
if group_response.get("failure-message"):
720-
_handle_simulation_error(
721-
group_response, cover_app_call_inner_transaction_fees=cover_app_call_inner_transaction_fees
719+
msg = group_response["failure-message"]
720+
if cover_app_call_inner_transaction_fees and "fee too small" in msg:
721+
raise ValueError(
722+
"Fees were too small to resolve execution info via simulate. "
723+
"You may need to increase an app call transaction maxFee."
724+
)
725+
failed_at = group_response.get("failed-at", [0])[0]
726+
raise ValueError(
727+
f"Error resolving execution info via simulate in transaction {failed_at}: "
728+
f"{group_response['failure-message']}"
722729
)
723730

724731
# Build execution info
@@ -756,36 +763,6 @@ def _get_group_execution_info(
756763
)
757764

758765

759-
def _handle_simulation_error(
760-
group_response: dict[str, Any], *, cover_app_call_inner_transaction_fees: bool | None
761-
) -> Never:
762-
msg = group_response["failure-message"]
763-
if cover_app_call_inner_transaction_fees and "fee too small" in msg:
764-
raise ValueError(
765-
"Fees were too small to resolve execution info via simulate. "
766-
"You may need to increase an app call transaction maxFee."
767-
)
768-
failed_at = group_response.get("failed-at", [0])[0]
769-
details = ""
770-
if "logic eval error" not in msg:
771-
# extract last pc from trace so we can format an error that can be parsed into a LogicError
772-
try:
773-
trace = group_response["txn-results"][failed_at]["exec-trace"]
774-
except (KeyError, IndexError):
775-
pass
776-
else:
777-
try:
778-
program_trace = trace["approval-program-trace"]
779-
except KeyError:
780-
program_trace = trace["clear-program-trace"]
781-
pc = program_trace[-1]["pc"]
782-
details = f". Details: pc={pc}"
783-
raise ValueError(
784-
f"Error resolving execution info via simulate in transaction {failed_at}: "
785-
f"{group_response['failure-message']}{details}"
786-
)
787-
788-
789766
def _calculate_required_fee_delta(
790767
txn: transaction.Transaction, txn_result: dict[str, Any], *, per_byte_txn_fee: int, min_txn_fee: int
791768
) -> int:

tests/applications/test_app_client.py

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import pytest
99
from algosdk.atomic_transaction_composer import TransactionSigner, TransactionWithSigner
1010

11-
from algokit_utils import SendParams
1211
from algokit_utils._legacy_v2.application_specification import ApplicationSpecification
1312
from algokit_utils.algorand import AlgorandClient
1413
from algokit_utils.applications.abi import ABIType
@@ -168,15 +167,44 @@ def testing_app_puya_arc32_app_spec() -> ApplicationSpecification:
168167

169168

170169
@pytest.fixture
171-
def test_app_client_puya(
170+
def testing_app_puya_arc32_app_id(
172171
algorand: AlgorandClient, funded_account: SigningAccount, testing_app_puya_arc32_app_spec: ApplicationSpecification
172+
) -> int:
173+
global_schema = testing_app_puya_arc32_app_spec.global_state_schema
174+
local_schema = testing_app_puya_arc32_app_spec.local_state_schema
175+
176+
response = algorand.send.app_create(
177+
AppCreateParams(
178+
sender=funded_account.address,
179+
approval_program=testing_app_puya_arc32_app_spec.approval_program,
180+
clear_state_program=testing_app_puya_arc32_app_spec.clear_program,
181+
schema={
182+
"global_byte_slices": int(global_schema.num_byte_slices) if global_schema.num_byte_slices else 0,
183+
"global_ints": int(global_schema.num_uints) if global_schema.num_uints else 0,
184+
"local_byte_slices": int(local_schema.num_byte_slices) if local_schema.num_byte_slices else 0,
185+
"local_ints": int(local_schema.num_uints) if local_schema.num_uints else 0,
186+
},
187+
)
188+
)
189+
return response.app_id
190+
191+
192+
@pytest.fixture
193+
def test_app_client_puya(
194+
algorand: AlgorandClient,
195+
funded_account: SigningAccount,
196+
testing_app_puya_arc32_app_spec: ApplicationSpecification,
197+
testing_app_puya_arc32_app_id: int,
173198
) -> AppClient:
174-
factory = algorand.client.get_app_factory(
175-
app_spec=testing_app_puya_arc32_app_spec,
176-
default_sender=funded_account.address,
199+
return AppClient(
200+
AppClientParams(
201+
default_sender=funded_account.address,
202+
default_signer=funded_account.signer,
203+
app_id=testing_app_puya_arc32_app_id,
204+
algorand=algorand,
205+
app_spec=testing_app_puya_arc32_app_spec,
206+
)
177207
)
178-
app_client, _ = factory.send.bare.create()
179-
return app_client
180208

181209

182210
def test_clone_overriding_default_sender_and_inheriting_app_name(
@@ -681,29 +709,6 @@ def test_box_methods_with_arc4_returns_parametrized(
681709
assert abi_decoded_boxes[0].value == arg_value
682710

683711

684-
@pytest.mark.parametrize(
685-
"populate",
686-
[
687-
True,
688-
# False, # enable this test once rejected transactions contain pc information
689-
],
690-
)
691-
def test_txn_with_reject(test_app_client_puya: AppClient, *, populate: bool) -> None:
692-
with pytest.raises(LogicError, match="expect this txn to be rejected"):
693-
test_app_client_puya.send.call(
694-
AppClientMethodCallParams(method="rejected"), send_params=SendParams(populate_app_call_resources=populate)
695-
)
696-
697-
698-
@pytest.mark.parametrize("populate", [True, False])
699-
def test_txn_with_logic_err(test_app_client_puya: AppClient, *, populate: bool) -> None:
700-
with pytest.raises(LogicError, match="expect this to be a logic err") as exc:
701-
test_app_client_puya.send.call(
702-
AppClientMethodCallParams(method="logic_err"), send_params=SendParams(populate_app_call_resources=populate)
703-
)
704-
assert exc
705-
706-
707712
def test_abi_with_default_arg_method(
708713
algorand: AlgorandClient,
709714
funded_account: SigningAccount,

0 commit comments

Comments
 (0)