Skip to content

Commit eaba635

Browse files
committed
feat: add support for populate-resources
See algorand/algorand-sdk-testing#319 for the test scenario
1 parent a2d610c commit eaba635

File tree

4 files changed

+78
-2
lines changed

4 files changed

+78
-2
lines changed

algosdk/atomic_transaction_composer.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from abc import ABC, abstractmethod
22
import base64
33
import copy
4+
from dataclasses import dataclass
45
from enum import IntEnum
56
from typing import (
67
Any,
@@ -25,6 +26,16 @@
2526
T = TypeVar("T")
2627

2728

29+
@dataclass(kw_only=True)
30+
class PopulatedResourceArrays:
31+
"""
32+
Contains the populated resource arrays when `populate_resources` is set to true on a simulate request
33+
"""
34+
apps: list[int]
35+
accounts: list[str]
36+
assets: list[int]
37+
boxes: list[tuple[int, bytes]]
38+
2839
def populate_foreign_array(
2940
value_to_add: T, foreign_array: List[T], zero_value: Optional[T] = None
3041
) -> int:
@@ -322,6 +333,8 @@ def __init__(
322333
results: List[SimulateABIResult],
323334
eval_overrides: Optional[SimulateEvalOverrides] = None,
324335
exec_trace_config: Optional[models.SimulateTraceConfig] = None,
336+
extra_resource_arrays: list[PopulatedResourceArrays] = None,
337+
populated_resource_arrays: list[PopulatedResourceArrays] = None
325338
) -> None:
326339
self.version = version
327340
self.failure_message = failure_message
@@ -331,6 +344,8 @@ def __init__(
331344
self.abi_results = results
332345
self.eval_overrides = eval_overrides
333346
self.exec_trace_config = exec_trace_config
347+
self.extra_resource_arrays = extra_resource_arrays
348+
self.populated_resource_arrays = populated_resource_arrays
334349

335350

336351
class AtomicTransactionComposer:
@@ -823,6 +838,28 @@ def simulate(
823838
)
824839
)
825840

841+
populated_resource_arrays = []
842+
for txn in txn_group["txn-results"]:
843+
if txn.get("populated-resource-arrays"):
844+
populated_resource_arrays.append(
845+
PopulatedResourceArrays(
846+
apps=txn["populated-resource-arrays"].get("apps", []),
847+
accounts=txn["populated-resource-arrays"].get("accounts", []),
848+
assets=txn["populated-resource-arrays"].get("assets", []),
849+
boxes=[(b["app"], base64.b64decode(b["name"])) for b in txn["populated-resource-arrays"].get("boxes", [])],
850+
)
851+
)
852+
853+
extra_resource_arrays = []
854+
for arrays in txn_group.get("extra-resource-arrays", []):
855+
extra_resource_arrays.append(
856+
PopulatedResourceArrays(
857+
apps=arrays.get("apps", []),
858+
accounts=arrays.get("accounts", []),
859+
assets=arrays.get("assets", []),
860+
boxes=[(b["app"], base64.b64decode(b["name"])) for b in arrays.get("boxes", [])],
861+
)
862+
)
826863
return SimulateAtomicTransactionResponse(
827864
version=simulation_result.get("version", 0),
828865
failure_message=txn_group.get("failure-message", ""),
@@ -834,6 +871,8 @@ def simulate(
834871
simulation_result
835872
),
836873
exec_trace_config=exec_trace_config,
874+
extra_resource_arrays=extra_resource_arrays,
875+
populated_resource_arrays=populated_resource_arrays
837876
)
838877

839878
def execute(

algosdk/v2client/models/simulate_request.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ def __init__(
7272
allow_unnamed_resources: bool = False,
7373
extra_opcode_budget: int = 0,
7474
exec_trace_config: Optional[SimulateTraceConfig] = None,
75+
populate_resources: bool = False,
7576
) -> None:
7677
self.txn_groups = txn_groups
7778
self.round = round
@@ -82,6 +83,7 @@ def __init__(
8283
self.exec_trace_config = (
8384
exec_trace_config if exec_trace_config else SimulateTraceConfig()
8485
)
86+
self.populate_resources = populate_resources
8587

8688
def dictify(self) -> Dict[str, Any]:
8789
return {
@@ -94,4 +96,5 @@ def dictify(self) -> Dict[str, Any]:
9496
"allow-empty-signatures": self.allow_empty_signatures,
9597
"extra-opcode-budget": self.extra_opcode_budget,
9698
"exec-trace-config": self.exec_trace_config.dictify(),
99+
"populate-resources": self.populate_resources
97100
}

tests/integration.tags

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@
1818
@simulate.lift_log_limits
1919
@simulate.extra_opcode_budget
2020
@simulate.exec_trace_with_stack_scratch
21-
@simulate.exec_trace_with_state_change_and_hash
21+
@simulate.exec_trace_with_state_change_and_hash
22+
@simulate.populate_resources

tests/steps/other_v2_steps.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import base64
22
import json
3+
from operator import truediv
34
import os
45
import unittest
56
import urllib
@@ -37,7 +38,6 @@
3738
from tests.steps.steps import algod_port, indexer_port
3839
from tests.steps.steps import token as daemon_token
3940

40-
4141
@parse.with_pattern(r".*")
4242
def parse_string(text):
4343
return text
@@ -2036,3 +2036,36 @@ def get_ledger_state_delta_for_transaction_group(context, id):
20362036
@when("we make a GetBlockTxids call against block number {round}")
20372037
def get_block_txids_call(context, round):
20382038
context.response = context.acl.get_block_txids(round)
2039+
2040+
@when(u'I set unnamed-resources "{value}"')
2041+
def step_impl(context, value):
2042+
context.simulate_request.allow_unnamed_resources = value == "true"
2043+
2044+
@when(u'I set populate-resources "{value}"')
2045+
def step_impl(context, value):
2046+
context.simulate_request.populate_resources = value == "true"
2047+
2048+
@then(u'the response should include populated-resource-arrays for the transaction')
2049+
def step_impl(context):
2050+
resp: SimulateAtomicTransactionResponse = context.atomic_transaction_composer_return
2051+
assert(len(resp.populated_resource_arrays) == 1)
2052+
2053+
resources = resp.populated_resource_arrays[0]
2054+
assert(resources.apps == [10000, 20000, 30000])
2055+
assert(resources.accounts == [
2056+
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ',
2057+
'AEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKE3PRHE',
2058+
'AIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGFFWAF4',
2059+
'AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANVWEXNA'
2060+
])
2061+
assert(resources.boxes == [(context.current_application_id, b'box_key')])
2062+
assert(resources.assets == [])
2063+
2064+
@then(u'the response should include extra-resource-arrays for the group')
2065+
def step_impl(context):
2066+
resp: SimulateAtomicTransactionResponse = context.atomic_transaction_composer_return
2067+
assert(len(resp.extra_resource_arrays) == 1)
2068+
assert(resp.extra_resource_arrays[0].apps == [40000])
2069+
assert(resp.extra_resource_arrays[0].accounts == ['AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJVBPJXY'])
2070+
assert(resp.extra_resource_arrays[0].assets == [10001])
2071+
assert(resp.extra_resource_arrays[0].boxes == [(0, b'')])

0 commit comments

Comments
 (0)