Skip to content

Commit 9c4fe83

Browse files
committed
fix: extract pc from simulation trace for rejected transactions during simulation
1 parent 3283c7b commit 9c4fe83

File tree

2 files changed

+36
-13
lines changed

2 files changed

+36
-13
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: 35 additions & 12 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 deprecated
24+
from typing_extensions import Never, 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( # noqa: C901, PLR0912
670+
def _get_group_execution_info( # noqa: C901
671671
atc: AtomicTransactionComposer,
672672
algod: AlgodClient,
673673
populate_app_call_resources: bool | None = None,
@@ -682,6 +682,7 @@ def _get_group_execution_info( # noqa: C901, PLR0912
682682
txn_groups=[],
683683
allow_unnamed_resources=True,
684684
allow_empty_signatures=True,
685+
exec_trace_config=algosdk.v2client.models.SimulateTraceConfig(enable=True),
685686
)
686687

687688
# Clone ATC with null signers
@@ -720,16 +721,8 @@ def _get_group_execution_info( # noqa: C901, PLR0912
720721
group_response = result.simulate_response["txn-groups"][0]
721722

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

735728
# Build execution info
@@ -782,6 +775,36 @@ def calculate_inner_fee_delta(inner_txns: list[dict], acc: int = 0) -> int:
782775
)
783776

784777

778+
def _handle_simulation_error(
779+
group_response: dict[str, Any], *, cover_app_call_inner_transaction_fees: bool | None
780+
) -> Never:
781+
msg = group_response["failure-message"]
782+
if cover_app_call_inner_transaction_fees and "fee too small" in msg:
783+
raise ValueError(
784+
"Fees were too small to resolve execution info via simulate. "
785+
"You may need to increase an app call transaction maxFee."
786+
)
787+
failed_at = group_response.get("failed-at", [0])[0]
788+
details = ""
789+
if "logic eval error" not in msg:
790+
# extract last pc from trace so we can format an error that can be parsed into a LogicError
791+
try:
792+
trace = group_response["txn-results"][failed_at]["exec-trace"]
793+
except (KeyError, IndexError):
794+
pass
795+
else:
796+
try:
797+
program_trace = trace["approval-program-trace"]
798+
except KeyError:
799+
program_trace = trace["clear-program-trace"]
800+
pc = program_trace[-1]["pc"]
801+
details = f". Details: pc={pc}"
802+
raise ValueError(
803+
f"Error resolving execution info via simulate in transaction {failed_at}: "
804+
f"{group_response['failure-message']}{details}"
805+
)
806+
807+
785808
def _find_available_transaction_index(
786809
txns: list[TransactionWithSigner], reference_type: str, reference: str | dict[str, Any] | int
787810
) -> int:

0 commit comments

Comments
 (0)