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

Dynamic teal #2126

Merged
merged 19 commits into from
May 14, 2021
Merged

Dynamic teal #2126

merged 19 commits into from
May 14, 2021

Conversation

jannotti
Copy link
Contributor

@jannotti jannotti commented May 3, 2021

No description provided.

Copy link
Contributor

@algorandskiy algorandskiy left a comment

Choose a reason for hiding this comment

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

Few comments and suggestions.
Please also consider adding backward branching tests into backward compatibility tests - like the program rejected before teal4 and accepted after

data/transactions/logic/eval.go Show resolved Hide resolved
data/transactions/logic/eval.go Show resolved Hide resolved
Comment on lines -300 to +312

// Evaluate the program
pass, err = eval(program, &cx)

return pass, err
return eval(program, &cx)
Copy link
Contributor

Choose a reason for hiding this comment

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

not needed change. This place was quite convenient place for debugging (breakpoints/dumpning some info)

Comment on lines -1635 to +1634
func checkPushBytes(cx *evalContext) int {
func checkPushBytes(cx *evalContext) error {
opPushBytes(cx)
return 1
return cx.err
Copy link
Contributor

Choose a reason for hiding this comment

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

it looks like check* functions needs to be moved to check.go from the assembler

data/transactions/logic/eval.go Show resolved Hide resolved
@@ -774,6 +771,41 @@ func opAddw(cx *evalContext) {
cx.stack[last].Uint = sum
}

func uint128(hi uint64, lo uint64) *big.Int {
whole := new(big.Int).SetUint64(hi)
Copy link
Contributor

Choose a reason for hiding this comment

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

it is interesting why does not big package like stack-allocated Ints... Have you tried

whole := &big.Int{}
whole.SetUint64(hi)
...

?

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 that's fine too, but why prefer two lines / statements instead of a single expression?

I wanted to use syntax that gave a single expression that produced a big.Int from a u64, especially since I needed similar syntax two lines later to create the low word.

data/transactions/logic/eval_test.go Show resolved Hide resolved
data/transactions/logic/eval_test.go Show resolved Hide resolved
data/transactions/logic/eval_test.go Outdated Show resolved Hide resolved
@jannotti
Copy link
Contributor Author

jannotti commented May 6, 2021

@algorandskiy You asked about testing old backjumps. This test does that

func TestAssembleRejectNegJump(t *testing.T) {
	t.Parallel()
	source := `wat:
int 1
bnz wat
int 2`
	for v := uint64(1); v < backBranchEnabledVersion; v++ {
		t.Run(fmt.Sprintf("v=%d", v), func(t *testing.T) {
			testProg(t, source, v, expect{3, "label wat is a back reference..."})
		})
	}
	for v := uint64(backBranchEnabledVersion); v <= AssemblerMaxVersion; v++ {
		t.Run(fmt.Sprintf("v=%d", v), func(t *testing.T) {
			testProg(t, source, v)
		})
	}
}

It tests that you get an error in all version up to backBranchEnabledVersion and then it works from that version onward.

Copy link
Contributor

@algorandskiy algorandskiy left a comment

Choose a reason for hiding this comment

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

Looks good except removing cost checks from txn verifier for pre-eval checks. Scenario: submit a long v2 program with jump to the end on a new and old node before protocol upgrade. It will fail on the old (sum up check) and pass on new.

@@ -1097,7 +1094,7 @@ var dryrunCmd = &cobra.Command{
}
pass, err := logic.Eval(txn.Lsig.Logic, ep)
// TODO: optionally include `inspect` output here?
fmt.Fprintf(os.Stdout, "tx[%d] cost=%d trace:\n%s\n", i, cost, sb.String())
fmt.Fprintf(os.Stdout, "tx[%d] trace:\n%s\n", i, sb.String())
Copy link
Contributor

Choose a reason for hiding this comment

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

why not printing the cost after eval?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because it's hidden inside the evaluation function and not exposed. If we find it important enough, I could rework the interfaces.

data/transactions/logic/README_in.md Outdated Show resolved Hide resolved
data/transactions/logic/opcodes.go Show resolved Hide resolved
data/transactions/verify/txn.go Show resolved Hide resolved
@jannotti jannotti marked this pull request as ready for review May 11, 2021 23:02
@algorandskiy
Copy link
Contributor

LGTM

algorandskiy
algorandskiy previously approved these changes May 12, 2021
Copy link
Contributor

@brianolson brianolson left a comment

Choose a reason for hiding this comment

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

Lots of good stuff here. A few small tweaks.

Probably worth having a paragraph in README_in.md about the callstack, how it's invisible except to two instructions, and any depth limit.

data/transactions/logic/eval.go Outdated Show resolved Hide resolved
cat >${TEMPDIR}/true.teal<<EOF
#pragma version 3
int 1
return
Copy link
Contributor

Choose a reason for hiding this comment

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

don't need return

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right this is a remnant from the teal-v2 test, where I wanted to be clear that I had v3 code (where return was introduced). I think it still makes some sense here because of that, but the one below should be changed to some v4 opcode.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope, I'm wrong. return was in v2. So it's entirely extraneous. I guess I got in the habit of doing that in tests when I wasn't sure of the stack.

test/scripts/e2e_subs/v26/teal-v3-only.sh Outdated Show resolved Hide resolved
@jannotti
Copy link
Contributor Author

Lots of good stuff here. A few small tweaks.

Probably worth having a paragraph in README_in.md about the callstack, how it's invisible except to two instructions, and any depth limit.

I'll add something in TEAL cannot do section - I'll create a new line about lack of indirect jumps and this will naturally fit there. (Though I'll do it the next PR, as I want to avoid having this thing run through CI again, until/unless I get feedback that needs a code change.)

My current thinking is NOT to restrict the call depth, and to simply let that be limited by the runtime of the program. That means a program of loop: callsub loop would get 20,000 deep in a logicsig, but that's just a 20k int array that immediately goes away. Didn't seem to matter. Thoughts?

jasonpaulos
jasonpaulos previously approved these changes May 13, 2021
Copy link
Contributor

@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.

Looks good!

My current thinking is NOT to restrict the call depth, and to simply let that be limited by the runtime of the program. That means a program of loop: callsub loop would get 20,000 deep in a logicsig, but that's just a 20k int array that immediately goes away. Didn't seem to matter. Thoughts?

From a programmer/debugger standpoint this seems like a good approach, though I can't comment on whether that's a significant memory usage or not.

Copy link
Contributor

@tsachiherman tsachiherman left a comment

Choose a reason for hiding this comment

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

Few minor issues mentioned above, but overall looks great.
I would be happy to see more extensive testing around the new teal opcodes - maybe some teal code that is doing a dual/triple recursion ?

@jannotti
Copy link
Contributor Author

maybe some teal code that is doing a dual/triple recursion ?

I'll do a mutually recursive odd() / even() implementation.

brianolson
brianolson previously approved these changes May 14, 2021
@jannotti jannotti dismissed stale reviews from brianolson, jasonpaulos, and algorandskiy via acbc483 May 14, 2021 16:10
@jannotti
Copy link
Contributor Author

Aw crap. I committed some changes to address @tsachiherman comments. So now approvals are dismissed. Once I get through CI, I'll ping for them again. Sorry.

@tsachiherman tsachiherman merged commit 009d57f into algorand:master May 14, 2021
tsachiherman pushed a commit to tsachiherman/go-algorand that referenced this pull request Jul 7, 2021
Add support for dynamic TEAL.
@jannotti jannotti deleted the dynamic-teal branch January 28, 2022 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

divw and friends TEAL - allow backward jumps or indirect jumps
7 participants