Skip to content

Commit 12b1cc2

Browse files
authored
Merge pull request #33 from algorandfoundation/feat/signature
feat: accept abi method reference as a parameter to arc4_signature method
2 parents 109f43c + a1cb365 commit 12b1cc2

File tree

3 files changed

+44
-12
lines changed

3 files changed

+44
-12
lines changed

.vscode/settings.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
"python.analysis.typeCheckingMode": "off",
1818

1919
"ruff.enable": true,
20-
"ruff.lint.run": "onSave",
21-
"ruff.lint.args": ["--config=pyproject.toml"],
20+
"ruff.configuration": "pyproject.toml",
2221
"ruff.importStrategy": "fromEnvironment",
2322
"ruff.fixAll": true, //lint and fix all files in workspace
2423
"ruff.organizeImports": true, //organize imports on save

src/_algopy_testing/arc4.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
)
3838

3939
if typing.TYPE_CHECKING:
40-
from collections.abc import Iterable, Iterator, Sequence
40+
from collections.abc import Callable, Iterable, Iterator, Sequence
4141

4242
import algopy
4343

@@ -56,24 +56,27 @@
5656
"Struct",
5757
"Tuple",
5858
"UFixedNxM",
59-
"UInt128",
59+
"UInt8",
6060
"UInt16",
61-
"UInt256",
6261
"UInt32",
63-
"UInt512",
6462
"UInt64",
65-
"UInt8",
63+
"UInt128",
64+
"UInt256",
65+
"UInt512",
6666
"UIntN",
6767
"abi_call",
6868
"arc4_create",
69-
"arc4_update",
7069
"arc4_signature",
70+
"arc4_update",
7171
"emit",
7272
]
7373

7474
_ABI_LENGTH_SIZE = 2
7575
_TBitSize = typing.TypeVar("_TBitSize", bound=int)
7676

77+
_P = typing.ParamSpec("_P")
78+
_R = typing.TypeVar("_R")
79+
7780

7881
class _TypeInfo:
7982
@property
@@ -179,12 +182,22 @@ def __hash__(self) -> int:
179182
return hash(self.bytes)
180183

181184

182-
def arc4_signature(signature: str, /) -> algopy.Bytes:
185+
def arc4_signature(signature: str | Callable[_P, _R], /) -> algopy.Bytes:
183186
"""Convert a signature to ARC4 bytes."""
184187
import algopy
185188

189+
from _algopy_testing.decorators.arc4 import get_arc4_metadata
190+
191+
if isinstance(signature, str):
192+
method_signature = signature
193+
else:
194+
arc4_signature = get_arc4_metadata(signature).arc4_signature
195+
if arc4_signature is None:
196+
raise ValueError("signature not found")
197+
method_signature = arc4_signature
198+
186199
hashed_signature = SHA512.new(truncate="256")
187-
hashed_signature.update(signature.encode("utf-8"))
200+
hashed_signature.update(method_signature.encode("utf-8"))
188201
return_value = hashed_signature.digest()[:4]
189202
return algopy.Bytes(return_value)
190203

@@ -1187,11 +1200,17 @@ def _find_bool(
11871200
) -> int:
11881201
"""Helper function to find consecutive booleans from current index in a tuple."""
11891202
until = 0
1203+
is_looking_forward = delta > 0
1204+
is_looking_backward = delta < 0
11901205
values_length = len(values) if isinstance(values, tuple | list) else values.length.value
11911206
while True:
11921207
curr = index + delta * until
1208+
is_curr_at_end = curr == values_length - 1
1209+
is_curr_at_start = curr == 0
11931210
if isinstance(values[curr], Bool):
1194-
if curr != values_length - 1 and delta > 0 or curr > 0 and delta < 0:
1211+
if (is_looking_forward and not is_curr_at_end) or (
1212+
is_looking_backward and not is_curr_at_start
1213+
):
11951214
until += 1
11961215
else:
11971216
break
@@ -1204,11 +1223,17 @@ def _find_bool(
12041223
def _find_bool_types(values: typing.Sequence[_TypeInfo], index: int, delta: int) -> int:
12051224
"""Helper function to find consecutive booleans from current index in a tuple."""
12061225
until = 0
1226+
is_looking_forward = delta > 0
1227+
is_looking_backward = delta < 0
12071228
values_length = len(values)
12081229
while True:
12091230
curr = index + delta * until
1231+
is_curr_at_end = curr == values_length - 1
1232+
is_curr_at_start = curr == 0
12101233
if isinstance(values[curr], _BoolTypeInfo):
1211-
if curr != values_length - 1 and delta > 0 or curr > 0 and delta < 0:
1234+
if (is_looking_forward and not is_curr_at_end) or (
1235+
is_looking_backward and not is_curr_at_start
1236+
):
12121237
until += 1
12131238
else:
12141239
break

tests/arc4/test_arc4_method_signature.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ def test_app_args_is_correct_with_simple_args(
8282
b"\x00\x05hello",
8383
b"\x00\x02\x01\x02",
8484
]
85+
assert app_args[0] == arc4.arc4_signature(SignaturesContract.sink)
8586

8687

8788
def test_app_args_is_correct_with_alias(
@@ -106,6 +107,7 @@ def test_app_args_is_correct_with_alias(
106107
b"\x00\x05hello",
107108
b"\x00\x02\x01\x02",
108109
]
110+
assert app_args[0] == arc4.arc4_signature(SignaturesContract.sink2)
109111

110112

111113
def test_app_args_is_correct_with_txn(
@@ -148,6 +150,7 @@ def test_app_args_is_correct_with_txn(
148150
b"\x00\x05hello",
149151
b"\x00\x02\x01\x02",
150152
]
153+
assert app_args[0] == arc4.arc4_signature(SignaturesContract.with_txn)
151154

152155

153156
def test_app_args_is_correct_with_asset(
@@ -186,6 +189,7 @@ def test_app_args_is_correct_with_asset(
186189
b"\x00",
187190
b"\x00\x02\x01\x02",
188191
]
192+
assert app_args[0] == arc4.arc4_signature(SignaturesContract.with_asset)
189193

190194

191195
def test_app_args_is_correct_with_account(
@@ -219,6 +223,7 @@ def test_app_args_is_correct_with_account(
219223
b"\x01",
220224
b"\x00\x02\x01\x02",
221225
]
226+
assert app_args[0] == arc4.arc4_signature(SignaturesContract.with_acc)
222227

223228

224229
def test_app_args_is_correct_with_application(
@@ -260,6 +265,7 @@ def test_app_args_is_correct_with_application(
260265
other_app_id.to_bytes(length=8), # app id as bytes
261266
b"\x00\x02\x01\x02",
262267
]
268+
assert app_args[0] == arc4.arc4_signature(SignaturesContract.with_app)
263269
assert app_foreign_apps == [
264270
self_app.id,
265271
other_app_id,
@@ -298,6 +304,7 @@ def test_app_args_is_correct_with_complex(
298304
b"\x01", # 0th index is the sender
299305
b"\x00\x01\x05",
300306
]
307+
assert app_args[0] == arc4.arc4_signature(SignaturesContract.complex_sig)
301308
assert result[0].bytes == struct.another_struct.bytes
302309
assert result[1].bytes == struct.bytes
303310

@@ -359,5 +366,6 @@ def test_prepare_txns_with_complex(
359366
b"\x01", # 0th index is the sender
360367
b"\x00\x01\x05",
361368
]
369+
assert app_args[0] == arc4.arc4_signature(SignaturesContract.complex_sig)
362370
assert result[0].bytes == struct.another_struct.bytes
363371
assert result[1].bytes == struct.bytes

0 commit comments

Comments
 (0)