VAA Processor PyTEAL [wip]
This commit is contained in:
parent
20a92e53c9
commit
fdc80e9184
|
@ -21,6 +21,7 @@ commit: Commit verified VAA, processing it according to its payload. Must be la
|
||||||
|
|
||||||
Global state:
|
Global state:
|
||||||
|
|
||||||
|
"vphash" : Hash of verification program logic
|
||||||
"gsexp" : Guardian set expiration time
|
"gsexp" : Guardian set expiration time
|
||||||
"gscount" : Guardian set size
|
"gscount" : Guardian set size
|
||||||
key N : address of guardian N
|
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)
|
Return, Cond, Bytes, Global, Not, Seq, Approve, App, Assert, For, And)
|
||||||
import pyteal
|
import pyteal
|
||||||
from pyteal.ast.binaryexpr import ShiftRight
|
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.scratch import ScratchLoad, ScratchSlot
|
||||||
from pyteal.ast.scratchvar import ScratchVar
|
from pyteal.ast.scratchvar import ScratchVar
|
||||||
from pyteal.ast.subroutine import Subroutine
|
from pyteal.ast.subroutine import Subroutine
|
||||||
|
from pyteal.ast.txn import TxnType
|
||||||
from pyteal.ast.while_ import While
|
from pyteal.ast.while_ import While
|
||||||
from pyteal.types import TealType
|
from pyteal.types import TealType
|
||||||
|
|
||||||
METHOD = Txn.application_args[0]
|
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
|
# Bootstrap with the initial list of guardians as application argument
|
||||||
|
|
||||||
|
@ -54,6 +59,7 @@ METHOD = Txn.application_args[0]
|
||||||
@Subroutine(TealType.uint64)
|
@Subroutine(TealType.uint64)
|
||||||
def bootstrap():
|
def bootstrap():
|
||||||
return Seq([
|
return Seq([
|
||||||
|
App.globalPut(Bytes("vphash"), Txn.application_args[0]),
|
||||||
Approve()
|
Approve()
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -68,40 +74,79 @@ def is_proper_group_size():
|
||||||
return Global.group_size() >= Int(3)
|
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():
|
def prepare():
|
||||||
# Sender must be owner
|
# Sender must be owner
|
||||||
# This call must be index 0 in a group of minimum 3 (prepare->verify->commit)
|
# 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)
|
ScratchVar(TealType.uint64, SLOTID_VERIFIED_GUARDIAN_BITS).store(Int(0))
|
||||||
gs_count = ScratchVar(TealType.uint64, 254)
|
i = ScratchVar(TealType.uint64, SLOTID_SCRATCH_0)
|
||||||
|
gs_count = ScratchVar(TealType.uint64, SLOTID_GUARDIAN_COUNT)
|
||||||
num_guardians = App.globalGet(Bytes("gscount"))
|
num_guardians = App.globalGet(Bytes("gscount"))
|
||||||
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, i.load())).store(App.globalGet(Itob(i.load()))
|
return Seq([
|
||||||
]))
|
Assert(And(is_creator(),
|
||||||
]))
|
is_proper_group_size(), Txn.group_index() == Int(0))),
|
||||||
return Approve()
|
|
||||||
|
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()))
|
||||||
|
]))
|
||||||
|
])),
|
||||||
|
Approve()
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
def verify():
|
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)
|
# 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(),
|
return Seq([Assert(And(is_proper_group_size(),
|
||||||
Txn.group_index() < Global.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()])
|
Approve()])
|
||||||
|
|
||||||
|
|
||||||
def commit():
|
def commit():
|
||||||
# Sender must be owner
|
# Sender must be owner
|
||||||
# This call must be last in a group of minimum 3 (prepare->verify->commit)
|
# 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([
|
return Seq([
|
||||||
Assert(And(is_proper_group_size(), Txn.group_index()
|
Assert(And(is_proper_group_size(),
|
||||||
== (Global.group_size() - Int(1)))),
|
Txn.group_index() == (Global.group_size() - Int(1)),
|
||||||
|
all_verified
|
||||||
|
)),
|
||||||
|
handle_vaa(),
|
||||||
Approve()
|
Approve()
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -116,7 +161,7 @@ def vaa_processor_program():
|
||||||
[METHOD == Bytes("commit"), commit()]
|
[METHOD == Bytes("commit"), commit()]
|
||||||
)
|
)
|
||||||
return Cond(
|
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.UpdateApplication, handle_update],
|
||||||
[Txn.on_completion() == OnComplete.DeleteApplication, handle_delete],
|
[Txn.on_completion() == OnComplete.DeleteApplication, handle_delete],
|
||||||
[Txn.on_completion() == OnComplete.NoOp, handle_noop]
|
[Txn.on_completion() == OnComplete.NoOp, handle_noop]
|
||||||
|
@ -124,8 +169,16 @@ def vaa_processor_program():
|
||||||
|
|
||||||
|
|
||||||
def clear_state_program():
|
def clear_state_program():
|
||||||
Return(Int(1))
|
return Int(1)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
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)
|
||||||
|
|
Loading…
Reference in New Issue