Skip to content

Commit

Permalink
Tuple Index Into Minor Fix (#663)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahangsu committed Feb 10, 2023
1 parent 5dbbc85 commit 5cd3252
Show file tree
Hide file tree
Showing 8 changed files with 563 additions and 11 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

## Fixed

* Fixed wrong encoding result in tuple get last item. ([#663](https://github.com/algorand/pyteal/pull/663))

## Changed

# v0.22.0
Expand Down
8 changes: 2 additions & 6 deletions pyteal/ast/abi/array_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def decode(
*,
start_index: Expr | None = None,
end_index: Expr | None = None,
length: Expr | None = None
length: Expr | None = None,
) -> Expr:
"""Decode a substring of the passed in encoded byte string and set it as this type's value.
Expand Down Expand Up @@ -128,11 +128,7 @@ def set(self, values: Sequence[T]) -> Expr:
for index, value in enumerate(values):
if self.type_spec().value_type_spec() != value.type_spec():
raise TealInputError(
"Cannot assign type {} at index {} to {}".format(
value.type_spec(),
index,
self.type_spec().value_type_spec(),
)
f"Cannot assign type {value.type_spec()} at index {index} to {self.type_spec().value_type_spec()}"
)

encoded = _encode_tuple(values)
Expand Down
6 changes: 3 additions & 3 deletions pyteal/ast/abi/tuple.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,9 @@ def _index_tuple(
if offset == 0:
# This is the first and only value in the tuple, so decode all of encoded
return output.decode(encoded)
# This is the last value in the tuple, so decode the substring from start_index to the end of
# encoded
return output.decode(encoded, start_index=start_index)
if all(not x.is_dynamic() for x in value_types):
# This is the last element in tuple with all elements being static typed
return output.decode(encoded, start_index=start_index)

if offset == 0:
# This is the first value in the tuple, so decode the substring from 0 with length length
Expand Down
18 changes: 18 additions & 0 deletions pyteal/ast/abi/tuple_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ class IndexTest(NamedTuple):
tuple_t = abi.TupleTypeSpec(abi.BoolTypeSpec(), abi.BoolTypeSpec())
dynamic_array_t1 = abi.DynamicArrayTypeSpec(abi.Uint64TypeSpec())
dynamic_array_t2 = abi.DynamicArrayTypeSpec(abi.Uint16TypeSpec())
static_bytes_t = abi.StaticBytesTypeSpec(2)

encoded = pt.Bytes("encoded")

Expand Down Expand Up @@ -371,6 +372,23 @@ class IndexTest(NamedTuple):
encoded, start_index=pt.ExtractUint16(encoded, pt.Int(0))
),
),
IndexTest(
types=[dynamic_array_t1, static_bytes_t],
typeIndex=1,
expected=lambda output: output.decode(
encoded,
start_index=pt.Int(2),
length=pt.Int(2),
),
),
IndexTest(
types=[static_bytes_t, static_bytes_t],
typeIndex=1,
expected=lambda output: output.decode(
encoded,
start_index=pt.Int(2),
),
),
IndexTest(
types=[byte_t, dynamic_array_t1, byte_t],
typeIndex=1,
Expand Down
4 changes: 2 additions & 2 deletions tests/compile_asserts.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def compile_and_save(approval, version: int, test_name: str) -> tuple[Path, str,
with open(tealdir / (name + ".teal"), "w") as f:
f.write(compiled)
print(
f"""Successfuly tested approval program <<{name}>> having
f"""Successfuly tested approval program <<{name}>> having
compiled it into {len(compiled)} characters. See the results in:
{tealdir}
"""
Expand Down Expand Up @@ -51,7 +51,7 @@ def assert_new_v_old(approve_func, version: int, test_name: str):
tealdir, name, compiled = compile_and_save(approve_func, version, test_name)

print(
f"""Compilation resulted in TEAL program of length {len(compiled)}.
f"""Compilation resulted in TEAL program of length {len(compiled)}.
To view output SEE <{name}.teal> in ({tealdir})
--------------"""
)
Expand Down
1 change: 1 addition & 0 deletions tests/integration/abi_roundtrip_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class NamedTupleInherit(abi.NamedTuple):
abi.Tuple1[abi.Uint32],
abi.Tuple1[abi.Uint64],
abi.Tuple2[abi.Bool, abi.Byte],
abi.Tuple2[abi.DynamicBytes, abi.StaticBytes[Literal[3]]],
abi.Tuple3[abi.Bool, abi.Uint64, abi.Uint32],
abi.Tuple3[abi.Byte, abi.Bool, abi.Uint64],
abi.Tuple3[abi.Uint8, abi.Byte, abi.Bool],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
#pragma version 6
txna ApplicationArgs 0
store 3
load 3
callsub roundtripper_1
store 2
byte 0x151f7c75
load 2
concat
log
int 1
return

// tuple_complement
tuplecomplement_0:
store 8
load 8
load 8
int 0
extract_uint16
dig 1
len
substring3
store 0
load 8
extract 2 3
store 1
load 0
callsub arraycomplement_3
store 0
load 1
callsub arraycomplement_5
store 1
load 0
store 27
load 27
store 26
int 5
store 25
load 25
itob
extract 6 0
load 1
concat
load 26
concat
store 9
load 9
retsub

// round_tripper
roundtripper_1:
store 4
load 4
callsub tuplecomplement_0
store 6
load 6
callsub tuplecomplement_0
store 7
load 4
store 31
load 31
store 30
int 6
store 28
load 28
load 31
len
+
store 29
load 29
int 65536
<
assert
load 28
itob
extract 6 0
load 6
store 31
load 30
load 31
concat
store 30
load 29
store 28
load 28
load 31
len
+
store 29
load 29
int 65536
<
assert
load 28
itob
extract 6 0
concat
load 7
store 31
load 30
load 31
concat
store 30
load 29
store 28
load 28
itob
extract 6 0
concat
load 30
concat
store 5
load 5
retsub

// numerical_comp
numericalcomp_2:
store 15
int 255
load 15
-
store 16
load 16
int 256
<
assert
load 16
retsub

// array_complement
arraycomplement_3:
store 10
load 10
int 1
int 0
*
int 2
+
getbyte
store 12
load 10
int 1
int 1
*
int 2
+
getbyte
store 13
load 10
int 1
int 2
*
int 2
+
getbyte
store 14
load 12
callsub numericalcomp_2
store 12
load 13
callsub numericalcomp_2
store 13
load 14
callsub numericalcomp_2
store 14
int 3
store 17
load 17
itob
extract 6 0
byte 0x00
int 0
load 12
setbyte
byte 0x00
int 0
load 13
setbyte
concat
byte 0x00
int 0
load 14
setbyte
concat
concat
store 11
load 11
retsub

// numerical_comp
numericalcomp_4:
store 23
int 255
load 23
-
store 24
load 24
int 256
<
assert
load 24
retsub

// array_complement
arraycomplement_5:
store 18
load 18
int 1
int 0
*
getbyte
store 20
load 18
int 1
int 1
*
getbyte
store 21
load 18
int 1
int 2
*
getbyte
store 22
load 20
callsub numericalcomp_4
store 20
load 21
callsub numericalcomp_4
store 21
load 22
callsub numericalcomp_4
store 22
byte 0x00
int 0
load 20
setbyte
byte 0x00
int 0
load 21
setbyte
concat
byte 0x00
int 0
load 22
setbyte
concat
store 19
load 19
retsub

0 comments on commit 5cd3252

Please sign in to comment.