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
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Use TEAL v4, rather than new consenus parameter to go dynamic.
  • Loading branch information
jannotti committed May 11, 2021
commit f8e281d1fe8bc1a9dbc5a39d5b9b59898edc24c9
6 changes: 2 additions & 4 deletions config/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,6 @@ type ConsensusParams struct {
// sum of estimated op cost must be less than this
LogicSigMaxCost uint64

// calculate TEAL costs at runtime
DynamicTealCost bool

// max decimal precision for assets
MaxAssetDecimals uint32

Expand Down Expand Up @@ -913,7 +910,8 @@ func initConsensusProtocols() {
// Enable transaction Merkle tree.
vFuture.PaysetCommit = PaysetCommitMerkle

vFuture.DynamicTealCost = true
// Enable TEAL 4
vFuture.LogicSigVersion = 4

Consensus[protocol.ConsensusFuture] = vFuture
}
Expand Down
20 changes: 17 additions & 3 deletions data/transactions/logic/backwardCompat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,14 +340,28 @@ func TestBackwardCompatTEALv1(t *testing.T) {
txn.Lsig.Logic = program
txn.Lsig.Args = [][]byte{data[:], sig[:], pk[:], txn.Txn.Sender[:], txn.Txn.Note}

// Cost is now dynamic and exactly 1 less, because bnz skips "err". It's caught during Eval
ep.Proto.LogicSigMaxCost = 2138
// Cost remains the same, because v0 does not get dynamic treatment
ep.Proto.LogicSigMaxCost = 2139
err = Check(program, ep)
require.Error(t, err)

ep.Proto.LogicSigMaxCost = 2140
err = Check(program, ep)
require.NoError(t, err)
pass, err = Eval(program, ep)
require.NoError(t, err)
require.True(t, pass)

// But in v4, cost is now dynamic and exactly 1 less than v2/v3,
// because bnz skips "err". It's caught during Eval
program[0] = 4
ep.Proto.LogicSigMaxCost = 2306
err = Check(program, ep)
require.NoError(t, err)
_, err = Eval(program, ep)
require.Error(t, err)

ep.Proto.LogicSigMaxCost = 2139
ep.Proto.LogicSigMaxCost = 2307
err = Check(program, ep)
require.NoError(t, err)
pass, err = Eval(program, ep)
Expand Down
14 changes: 7 additions & 7 deletions data/transactions/logic/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,17 +434,17 @@ func eval(program []byte, cx *evalContext) (pass bool, err error) {
// CheckStateful should be faster than EvalStateful. It can perform
// static checks and reject programs that are invalid. Returns a cost
jannotti marked this conversation as resolved.
Show resolved Hide resolved
// estimate of relative execution time. This cost is not relevent when
// params.Proto.DynamicTealCost is true, and so 1 is returned so that
// callers may continue to check for a high cost being invalid.
// the program is v4 or higher, and so 1 is returned so that callers
// may continue to check for a high cost being invalid.
func CheckStateful(program []byte, params EvalParams) error {
params.runModeFlags = runModeApplication
return check(program, params)
}

// Check should be faster than Eval. It can perform static checks and
// reject programs that are invalid. Returns a cost estimate of
// relative execution time. This cost is no relevent when
// proto.DynamicTealCost is true, and so 1 is returned so that callers
// relative execution time. This cost is not relevent when
// the program is v4 or higher, and so 1 is returned so that callers
// may continue to check for a high cost being invalid.
func Check(program []byte, params EvalParams) error {
params.runModeFlags = runModeSignature
Expand Down Expand Up @@ -499,7 +499,7 @@ func check(program []byte, params EvalParams) (err error) {
cx.instructionStarts = make(map[int]bool)

maxCost := params.budget()
if params.Proto.DynamicTealCost {
if version >= backBranchEnabledVersion {
maxCost = math.MaxInt32
}
staticCost := 0
Expand All @@ -511,7 +511,7 @@ func check(program []byte, params EvalParams) (err error) {
}
staticCost += stepCost
if staticCost > maxCost {
return fmt.Errorf("pc=%3d static cost budget %d exceeded", cx.pc, maxCost)
return fmt.Errorf("pc=%3d static cost budget of %d exceeded", cx.pc, maxCost)
}
if cx.pc <= prevpc {
// Recall, this is advancing through opcodes
Expand Down Expand Up @@ -583,7 +583,7 @@ func (cx *evalContext) step() {
}
cx.cost += deets.Cost
if cx.cost > cx.budget() {
cx.err = fmt.Errorf("budget of %d exceeded at pc=%d, executing %s", cx.budget(), cx.pc, spec.Name)
cx.err = fmt.Errorf("pc=%3d dynamic cost budget of %d exceeded, executing %s", cx.pc, cx.budget(), spec.Name)
return
}
spec.op(cx)
Expand Down
5 changes: 2 additions & 3 deletions data/transactions/logic/eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ func defaultEvalProtoWithVersion(version uint64) config.ConsensusParams {
return config.ConsensusParams{
LogicSigVersion: version,
LogicSigMaxCost: 20000,
DynamicTealCost: version >= backBranchEnabledVersion,
MaxAppProgramCost: 700,
MaxAppKeyLen: 64,
MaxAppBytesValueLen: 64,
Expand Down Expand Up @@ -2409,14 +2408,14 @@ func TestSlowLogic(t *testing.T) {
require.NoError(t, err)
_, err = Eval(ops.Program, ep4)
require.Error(t, err)
require.Contains(t, err.Error(), "exceeded at pc")
require.Contains(t, err.Error(), "dynamic cost")

ops = testProg(t, v2overspend, 4)
err = Check(ops.Program, ep4)
require.NoError(t, err)
_, err = Eval(ops.Program, ep4)
require.Error(t, err)
require.Contains(t, err.Error(), "exceeded at pc")
require.Contains(t, err.Error(), "dynamic cost")
}

func isNotPanic(t *testing.T, err error) {
Expand Down
13 changes: 7 additions & 6 deletions test/e2e-go/cli/goal/expect/tealConsensusTest.exp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ if { [catch {
set TEST_ROOT_DIR $TEST_ALGO_DIR/root
set TEST_PRIMARY_NODE_DIR $TEST_ROOT_DIR/Primary/
set NETWORK_NAME test_net_expect_$TIME_STAMP
set NETWORK_TEMPLATE "$TEST_DATA_DIR/nettemplates/TwoNodes50Each.json"
set NETWORK_TEMPLATE "$TEST_DATA_DIR/nettemplates/TwoNodes50EachFuture.json"

# Create network
::AlgorandGoal::CreateNetwork $NETWORK_NAME $NETWORK_TEMPLATE $TEST_ALGO_DIR $TEST_ROOT_DIR
Expand Down Expand Up @@ -80,18 +80,19 @@ if { [catch {
exec goal clerk send -F "$TEST_ROOT_DIR/small-sig.teal" -t GXBNLU4AXQABPLHXJDMTG2YXSDT4EWUZACT7KTPFXDQW52XPTIUS5OZ5HQ -a 100 -d $TEST_PRIMARY_NODE_DIR -o $TEST_ROOT_DIR/small-sig.tx
spawn goal clerk dryrun -t $TEST_ROOT_DIR/small-sig.tx
expect {
" - pass -" { puts "smallsig dryrun pass" }
" - pass -" { puts "small-sig dryrun pass" }
"REJECT" { ::AlgorandGoal::Abort $expect_out(buffer) }
"too large" { ::AlgorandGoal::Abort $expect_out(buffer) }
"static cost budget" { ::AlgorandGoal::Abort $expect_out(buffer) }
}

teal "$TEST_ROOT_DIR/slow-sig.teal" 2 1 20001
exec goal clerk compile "$TEST_ROOT_DIR/slow-sig.teal"
exec goal clerk send -F "$TEST_ROOT_DIR/slow-sig.teal" -t GXBNLU4AXQABPLHXJDMTG2YXSDT4EWUZACT7KTPFXDQW52XPTIUS5OZ5HQ -a 100 -d $TEST_PRIMARY_NODE_DIR -o $TEST_ROOT_DIR/slow-sig.tx
spawn goal clerk dryrun -t $TEST_ROOT_DIR/slow-sig.tx
spawn goal clerk dryrun -P future -t $TEST_ROOT_DIR/slow-sig.tx # Should succeed Check, fail Eval
expect {
"program cost too large" {puts "slowsig pass"}
"\n" { ::AlgorandGoal::Abort $expect_out(buffer) }
"dynamic cost budget" { puts "slow-sig dryrun pass" }
" - pass -" { ::AlgorandGoal::Abort $expect_out(buffer) }
"REJECT" { ::AlgorandGoal::Abort $expect_out(buffer) }
}

# Shutdown the network
Expand Down