Skip to content

Commit 9964004

Browse files
committed
Merge branch 'release/v1.16.1'
2 parents a8508ab + 77e196d commit 9964004

10 files changed

+146
-71
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
# v1.16.1
4+
### Bugfixes
5+
* bug-fix: add check to desc so we dont output null if undefined by @barnjamin in https://github.com/algorand/py-algorand-sdk/pull/368
6+
### Enhancements
7+
* AVM: Consolidate TEAL and AVM versions by @michaeldiamant in https://github.com/algorand/py-algorand-sdk/pull/361
8+
* Testing: Modify cucumber steps to use dev mode network by @algochoi in https://github.com/algorand/py-algorand-sdk/pull/360
9+
310
# v1.16.0
411

512
## What's Changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ UNITS = "@unit.abijson or @unit.abijson.byname or @unit.algod or @unit.algod.led
22
unit:
33
behave --tags=$(UNITS) tests -f progress2
44

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.keyregtxn or @send or @compile.sourcemap"
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_v1 or @send.keyregtxn or @send or @compile.sourcemap"
66
integration:
77
behave --tags=$(INTEGRATIONS) tests -f progress2
88

algosdk/abi/contract.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ def dictify(self) -> dict:
4747
d = {}
4848
d["name"] = self.name
4949
d["methods"] = [m.dictify() for m in self.methods]
50-
d["desc"] = self.desc
5150
d["networks"] = {k: v.dictify() for k, v in self.networks.items()}
51+
if self.desc is not None:
52+
d["desc"] = self.desc
5253
return d
5354

5455
@staticmethod

algosdk/logic.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def read_program(program, args=None):
100100
# costs calculated dynamically starting in v4
101101
if version < 4 and cost >= constants.logic_sig_max_cost:
102102
raise error.InvalidProgram(
103-
"program too costly for Teal version < 4. consider using v4."
103+
"program too costly for version < 4. consider using v4."
104104
)
105105

106106
return True, ints, bytearrays

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
description="Algorand SDK in Python",
1010
author="Algorand",
1111
author_email="[email protected]",
12-
version="v1.16.0",
12+
version="v1.16.1",
1313
long_description=long_description,
1414
long_description_content_type="text/markdown",
1515
license="MIT",

tests/steps/account_v2_steps.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
from behave import given, then, when
21
from typing import Union
32

4-
from algosdk import account, encoding, logic
3+
from algosdk import account, constants, encoding, logic
54
from algosdk.future import transaction
6-
7-
import tests.steps.other_v2_steps
5+
from behave import given, then, when
6+
import tests.steps.other_v2_steps # Imports MaybeString
87

98

109
def fund_account_address(
@@ -19,7 +18,7 @@ def fund_account_address(
1918
)
2019
signed_payment = context.wallet.sign_transaction(payment)
2120
context.app_acl.send_transaction(signed_payment)
22-
transaction.wait_for_confirmation(context.app_acl, payment.get_txid(), 10)
21+
transaction.wait_for_confirmation(context.app_acl, payment.get_txid(), 1)
2322

2423

2524
@when(
@@ -454,7 +453,7 @@ def create_transient_and_fund(context, transient_fund_amount):
454453
)
455454
signed_payment = context.wallet.sign_transaction(payment)
456455
context.app_acl.send_transaction(signed_payment)
457-
transaction.wait_for_confirmation(context.app_acl, payment.get_txid(), 10)
456+
transaction.wait_for_confirmation(context.app_acl, payment.get_txid(), 1)
458457

459458

460459
@then(

tests/steps/application_v2_steps.py

+18-11
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
import base64
22
import json
33
import re
4+
import time
45

5-
from behave import given, step, then, when
66
import pytest
7-
87
from algosdk import abi, atomic_transaction_composer, encoding, mnemonic
98
from algosdk.abi.contract import NetworkInfo
109
from algosdk.error import (
1110
ABITypeError,
12-
IndexerHTTPError,
1311
AtomicTransactionComposerError,
12+
IndexerHTTPError,
1413
)
1514
from algosdk.future import transaction
16-
17-
from tests.steps.other_v2_steps import read_program
15+
from behave import given, step, then, when
16+
from tests.steps.other_v2_steps import (
17+
read_program,
18+
)
1819

1920

2021
def operation_string_to_enum(operation):
@@ -402,20 +403,26 @@ def remember_app_id(context):
402403
context.app_ids.append(app_id)
403404

404405

406+
def wait_for_algod_transaction_processing_to_complete():
407+
"""
408+
wait_for_algod_transaction_processing_to_complete is a Dev mode helper method that's a rough analog to `context.app_acl.status_after_block(last_round + 2)`.
409+
* <p>
410+
* Since Dev mode produces blocks on a per transaction basis, it's possible algod generates a block _before_ the corresponding SDK call to wait for a block. Without _any_ wait, it's possible the SDK looks for the transaction before algod completes processing. So, the method performs a local sleep to simulate waiting for a block.
411+
412+
"""
413+
time.sleep(0.5)
414+
415+
405416
@step("I wait for the transaction to be confirmed.")
406417
def wait_for_app_txn_confirm(context):
407-
sp = context.app_acl.suggested_params()
408-
last_round = sp.first
409-
context.app_acl.status_after_block(last_round + 2)
418+
wait_for_algod_transaction_processing_to_complete()
410419
if hasattr(context, "acl"):
411420
assert "type" in context.acl.transaction_info(
412421
context.transient_pk, context.app_txid
413422
)
414423
assert "type" in context.acl.transaction_by_id(context.app_txid)
415424
else:
416-
transaction.wait_for_confirmation(
417-
context.app_acl, context.app_txid, 10
418-
)
425+
transaction.wait_for_confirmation(context.app_acl, context.app_txid, 1)
419426

420427

421428
@given("an application id {app_id}")

tests/steps/other_v2_steps.py

+16-17
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,35 @@
11
import base64
22
import json
33
import os
4-
import urllib
54
import unittest
5+
import urllib
66
from datetime import datetime
77
from pathlib import Path
88
from urllib.request import Request, urlopen
99

10-
from behave import (
11-
given,
12-
when,
13-
then,
14-
register_type,
15-
step,
16-
) # pylint: disable=no-name-in-module
17-
18-
from glom import glom
1910
import parse
20-
21-
from algosdk import dryrun_results, encoding, error, mnemonic, source_map
11+
from algosdk import (
12+
dryrun_results,
13+
encoding,
14+
error,
15+
mnemonic,
16+
source_map,
17+
)
2218
from algosdk.error import AlgodHTTPError
2319
from algosdk.future import transaction
20+
from algosdk.testing.dryrun import DryrunTestCaseMixin
2421
from algosdk.v2client import *
2522
from algosdk.v2client.models import (
26-
DryrunRequest,
27-
DryrunSource,
2823
Account,
2924
ApplicationLocalState,
25+
DryrunRequest,
26+
DryrunSource,
3027
)
31-
from algosdk.testing.dryrun import DryrunTestCaseMixin
32-
33-
from tests.steps.steps import algod_port, token as daemon_token
28+
from behave import register_type # pylint: disable=no-name-in-module
29+
from behave import given, step, then, when
30+
from glom import glom
31+
from tests.steps.steps import algod_port
32+
from tests.steps.steps import token as daemon_token
3433

3534

3635
@parse.with_pattern(r".*")

tests/steps/steps.py

+85-23
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,73 @@
1-
from behave import given, when, then
21
import base64
3-
from algosdk import kmd
4-
from algosdk.future import transaction
5-
from algosdk import encoding
6-
from algosdk import algod
7-
from algosdk import account
8-
from algosdk import mnemonic
9-
from algosdk import wallet
10-
from algosdk import auction
11-
from algosdk import util
12-
from algosdk import constants
13-
from algosdk import logic
14-
from algosdk.future import template
152
import os
3+
import random
4+
import time
165
from datetime import datetime
17-
import hashlib
186

7+
from algosdk import (
8+
account,
9+
algod,
10+
auction,
11+
encoding,
12+
kmd,
13+
logic,
14+
mnemonic,
15+
util,
16+
wallet,
17+
)
18+
from algosdk.future import transaction
19+
from behave import given, then, when
1920
from nacl.signing import SigningKey
2021

2122
token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
2223
algod_port = 60000
2324
kmd_port = 60001
2425

26+
DEV_ACCOUNT_INITIAL_MICROALGOS: int = 10_000_000
27+
28+
29+
def wait_for_algod_transaction_processing_to_complete():
30+
"""
31+
wait_for_algod_transaction_processing_to_complete is a Dev mode helper method that's a rough analog to `context.app_acl.status_after_block(last_round + 2)`.
32+
* <p>
33+
* Since Dev mode produces blocks on a per transaction basis, it's possible algod generates a block _before_ the corresponding SDK call to wait for a block.
34+
* Without _any_ wait, it's possible the SDK looks for the transaction before algod completes processing.
35+
* So, the method performs a local sleep to simulate waiting for a block.
36+
"""
37+
time.sleep(0.5)
38+
39+
40+
# Initialize a transient account in dev mode to make payment transactions.
41+
def initialize_account(context, account):
42+
payment = transaction.PaymentTxn(
43+
sender=context.accounts[0],
44+
sp=context.acl.suggested_params_as_object(),
45+
receiver=account,
46+
amt=DEV_ACCOUNT_INITIAL_MICROALGOS,
47+
)
48+
signed_payment = context.wallet.sign_transaction(payment)
49+
context.acl.send_transaction(signed_payment)
50+
# Wait to let transaction get confirmed in dev mode in v1.
51+
wait_for_algod_transaction_processing_to_complete()
52+
53+
54+
# Send a self-payment transaction to itself to advance blocks in dev mode.
55+
def self_pay_transactions(context, num_txns=1):
56+
if not hasattr(context, "dev_pk"):
57+
context.dev_sk, context.dev_pk = account.generate_account()
58+
initialize_account(context, context.dev_pk)
59+
for _ in range(num_txns):
60+
payment = transaction.PaymentTxn(
61+
sender=context.dev_pk,
62+
sp=context.acl.suggested_params_as_object(),
63+
receiver=context.dev_pk,
64+
amt=random.randint(1, int(DEV_ACCOUNT_INITIAL_MICROALGOS * 0.01)),
65+
)
66+
signed_payment = payment.sign(context.dev_sk)
67+
context.acl.send_transaction(signed_payment)
68+
# Wait to let transaction get confirmed in dev mode in v1.
69+
wait_for_algod_transaction_processing_to_complete()
70+
2571

2672
@when("I create a wallet")
2773
def create_wallet(context):
@@ -225,13 +271,15 @@ def status(context):
225271

226272
@when("I get status after this block")
227273
def status_block(context):
274+
self_pay_transactions(context)
228275
context.status_after = context.acl.status_after_block(
229276
context.status["lastRound"]
230277
)
231278

232279

233280
@then("I can get the block info")
234281
def block(context):
282+
self_pay_transactions(context)
235283
context.block = context.acl.block_info(context.status["lastRound"] + 1)
236284

237285

@@ -274,6 +322,12 @@ def gen_key_kmd(context):
274322
context.pk = context.wallet.generate_key()
275323

276324

325+
@when("I generate a key using kmd for rekeying and fund it")
326+
def gen_rekey_kmd(context):
327+
context.rekey = context.wallet.generate_key()
328+
initialize_account(context, context.rekey)
329+
330+
277331
@then("the key should be in the wallet")
278332
def key_in_wallet(context):
279333
keys = context.wallet.list_keys()
@@ -320,6 +374,7 @@ def algod_client(context):
320374
algod_address = "http://localhost:" + str(algod_port)
321375
context.acl = algod.AlgodClient(token, algod_address)
322376
if context.acl.status()["lastRound"] < 2:
377+
self_pay_transactions(context, 2)
323378
context.acl.status_after_block(2)
324379

325380

@@ -334,18 +389,27 @@ def wallet_info(context):
334389
context.accounts = context.wallet.list_keys()
335390

336391

337-
@given('default transaction with parameters {amt} "{note}"')
338-
def default_txn(context, amt, note):
392+
def default_txn_with_addr(context, amt, note, sender_addr):
339393
params = context.acl.suggested_params_as_object()
340394
context.last_round = params.first
341395
if note == "none":
342396
note = None
343397
else:
344398
note = base64.b64decode(note)
345399
context.txn = transaction.PaymentTxn(
346-
context.accounts[0], params, context.accounts[1], int(amt), note=note
400+
sender_addr, params, context.accounts[1], int(amt), note=note
347401
)
348-
context.pk = context.accounts[0]
402+
context.pk = sender_addr
403+
404+
405+
@given('default transaction with parameters {amt} "{note}"')
406+
def default_txn(context, amt, note):
407+
default_txn_with_addr(context, amt, note, context.accounts[0])
408+
409+
410+
@given('default transaction with parameters {amt} "{note}" and rekeying key')
411+
def default_txn_rekey(context, amt, note):
412+
default_txn_with_addr(context, amt, note, context.rekey)
349413

350414

351415
@given('default multisig transaction with parameters {amt} "{note}"')
@@ -404,11 +468,10 @@ def send_msig_txn(context):
404468

405469
@then("the transaction should go through")
406470
def check_txn(context):
407-
last_round = context.acl.status()["lastRound"]
471+
wait_for_algod_transaction_processing_to_complete()
408472
assert "type" in context.acl.pending_transaction_info(
409473
context.txn.get_txid()
410474
)
411-
context.acl.status_after_block(last_round + 2)
412475
assert "type" in context.acl.transaction_info(
413476
context.txn.sender, context.txn.get_txid()
414477
)
@@ -417,7 +480,7 @@ def check_txn(context):
417480

418481
@then("I can get the transaction by ID")
419482
def get_txn_by_id(context):
420-
context.acl.status_after_block(context.last_round + 2)
483+
wait_for_algod_transaction_processing_to_complete()
421484
assert "type" in context.acl.transaction_by_id(context.txn.get_txid())
422485

423486

@@ -492,8 +555,7 @@ def check_save_txn(context):
492555
dir_path = os.path.dirname(os.path.dirname(dir_path))
493556
stx = transaction.retrieve_from_file(dir_path + "/temp/txn.tx")[0]
494557
txid = stx.transaction.get_txid()
495-
last_round = context.acl.status()["lastRound"]
496-
context.acl.status_after_block(last_round + 2)
558+
wait_for_algod_transaction_processing_to_complete()
497559
assert context.acl.transaction_info(stx.transaction.sender, txid)
498560

499561

0 commit comments

Comments
 (0)