From 4e1349178d70ece757161a4ff95fe9b3ff65412d Mon Sep 17 00:00:00 2001 From: Hang Su Date: Mon, 24 Apr 2023 14:51:05 -0400 Subject: [PATCH 01/22] allow for lift_log_limits in simulation request --- algosdk/v2client/models/simulate_request.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/algosdk/v2client/models/simulate_request.py b/algosdk/v2client/models/simulate_request.py index 51d7ed63..86a9d928 100644 --- a/algosdk/v2client/models/simulate_request.py +++ b/algosdk/v2client/models/simulate_request.py @@ -18,15 +18,21 @@ def dictify(self) -> Dict[str, Any]: class SimulateRequest(object): txn_groups: List[SimulateRequestTransactionGroup] + lift_lot_limits: bool def __init__( - self, *, txn_groups: List[SimulateRequestTransactionGroup] + self, + *, + txn_groups: List[SimulateRequestTransactionGroup], + lift_log_limits: bool = False, ) -> None: self.txn_groups = txn_groups + self.lift_lot_limits = lift_log_limits def dictify(self) -> Dict[str, Any]: return { "txn-groups": [ txn_group.dictify() for txn_group in self.txn_groups - ] + ], + "lift-log-limits": self.lift_lot_limits, } From 7f792ef59212c41fd07a5d1c4eccdc04ec0c0075 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Mon, 24 Apr 2023 14:51:45 -0400 Subject: [PATCH 02/22] allow for lift_log_limits in simulation request --- algosdk/v2client/models/simulate_request.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/algosdk/v2client/models/simulate_request.py b/algosdk/v2client/models/simulate_request.py index 86a9d928..9f9649c5 100644 --- a/algosdk/v2client/models/simulate_request.py +++ b/algosdk/v2client/models/simulate_request.py @@ -18,7 +18,7 @@ def dictify(self) -> Dict[str, Any]: class SimulateRequest(object): txn_groups: List[SimulateRequestTransactionGroup] - lift_lot_limits: bool + lift_log_limits: bool def __init__( self, @@ -27,12 +27,12 @@ def __init__( lift_log_limits: bool = False, ) -> None: self.txn_groups = txn_groups - self.lift_lot_limits = lift_log_limits + self.lift_log_limits = lift_log_limits def dictify(self) -> Dict[str, Any]: return { "txn-groups": [ txn_group.dictify() for txn_group in self.txn_groups ], - "lift-log-limits": self.lift_lot_limits, + "lift-log-limits": self.lift_log_limits, } From d04d2b4a2714c43d90c3d382f3eb130d1a4c8896 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Tue, 25 Apr 2023 15:25:04 -0400 Subject: [PATCH 03/22] muck up Simulate_with_request in ATC, need to change SimulateATCResponse --- algosdk/atomic_transaction_composer.py | 38 ++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/algosdk/atomic_transaction_composer.py b/algosdk/atomic_transaction_composer.py index 0ca9aaa3..dd053be0 100644 --- a/algosdk/atomic_transaction_composer.py +++ b/algosdk/atomic_transaction_composer.py @@ -17,6 +17,7 @@ from algosdk.transaction import GenericSignedTransaction from algosdk.abi.address_type import AddressType from algosdk.v2client import algod +from algosdk.v2client.models import models # The first four bytes of an ABI method call return must have this hash ABI_RETURN_HASH = b"\x15\x1f\x7c\x75" @@ -716,6 +717,9 @@ def simulate( simulation_result = cast( Dict[str, Any], client.simulate_raw_transactions(self.signed_txns) ) + return self.__report_simulation_response(simulation_result) + + def __report_simulation_response(self, simulation_result: Dict[str, Any]): # Only take the first group in the simulate response txn_group: Dict[str, Any] = simulation_result["txn-groups"][0] @@ -768,6 +772,40 @@ def simulate( results=sim_results, ) + def simulate_with_request( + self, + client: algod.AlgodClient, + request: models.SimulateRequest = models.SimulateRequest(), + ): + current_simulation_request = request + + if ( + self.status < AtomicTransactionComposerStatus.BUILT + or self.status > AtomicTransactionComposerStatus.SUBMITTED + ): + raise error.AtomicTransactionComposerError( + "AtomicTransactionComposerStatus must be in range [BUILT, SUBMITTED] " + "to simulate a group" + ) + elif self.status == AtomicTransactionComposerStatus.BUILT: + unsigned_txn: List[transaction.GenericSignedTransaction] = [ + transaction.SignedTransaction(txn_with_signer.txn, "") + for txn_with_signer in self.txn_list + ] + current_simulation_request.txn_groups = [ + models.SimulateRequestTransactionGroup(txns=unsigned_txn) + ] + else: + current_simulation_request.txn_groups = [ + models.SimulateRequestTransactionGroup(txns=self.signed_txns) + ] + + simulation_result = cast( + Dict[str, Any], + client.simulate_transactions(current_simulation_request), + ) + return self.__report_simulation_response(simulation_result) + def execute( self, client: algod.AlgodClient, wait_rounds: int ) -> AtomicTransactionResponse: From f67ff3295f9956925cb96ec52f189ab81794be81 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Tue, 25 Apr 2023 15:50:34 -0400 Subject: [PATCH 04/22] muck up changes for SimulateATCResponse --- algosdk/atomic_transaction_composer.py | 39 ++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/algosdk/atomic_transaction_composer.py b/algosdk/atomic_transaction_composer.py index dd053be0..31c281bf 100644 --- a/algosdk/atomic_transaction_composer.py +++ b/algosdk/atomic_transaction_composer.py @@ -17,7 +17,7 @@ from algosdk.transaction import GenericSignedTransaction from algosdk.abi.address_type import AddressType from algosdk.v2client import algod -from algosdk.v2client.models import models +from algosdk.v2client import models # The first four bytes of an ABI method call return must have this hash ABI_RETURN_HASH = b"\x15\x1f\x7c\x75" @@ -267,6 +267,34 @@ def __init__( self.missing_signature = missing_signature +class SimulateEvalOverrides: + def __init__( + self, + *, + max_log_calls: Optional[int] = None, + max_log_size: Optional[int] = None, + ) -> None: + self.max_log_calls = max_log_calls + self.max_log_size = max_log_size + + @staticmethod + def from_simulation_result( + simulation_result: Dict[str, Any] + ) -> Optional["SimulateEvalOverrides"]: + if "eval-overrides" not in simulation_result: + return None + + eval_override_dict = simulation_result.get("eval-overrides", dict()) + eval_override = SimulateEvalOverrides() + + if "max-log-calls" in eval_override_dict: + eval_override.max_log_calls = eval_override_dict["max-log-calls"] + if "max-log-size" in eval_override_dict: + eval_override.max_log_size = eval_override_dict["max-log-size"] + + return eval_override + + class SimulateAtomicTransactionResponse: def __init__( self, @@ -277,6 +305,7 @@ def __init__( simulate_response: Dict[str, Any], tx_ids: List[str], results: List[SimulateABIResult], + eval_overrides: Optional[SimulateEvalOverrides], ) -> None: self.version = version self.would_succeed = would_succeed @@ -285,6 +314,7 @@ def __init__( self.simulate_response = simulate_response self.tx_ids = tx_ids self.abi_results = results + self.eval_overrides = eval_overrides class AtomicTransactionComposer: @@ -770,12 +800,17 @@ def __report_simulation_response(self, simulation_result: Dict[str, Any]): simulate_response=simulation_result, tx_ids=self.tx_ids, results=sim_results, + eval_overrides=SimulateEvalOverrides.from_simulation_result( + simulation_result + ), ) def simulate_with_request( self, client: algod.AlgodClient, - request: models.SimulateRequest = models.SimulateRequest(), + request: models.SimulateRequest = models.SimulateRequest( + txn_groups=list() + ), ): current_simulation_request = request From 2ce9a0e126180d8a25b80295e80330b128525aa1 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Wed, 26 Apr 2023 14:31:30 -0400 Subject: [PATCH 05/22] minor, change branch of testing, one first step for making simulate request --- .test-env | 2 +- algosdk/atomic_transaction_composer.py | 2 +- tests/integration.tags | 1 + tests/steps/other_v2_steps.py | 6 ++++++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.test-env b/.test-env index df783a4f..c8732a95 100644 --- a/.test-env +++ b/.test-env @@ -1,6 +1,6 @@ # Configs for testing repo download: SDK_TESTING_URL="https://github.com/algorand/algorand-sdk-testing" -SDK_TESTING_BRANCH="master" +SDK_TESTING_BRANCH="simulate-request-log-option" SDK_TESTING_HARNESS="test-harness" INSTALL_ONLY=0 diff --git a/algosdk/atomic_transaction_composer.py b/algosdk/atomic_transaction_composer.py index 31c281bf..0545437e 100644 --- a/algosdk/atomic_transaction_composer.py +++ b/algosdk/atomic_transaction_composer.py @@ -305,7 +305,7 @@ def __init__( simulate_response: Dict[str, Any], tx_ids: List[str], results: List[SimulateABIResult], - eval_overrides: Optional[SimulateEvalOverrides], + eval_overrides: Optional[SimulateEvalOverrides] = None, ) -> None: self.version = version self.would_succeed = would_succeed diff --git a/tests/integration.tags b/tests/integration.tags index 479c9b62..d2c62ff4 100644 --- a/tests/integration.tags +++ b/tests/integration.tags @@ -15,3 +15,4 @@ @send @send.keyregtxn @simulate +@simulate.lift_log_limits diff --git a/tests/steps/other_v2_steps.py b/tests/steps/other_v2_steps.py index 63d42b09..06f1c3c8 100644 --- a/tests/steps/other_v2_steps.py +++ b/tests/steps/other_v2_steps.py @@ -31,6 +31,7 @@ ApplicationLocalState, DryrunRequest, DryrunSource, + SimulateRequest, ) from tests.steps.steps import algod_port, indexer_port from tests.steps.steps import token as daemon_token @@ -1474,6 +1475,11 @@ def simulate_atc_failure(context, group, path, message): assert message in resp.failure_message +@when("I make a new simulate request") +def make_simulate_request(context): + context.simulate_request = SimulateRequest(txn_groups=[]) + + @when("I prepare the transaction without signatures for simulation") def step_impl(context): context.stx = transaction.SignedTransaction(context.txn, None) From 99393a37d5adccc80d5f65989e1c78645b9c3911 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Wed, 26 Apr 2023 14:55:50 -0400 Subject: [PATCH 06/22] steps --- tests/steps/other_v2_steps.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/steps/other_v2_steps.py b/tests/steps/other_v2_steps.py index 06f1c3c8..e7cf6b8f 100644 --- a/tests/steps/other_v2_steps.py +++ b/tests/steps/other_v2_steps.py @@ -1475,11 +1475,23 @@ def simulate_atc_failure(context, group, path, message): assert message in resp.failure_message -@when("I make a new simulate request") +@when("I make a new simulate request.") def make_simulate_request(context): context.simulate_request = SimulateRequest(txn_groups=[]) +@then("I lift log limits on that simulate request.") +def lift_log_limits_in_request(context): + context.simulate_request.lift_log_limits = True + + +@then( + "I attach the simulate request to the transaction group to be simulated." +) +def attach_sim_request_to_txn_group_simulation(context): + pass + + @when("I prepare the transaction without signatures for simulation") def step_impl(context): context.stx = transaction.SignedTransaction(context.txn, None) From a8b11e837821382e2403387248bf1c9261630801 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Wed, 26 Apr 2023 15:47:28 -0400 Subject: [PATCH 07/22] should be good --- tests/steps/other_v2_steps.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/steps/other_v2_steps.py b/tests/steps/other_v2_steps.py index e7cf6b8f..c1dbd774 100644 --- a/tests/steps/other_v2_steps.py +++ b/tests/steps/other_v2_steps.py @@ -1485,11 +1485,13 @@ def lift_log_limits_in_request(context): context.simulate_request.lift_log_limits = True -@then( - "I attach the simulate request to the transaction group to be simulated." -) +@then("I attach the simulate request to simulate the transaction group.") def attach_sim_request_to_txn_group_simulation(context): - pass + context.simulate_response = ( + context.atomic_transaction_composer.simulate_with_request( + context.app_acl, context.simulate_request + ) + ) @when("I prepare the transaction without signatures for simulation") From 00e5bbc744160ef72246a1a3d0e1a06188192d20 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Wed, 26 Apr 2023 17:01:03 -0400 Subject: [PATCH 08/22] power pack checking --- tests/steps/other_v2_steps.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/steps/other_v2_steps.py b/tests/steps/other_v2_steps.py index c1dbd774..13b17655 100644 --- a/tests/steps/other_v2_steps.py +++ b/tests/steps/other_v2_steps.py @@ -1494,6 +1494,19 @@ def attach_sim_request_to_txn_group_simulation(context): ) +@then('the simulation with "{power}" should not have failure message.') +def power_pack_simulation_should_pass(context, power: str): + packs = power.split(",") + if len(packs) > 0: + assert context.simulate_response.eval_overrides + + if "allow-more-logging" in packs: + assert context.simulate_response.eval_overrides.max_log_calls + assert context.simulate_response.eval_overrides.max_log_size + + assert len(context.simulate_response.failure_message) == 0 + + @when("I prepare the transaction without signatures for simulation") def step_impl(context): context.stx = transaction.SignedTransaction(context.txn, None) From 2b9ec82c9f9eeed5281c6da1433f862a1f9f1786 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Wed, 26 Apr 2023 17:23:46 -0400 Subject: [PATCH 09/22] muck up some changes, missing sig todo --- algosdk/atomic_transaction_composer.py | 6 ------ algosdk/v2client/models/simulate_request.py | 2 +- tests/steps/other_v2_steps.py | 12 ++++++------ 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/algosdk/atomic_transaction_composer.py b/algosdk/atomic_transaction_composer.py index 0545437e..9a3937cb 100644 --- a/algosdk/atomic_transaction_composer.py +++ b/algosdk/atomic_transaction_composer.py @@ -256,7 +256,6 @@ def __init__( decode_error: Optional[Exception], tx_info: dict, method: abi.Method, - missing_signature: bool, ) -> None: self.tx_id = tx_id self.raw_value = raw_value @@ -264,7 +263,6 @@ def __init__( self.decode_error = decode_error self.tx_info = tx_info self.method = method - self.missing_signature = missing_signature class SimulateEvalOverrides: @@ -299,7 +297,6 @@ class SimulateAtomicTransactionResponse: def __init__( self, version: int, - would_succeed: bool, failure_message: str, failed_at: Optional[List[int]], simulate_response: Dict[str, Any], @@ -308,7 +305,6 @@ def __init__( eval_overrides: Optional[SimulateEvalOverrides] = None, ) -> None: self.version = version - self.would_succeed = would_succeed self.failure_message = failure_message self.failed_at = failed_at self.simulate_response = simulate_response @@ -788,13 +784,11 @@ def __report_simulation_response(self, simulation_result: Dict[str, Any]): decode_error=result.decode_error, tx_info=result.tx_info, method=result.method, - missing_signature=sim_txn.get("missing-signature", False), ) ) return SimulateAtomicTransactionResponse( version=simulation_result.get("version", 0), - would_succeed=simulation_result.get("would-succeed", False), failure_message=txn_group.get("failure-message", ""), failed_at=txn_group.get("failed-at"), simulate_response=simulation_result, diff --git a/algosdk/v2client/models/simulate_request.py b/algosdk/v2client/models/simulate_request.py index 9f9649c5..c83bf781 100644 --- a/algosdk/v2client/models/simulate_request.py +++ b/algosdk/v2client/models/simulate_request.py @@ -34,5 +34,5 @@ def dictify(self) -> Dict[str, Any]: "txn-groups": [ txn_group.dictify() for txn_group in self.txn_groups ], - "lift-log-limits": self.lift_log_limits, + "allow-more-logging": self.lift_log_limits, } diff --git a/tests/steps/other_v2_steps.py b/tests/steps/other_v2_steps.py index 13b17655..cab8a6e8 100644 --- a/tests/steps/other_v2_steps.py +++ b/tests/steps/other_v2_steps.py @@ -1442,9 +1442,12 @@ def simulate_transaction(context): @then("the simulation should succeed without any failure message") def simulate_transaction_succeed(context): if hasattr(context, "simulate_response"): - assert context.simulate_response["would-succeed"] is True + assert len(context.simulate_response["failure-message"]) == 0 else: - assert context.atomic_transaction_composer_return.would_succeed is True + assert ( + len(context.atomic_transaction_composer_return.failure_message) + == 0 + ) @then("I simulate the current transaction group with the composer") @@ -1470,7 +1473,6 @@ def simulate_atc_failure(context, group, path, message): ] ] ) - assert resp.would_succeed is False assert fail_path == path assert message in resp.failure_message @@ -1524,10 +1526,8 @@ def check_missing_signatures(context, group, path): group_idx: int = int(group) tx_idxs: list[int] = [int(pe) for pe in path.split(",")] - assert resp["would-succeed"] is False - for tx_idx in tx_idxs: missing_sig = resp["txn-groups"][group_idx]["txn-results"][tx_idx][ - "missing-signature" + "failure-message" ] assert missing_sig is True From d7748d5c475cea279a7fb546770f94ee5c1d7478 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Thu, 27 Apr 2023 11:49:54 -0400 Subject: [PATCH 10/22] check powerpacks for log lifting, update internal variable names --- algosdk/v2client/models/simulate_request.py | 8 ++++---- tests/steps/other_v2_steps.py | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/algosdk/v2client/models/simulate_request.py b/algosdk/v2client/models/simulate_request.py index c83bf781..e8e0f8e5 100644 --- a/algosdk/v2client/models/simulate_request.py +++ b/algosdk/v2client/models/simulate_request.py @@ -18,21 +18,21 @@ def dictify(self) -> Dict[str, Any]: class SimulateRequest(object): txn_groups: List[SimulateRequestTransactionGroup] - lift_log_limits: bool + allow_more_logs: bool def __init__( self, *, txn_groups: List[SimulateRequestTransactionGroup], - lift_log_limits: bool = False, + allow_more_logs: bool = False, ) -> None: self.txn_groups = txn_groups - self.lift_log_limits = lift_log_limits + self.allow_more_logs = allow_more_logs def dictify(self) -> Dict[str, Any]: return { "txn-groups": [ txn_group.dictify() for txn_group in self.txn_groups ], - "allow-more-logging": self.lift_log_limits, + "allow-more-logging": self.allow_more_logs, } diff --git a/tests/steps/other_v2_steps.py b/tests/steps/other_v2_steps.py index cab8a6e8..75fa35b2 100644 --- a/tests/steps/other_v2_steps.py +++ b/tests/steps/other_v2_steps.py @@ -1442,7 +1442,7 @@ def simulate_transaction(context): @then("the simulation should succeed without any failure message") def simulate_transaction_succeed(context): if hasattr(context, "simulate_response"): - assert len(context.simulate_response["failure-message"]) == 0 + assert len(context.simulate_response.failure_message) == 0 else: assert ( len(context.atomic_transaction_composer_return.failure_message) @@ -1482,9 +1482,9 @@ def make_simulate_request(context): context.simulate_request = SimulateRequest(txn_groups=[]) -@then("I lift log limits on that simulate request.") -def lift_log_limits_in_request(context): - context.simulate_request.lift_log_limits = True +@then("I allow more logs on that simulate request.") +def allow_more_logs_in_request(context): + context.simulate_request.allow_more_logs = True @then("I attach the simulate request to simulate the transaction group.") @@ -1496,18 +1496,18 @@ def attach_sim_request_to_txn_group_simulation(context): ) -@then('the simulation with "{power}" should not have failure message.') +@then('I check the simulation result has power packs "{power}".') def power_pack_simulation_should_pass(context, power: str): packs = power.split(",") - if len(packs) > 0: + if len(packs) == 0: + assert not context.simulate_response.eval_overrides + else: assert context.simulate_response.eval_overrides if "allow-more-logging" in packs: assert context.simulate_response.eval_overrides.max_log_calls assert context.simulate_response.eval_overrides.max_log_size - assert len(context.simulate_response.failure_message) == 0 - @when("I prepare the transaction without signatures for simulation") def step_impl(context): From daf34fd9127a86d9c3ececf442b8e43372a47312 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Thu, 27 Apr 2023 12:04:51 -0400 Subject: [PATCH 11/22] merge import, remove default arg for request --- algosdk/atomic_transaction_composer.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/algosdk/atomic_transaction_composer.py b/algosdk/atomic_transaction_composer.py index 9a3937cb..bbc2486f 100644 --- a/algosdk/atomic_transaction_composer.py +++ b/algosdk/atomic_transaction_composer.py @@ -16,8 +16,8 @@ from algosdk import abi, error, transaction from algosdk.transaction import GenericSignedTransaction from algosdk.abi.address_type import AddressType -from algosdk.v2client import algod -from algosdk.v2client import models +from algosdk.v2client import algod, models + # The first four bytes of an ABI method call return must have this hash ABI_RETURN_HASH = b"\x15\x1f\x7c\x75" @@ -802,9 +802,7 @@ def __report_simulation_response(self, simulation_result: Dict[str, Any]): def simulate_with_request( self, client: algod.AlgodClient, - request: models.SimulateRequest = models.SimulateRequest( - txn_groups=list() - ), + request: models.SimulateRequest, ): current_simulation_request = request From 1fc588c2f91d8a4cbf2a03927afbdd867d58d756 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Thu, 27 Apr 2023 12:15:02 -0400 Subject: [PATCH 12/22] move simulate_with_request to simulate, partly --- algosdk/atomic_transaction_composer.py | 15 +++++++++++++-- tests/steps/other_v2_steps.py | 6 ++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/algosdk/atomic_transaction_composer.py b/algosdk/atomic_transaction_composer.py index bbc2486f..59bbde5a 100644 --- a/algosdk/atomic_transaction_composer.py +++ b/algosdk/atomic_transaction_composer.py @@ -713,7 +713,9 @@ def submit(self, client: algod.AlgodClient) -> List[str]: return self.tx_ids def simulate( - self, client: algod.AlgodClient + self, + client: algod.AlgodClient, + request: Optional[models.SimulateRequest] = None, ) -> SimulateAtomicTransactionResponse: """ Send the transaction group to the `simulate` endpoint and wait for results. @@ -723,6 +725,7 @@ def simulate( Args: client (AlgodClient): Algod V2 client + request (models.SimulateReuqest): SimulateRequest with options in simulation. Returns: SimulateAtomicTransactionResponse: Object with simulation results for this @@ -740,8 +743,16 @@ def simulate( "lower to simulate a group" ) + current_simulation_request = ( + request if request else models.SimulateRequest(txn_groups=list()) + ) + current_simulation_request.txn_groups = [ + models.SimulateRequestTransactionGroup(txns=self.signed_txns) + ] + simulation_result = cast( - Dict[str, Any], client.simulate_raw_transactions(self.signed_txns) + Dict[str, Any], + client.simulate_transactions(current_simulation_request), ) return self.__report_simulation_response(simulation_result) diff --git a/tests/steps/other_v2_steps.py b/tests/steps/other_v2_steps.py index 75fa35b2..ce3ead49 100644 --- a/tests/steps/other_v2_steps.py +++ b/tests/steps/other_v2_steps.py @@ -1489,10 +1489,8 @@ def allow_more_logs_in_request(context): @then("I attach the simulate request to simulate the transaction group.") def attach_sim_request_to_txn_group_simulation(context): - context.simulate_response = ( - context.atomic_transaction_composer.simulate_with_request( - context.app_acl, context.simulate_request - ) + context.simulate_response = context.atomic_transaction_composer.simulate( + context.app_acl, context.simulate_request ) From 1a2c601beae2a79012101186cb4b347e3ffdc893 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Thu, 27 Apr 2023 12:21:22 -0400 Subject: [PATCH 13/22] make only one step for allow more logging --- tests/steps/other_v2_steps.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/tests/steps/other_v2_steps.py b/tests/steps/other_v2_steps.py index ce3ead49..99af3f1d 100644 --- a/tests/steps/other_v2_steps.py +++ b/tests/steps/other_v2_steps.py @@ -1494,17 +1494,10 @@ def attach_sim_request_to_txn_group_simulation(context): ) -@then('I check the simulation result has power packs "{power}".') -def power_pack_simulation_should_pass(context, power: str): - packs = power.split(",") - if len(packs) == 0: - assert not context.simulate_response.eval_overrides - else: - assert context.simulate_response.eval_overrides - - if "allow-more-logging" in packs: - assert context.simulate_response.eval_overrides.max_log_calls - assert context.simulate_response.eval_overrides.max_log_size +@then('I check the simulation result has power packs allow-more-logging.') +def power_pack_simulation_should_pass(context): + assert context.simulate_response.eval_overrides.max_log_calls + assert context.simulate_response.eval_overrides.max_log_size @when("I prepare the transaction without signatures for simulation") From acdad32faf659625c2f6580f1c879a3a18535bb9 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Thu, 27 Apr 2023 12:25:56 -0400 Subject: [PATCH 14/22] move simulate_with_request to simulate --- algosdk/atomic_transaction_composer.py | 36 -------------------------- tests/steps/other_v2_steps.py | 8 +++--- 2 files changed, 5 insertions(+), 39 deletions(-) diff --git a/algosdk/atomic_transaction_composer.py b/algosdk/atomic_transaction_composer.py index 59bbde5a..6aa986b7 100644 --- a/algosdk/atomic_transaction_composer.py +++ b/algosdk/atomic_transaction_composer.py @@ -754,9 +754,7 @@ def simulate( Dict[str, Any], client.simulate_transactions(current_simulation_request), ) - return self.__report_simulation_response(simulation_result) - def __report_simulation_response(self, simulation_result: Dict[str, Any]): # Only take the first group in the simulate response txn_group: Dict[str, Any] = simulation_result["txn-groups"][0] @@ -810,40 +808,6 @@ def __report_simulation_response(self, simulation_result: Dict[str, Any]): ), ) - def simulate_with_request( - self, - client: algod.AlgodClient, - request: models.SimulateRequest, - ): - current_simulation_request = request - - if ( - self.status < AtomicTransactionComposerStatus.BUILT - or self.status > AtomicTransactionComposerStatus.SUBMITTED - ): - raise error.AtomicTransactionComposerError( - "AtomicTransactionComposerStatus must be in range [BUILT, SUBMITTED] " - "to simulate a group" - ) - elif self.status == AtomicTransactionComposerStatus.BUILT: - unsigned_txn: List[transaction.GenericSignedTransaction] = [ - transaction.SignedTransaction(txn_with_signer.txn, "") - for txn_with_signer in self.txn_list - ] - current_simulation_request.txn_groups = [ - models.SimulateRequestTransactionGroup(txns=unsigned_txn) - ] - else: - current_simulation_request.txn_groups = [ - models.SimulateRequestTransactionGroup(txns=self.signed_txns) - ] - - simulation_result = cast( - Dict[str, Any], - client.simulate_transactions(current_simulation_request), - ) - return self.__report_simulation_response(simulation_result) - def execute( self, client: algod.AlgodClient, wait_rounds: int ) -> AtomicTransactionResponse: diff --git a/tests/steps/other_v2_steps.py b/tests/steps/other_v2_steps.py index 99af3f1d..4d51e471 100644 --- a/tests/steps/other_v2_steps.py +++ b/tests/steps/other_v2_steps.py @@ -1489,12 +1489,14 @@ def allow_more_logs_in_request(context): @then("I attach the simulate request to simulate the transaction group.") def attach_sim_request_to_txn_group_simulation(context): - context.simulate_response = context.atomic_transaction_composer.simulate( - context.app_acl, context.simulate_request + context.atomic_transaction_composer_return = ( + context.atomic_transaction_composer.simulate( + context.app_acl, context.simulate_request + ) ) -@then('I check the simulation result has power packs allow-more-logging.') +@then("I check the simulation result has power packs allow-more-logging.") def power_pack_simulation_should_pass(context): assert context.simulate_response.eval_overrides.max_log_calls assert context.simulate_response.eval_overrides.max_log_size From 7de6a530703ea9c321dedbde0877daf2771a5331 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Thu, 27 Apr 2023 13:53:38 -0400 Subject: [PATCH 15/22] fix no failure message? --- tests/steps/other_v2_steps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/steps/other_v2_steps.py b/tests/steps/other_v2_steps.py index 8347b87e..cdd393db 100644 --- a/tests/steps/other_v2_steps.py +++ b/tests/steps/other_v2_steps.py @@ -1447,7 +1447,7 @@ def simulate_transaction(context): @then("the simulation should succeed without any failure message") def simulate_transaction_succeed(context): if hasattr(context, "simulate_response"): - assert len(context.simulate_response.failure_message) == 0 + assert "failure-message" not in context.simulate_response["txn-groups"] else: assert ( len(context.atomic_transaction_composer_return.failure_message) From 179c6c0589e8e2859d71ab6d4aee02c621379bf2 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Thu, 27 Apr 2023 14:14:57 -0400 Subject: [PATCH 16/22] bro set request field wrong, bro dumb --- tests/steps/other_v2_steps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/steps/other_v2_steps.py b/tests/steps/other_v2_steps.py index cdd393db..ad236c97 100644 --- a/tests/steps/other_v2_steps.py +++ b/tests/steps/other_v2_steps.py @@ -1489,7 +1489,7 @@ def make_simulate_request(context): @then("I allow more logs on that simulate request.") def allow_more_logs_in_request(context): - context.atomic_transaction_composer_return.allow_more_logs = True + context.simulate_request.allow_more_logs = True @then("I attach the simulate request to simulate the transaction group.") From 238e9d354d80a59f8e6f31e132ce017b1de9093d Mon Sep 17 00:00:00 2001 From: Hang Su Date: Thu, 27 Apr 2023 14:56:57 -0400 Subject: [PATCH 17/22] unsigned txns steps --- tests/steps/other_v2_steps.py | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/tests/steps/other_v2_steps.py b/tests/steps/other_v2_steps.py index ad236c97..c5d43337 100644 --- a/tests/steps/other_v2_steps.py +++ b/tests/steps/other_v2_steps.py @@ -1466,20 +1466,16 @@ def simulate_atc(context): 'the simulation should report a failure at group "{group}", path "{path}" with message "{message}"' ) def simulate_atc_failure(context, group, path, message): - resp: SimulateAtomicTransactionResponse = ( - context.atomic_transaction_composer_return - ) + if hasattr(context, "simulate_response"): + resp = context.simulate_response + else: + resp = context.atomic_transaction_composer_return.simulate_response group_idx: int = int(group) fail_path = ",".join( - [ - str(pe) - for pe in resp.simulate_response["txn-groups"][group_idx][ - "failed-at" - ] - ] + [str(pe) for pe in resp["txn-groups"][group_idx]["failed-at"]] ) assert fail_path == path - assert message in resp.failure_message + assert message in resp["txn-groups"][group_idx]["failure-message"] @when("I make a new simulate request.") @@ -1516,25 +1512,6 @@ def step_impl(context): context.stx = transaction.SignedTransaction(context.txn, None) -@then( - 'the simulation should report missing signatures at group "{group}", transactions "{path}"' -) -def check_missing_signatures(context, group, path): - if hasattr(context, "simulate_response"): - resp = context.simulate_response - else: - resp = context.atomic_transaction_composer_return.simulate_response - - group_idx: int = int(group) - tx_idxs: list[int] = [int(pe) for pe in path.split(",")] - - for tx_idx in tx_idxs: - missing_sig = resp["txn-groups"][group_idx]["txn-results"][tx_idx][ - "failure-message" - ] - assert missing_sig is True - - @when("we make a GetLedgerStateDelta call against round {round}") def get_ledger_state_delta_call(context, round): context.response = context.acl.get_ledger_state_delta(round) From eb40f7226619c571800dacd91009f186cb9c8b4a Mon Sep 17 00:00:00 2001 From: Hang Su Date: Thu, 27 Apr 2023 18:17:48 -0400 Subject: [PATCH 18/22] renaming a step --- tests/steps/other_v2_steps.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/steps/other_v2_steps.py b/tests/steps/other_v2_steps.py index c5d43337..251e95d2 100644 --- a/tests/steps/other_v2_steps.py +++ b/tests/steps/other_v2_steps.py @@ -1488,8 +1488,8 @@ def allow_more_logs_in_request(context): context.simulate_request.allow_more_logs = True -@then("I attach the simulate request to simulate the transaction group.") -def attach_sim_request_to_txn_group_simulation(context): +@then("I simulate the transaction group with the simulate request.") +def simulate_group_with_request(context): context.atomic_transaction_composer_return = ( context.atomic_transaction_composer.simulate( context.app_acl, context.simulate_request From 939e1216a567006d6667ecd622965788719a41cf Mon Sep 17 00:00:00 2001 From: Hang Su Date: Thu, 27 Apr 2023 18:44:06 -0400 Subject: [PATCH 19/22] pr response --- algosdk/atomic_transaction_composer.py | 9 ++++++++- algosdk/v2client/models/simulate_request.py | 4 ++++ tests/steps/other_v2_steps.py | 15 ++++++++------- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/algosdk/atomic_transaction_composer.py b/algosdk/atomic_transaction_composer.py index 6aa986b7..f08c0963 100644 --- a/algosdk/atomic_transaction_composer.py +++ b/algosdk/atomic_transaction_composer.py @@ -271,9 +271,11 @@ def __init__( *, max_log_calls: Optional[int] = None, max_log_size: Optional[int] = None, + allow_empty_signatures: Optional[int] = None, ) -> None: self.max_log_calls = max_log_calls self.max_log_size = max_log_size + self.allow_empty_signatures = allow_empty_signatures @staticmethod def from_simulation_result( @@ -289,6 +291,10 @@ def from_simulation_result( eval_override.max_log_calls = eval_override_dict["max-log-calls"] if "max-log-size" in eval_override_dict: eval_override.max_log_size = eval_override_dict["max-log-size"] + if "allow-empty-signatures" in eval_override_dict: + eval_override.allow_empty_signatures = eval_override_dict[ + "allow-empty-signatures" + ] return eval_override @@ -725,7 +731,8 @@ def simulate( Args: client (AlgodClient): Algod V2 client - request (models.SimulateReuqest): SimulateRequest with options in simulation. + request (models.SimulateRequest): SimulateRequest with options in simulation. + The request's transaction group will be overrwritten by the composer's group, only simulation related options will be used. Returns: SimulateAtomicTransactionResponse: Object with simulation results for this diff --git a/algosdk/v2client/models/simulate_request.py b/algosdk/v2client/models/simulate_request.py index e8e0f8e5..909eb223 100644 --- a/algosdk/v2client/models/simulate_request.py +++ b/algosdk/v2client/models/simulate_request.py @@ -19,15 +19,18 @@ def dictify(self) -> Dict[str, Any]: class SimulateRequest(object): txn_groups: List[SimulateRequestTransactionGroup] allow_more_logs: bool + allow_empty_signatures: bool def __init__( self, *, txn_groups: List[SimulateRequestTransactionGroup], allow_more_logs: bool = False, + allow_empty_signatures: bool = False, ) -> None: self.txn_groups = txn_groups self.allow_more_logs = allow_more_logs + self.allow_empty_signatures = allow_empty_signatures def dictify(self) -> Dict[str, Any]: return { @@ -35,4 +38,5 @@ def dictify(self) -> Dict[str, Any]: txn_group.dictify() for txn_group in self.txn_groups ], "allow-more-logging": self.allow_more_logs, + "allow-empty-signatures": self.allow_empty_signatures, } diff --git a/tests/steps/other_v2_steps.py b/tests/steps/other_v2_steps.py index 251e95d2..27449212 100644 --- a/tests/steps/other_v2_steps.py +++ b/tests/steps/other_v2_steps.py @@ -1446,13 +1446,14 @@ def simulate_transaction(context): @then("the simulation should succeed without any failure message") def simulate_transaction_succeed(context): - if hasattr(context, "simulate_response"): - assert "failure-message" not in context.simulate_response["txn-groups"] - else: - assert ( - len(context.atomic_transaction_composer_return.failure_message) - == 0 - ) + resp = ( + context.simulate_response + if hasattr(context, "simulate_response") + else context.atomic_transaction_composer_return.simulate_response + ) + + for group in resp["txn-groups"]: + assert "failure-message" not in group @then("I simulate the current transaction group with the composer") From 774d8001e5fca230c33624cb38b15e38eac2da14 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Fri, 28 Apr 2023 10:49:41 -0400 Subject: [PATCH 20/22] minor --- tests/steps/other_v2_steps.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/steps/other_v2_steps.py b/tests/steps/other_v2_steps.py index 27449212..0d213911 100644 --- a/tests/steps/other_v2_steps.py +++ b/tests/steps/other_v2_steps.py @@ -1500,6 +1500,7 @@ def simulate_group_with_request(context): @then("I check the simulation result has power packs allow-more-logging.") def power_pack_simulation_should_pass(context): + assert context.atomic_transaction_composer_return.eval_overrides assert ( context.atomic_transaction_composer_return.eval_overrides.max_log_calls ) From f76cf11defe7504f7c7eae5a8c613792895de153 Mon Sep 17 00:00:00 2001 From: Hang Su Date: Fri, 28 Apr 2023 12:23:35 -0400 Subject: [PATCH 21/22] minor --- algosdk/atomic_transaction_composer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/algosdk/atomic_transaction_composer.py b/algosdk/atomic_transaction_composer.py index f08c0963..66291934 100644 --- a/algosdk/atomic_transaction_composer.py +++ b/algosdk/atomic_transaction_composer.py @@ -271,7 +271,7 @@ def __init__( *, max_log_calls: Optional[int] = None, max_log_size: Optional[int] = None, - allow_empty_signatures: Optional[int] = None, + allow_empty_signatures: Optional[bool] = None, ) -> None: self.max_log_calls = max_log_calls self.max_log_size = max_log_size From db85f5287f39d77dde2d8f4d4f52fe705c6f7843 Mon Sep 17 00:00:00 2001 From: Hang Su <87964331+ahangsu@users.noreply.github.com> Date: Fri, 28 Apr 2023 13:04:20 -0400 Subject: [PATCH 22/22] Update .test-env --- .test-env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.test-env b/.test-env index c8732a95..df783a4f 100644 --- a/.test-env +++ b/.test-env @@ -1,6 +1,6 @@ # Configs for testing repo download: SDK_TESTING_URL="https://github.com/algorand/algorand-sdk-testing" -SDK_TESTING_BRANCH="simulate-request-log-option" +SDK_TESTING_BRANCH="master" SDK_TESTING_HARNESS="test-harness" INSTALL_ONLY=0