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

New keyreg txn field #244

Merged
merged 13 commits into from
Feb 14, 2022
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ venv.bak/
# vscode
.vscode/

# pycharm
.idea

# DS_Store
.DS_Store

Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
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"
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.transactions.keyreg or @unit.responses or @unit.responses.231 or @unit.tealsign or @unit.transactions or @unit.transactions.payment"
unit:
behave --tags=$(UNITS) test -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"
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"
integration:
behave --tags=$(INTEGRATIONS) test -f progress2

Expand Down
43 changes: 36 additions & 7 deletions algosdk/future/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ class KeyregTxn(Transaction):
transaction's valid rounds
rekey_to (str, optional): additionally rekey the sender to this address
nonpart (bool, optional): mark the account non-participating if true
StateProofPK: state proof

Attributes:
sender (str)
Expand All @@ -446,6 +447,7 @@ class KeyregTxn(Transaction):
lease (byte[32])
rekey_to (str)
nonpart (bool)
sprfkey (str)
"""

def __init__(
Expand All @@ -461,6 +463,7 @@ def __init__(
lease=None,
rekey_to=None,
nonpart=None,
sprfkey=None,
):
Transaction.__init__(
self, sender, sp, note, lease, constants.keyreg_txn, rekey_to
Expand All @@ -471,6 +474,8 @@ def __init__(
self.votelst = votelst
self.votekd = votekd
self.nonpart = nonpart
self.sprfkey = sprfkey

if not sp.flat_fee:
self.fee = max(
self.estimate_size() * self.fee, constants.min_txn_fee
Expand All @@ -490,6 +495,9 @@ def dictify(self):
d["votelst"] = self.votelst
if self.nonpart is not None:
d["nonpart"] = self.nonpart
if self.sprfkey is not None:
d["sprfkey"] = base64.b64decode(self.sprfkey)

d.update(super(KeyregTxn, self).dictify())
od = OrderedDict(sorted(d.items()))

Expand All @@ -506,6 +514,7 @@ def __eq__(self, other):
and self.votelst == other.votelst
and self.votekd == other.votekd
and self.nonpart == other.nonpart
and self.sprfkey == other.sprfkey
)


Expand All @@ -527,6 +536,7 @@ class KeyregOnlineTxn(KeyregTxn):
with the same sender and lease can be confirmed in this
transaction's valid rounds
rekey_to (str, optional): additionally rekey the sender to this address
sprfkey (str, optional): state proof ID

Attributes:
sender (str)
Expand All @@ -545,6 +555,7 @@ class KeyregOnlineTxn(KeyregTxn):
type (str)
lease (byte[32])
rekey_to (str)
sprfkey (str)
"""

def __init__(
Expand All @@ -559,6 +570,7 @@ def __init__(
note=None,
lease=None,
rekey_to=None,
sprfkey=None,
):
KeyregTxn.__init__(
self,
Expand All @@ -573,12 +585,14 @@ def __init__(
lease,
rekey_to,
nonpart=False,
sprfkey=sprfkey,
)
self.votepk = votekey
self.selkey = selkey
self.votefst = votefst
self.votelst = votelst
self.votekd = votekd
self.sprfkey = sprfkey
if votekey is None:
raise error.KeyregOnlineTxnInitError("votekey")
if selkey is None:
Expand All @@ -601,13 +615,26 @@ def _undictify(d):
votefst = d["votefst"]
votelst = d["votelst"]
votekd = d["votekd"]
args = {
"votekey": votekey,
"selkey": selkey,
"votefst": votefst,
"votelst": votelst,
"votekd": votekd,
}
if "sprfkey" in d:
sprfID = base64.b64encode(d["sprfkey"]).decode()

args = {
"votekey": votekey,
"selkey": selkey,
"votefst": votefst,
"votelst": votelst,
"votekd": votekd,
"sprfkey": sprfID,
}
else:
args = {
"votekey": votekey,
"selkey": selkey,
"votefst": votefst,
"votelst": votelst,
"votekd": votekd,
}

return args

def __eq__(self, other):
Expand Down Expand Up @@ -658,6 +685,7 @@ def __init__(self, sender, sp, note=None, lease=None, rekey_to=None):
lease=lease,
rekey_to=rekey_to,
nonpart=False,
sprfkey=None,
)
if not sp.flat_fee:
self.fee = max(
Expand Down Expand Up @@ -717,6 +745,7 @@ def __init__(self, sender, sp, note=None, lease=None, rekey_to=None):
lease=lease,
rekey_to=rekey_to,
nonpart=True,
sprfkey=None,
)
if not sp.flat_fee:
self.fee = max(
Expand Down
28 changes: 28 additions & 0 deletions algosdk/v2client/models/account_participation.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class AccountParticipation(object):
"vote_key_dilution": "int",
"vote_last_valid": "int",
"vote_participation_key": "str",
"state-proof-key": "str",
}

attribute_map = {
Expand All @@ -27,6 +28,7 @@ class AccountParticipation(object):
"vote_key_dilution": "vote-key-dilution",
"vote_last_valid": "vote-last-valid",
"vote_participation_key": "vote-participation-key",
"state_proof_key": "state-proof-key",
}

def __init__(
Expand All @@ -36,6 +38,7 @@ def __init__(
vote_key_dilution=None,
vote_last_valid=None,
vote_participation_key=None,
state_proof_key=None,
): # noqa: E501
"""AccountParticipation - a model defined in OpenAPI""" # noqa: E501

Expand All @@ -44,12 +47,14 @@ def __init__(
self._vote_key_dilution = None
self._vote_last_valid = None
self._vote_participation_key = None
self._state_proof_key = None

self.selection_participation_key = selection_participation_key
self.vote_first_valid = vote_first_valid
self.vote_key_dilution = vote_key_dilution
self.vote_last_valid = vote_last_valid
self.vote_participation_key = vote_participation_key
self.state_proof_key = state_proof_key

@property
def selection_participation_key(self):
Expand Down Expand Up @@ -166,6 +171,29 @@ def vote_participation_key(self, vote_participation_key):

self._vote_participation_key = vote_participation_key

@property
def state_proof_key(self):
"""Gets the state_proof_key of this AccountParticipation. # noqa: E501

\\[sprfkey\\] merkle verifier (if any) stored for this round. # noqa: E501

:return: The state_proof_key of this AccountParticipation. # noqa: E501
:rtype: str
"""
return self._state_proof_key

@state_proof_key.setter
def state_proof_key(self, state_proof_key):
"""Sets the state_proof_key of this AccountParticipation.

\\[sprfkey\\] merkle verifier (if any) stored for this round. # noqa: E501

:param state_proof_key: The state_proof_key of this AccountParticipation. # noqa: E501
:type state_proof_key: str
"""

self._state_proof_key = state_proof_key

def dictify(self):
"""Returns the model properties as a dict"""
result = {}
Expand Down
33 changes: 33 additions & 0 deletions test/steps/steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,13 @@ def create_keyreg_txn(context):
)


@given("default V2 key registration transaction {type}")
def default_v2_keyreg_txn(context, type):
context.params = context.acl.suggested_params_as_object()
context.pk = context.accounts[0]
context.txn = buildTxn(type, context.pk, context.params)


@when("I get recent transactions, limited by {cnt} transactions")
def step_impl(context, cnt):
txns = context.acl.transactions_by_address(
Expand Down Expand Up @@ -1031,3 +1038,29 @@ def fee_not_in_txn(context):
else:
stxn = context.mtx.dictify()
assert "fee" not in stxn["txn"]


def buildTxn(t, sender, params):
txn = None
if "online" in t:
votekey = "9mr13Ri8rFepxN3ghIUrZNui6LqqM5hEzB45Rri5lkU="
selkey = "dx717L3uOIIb/jr9OIyls1l5Ei00NFgRa380w7TnPr4="
votefst = 0
votelst = 2000
votekd = 10
sprf = "mYR0GVEObMTSNdsKM6RwYywHYPqVDqg3E4JFzxZOreH9NU8B+tKzUanyY8AQ144hETgSMX7fXWwjBdHz6AWk9w=="
txn = transaction.KeyregOnlineTxn(
sender,
params,
votekey,
selkey,
votefst,
votelst,
votekd,
sprfkey=sprf,
)
elif "offline" in t:
txn = transaction.KeyregOfflineTxn(sender, params)
elif "nonparticipation" in t:
txn = transaction.KeyregNonparticipatingTxn(sender, params)
return txn
45 changes: 45 additions & 0 deletions test/steps/v2_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -1685,6 +1685,51 @@ def suggested_transaction_parameters(
)


@when(
'I build a keyreg transaction with sender "{sender}", nonparticipation "{nonpart:MaybeBool}", vote first {vote_first}, vote last {vote_last}, key dilution {key_dilution}, vote public key "{vote_pk:MaybeString}", selection public key "{selection_pk:MaybeString}", and state proof public key "{state_proof_pk:MaybeString}"'
)
def step_impl(
context,
sender,
nonpart,
vote_first,
vote_last,
key_dilution,
vote_pk,
selection_pk,
state_proof_pk,
):
if nonpart:
context.transaction = transaction.KeyregNonparticipatingTxn(
sender, context.suggested_params
)
return

if len(vote_pk) == 0:
vote_pk = None
if len(selection_pk) == 0:
selection_pk = None
if len(state_proof_pk) == 0:
state_proof_pk = None

if vote_pk is None and selection_pk is None and state_proof_pk is None:
context.transaction = transaction.KeyregOfflineTxn(
sender, context.suggested_params
)
return

context.transaction = transaction.KeyregOnlineTxn(
sender,
context.suggested_params,
vote_pk,
selection_pk,
int(vote_first),
int(vote_last),
int(key_dilution),
sprfkey=state_proof_pk,
)


@given("suggested transaction parameters from the algod v2 client")
def get_sp_from_algod(context):
context.suggested_params = context.app_acl.suggested_params()
Expand Down
Loading