-
Notifications
You must be signed in to change notification settings - Fork 141
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Box support for Application calls and Atomic Transaction Composer (#338)
* starting to add box support * Add boxes to atc * Format files with black * Add boxes docstring * Add boxes support for appl creation * Update cucumber steps for appl txn encoding for boxes * Formatting * Point testing branch to box-reference (WIP) * Sort imports on relevant files and format * Add translation for foreign apps in box refs and some local unit tests * Add some invalid cases for box translation * Check for None when iterating box refs * Add self app id references and tests * Minor changes for box support * Split boxref to separate file * Change box name type to bytes * Change docs references from box string to bytes * Refactor cucumber steps * Refactoring code and adding docstrings * Add another comment * Change test steps to encode box args like app args * Add safety checks for box references * Add some detailed errors and refactor * Format unit test * Fix foreign index error and revise undictify method * Finish merging cucumber steps * Formatting * Fix box tests again * Encoded as bytes unit test (#344) * Unit test for encoding.py's `encode_as_bytes()` * Accept AttributeError for foreign apps array if it is referencing its own app id * Add unit test for empty foreign app array * Change unit test to pass in None foreign array * Change undictify method for boxes * Formatting * Change test branch * Change type hints for atc boxes * Check for int type for box reference id * Change type ignore annotation Co-authored-by: Ben Guidarelli <[email protected]> Co-authored-by: Zeph Grunschlag <[email protected]>
- Loading branch information
1 parent
faa13be
commit d056766
Showing
10 changed files
with
339 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
from collections import OrderedDict | ||
from typing import List, Tuple, Union | ||
|
||
from algosdk import encoding, error | ||
|
||
|
||
class BoxReference: | ||
""" | ||
Represents a box reference with a foreign app index and the box name. | ||
Args: | ||
app_index (int): index of the application in the foreign app array | ||
name (bytes): key for the box in bytes | ||
""" | ||
|
||
def __init__(self, app_index: int, name: bytes): | ||
if app_index < 0: | ||
raise ValueError( | ||
f"Box app index must be a non-negative integer: {app_index}" | ||
) | ||
self.app_index = app_index | ||
self.name = name | ||
|
||
@staticmethod | ||
def translate_box_reference( | ||
ref: Tuple[int, Union[bytes, bytearray, str, int]], | ||
foreign_apps: List[int], | ||
this_app_id: int, | ||
) -> "BoxReference": | ||
# Try checking reference id and name type. | ||
ref_id, ref_name = ref[0], encoding.encode_as_bytes(ref[1]) | ||
if not isinstance(ref_id, int): | ||
raise TypeError("Box reference ID must be an int") | ||
|
||
index = 0 | ||
try: | ||
# Foreign apps start from index 1; index 0 is its own app ID. | ||
index = foreign_apps.index(ref_id) + 1 | ||
except (ValueError, AttributeError): | ||
# Check if the app referenced is itself after checking the | ||
# foreign apps array (in case its own app id is in its own | ||
# foreign apps array). | ||
if ref_id != 0 and ref_id != this_app_id: | ||
raise error.InvalidForeignIndexError( | ||
f"Box ref with appId {ref_id} not in foreign-apps" | ||
) | ||
return BoxReference(index, ref_name) | ||
|
||
@staticmethod | ||
def translate_box_references( | ||
references: List[Tuple[int, Union[bytes, bytearray, str, int]]], | ||
foreign_apps: List[int], | ||
this_app_id: int, | ||
) -> List["BoxReference"]: | ||
""" | ||
Translates a list of tuples with app IDs and names into an array of | ||
BoxReferences with foreign indices. | ||
Args: | ||
references (list[(int, bytes)]): list of tuples specifying app id | ||
and key for boxes the app may access | ||
foreign_apps (list[int]): list of other applications in appl call | ||
this_app_id (int): app ID of the box being references | ||
""" | ||
if not references: | ||
return [] | ||
|
||
return [ | ||
BoxReference.translate_box_reference( | ||
ref, foreign_apps, this_app_id | ||
) | ||
for ref in references | ||
] | ||
|
||
def dictify(self): | ||
d = dict() | ||
if self.app_index: | ||
d["i"] = self.app_index | ||
if self.name: | ||
d["n"] = self.name | ||
od = OrderedDict(sorted(d.items())) | ||
return od | ||
|
||
@staticmethod | ||
def undictify(d): | ||
return BoxReference( | ||
d["i"] if "i" in d else None, | ||
d["n"] if "n" in d else None, | ||
) | ||
|
||
def __eq__(self, other): | ||
if not isinstance(other, BoxReference): | ||
return False | ||
return self.app_index == other.app_index and self.name == other.name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.