Skip to content

Commit

Permalink
Merge branch 'release/v1.16.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
algobarb committed Aug 18, 2022
2 parents a8508ab + 77e196d commit 9964004
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 71 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

# v1.16.1
### Bugfixes
* 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
### Enhancements
* AVM: Consolidate TEAL and AVM versions by @michaeldiamant in https://github.com/algorand/py-algorand-sdk/pull/361
* Testing: Modify cucumber steps to use dev mode network by @algochoi in https://github.com/algorand/py-algorand-sdk/pull/360

# v1.16.0

## What's Changed
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ UNITS = "@unit.abijson or @unit.abijson.byname or @unit.algod or @unit.algod.led
unit:
behave --tags=$(UNITS) tests -f progress2

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"
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"
integration:
behave --tags=$(INTEGRATIONS) tests -f progress2

Expand Down
3 changes: 2 additions & 1 deletion algosdk/abi/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ def dictify(self) -> dict:
d = {}
d["name"] = self.name
d["methods"] = [m.dictify() for m in self.methods]
d["desc"] = self.desc
d["networks"] = {k: v.dictify() for k, v in self.networks.items()}
if self.desc is not None:
d["desc"] = self.desc
return d

@staticmethod
Expand Down
2 changes: 1 addition & 1 deletion algosdk/logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def read_program(program, args=None):
# costs calculated dynamically starting in v4
if version < 4 and cost >= constants.logic_sig_max_cost:
raise error.InvalidProgram(
"program too costly for Teal version < 4. consider using v4."
"program too costly for version < 4. consider using v4."
)

return True, ints, bytearrays
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
description="Algorand SDK in Python",
author="Algorand",
author_email="[email protected]",
version="v1.16.0",
version="v1.16.1",
long_description=long_description,
long_description_content_type="text/markdown",
license="MIT",
Expand Down
11 changes: 5 additions & 6 deletions tests/steps/account_v2_steps.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from behave import given, then, when
from typing import Union

from algosdk import account, encoding, logic
from algosdk import account, constants, encoding, logic
from algosdk.future import transaction

import tests.steps.other_v2_steps
from behave import given, then, when
import tests.steps.other_v2_steps # Imports MaybeString


def fund_account_address(
Expand All @@ -19,7 +18,7 @@ def fund_account_address(
)
signed_payment = context.wallet.sign_transaction(payment)
context.app_acl.send_transaction(signed_payment)
transaction.wait_for_confirmation(context.app_acl, payment.get_txid(), 10)
transaction.wait_for_confirmation(context.app_acl, payment.get_txid(), 1)


@when(
Expand Down Expand Up @@ -454,7 +453,7 @@ def create_transient_and_fund(context, transient_fund_amount):
)
signed_payment = context.wallet.sign_transaction(payment)
context.app_acl.send_transaction(signed_payment)
transaction.wait_for_confirmation(context.app_acl, payment.get_txid(), 10)
transaction.wait_for_confirmation(context.app_acl, payment.get_txid(), 1)


@then(
Expand Down
29 changes: 18 additions & 11 deletions tests/steps/application_v2_steps.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import base64
import json
import re
import time

from behave import given, step, then, when
import pytest

from algosdk import abi, atomic_transaction_composer, encoding, mnemonic
from algosdk.abi.contract import NetworkInfo
from algosdk.error import (
ABITypeError,
IndexerHTTPError,
AtomicTransactionComposerError,
IndexerHTTPError,
)
from algosdk.future import transaction

from tests.steps.other_v2_steps import read_program
from behave import given, step, then, when
from tests.steps.other_v2_steps import (
read_program,
)


def operation_string_to_enum(operation):
Expand Down Expand Up @@ -402,20 +403,26 @@ def remember_app_id(context):
context.app_ids.append(app_id)


def wait_for_algod_transaction_processing_to_complete():
"""
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)`.
* <p>
* 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.
"""
time.sleep(0.5)


@step("I wait for the transaction to be confirmed.")
def wait_for_app_txn_confirm(context):
sp = context.app_acl.suggested_params()
last_round = sp.first
context.app_acl.status_after_block(last_round + 2)
wait_for_algod_transaction_processing_to_complete()
if hasattr(context, "acl"):
assert "type" in context.acl.transaction_info(
context.transient_pk, context.app_txid
)
assert "type" in context.acl.transaction_by_id(context.app_txid)
else:
transaction.wait_for_confirmation(
context.app_acl, context.app_txid, 10
)
transaction.wait_for_confirmation(context.app_acl, context.app_txid, 1)


@given("an application id {app_id}")
Expand Down
33 changes: 16 additions & 17 deletions tests/steps/other_v2_steps.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,35 @@
import base64
import json
import os
import urllib
import unittest
import urllib
from datetime import datetime
from pathlib import Path
from urllib.request import Request, urlopen

from behave import (
given,
when,
then,
register_type,
step,
) # pylint: disable=no-name-in-module

from glom import glom
import parse

from algosdk import dryrun_results, encoding, error, mnemonic, source_map
from algosdk import (
dryrun_results,
encoding,
error,
mnemonic,
source_map,
)
from algosdk.error import AlgodHTTPError
from algosdk.future import transaction
from algosdk.testing.dryrun import DryrunTestCaseMixin
from algosdk.v2client import *
from algosdk.v2client.models import (
DryrunRequest,
DryrunSource,
Account,
ApplicationLocalState,
DryrunRequest,
DryrunSource,
)
from algosdk.testing.dryrun import DryrunTestCaseMixin

from tests.steps.steps import algod_port, token as daemon_token
from behave import register_type # pylint: disable=no-name-in-module
from behave import given, step, then, when
from glom import glom
from tests.steps.steps import algod_port
from tests.steps.steps import token as daemon_token


@parse.with_pattern(r".*")
Expand Down
108 changes: 85 additions & 23 deletions tests/steps/steps.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,73 @@
from behave import given, when, then
import base64
from algosdk import kmd
from algosdk.future import transaction
from algosdk import encoding
from algosdk import algod
from algosdk import account
from algosdk import mnemonic
from algosdk import wallet
from algosdk import auction
from algosdk import util
from algosdk import constants
from algosdk import logic
from algosdk.future import template
import os
import random
import time
from datetime import datetime
import hashlib

from algosdk import (
account,
algod,
auction,
encoding,
kmd,
logic,
mnemonic,
util,
wallet,
)
from algosdk.future import transaction
from behave import given, then, when
from nacl.signing import SigningKey

token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
algod_port = 60000
kmd_port = 60001

DEV_ACCOUNT_INITIAL_MICROALGOS: int = 10_000_000


def wait_for_algod_transaction_processing_to_complete():
"""
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)`.
* <p>
* 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.
"""
time.sleep(0.5)


# Initialize a transient account in dev mode to make payment transactions.
def initialize_account(context, account):
payment = transaction.PaymentTxn(
sender=context.accounts[0],
sp=context.acl.suggested_params_as_object(),
receiver=account,
amt=DEV_ACCOUNT_INITIAL_MICROALGOS,
)
signed_payment = context.wallet.sign_transaction(payment)
context.acl.send_transaction(signed_payment)
# Wait to let transaction get confirmed in dev mode in v1.
wait_for_algod_transaction_processing_to_complete()


# Send a self-payment transaction to itself to advance blocks in dev mode.
def self_pay_transactions(context, num_txns=1):
if not hasattr(context, "dev_pk"):
context.dev_sk, context.dev_pk = account.generate_account()
initialize_account(context, context.dev_pk)
for _ in range(num_txns):
payment = transaction.PaymentTxn(
sender=context.dev_pk,
sp=context.acl.suggested_params_as_object(),
receiver=context.dev_pk,
amt=random.randint(1, int(DEV_ACCOUNT_INITIAL_MICROALGOS * 0.01)),
)
signed_payment = payment.sign(context.dev_sk)
context.acl.send_transaction(signed_payment)
# Wait to let transaction get confirmed in dev mode in v1.
wait_for_algod_transaction_processing_to_complete()


@when("I create a wallet")
def create_wallet(context):
Expand Down Expand Up @@ -225,13 +271,15 @@ def status(context):

@when("I get status after this block")
def status_block(context):
self_pay_transactions(context)
context.status_after = context.acl.status_after_block(
context.status["lastRound"]
)


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


Expand Down Expand Up @@ -274,6 +322,12 @@ def gen_key_kmd(context):
context.pk = context.wallet.generate_key()


@when("I generate a key using kmd for rekeying and fund it")
def gen_rekey_kmd(context):
context.rekey = context.wallet.generate_key()
initialize_account(context, context.rekey)


@then("the key should be in the wallet")
def key_in_wallet(context):
keys = context.wallet.list_keys()
Expand Down Expand Up @@ -320,6 +374,7 @@ def algod_client(context):
algod_address = "http://localhost:" + str(algod_port)
context.acl = algod.AlgodClient(token, algod_address)
if context.acl.status()["lastRound"] < 2:
self_pay_transactions(context, 2)
context.acl.status_after_block(2)


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


@given('default transaction with parameters {amt} "{note}"')
def default_txn(context, amt, note):
def default_txn_with_addr(context, amt, note, sender_addr):
params = context.acl.suggested_params_as_object()
context.last_round = params.first
if note == "none":
note = None
else:
note = base64.b64decode(note)
context.txn = transaction.PaymentTxn(
context.accounts[0], params, context.accounts[1], int(amt), note=note
sender_addr, params, context.accounts[1], int(amt), note=note
)
context.pk = context.accounts[0]
context.pk = sender_addr


@given('default transaction with parameters {amt} "{note}"')
def default_txn(context, amt, note):
default_txn_with_addr(context, amt, note, context.accounts[0])


@given('default transaction with parameters {amt} "{note}" and rekeying key')
def default_txn_rekey(context, amt, note):
default_txn_with_addr(context, amt, note, context.rekey)


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

@then("the transaction should go through")
def check_txn(context):
last_round = context.acl.status()["lastRound"]
wait_for_algod_transaction_processing_to_complete()
assert "type" in context.acl.pending_transaction_info(
context.txn.get_txid()
)
context.acl.status_after_block(last_round + 2)
assert "type" in context.acl.transaction_info(
context.txn.sender, context.txn.get_txid()
)
Expand All @@ -417,7 +480,7 @@ def check_txn(context):

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


Expand Down Expand Up @@ -492,8 +555,7 @@ def check_save_txn(context):
dir_path = os.path.dirname(os.path.dirname(dir_path))
stx = transaction.retrieve_from_file(dir_path + "/temp/txn.tx")[0]
txid = stx.transaction.get_txid()
last_round = context.acl.status()["lastRound"]
context.acl.status_after_block(last_round + 2)
wait_for_algod_transaction_processing_to_complete()
assert context.acl.transaction_info(stx.transaction.sender, txid)


Expand Down
Loading

0 comments on commit 9964004

Please sign in to comment.