-
Notifications
You must be signed in to change notification settings - Fork 114
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
Refactoring Router taking CSP expression #636
Conversation
pyteal/ast/router.py
Outdated
def __post_init__(self): | ||
if self.clear_state != CallConfig.NEVER: | ||
raise TealInputError( | ||
"Attempt to construct clear state program from MethodConfig, " | ||
"use Router top level argument `clear_state` instead" | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: this function will error if one sets clear_state
to anything other than default. Are we good here, or any more steps needed to totally remove the keyword arg clear_state
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems sufficient to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to have a link to a URL that explains in more detail. But that can also be added in the followup pr/release.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I update the doc a little bit and referred to doc in 030eaf4, keep looking into what should be done for csp refactoring.
pyteal/ast/router.py
Outdated
def __post_init__(self): | ||
if self.clear_state != CallConfig.NEVER: | ||
raise TealInputError( | ||
"Attempt to construct clear state program from MethodConfig, " | ||
"use Router top level argument `clear_state` instead" | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems sufficient to me
Note that we will also need to update the docs, notably https://pyteal.readthedocs.io/en/stable/abi.html#registering-bare-app-calls |
We can add usage examples to the PR description. Can be done after merging as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition to a URL, I left a point of discussion. But overall, looking good.
@pt.ABIReturnSubroutine | ||
def approve_if_odd(condition_encoding: pt.abi.Uint32) -> pt.Expr: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This deleted router method is a great example to think through.
In the short term, I support the current strict approach. But in the medium term, it's worth seeing if we can relax the restrictions a bit.
As we discussed, there could still be a use case when someone actually wants to fail during a clear state cleanup action. So the approve_if_odd
can be a stand-in for that. How would we want to enable such a call? Some ideas:
- Do we allow any arguments at all?
- If so, what kind of checks for the arguments should we generate? In particular, what happens if the 0'th argument - for the method selector - is incorrect?
- Should we allow an option that instead of issuing
err
issuesint 1; return
immediately instead?
These questions get kind of dicey, but I can imagine modifying @router.method
(or maybe even introducing @router.clear_method
) with some parameters that control this. EG:
for_clear: bool
(unneeded in the case of@router.clear_method
) indicates whether this is intended for the clear program, and then enables the following parameters:no_erroring = True
- in the case that the method selector (or any other parameter) is wrong, will issue anint 1; return
instead oferr
. But this means that all the other@router.clear_method
would need to have the sameno_erroring
value. So maybe the routing err behavior belongs as a router level option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think my take on the discussion is that, we might want to let router user to explicitly specify what kind of logic they want to use in clear state program (CSP), so my thoughts and opinions are as follows:
Do we allow any arguments at all?
There is no way we are disallowing args, one can always use Txn.application_args
in their composed Expr
. We will just no longer generate code to handle the IO process in CSP.
If so, what kind of checks for the arguments should we generate? In particular, what happens if the 0'th argument - for the method selector - is incorrect?
If we go down the path of letting users to specify whatever logic in CSP, then I don't see too good a way to generate checks for arguments.
For now, I haven't thought through how much flexibility and check can be done on our side, but rather, probably we want to hand the full control over CSP to router users?
I had some docs improvement ideas, so I opened #641 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor grammatical suggestions and a controversial suggestion to default to generating int 1
for the clear program
""" | ||
|
||
self.name: str = name | ||
self.descr = descr | ||
|
||
self.approval_ast = ASTBuilder() | ||
self.clear_state_ast = ASTBuilder() | ||
self.clear_state: Expr = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is backwards compatible in the sense that if we have a pyteal-program written today with no information about clear-state, it will generate an int 0
for its clear-program.
However, it is arguable that even in this default case, we still want a NEW behavior and produce int 1
instead for the clear program.
And assuming we agree with this point, then unfortunately, the parameter will need to become mandatory because of the lack of backwards compatibility. So keeping it as kwarg-only param, we would need to have something like:
assert clear_state, "... something similar to the other error messages above ..."
In either case, I encourage the creation of a tiny unit test (assuming it doesn't already exist) that will assert that the simplest compiling PyTeal program generates the approval and clear programs that we would like to generate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upon further reflection, I changed my mind.... int 0
for the simplest possible clear program still makes sense because there is no state that is changing inside of the program and that needs to be preserved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought for a bit, we still keep the backwards compatible way, right?
One question: even one call a CSP with int 0
, then it failed, it still get its state cleared, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's nearly there for me, just waiting on the below comment and #636 (comment)
Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
An attempt made, so we can get around the erroring in csp.
Closes #638