VAA Processor PyTEAL [wip]

This commit is contained in:
Hernán Di Pietro 2021-10-25 16:40:04 -03:00
parent 20a92e53c9
commit fdc80e9184
1 changed files with 73 additions and 20 deletions

View File

@ -21,6 +21,7 @@ commit: Commit verified VAA, processing it according to its payload. Must be la
Global state:
"vphash" : Hash of verification program logic
"gsexp" : Guardian set expiration time
"gscount" : Guardian set size
key N : address of guardian N
@ -34,7 +35,7 @@ SLOT 4*i: key of guardian i (as of Nov'21 there are 19 guardians)
================================================================================================
"""
from pyteal import (compileTeal, Int, Mode, Txn, OnComplete,
from pyteal import (compileTeal, Int, Mode, Txn, OnComplete, Itob, Btoi,
Return, Cond, Bytes, Global, Not, Seq, Approve, App, Assert, For, And)
import pyteal
from pyteal.ast.binaryexpr import ShiftRight
@ -43,10 +44,14 @@ from pyteal.ast.return_ import Reject
from pyteal.ast.scratch import ScratchLoad, ScratchSlot
from pyteal.ast.scratchvar import ScratchVar
from pyteal.ast.subroutine import Subroutine
from pyteal.ast.txn import TxnType
from pyteal.ast.while_ import While
from pyteal.types import TealType
METHOD = Txn.application_args[0]
SLOTID_SCRATCH_0 = 251
SLOTID_VERIFIED_GUARDIAN_BITS = 254
SLOTID_GUARDIAN_COUNT = 255
# Bootstrap with the initial list of guardians as application argument
@ -54,6 +59,7 @@ METHOD = Txn.application_args[0]
@Subroutine(TealType.uint64)
def bootstrap():
return Seq([
App.globalPut(Bytes("vphash"), Txn.application_args[0]),
Approve()
])
@ -68,40 +74,79 @@ def is_proper_group_size():
return Global.group_size() >= Int(3)
# @Subroutine(TealType.none)
# # set bitfield bits [from,to]
# def set_bits(i_from, i_to):
# count = Int(1) #ScratchVar(TealType.uint64, SLOTID_SCRATCH_0)
# #count.store(Int(i_to) - Int(i_from) + Int(1))
# # set Verified_bits |= ((2^count) - 1) << i_from
# bitfield = ScratchVar(TealType.uint64, SLOTID_VERIFIED_GUARDIAN_BITS)
# return Seq([
# bitfield.store(bitfield.load() | (
# ((Int(2) ** count) - Int(1) << Int(2))
# ))
# ])
def prepare():
# Sender must be owner
# This call must be index 0 in a group of minimum 3 (prepare->verify->commit)
Assert(And(is_creator(),
is_proper_group_size(), Txn.group_index() == Int(0)))
i = ScratchVar(TealType.uint64, 253)
gs_count = ScratchVar(TealType.uint64, 254)
ScratchVar(TealType.uint64, SLOTID_VERIFIED_GUARDIAN_BITS).store(Int(0))
i = ScratchVar(TealType.uint64, SLOTID_SCRATCH_0)
gs_count = ScratchVar(TealType.uint64, SLOTID_GUARDIAN_COUNT)
num_guardians = App.globalGet(Bytes("gscount"))
return Seq([
Assert(And(is_creator(),
is_proper_group_size(), Txn.group_index() == Int(0))),
If(num_guardians == Int(0), Reject(), Seq([
gs_count.store(num_guardians),
For(i.store(Int(0)), i.load() < num_guardians, i.store(i.load() + Int(1))).Do(
Seq([
ScratchVar(TealType.uint64, 1).store(
App.globalGet(Itob(i.load())))
# (ScratchVar(TealType.uint64, i.load())).store(App.globalGet(Itob(i.load()))
]))
]))
return Approve()
])),
Approve()
])
def verify():
# Sender must be stateless logic.
# This call must be not the first or last in a group of minimum 3 (prepare->verify->commit)
# First guardian index to verify
verify_from = Txn.application_args[0]
# Last guardian index to verify
verify_to = Txn.application_args[1]
bitfield = ScratchVar(TealType.uint64, SLOTID_VERIFIED_GUARDIAN_BITS)
p_val = bitfield.load()
count = Btoi(verify_to) - Btoi(verify_from) + Int(1)
return Seq([Assert(And(is_proper_group_size(),
Txn.group_index() < Global.group_size(),
Txn.group_index() > Int(0))),
Txn.group_index() > Int(0),
Btoi(verify_to) > Btoi(verify_from),
Txn.sender() == App.globalGet(Bytes("vphash")))),
#bitfield.store(bitfield.load() + Int(1)),
Approve()])
def commit():
# Sender must be owner
# This call must be last in a group of minimum 3 (prepare->verify->commit)
# Bitfield must indicate all guardians verified.
all_verified = ScratchVar(TealType.uint64, SLOTID_VERIFIED_GUARDIAN_BITS).load() ==
return Seq([
Assert(And(is_proper_group_size(), Txn.group_index()
== (Global.group_size() - Int(1)))),
Assert(And(is_proper_group_size(),
Txn.group_index() == (Global.group_size() - Int(1)),
all_verified
)),
handle_vaa(),
Approve()
])
@ -116,7 +161,7 @@ def vaa_processor_program():
[METHOD == Bytes("commit"), commit()]
)
return Cond(
[Not(Txn.application_id()), handle_create],
[Txn.application_id() == Int(0), handle_create],
[Txn.on_completion() == OnComplete.UpdateApplication, handle_update],
[Txn.on_completion() == OnComplete.DeleteApplication, handle_delete],
[Txn.on_completion() == OnComplete.NoOp, handle_noop]
@ -124,8 +169,16 @@ def vaa_processor_program():
def clear_state_program():
Return(Int(1))
return Int(1)
if __name__ == "__main__":
print(compileTeal(vaa_processor_program(), mode=Mode.Application, version=5))
with open("vaa-processor-approval.teal", "w") as f:
compiled = compileTeal(vaa_processor_program(),
mode=Mode.Application, version=5)
f.write(compiled)
with open("vaa-processor-clear.teal", "w") as f:
compiled = compileTeal(clear_state_program(),
mode=Mode.Application, version=5)
f.write(compiled)