Last TX enhanced state checking according to JJ comments.
This commit is contained in:
parent
4fb463ed38
commit
1c920c7c92
|
@ -41,19 +41,20 @@ SLOT 255: number of guardians in set
|
||||||
"""
|
"""
|
||||||
from pyteal.ast import *
|
from pyteal.ast import *
|
||||||
from pyteal.types import *
|
from pyteal.types import *
|
||||||
from pyteal.compiler import *
|
from pyteal.compiler import *
|
||||||
from pyteal.ir import *
|
from pyteal.ir import *
|
||||||
from globals import MAX_SIGNATURES_PER_VERIFICATION_STEP, get_group_size
|
from globals import MAX_SIGNATURES_PER_VERIFICATION_STEP, get_group_size, get_sig_count_in_step
|
||||||
|
|
||||||
METHOD = Txn.application_args[0]
|
METHOD = Txn.application_args[0]
|
||||||
VERIFY_ARG_GUARDIAN_KEY_SUBSET = Txn.application_args[1]
|
VERIFY_ARG_GUARDIAN_KEY_SUBSET = Txn.application_args[1]
|
||||||
VERIFY_ARG_GUARDIAN_SET_SIZE = Txn.application_args[2]
|
VERIFY_ARG_GUARDIAN_SET_SIZE = Txn.application_args[2]
|
||||||
VERIFY_ARG_PAYLOAD = Txn.note()
|
VERIFY_ARG_PAYLOAD = Txn.note()
|
||||||
SLOTID_TEMP_0 = 251
|
SLOTID_TEMP_0 = 251
|
||||||
SLOTID_VERIFIED_GUARDIAN_BITS = 254
|
SLOTID_VERIFIED_BIT = 254
|
||||||
SLOTID_GUARDIAN_COUNT = 255
|
|
||||||
STATELESS_LOGIC_HASH = App.globalGet(Bytes("vphash"))
|
STATELESS_LOGIC_HASH = App.globalGet(Bytes("vphash"))
|
||||||
NUM_GUARDIANS = App.globalGet(Bytes("gscount"))
|
NUM_GUARDIANS = App.globalGet(Bytes("gscount"))
|
||||||
|
SLOT_VERIFIED_BITFIELD = ScratchVar(TealType.uint64, SLOTID_VERIFIED_BIT)
|
||||||
|
SLOT_TEMP = ScratchVar(TealType.uint64, SLOTID_TEMP_0)
|
||||||
|
|
||||||
# defined chainId/contracts
|
# defined chainId/contracts
|
||||||
|
|
||||||
|
@ -81,17 +82,6 @@ def bootstrap():
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
@Subroutine(TealType.uint64)
|
|
||||||
def verify_from():
|
|
||||||
return Txn.group_index() * Int(MAX_SIGNATURES_PER_VERIFICATION_STEP)
|
|
||||||
|
|
||||||
|
|
||||||
@Subroutine(TealType.uint64)
|
|
||||||
def verify_to():
|
|
||||||
return min(VERIFY_ARG_GUARDIAN_SET_SIZE, verify_from +
|
|
||||||
(Int(MAX_SIGNATURES_PER_VERIFICATION_STEP) - Int(1)))
|
|
||||||
|
|
||||||
|
|
||||||
@Subroutine(TealType.uint64)
|
@Subroutine(TealType.uint64)
|
||||||
def is_creator():
|
def is_creator():
|
||||||
return Txn.sender() == Global.creator_address()
|
return Txn.sender() == Global.creator_address()
|
||||||
|
@ -102,11 +92,14 @@ def check_guardian_key_subset():
|
||||||
# Verify that the passed argument for guardian keys [i..j] match the
|
# Verify that the passed argument for guardian keys [i..j] match the
|
||||||
# global state for the same keys.
|
# global state for the same keys.
|
||||||
#
|
#
|
||||||
i = ScratchVar(TealType.uint64, SLOTID_TEMP_0)
|
i = SLOT_TEMP
|
||||||
return Seq([For(i.store(Int(0)), i.load() < Int(MAX_SIGNATURES_PER_VERIFICATION_STEP), i.store(i.load() + Int(1))).Do(
|
return Seq([
|
||||||
If(App.globalGet(Itob(i.load())) != Extract(VERIFY_ARG_GUARDIAN_KEY_SUBSET,
|
For(i.store(Int(0)),
|
||||||
i.load() * Int(64), Int(64))).Then(Return(Int(0))) # get and compare stored global key
|
i.load() < get_sig_count_in_step(Txn.group_index(), NUM_GUARDIANS),
|
||||||
),
|
i.store(i.load() + Int(1))).Do(
|
||||||
|
If(App.globalGet(Itob(i.load())) != Extract(VERIFY_ARG_GUARDIAN_KEY_SUBSET,
|
||||||
|
i.load() * Int(64), Int(64))).Then(Return(Int(0))) # get and compare stored global key
|
||||||
|
),
|
||||||
Return(Int(1))
|
Return(Int(1))
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -155,6 +148,21 @@ def commit_vaa():
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
@Subroutine(TealType.uint64)
|
||||||
|
def check_final_verification_state():
|
||||||
|
i = SLOT_TEMP
|
||||||
|
return Seq([
|
||||||
|
For(i.store(Int(0)),
|
||||||
|
i.load() < Global.group_size(),
|
||||||
|
i.store(i.load() + Int(0))).Do(
|
||||||
|
Assert(
|
||||||
|
And(Gtxn[i.load()].application_id() == Txn.application_id(),
|
||||||
|
GetBit(ImportScratchValue(i.load(), SLOTID_VERIFIED_BIT), i.load()) == Int(1)))
|
||||||
|
),
|
||||||
|
Return(Int(1))
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
def setvphash():
|
def setvphash():
|
||||||
#
|
#
|
||||||
# Sets the hash of the verification stateless program.
|
# Sets the hash of the verification stateless program.
|
||||||
|
@ -173,21 +181,30 @@ def setvphash():
|
||||||
def verify():
|
def verify():
|
||||||
# * Sender must be stateless logic.
|
# * Sender must be stateless logic.
|
||||||
# * Let N be the number of signatures per verification step, for the TX(i) in group, we verify signatures [j..k] where j = i*N, k = j+(N-1)
|
# * Let N be the number of signatures per verification step, for the TX(i) in group, we verify signatures [j..k] where j = i*N, k = j+(N-1)
|
||||||
# * Argument 1 must contain guardian public keys for guardians [i..j] (read by stateless logic)
|
# * Argument 1 must contain guardian public keys for guardians [i..j] (read by stateless logic).
|
||||||
|
# Public keys are 32 bytes long so expected argument length is 32 * (j - i + 1)
|
||||||
# * Argument 2 must contain current guardian set size (read by stateless logic)
|
# * Argument 2 must contain current guardian set size (read by stateless logic)
|
||||||
# * Passed guardian public keys [i..j] must match the current global state.
|
# * Passed guardian public keys [i..j] must match the current global state.
|
||||||
# * Note must contain VAA message-in-digest (header+payload) (up to 1KB) (read by stateless logic)
|
# * Note must contain VAA message-in-digest (header+payload) (up to 1KB) (read by stateless logic)
|
||||||
#
|
#
|
||||||
# Last TX in group will trigger VAA handling depending on payload.
|
# Last TX in group will trigger VAA handling depending on payload. It is required that
|
||||||
|
# all previous transactions are app-calls for this AppId and all bitfields are set.
|
||||||
|
|
||||||
return Seq([Assert(And(Global.group_size() == get_group_size(NUM_GUARDIANS),
|
return Seq([
|
||||||
Txn.application_args.length() == Int(3),
|
SLOT_VERIFIED_BITFIELD.store(Int(0)),
|
||||||
Txn.sender() == STATELESS_LOGIC_HASH,
|
Assert(And(Global.group_size() == get_group_size(NUM_GUARDIANS),
|
||||||
check_guardian_set_size(),
|
Txn.application_args.length() == Int(3),
|
||||||
check_guardian_key_subset())),
|
Txn.sender() == STATELESS_LOGIC_HASH,
|
||||||
If(Txn.group_index() == Global.group_size() -
|
check_guardian_set_size(),
|
||||||
Int(1)).Then(Return(commit_vaa())),
|
check_guardian_key_subset())),
|
||||||
Approve()])
|
SLOT_VERIFIED_BITFIELD.store(SetBit(SLOT_VERIFIED_BITFIELD.load(), Txn.group_index(), Int(1))),
|
||||||
|
If(Txn.group_index() == Global.group_size() -
|
||||||
|
Int(1)).Then(
|
||||||
|
Return(Seq([
|
||||||
|
Assert(check_final_verification_state()),
|
||||||
|
commit_vaa()
|
||||||
|
]))),
|
||||||
|
Approve()])
|
||||||
|
|
||||||
|
|
||||||
def vaa_processor_program():
|
def vaa_processor_program():
|
||||||
|
|
Loading…
Reference in New Issue