-
Notifications
You must be signed in to change notification settings - Fork 493
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
Add opcodes for dynamically indexing into Txn array fields #2847
Add opcodes for dynamically indexing into Txn array fields #2847
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2847 +/- ##
========================================
Coverage 47.25% 47.26%
========================================
Files 351 351
Lines 56363 56481 +118
========================================
+ Hits 26634 26694 +60
- Misses 26735 26772 +37
- Partials 2994 3015 +21
Continue to review full report at Codecov.
|
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 need to think about whether we should add some pseudo op support. Currently, txn ApplicationArgs 0
gets compiled to txna ApplicationArgs 0
, because of the two arguments signaling that it's an array ref. txnsa
can also be compiled from txns
(I think).
I'm not sure we can do much here, but it is a little strange that once you move to the stack versions, the "a" becomes required.
Let me talk through a strawman proposal and see if it makes sense:
txns
could be introduced as a substitute for txnas
gtxns
could compile to gtxnas
if it is using an Array field? (this would be a departure, we normally go by the number of immediates, but the whole point of these new opcodes is that they access an array but do NOT, have an extra immediate)
gtxnss
could compile to gtxnsas
I'm really unsure this makes sense. I'm just trying to fit in with our existing choices to not require the "a" in the the txn opcodes during assembly.
… algochoi/dynamic-index-array
if gtxid >= len(cx.TxnGroup) { | ||
cx.err = fmt.Errorf("gtxnas lookup TxnGroup[%d] but it only has %d", gtxid, len(cx.TxnGroup)) | ||
return | ||
} else if gtxid < 0 { | ||
cx.err = fmt.Errorf("gtxnas lookup %d cannot be negative", gtxid) | ||
return | ||
} |
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'll fix this up when I do loads, stores, but just want to point out that we don't want to complain that the number is negative. In AVM, it isn't. It's only negative (potentially) because this code casted a big uint64 to an int, and that can give you a negative result.
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.
Makes sense!
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.
PS, I liked the way you handled this in args a lot. There, you used uint64 mostly, and casted the len() calls instead of the stack argument. I think I will fix this stuff up that way, instead of the way I had been contemplating.
@@ -980,6 +1034,27 @@ func assembleGtxnsa(ops *OpStream, spec *OpSpec, args []string) error { | |||
return nil | |||
} | |||
|
|||
func assembleGtxnsas(ops *OpStream, spec *OpSpec, args []string) error { | |||
if len(args) != 1 { | |||
return ops.error("gtxnsas expects one immediate argument") |
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.
Let's try to use %s and spec.Name as often as possible.
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.
Agreed - I think we can potentially save ourselves time in the future by doing this.
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.
Mostly good, I just have some test suggestions. Also it would be nice if some code could be reused between the similar opcodes, but that can wait until later.
int 0 | ||
== | ||
&& | ||
gtxn 1 ExtraProgramPages | ||
int 2 | ||
== | ||
&& | ||
` | ||
|
||
gtxnTextV5 := gtxnTextV4 + `int 0 |
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 is missing txnas
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 put txnas
in the testTxnProgramTextV5
section I think.
txgroup[0] = txn | ||
ep := defaultEvalParams(nil, &txn) | ||
ep.TxnGroup = txgroup | ||
_, err := Eval(ops.Program, ep) |
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 you're just checking that the programs runs, not that it passes? It would be a stronger test to instead check that a simple use of txnas
passes. I'd suggest something like the following, and you could adapt it for gtxnas
and gtxnsas
too.
int 0
txnas Accounts
txna Accounts 0
==
int 0
txnas ApplicationArgs
txna ApplicationArgs 0
==
&&
int 1
txnas ApplicationArgs
txna ApplicationArgs 1
==
&&
return
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.
Good point, I will check these with e.g. testAccepts(t, "int 0; txnas Accounts; txna Accounts 0; ==", 5)
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 merged what existed, I'll add these.
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 concluded these were fine. The following tests checked pass
, and they were grabbing the accounts and comparing them to app args.
Summary
This commit adds
txnas
,gtxnas
, andgtxnsas
op codes that allow for array indices to be dynamically pushed into the stack instead of being supplied by immediate values. It also adds theargs
op code to dynamically specify an arg index from the stack.TODO: Implement
stores
,loads
Closes #2799
Test Plan