-
Notifications
You must be signed in to change notification settings - Fork 8
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
ABI Method / Routing / Contract functionality #21
Conversation
…nst too many args
Co-authored-by: Michael Diamant <michaeldiamant@users.noreply.github.com>
# since execution REJECTS for 0, expect last log for this case to be None | ||
(i,): Encoder.hex(i * i) if i else None | ||
for i in range(100) | ||
}, |
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.
An upgrade to go-algorand's dry run is returning logs even when rejecting.
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.
@tzaffi Thanks for the effort here to improve our confidence in PyTeal-generated ABI routing! ☕
We'll extend the effort via these stories in future iterations:
setup.py
Outdated
install_requires=["py-algorand-sdk", "tabulate==0.8.9"], | ||
python_requires=">=3.9", | ||
install_requires=[ | ||
"py-algorand-sdk @ git+https://github.com/algorand/py-algorand-sdk@develop", |
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.
Changed this to point to develop
but still should not merge until the next release so that pull from PyPi
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.
py-algorand-sdk
v 1.15.0 is out, so I'll revert and merge very soon.
Graviton ABI-Router Functionality
Still working on more test cases but the core functionality for testing ABI Router / ARC-4 compliant programs is in place.
Changes
Issues addressed
Bugs Fixed
Python Support
New Functionality
Makefile
- runmypy
with--show-error-codes
graviton/abi_strategy.py
- introducing classRandomABIStrategyHalfSized
which allows restricting integers to ½ their bit size for testing multiplication and addition without oveflowgraviton/blackbox.py
- introducing classABIContractExecutor
which applies the functionality ofDryRunExecutor
to the case of ABI-routable programsgraviton/invariant.py
- makemypy
a little happier and other small refactorings. ClassInvariant
was heavily utilized in the new teststests/integration/abi_test.py
- adding tests of ABI-routable programs. In particular:test_method_or_barecall_positive
- test all valid method and bare app calls for the contract including consideration of:is_app_create
- simulate the program execution during app creation, or after it already exists as appropriateon_complete
- simulate all appropriate OnComplete actionsargs
- simulate NUM_ROUTER_DRYRUNS random sets of validargs
as inputs for each method (currentlyNUM_ROUTER_DRYRUNS = 7
)sub()
actually subtracts,add()
adds, etc.)test_method_or_barecall_negative
- test all INVALID method and bare app calls for the contract. In particular:is_app_create
andon_complete
combinations with all other parameters valid and verify that the app call is rejected with errorarg[0]
) by removing/adding/replacing a byte for an otherwise valid app call and verify that the app call is rejected with errorABI-Router Bugs? Catalog
Approval Program Routing
These (alleged) bugs were discovered for the approval ABI contract and program generated by PyTeal in
compiler_test.py
as _router_with_ocApart from enforcingtxn NumAppArgs > 0
, there is no enforcement that the number of arguments provided to a method is the number expected. Strictly speaking, this is not specified in ARC-4 however one can read between the lines in methods and implementing a method and argue that this is the intent. in particular "Invoking a method involves creating an Application call transaction to specifically call that method." seems like it would imply providing exactly the arguments definied in a method's signature.whensub
was provided arguments2837233049, 2497150219, 2497150219
it PASSED instead of rejected (arg[3]
was ignored, but should be disallowed IMO)all the other contract methods suffer the same problem. EG addsimilarly, whenall_laid_args
which can handle 16 non-selector args by converting the last 2 into a tuple was provided 17 non-selector args, it PASSED. I believe this is a separate issue from the first one which requires a different approach in PyTEAL than the first (i.e., you can't just enforce withtxn NumAppArgs; int {NUMBER_OF_ACTUAL_ARGS}; ==; assert
)Remaining Actions
Tasks
temporarily_skip_iia
variable intests/integration/abi_test.py
and start failing that test againsub
andadd
do not depend on each-other, they enforce the usage of separate scratch slots. For a contract with many methods, this could result in needlessly running out of available slots. Please see PyTEAL issue 390.Add(this is actually covered bytest_bad_method_selectors
to verifies that ABI-router program rejects with error invalid method selectorstest_method_or_barecall_negative
's "edit the method selector..." scenarios)Test that REJECT with error or assert when use(Similarly to the previous, this is also covered byarg[0]
different from the selector of any contract method - "If an Application is called with greater than zero Application call arguments (NOT a bare Application call), the Application MUST always treat the first argument as a method selector and invoke the specified method, regardless of the OnCompletion action of the Application call. This applies to Application creation transactions as well, where the supplied Application ID is 0."test_method_or_barecall_negative
's "edit the method selector..." scenarios)@ABIReturnSubroutine
conditional_factorial - this is being addressed in PyTEAL PR #391, and in particular in this test method.ABIContractExecutor
and use it to test more realistic programs such as. This is punted to PyTEAL issue #394we would need to addUPSHOT: the answer is back and it's "NO - not right now". That is, we are not holding up release on account of this not being implemented. Hence, testing of this functionality is on hold for now.test_barecall_for_action_implies_methods_allowed
: test that if a bare app call is allowed for a particularis_app_create, on_complete
combination, then all the contract methods can be called for such combo. This guidance is provided in ARC-4 according to: "If a Contract elects to allow bare Application calls for some OnCompletion actions, then that Contract SHOULD also allow any of its methods to be called with those OnCompletion actions, as long as this would not cause undesirable or nonsensical behavior."Questions
ARC-4
PyTEAL
empty_return_subroutine()
andlog_1()
) is allowed for opting in. ANSWER: Ideally, we should follow ARC-4 and allow method calls right after anopt-in
bare app call, and right beforeclose-out
bare app calls, but this is not what is currently supported. Currently, we don't compose bare-app calls with method calls. This should not hold up release, however it is important that we be able to upgrade the router and -in order to enable this in the smart contract space- we need to introduce strict ABI Router versioning. @michaeldiamant will draft a story around this. TLDR; the answer "NO - not right now"txn OnCompletion; int ClearState; ==; assert
at the beginning? We can see that this isn't currently the case. - NO however, we should probably make it very easy to generate clear state programs whose entire contents isint 1
verify()
method on ABI types.Future Work - cf #22
pay / axfr / ...
transactions are too far away (compared to the number of such args in the method signature) the program is rejected with error.