Skip to content

Commit 4ee2d3d

Browse files
tzaffialgochoi
andauthored
C2C Feature and Testing (#268)
* Start ABI JSON interaction * Add static annoation * Fix Method argument parsing * Add ABI Typing to Method arguments * [WIP] Add AtomicTransactionComposer build functions * [WIP] Sign and send atomic transaction groups * Add unit tests for object parsing * Clean up method calls * Address PR comments on JSON objects * Refactor ABI Type to ABIType so it can be exposed to outside world * Add cucumber steps for ABI tests and update existing implementation so it can pass these tests * Refactor TransactionSigner to Abstract class and merge signatures when signing * Update testing to reflect json unit tests and composer tests * Formatting and docstring fixes * Add foreign types for method arguments * Clean up imports * Fix unit test for appId * Add unit test for foreign array * Refactor some names and add txn as an arg type * Partially address PR comments * Fix encoding args for foreign types * Add some additional checks for safety * Fix a step so we check for empty string instead of None * Correct foreign app and account indices accounting for the implicit argument * Resolve formatting * Fix unit tests * Fix foreign objects to compact duplicates and special values * Refactor foreign objects, transactions, and address some new ABI changes * ABI composer modifications and test updates * Change Interface and Contract to newest ABI changes * Fix some integration tests for composer * Fix remaining composer tests * Formatting changes * Fix method json tests * add an empty __init__.py * add step to sanity check *.teal.tok against algod's compilation of *.teal * Add the ability to create apps without the binary * step for asserting ABI return type of return values * temporararily adding unfounded mandate z_steps.py * unit test for array_static of byte * add context.app_ids - list of all app ids that have been added * refeactor add_abi_method_call* using abi_method_adder() * don't pass in schemas, unless a component has been defined * With so many tags, let's create variables for easier selction of unit/integration tests * Alphabetize tags and remove deprecated 'templates' * add method using a non-current app * place it back * got to the point of a bug in randomByte * wip * use pathlib * fix bad arg ordering in call * 1. Return application's account address in app-info response 2. now passing 2-level tests for innter txn's 3. next up: 3 levels * clean up unneeded step * close but no cigar * wip * tests are failing where they _should be_ * all necessary functionality... but too many tests * assertion about inner group ids also * passing the megatest * hash non-deterministic step for ABI method * regex match step * test c2c on circle * grammar * remove unused step * route get_application_address() to application_address() * dangit... we already have logic.get_application_address * use logic.get_application_address() * small import re-org (and msgpack not needed) * alphabetize * add type assertion to get_application_address() * refactor v2_steps.py into smaller chuncks * per cr suggestion, split with : not # * per cr comments * Per CR suggetions: remove from transactions_trace() from SDK, and make into a test utility function * eval delta step - and adding glom to requirements * 'Did you mean == ?' - yes i certainly did * for completeness, provide tx_info even for non-appl txns * steps more general than the indexer * require the ability to calculate app addresses, but not from app_info * revert algod changes (except for import re-org) * remove file inadvertently added * spacing * formatting * explicit nonce instead of nonce hook * un-breakup v2_steps.py so it can be easier to see changes * remove implmentation of redundant step * as the Rolling Stones said "I want it painted black" * per review suggestion * per CR suggestion: send the request inside of a try block * pytest for "with pytest.raises" context * handle the void abi type * per CR suggestions * per CR comments. Call pending txn's at the top of the for-loop for method calls * remove unused import * spacing * don't overwrite confirmed_round in subsequent pending txn calls * comment in test method * remove unused import * Alas, poor Yorick... * remove unused import * import reorg * re-kick off the tests * implement "I rest the array of application IDs to remember." * markdownlint * deprecating templates and removing associated tests * fix test * Update README.md a -> an and trigger new tests! * Update algosdk/future/template.py remove period and trigger new test * todo about v2_steps being too big Co-authored-by: algochoi <[email protected]>
1 parent d50d997 commit 4ee2d3d

File tree

13 files changed

+419
-590
lines changed

13 files changed

+419
-590
lines changed

Makefile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
UNITS = "@unit.abijson or @unit.algod or @unit.applications or @unit.atomic_transaction_composer or @unit.dryrun or @unit.feetest or @unit.indexer or @unit.indexer.logs or @unit.offline or @unit.rekey or @unit.responses or @unit.responses.231 or @unit.tealsign or @unit.transactions or @unit.transactions.payment"
12
unit:
2-
behave --tags="@unit.offline or @unit.algod or @unit.indexer or @unit.rekey or @unit.tealsign or @unit.dryrun or @unit.applications or @unit.responses or @unit.transactions or @unit.transactions.payment or @unit.responses.231 or @unit.feetest or @unit.indexer.logs or @unit.abijson or @unit.atomic_transaction_composer" test -f progress2
3+
behave --tags=$(UNITS) test -f progress2
34

5+
INTEGRATIONS = "@abi or @algod or @applications or @applications.verified or @assets or @auction or @c2c or @compile or @dryrun or @dryrun.testing or @indexer or @indexer.231 or @indexer.applications or @kmd or @rekey or @send"
46
integration:
5-
behave --tags="@algod or @assets or @auction or @kmd or @send or @template or @indexer or @indexer.applications or @rekey or @compile or @dryrun or @dryrun.testing or @applications or @applications.verified or @indexer.231 or @abi" test -f progress2
7+
behave --tags=$(INTEGRATIONS) test -f progress2
68

79
docker-test:
810
./run_integration.sh

README.md

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,31 @@
11
# py-algorand-sdk
2-
[![Build Status](https://travis-ci.com/algorand/py-algorand-sdk.svg?branch=master)](https://travis-ci.com/algorand/py-algorand-sdk)
3-
[![PyPI version](https://badge.fury.io/py/py-algorand-sdk.svg)](https://badge.fury.io/py/py-algorand-sdk)
4-
[![Documentation Status](https://readthedocs.org/projects/py-algorand-sdk/badge/?version=latest&style=flat)](https://py-algorand-sdk.readthedocs.io/en/latest)
2+
3+
[![Build Status](https://travis-ci.com/algorand/py-algorand-sdk.svg?branch=master)](https://travis-ci.com/algorand/py-algorand-sdk)
4+
[![PyPI version](https://badge.fury.io/py/py-algorand-sdk.svg)](https://badge.fury.io/py/py-algorand-sdk)
5+
[![Documentation Status](https://readthedocs.org/projects/py-algorand-sdk/badge/?version=latest&style=flat)](https://py-algorand-sdk.readthedocs.io/en/latest)
56
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
67

78
A python library for interacting with the Algorand network.
89

910
## Installation
1011

11-
Run ```$ pip3 install py-algorand-sdk``` to install the package.
12+
Run `$ pip3 install py-algorand-sdk` to install the package.
1213

13-
Alternatively, choose a [distribution file](https://pypi.org/project/py-algorand-sdk/#files), and run ```$ pip3 install [file name]```.
14+
Alternatively, choose a [distribution file](https://pypi.org/project/py-algorand-sdk/#files), and run `$ pip3 install [file name]`.
1415

1516
## SDK Development
1617

1718
Install dependencies
18-
* `pip install -r requirements.txt`
19+
20+
- `pip install -r requirements.txt`
1921

2022
Run tests
21-
* `make docker-test`
23+
24+
- `make docker-test`
2225

2326
Format code:
24-
* `black .`
27+
28+
- `black .`
2529

2630
## Quick start
2731

@@ -50,18 +54,18 @@ Follow the instructions in Algorand's [developer resources](https://developer.al
5054

5155
Before running [example.py](https://github.com/algorand/py-algorand-sdk/blob/master/examples/example.py), start kmd on a private network or testnet node:
5256

53-
```
54-
$ ./goal kmd start -d [data directory]
57+
```bash
58+
./goal kmd start -d [data directory]
5559
```
5660

5761
Next, create a wallet and an account:
5862

59-
```
60-
$ ./goal wallet new [wallet name] -d [data directory]
63+
```bash
64+
./goal wallet new [wallet name] -d [data directory]
6165
```
6266

63-
```
64-
$ ./goal account new -d [data directory] -w [wallet name]
67+
```bash
68+
./goal account new -d [data directory] -w [wallet name]
6569
```
6670

6771
Visit the [Algorand dispenser](https://bank.testnet.algorand.network/) and enter the account address to fund your account.
@@ -71,7 +75,9 @@ Next, in [tokens.py](https://github.com/algorand/py-algorand-sdk/blob/master/exa
7175
You're now ready to run example.py!
7276

7377
## Documentation
78+
7479
Documentation for the Python SDK is available at [py-algorand-sdk.readthedocs.io](https://py-algorand-sdk.readthedocs.io/en/latest/).
7580

7681
## License
77-
py-algorand-sdk is licensed under a MIT license. See the [LICENSE](https://github.com/algorand/py-algorand-sdk/blob/master/LICENSE) file for details.
82+
83+
py-algorand-sdk is licensed under an MIT license. See the [LICENSE](https://github.com/algorand/py-algorand-sdk/blob/master/LICENSE) file for details.

algosdk/atomic_transaction_composer.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -495,26 +495,27 @@ def execute(
495495
raw_value = None
496496
return_value = None
497497
decode_error = None
498+
tx_info = None
498499

499500
if i not in self.method_dict:
500501
continue
501-
# Return is void
502-
if self.method_dict[i].returns.type == abi.Returns.VOID:
503-
method_results.append(
504-
ABIResult(
505-
tx_id=tx_id,
506-
raw_value=raw_value,
507-
return_value=return_value,
508-
decode_error=decode_error,
509-
)
510-
)
511-
continue
512502

513503
# Parse log for ABI method return value
514504
try:
515-
resp = client.pending_transaction_info(tx_id)
516-
confirmed_round = resp["confirmed-round"]
517-
logs = resp["logs"] if "logs" in resp else []
505+
tx_info = client.pending_transaction_info(tx_id)
506+
if self.method_dict[i].returns.type == abi.Returns.VOID:
507+
method_results.append(
508+
ABIResult(
509+
tx_id=tx_id,
510+
raw_value=raw_value,
511+
return_value=return_value,
512+
decode_error=decode_error,
513+
tx_info=tx_info,
514+
)
515+
)
516+
continue
517+
518+
logs = tx_info["logs"] if "logs" in tx_info else []
518519

519520
# Look for the last returned value in the log
520521
if not logs:
@@ -543,6 +544,7 @@ def execute(
543544
raw_value=raw_value,
544545
return_value=return_value,
545546
decode_error=decode_error,
547+
tx_info=tx_info,
546548
)
547549
method_results.append(abi_result)
548550

@@ -689,16 +691,18 @@ def __init__(
689691
raw_value: bytes,
690692
return_value: Any,
691693
decode_error: error,
694+
tx_info: dict,
692695
) -> None:
693696
self.tx_id = tx_id
694697
self.raw_value = raw_value
695698
self.return_value = return_value
696699
self.decode_error = decode_error
700+
self.tx_info = tx_info
697701

698702

699703
class AtomicTransactionResponse:
700704
def __init__(
701-
self, confirmed_round: int, tx_ids: List[str], results: ABIResult
705+
self, confirmed_round: int, tx_ids: List[str], results: List[ABIResult]
702706
) -> None:
703707
self.confirmed_round = confirmed_round
704708
self.tx_ids = tx_ids

algosdk/future/template.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77

88

99
class Template:
10+
"""
11+
NOTE: This class is deprecated
12+
"""
13+
1014
def get_address(self):
1115
"""
1216
Return the address of the contract.
@@ -19,6 +23,8 @@ def get_program(self):
1923

2024
class Split(Template):
2125
"""
26+
NOTE: This class is deprecated.
27+
2228
Split allows locking algos in an account which allows transfering to two
2329
predefined addresses in a specified ratio such that for the given ratn and
2430
ratd parameters we have:
@@ -156,6 +162,8 @@ def get_split_funds_transaction(contract, amount: int, sp):
156162

157163
class HTLC(Template):
158164
"""
165+
NOTE: This class is deprecated.
166+
159167
Hash Time Locked Contract allows a user to recieve the Algo prior to a
160168
deadline (in terms of a round) by proving knowledge of a special value
161169
or to forfeit the ability to claim, returning it to the payer.
@@ -291,6 +299,8 @@ def get_transaction(contract, preimage, sp):
291299

292300
class DynamicFee(Template):
293301
"""
302+
NOTE: This class is deprecated.
303+
294304
DynamicFee contract allows you to create a transaction without
295305
specifying the fee. The fee will be determined at the moment of
296306
transfer.
@@ -416,6 +426,8 @@ def sign_dynamic_fee(self, private_key):
416426

417427
class PeriodicPayment(Template):
418428
"""
429+
NOTE: This class is deprecated.
430+
419431
PeriodicPayment contract enables creating an account which allows the
420432
withdrawal of a fixed amount of assets every fixed number of rounds to a
421433
specific Algrorand Address. In addition, the contract allows to add
@@ -528,6 +540,8 @@ def get_withdrawal_transaction(contract, sp):
528540

529541
class LimitOrder(Template):
530542
"""
543+
NOTE: This class is deprecated.
544+
531545
Limit Order allows to trade Algos for other assets given a specific ratio;
532546
for N Algos, swap for Rate * N Assets.
533547
...

algosdk/logic.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,12 @@ def get_application_address(appID: int) -> str:
278278
Returns:
279279
str: The address corresponding to that application's escrow account.
280280
"""
281+
assert isinstance(
282+
appID, int
283+
), "(Expected an int for appID but got [{}] which has type [{}])".format(
284+
appID, type(appID)
285+
)
286+
281287
to_sign = constants.APPID_PREFIX + appID.to_bytes(8, "big")
282288
checksum = encoding.checksum(to_sign)
283289
return encoding.encode_address(checksum)

algosdk/v2client/algod.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
from urllib.request import Request, urlopen
1+
import base64
2+
import json
23
from urllib import parse
34
import urllib.error
4-
import json
5-
import base64
6-
from .. import error
7-
from .. import encoding
8-
from .. import constants
9-
from .. import future
10-
import msgpack
11-
from .. import util
5+
from urllib.request import Request, urlopen
6+
7+
from .. import constants, encoding, error, future, logic, util
128

139
api_version_path_prefix = "/v2"
1410

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
.
22
black==21.9b0
3+
glom==20.11.0
4+
pytest==6.2.5
35
git+https://github.com/behave/behave

run_integration.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pushd $rootdir
77

88
# Reset test harness
99
rm -rf test-harness
10-
git clone --single-branch --branch master https://github.com/algorand/algorand-sdk-testing.git test-harness
10+
git clone --single-branch --branch zc2c https://github.com/algorand/algorand-sdk-testing.git test-harness
1111

1212
## Copy feature files into the project resources
1313
mkdir -p test/features

test/environment.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def encode_bytes(d):
3232
encode_bytes(d[i])
3333
else:
3434
if isinstance(d[i], bytes):
35-
d[i] = base64.b64encode(v).decode()
35+
d[i] = base64.b64encode(d[i]).decode()
3636
return d
3737

3838

test/steps/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)