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

Refactoring Router taking CSP expression #636

Merged
merged 21 commits into from
Jan 20, 2023
Merged

Refactoring Router taking CSP expression #636

merged 21 commits into from
Jan 20, 2023

Conversation

ahangsu
Copy link
Contributor

@ahangsu ahangsu commented Jan 18, 2023

An attempt made, so we can get around the erroring in csp.

Closes #638

@ahangsu ahangsu marked this pull request as ready for review January 18, 2023 23:45
@ahangsu ahangsu changed the title Default CSP branch at the end of cond Refactoring Router taking CSP expression Jan 19, 2023
Comment on lines 86 to 92
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"
)

Copy link
Contributor Author

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?

Copy link
Member

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

Copy link
Contributor

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.

Copy link
Contributor Author

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.

Comment on lines 86 to 92
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"
)

Copy link
Member

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

pyteal/ast/router.py Outdated Show resolved Hide resolved
pyteal/ast/router.py Show resolved Hide resolved
@jasonpaulos
Copy link
Member

Note that we will also need to update the docs, notably https://pyteal.readthedocs.io/en/stable/abi.html#registering-bare-app-calls

@tzaffi
Copy link
Contributor

tzaffi commented Jan 19, 2023

An attempt made, so we can get around the erroring in csp.

Closes #638

We can add usage examples to the PR description. Can be done after merging as well.

Copy link
Contributor

@tzaffi tzaffi left a 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.

Comment on lines -2329 to -2330
@pt.ABIReturnSubroutine
def approve_if_odd(condition_encoding: pt.abi.Uint32) -> pt.Expr:
Copy link
Contributor

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 issues int 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 an int 1; return instead of err. But this means that all the other @router.clear_method would need to have the same no_erroring value. So maybe the routing err behavior belongs as a router level option.

Copy link
Contributor Author

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?

pyteal/ast/router_test.py Outdated Show resolved Hide resolved
pyteal/ast/router.py Show resolved Hide resolved
pyteal/ast/router.py Outdated Show resolved Hide resolved
pyteal/ast/router.py Show resolved Hide resolved
@jasonpaulos
Copy link
Member

I had some docs improvement ideas, so I opened #641

Copy link
Contributor

@tzaffi tzaffi left a 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

pyteal/ast/router.py Outdated Show resolved Hide resolved
pyteal/ast/router.py Show resolved Hide resolved
pyteal/ast/router.py Outdated Show resolved Hide resolved
"""

self.name: str = name
self.descr = descr

self.approval_ast = ASTBuilder()
self.clear_state_ast = ASTBuilder()
self.clear_state: Expr = (
Copy link
Contributor

@tzaffi tzaffi Jan 20, 2023

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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?

Copy link
Member

@jasonpaulos jasonpaulos left a 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)

CHANGELOG.md Show resolved Hide resolved
CHANGELOG.md Outdated Show resolved Hide resolved
Co-authored-by: Zeph Grunschlag <tzaffi@users.noreply.github.com>
Copy link
Contributor

@tzaffi tzaffi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ahangsu ahangsu merged commit 8752ad5 into master Jan 20, 2023
@ahangsu ahangsu deleted the csp-default branch January 20, 2023 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Improve Router clear state program generation
4 participants