Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ABI Method / Routing / Contract functionality #21

Merged
merged 23 commits into from
Jun 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ff56c2b
Experimental: test abi methods
Jun 9, 2022
439e447
ABIStrategy -> RandomABIStrategy + abstract class
Jun 10, 2022
a6fdd4f
better mypy via PY_TYPES alias
Jun 10, 2022
e0a0b55
wip - router test positive cases half way there
Jun 10, 2022
c737556
passing the POSITIVE test cases. Next, need to explore the NEGATIVE s…
Jun 11, 2022
9b3190b
prep CHANGELOG
Jun 11, 2022
b5f1b15
start exploring the negative space
Jun 11, 2022
573206a
Better assertion message for invariant predicates of 2 variables + be…
Jun 12, 2022
8fe7d69
inputs validation
Jun 12, 2022
2ad23a1
negative space eploration: 1. disallowed is_create_app + on_complete …
Jun 12, 2022
5ed03a3
make note of this failing test - shows that router doesn't guard agai…
Jun 12, 2022
b54296b
only failing because of bugs
Jun 13, 2022
22ae13b
finish negative case but temporarily_skip_iia
Jun 13, 2022
5a676db
bump min python from 3.8 to 3.8 because need random.randbytes()
Jun 13, 2022
e7609a4
remove temporarily_skip_iia
Jun 13, 2022
9680dec
Update tests/teal/router/questionable.teal
tzaffi Jun 14, 2022
b4dbc83
refactoring and respond to CR suggestions
Jun 14, 2022
11800d2
all tests in place for "QUESTIONABLE" approval + clear X positive + n…
Jun 14, 2022
3fc9a9f
looks like recent updates of dry run give log when rejecting... adjus…
Jun 15, 2022
0727a96
yacc copy pasta
Jun 15, 2022
75f9bff
flake8
Jun 15, 2022
0ced9d7
pin py-algorand-sdk@develop after get-method-by-name branch has been …
Jun 15, 2022
2a50f1b
point py-algorand-sdk==1.15.0 before merging
Jun 16, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[flake8]
ignore = E501, W503
ignore = E203, E501, W503
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
container: python:${{ matrix.python }}
strategy:
matrix:
python: [ "3.8", "3.9", "3.10" ]
python: [ "3.9", "3.10" ]
steps:
- run: python3 --version
- name: Check out code
Expand All @@ -30,7 +30,7 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
python: [ "3.8", "3.9", "3.10" ]
python: [ "3.9", "3.10" ]
steps:
- name: Check out code
uses: actions/checkout@v2
Expand Down
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
<!-- markdownlint-disable MD024 -->
# Changelog

## `v0.4.0` (_aka_ 🐕)

### Added

* ABI Contract / Router / Execution functionality

### Fixed

* A bug that made all app calls run as if during creation
* Addressed [Issue #5](https://github.com/algorand/graviton/issues/5): Better assertion message for invariant predicates of 2 variables

### Upgraded

* Minimum python is bumped up to 3.9 (previously 3.8)

## `v0.3.0` (_aka_ 🐈)

### Added
Expand All @@ -13,7 +28,7 @@

### Added

* ABI Functionality
* ABI Functionality (types only)

## `v0.1.2`

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ flake8:
flake8 graviton tests

mypy:
mypy .
mypy --show-error-codes .

lint: black flake8 mypy

Expand Down
64 changes: 48 additions & 16 deletions graviton/abi_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,27 @@

TODO: Leverage Hypothesis!
"""
from abc import ABC, abstractmethod
from collections import OrderedDict
import random
import string
from typing import Callable, Dict, List, Optional, Union, cast
from typing import Callable, Dict, List, Optional, Sequence, Union, cast

from algosdk import abi, encoding

PY_TYPES = Union[bool, int, list, str, bytes]
PY_TYPES = Union[bool, int, Sequence, str, bytes]


class ABIStrategy:
class ABIStrategy(ABC):
@abstractmethod
def get(self) -> PY_TYPES:
pass

def get_many(self, n: int) -> List[PY_TYPES]:
return [self.get() for _ in range(n)]


class RandomABIStrategy(ABIStrategy):
DEFAULT_DYNAMIC_ARRAY_LENGTH = 3
STRING_CHARS = string.digits + string.ascii_letters + string.punctuation

Expand Down Expand Up @@ -46,7 +56,7 @@ def __init__(self, abi_instance: abi.ABIType, dynamic_length: Optional[int] = No
self.abi_type: abi.ABIType = abi_instance
self.dynamic_length: Optional[int] = dynamic_length

def get_random(self) -> Union[bool, int, list, str, bytes]:
def get(self) -> PY_TYPES:
if isinstance(self.abi_type, abi.UfixedType):
raise NotImplementedError(
f"Currently cannot get a random sample for {self.abi_type}"
Expand All @@ -59,17 +69,17 @@ def get_random(self) -> Union[bool, int, list, str, bytes]:
return random.randint(0, (1 << self.abi_type.bit_size) - 1)

if isinstance(self.abi_type, abi.ByteType):
return ABIStrategy(abi.UintType(8)).get_random()
return RandomABIStrategy(abi.UintType(8)).get()

if isinstance(self.abi_type, abi.TupleType):
return [
ABIStrategy(child_type).get_random()
RandomABIStrategy(child_type).get()
for child_type in self.abi_type.child_types
]

if isinstance(self.abi_type, abi.ArrayStaticType):
return [
ABIStrategy(self.abi_type.child_type).get_random()
RandomABIStrategy(self.abi_type.child_type).get()
for _ in range(self.abi_type.static_length)
]

Expand All @@ -78,11 +88,11 @@ def get_random(self) -> Union[bool, int, list, str, bytes]:
bytearray(
cast(
List[int],
ABIStrategy(
RandomABIStrategy(
abi.ArrayStaticType(
abi.ByteType(), self.abi_type.byte_len()
)
).get_random(),
).get(),
)
)
)
Expand All @@ -94,8 +104,7 @@ def get_random(self) -> Union[bool, int, list, str, bytes]:
)
if isinstance(self.abi_type, abi.ArrayDynamicType):
return [
ABIStrategy(self.abi_type.child_type).get_random()
for _ in dynamic_range
RandomABIStrategy(self.abi_type.child_type).get() for _ in dynamic_range
]

if isinstance(self.abi_type, abi.StringType):
Expand Down Expand Up @@ -125,7 +134,7 @@ def address_logic(x):
y = encoding.decode_address(x)
return encoding.encode_address(
bytearray(
ABIStrategy(
RandomABIStrategy(
abi.ArrayStaticType(abi.ByteType(), len(y))
).mutate_for_roundtrip(y)
)
Expand All @@ -138,27 +147,33 @@ def address_logic(x):
(abi.UintType, lambda x: (1 << self.abi_type.bit_size) - 1 - x),
(
abi.ByteType,
lambda x: ABIStrategy(abi.UintType(8)).mutate_for_roundtrip(x),
lambda x: RandomABIStrategy(abi.UintType(8)).mutate_for_roundtrip(
x
),
),
(
abi.TupleType,
lambda x: [
ABIStrategy(child_type).mutate_for_roundtrip(x[i])
RandomABIStrategy(child_type).mutate_for_roundtrip(x[i])
for i, child_type in enumerate(self.abi_type.child_types)
],
),
(
abi.ArrayStaticType,
lambda x: [
ABIStrategy(self.abi_type.child_type).mutate_for_roundtrip(y)
RandomABIStrategy(
self.abi_type.child_type
).mutate_for_roundtrip(y)
for y in x
],
),
(abi.AddressType, address_logic),
(
abi.ArrayDynamicType,
lambda x: [
ABIStrategy(self.abi_type.child_type).mutate_for_roundtrip(y)
RandomABIStrategy(
self.abi_type.child_type
).mutate_for_roundtrip(y)
for y in x
],
),
Expand All @@ -168,3 +183,20 @@ def address_logic(x):
)

return self.map(waterfall, py_abi_instance)


class RandomABIStrategyHalfSized(RandomABIStrategy):
def __init__(
self,
abi_instance: abi.ABIType,
dynamic_length: Optional[int] = None,
):
super().__init__(abi_instance, dynamic_length=dynamic_length)

def get(self) -> PY_TYPES:
full_random = super().get()

if not isinstance(self.abi_type, abi.UintType):
return full_random

return full_random % (1 << (self.abi_type.bit_size // 2))
Loading