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
Next Next commit
basics for divw, teal v4
  • Loading branch information
jannotti committed Apr 27, 2021
commit b4a55af7973050e96372d117a83573afa55881ba
87 changes: 50 additions & 37 deletions data/transactions/logic/assembler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,30 @@ pushint 1000
pushbytes "john"
`

// Keep in mind, only use existing int and byte constants, or else use
// push* instead. The idea is to not cause the *cblocks to change.
const v4Nonsense = `
int 1
pushint 2000
int 0
int 2
divw
`

var nonsense = map[uint64]string{
1: v1Nonsense,
2: v1Nonsense + v2Nonsense,
3: v1Nonsense + v2Nonsense + v3Nonsense,
4: v1Nonsense + v2Nonsense + v3Nonsense + v4Nonsense,
}

var compiled = map[uint64]string{
1: "012008b7a60cf8acd19181cf959a12f8acd19181cf951af8acd19181cf15f8acd191810f01020026050212340c68656c6c6f20776f726c6421208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d024242047465737400320032013202320328292929292a0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e0102222324252104082209240a220b230c240d250e230f23102311231223132314181b1c2b1716154000032903494",
2: "022008b7a60cf8acd19181cf959a12f8acd19181cf951af8acd19181cf15f8acd191810f01020026050212340c68656c6c6f20776f726c6421208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d024242047465737400320032013202320328292929292a0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e0102222324252104082209240a220b230c240d250e230f23102311231223132314181b1c2b171615400003290349483403350222231d4a484848482a50512a63222352410003420000432105602105612105270463484821052b62482b642b65484821052b2106662b21056721072b682b692107210570004848210771004848361c0037001a0031183119311b311d311e311f3120210721051e312131223123312431253126312731283129312a312b312c312d312e312f",
3: "032008b7a60cf8acd19181cf959a12f8acd19181cf951af8acd19181cf15f8acd191810f01020026050212340c68656c6c6f20776f726c6421208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d024242047465737400320032013202320328292929292a0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e0102222324252104082209240a220b230c240d250e230f23102311231223132314181b1c2b171615400003290349483403350222231d4a484848482a50512a63222352410003420000432105602105612105270463484821052b62482b642b65484821052b2106662b21056721072b682b692107210570004848210771004848361c0037001a0031183119311b311d311e311f3120210721051e312131223123312431253126312731283129312a312b312c312d312e312f4478222105531421055427042106552105082106564c4d4b02210538212106391c0081e80780046a6f686e",
4: "042008b7a60cf8acd19181cf959a12f8acd19181cf951af8acd19181cf15f8acd191810f01020026050212340c68656c6c6f20776f726c6421208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d024242047465737400320032013202320328292929292a0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e0102222324252104082209240a220b230c240d250e230f23102311231223132314181b1c2b171615400003290349483403350222231d4a484848482a50512a63222352410003420000432105602105612105270463484821052b62482b642b65484821052b2106662b21056721072b682b692107210570004848210771004848361c0037001a0031183119311b311d311e311f3120210721051e312131223123312431253126312731283129312a312b312c312d312e312f4478222105531421055427042106552105082106564c4d4b02210538212106391c0081e80780046a6f686e210581d00f210721061f",
}

func pseudoOp(opcode string) bool {
// We don't test every combination of
// intcblock,bytecblock,intc*,bytec*,arg* here. Not all of
Expand All @@ -263,44 +287,33 @@ func TestAssemble(t *testing.T) {
// Run test. It should pass.
//
// This doesn't have to be a sensible program to run, it just has to compile.
for _, spec := range OpSpecs {
// Ensure that we have some basic check of all the ops, except
if !strings.Contains(v1Nonsense+v2Nonsense, spec.Name) &&
!pseudoOp(spec.Name) && spec.Version <= 2 {
t.Errorf("v2 nonsense test should contain op %v", spec.Name)
}
}
// First, we test v2, not AssemblerMaxVersion. A higher version is
// allowed to differ (and must, in the first byte).
ops := testProg(t, v1Nonsense+v2Nonsense, 2)
// check that compilation is stable over time and we assemble to the same bytes this month that we did last month.
expectedBytes, _ := hex.DecodeString("022008b7a60cf8acd19181cf959a12f8acd19181cf951af8acd19181cf15f8acd191810f01020026050212340c68656c6c6f20776f726c6421208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d024242047465737400320032013202320328292929292a0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e0102222324252104082209240a220b230c240d250e230f23102311231223132314181b1c2b171615400003290349483403350222231d4a484848482a50512a63222352410003420000432105602105612105270463484821052b62482b642b65484821052b2106662b21056721072b682b692107210570004848210771004848361c0037001a0031183119311b311d311e311f3120210721051e312131223123312431253126312731283129312a312b312c312d312e312f")
if bytes.Compare(expectedBytes, ops.Program) != 0 {
// this print is for convenience if the program has been changed. the hex string can be copy pasted back in as a new expected result.
t.Log(hex.EncodeToString(ops.Program))
}
require.Equal(t, expectedBytes, ops.Program)

// We test v3 here, and compare to AssemblerMaxVersion, with
// the intention that the test breaks the next time
// AssemblerMaxVersion is increased. At that point, we would
// add a new test for v4, and leave behind this test for v3.

for _, spec := range OpSpecs {
// Ensure that we have some basic check of all the ops, except
if !strings.Contains(v1Nonsense+v2Nonsense+v3Nonsense, spec.Name) &&
!pseudoOp(spec.Name) && spec.Version <= 3 {
t.Errorf("v3 nonsense test should contain op %v", spec.Name)
}
}
ops = testProg(t, v1Nonsense+v2Nonsense+v3Nonsense, AssemblerMaxVersion)
// check that compilation is stable over time and we assemble to the same bytes this month that we did last month.
expectedBytes, _ = hex.DecodeString("032008b7a60cf8acd19181cf959a12f8acd19181cf951af8acd19181cf15f8acd191810f01020026050212340c68656c6c6f20776f726c6421208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d024242047465737400320032013202320328292929292a0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e0102222324252104082209240a220b230c240d250e230f23102311231223132314181b1c2b171615400003290349483403350222231d4a484848482a50512a63222352410003420000432105602105612105270463484821052b62482b642b65484821052b2106662b21056721072b682b692107210570004848210771004848361c0037001a0031183119311b311d311e311f3120210721051e312131223123312431253126312731283129312a312b312c312d312e312f4478222105531421055427042106552105082106564c4d4b02210538212106391c0081e80780046a6f686e")
if bytes.Compare(expectedBytes, ops.Program) != 0 {
// this print is for convenience if the program has been changed. the hex string can be copy pasted back in as a new expected result.
t.Log(hex.EncodeToString(ops.Program))

t.Parallel()
tsachiherman marked this conversation as resolved.
Show resolved Hide resolved
for v := uint64(2); v <= AssemblerMaxVersion; v++ {
t.Run(fmt.Sprintf("v=%d", v), func(t *testing.T) {
for _, spec := range OpSpecs {
// Make sure our nonsense covers the ops
if !strings.Contains(nonsense[v], spec.Name) &&
!pseudoOp(spec.Name) && spec.Version <= v {
t.Errorf("v%d nonsense test should contain op %v", v, spec.Name)
}
}

ops := testProg(t, nonsense[v], v)
// check that compilation is stable over
// time. we must assemble to the same bytes
// this month that we did last month.
expectedBytes, _ := hex.DecodeString(compiled[v])
if bytes.Compare(expectedBytes, ops.Program) != 0 {
// this print is for convenience if
// the program has been changed. the
// hex string can be copy pasted back
// in as a new expected result.
t.Log(hex.EncodeToString(ops.Program))
}
require.Equal(t, expectedBytes, ops.Program)
})
}
require.Equal(t, expectedBytes, ops.Program)
}

func TestAssembleAlias(t *testing.T) {
Expand Down
17 changes: 17 additions & 0 deletions data/transactions/logic/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,23 @@ func opAddw(cx *evalContext) {
cx.stack[last].Uint = sum
}

func opDivwImpl(hiNum, loNum, hiDen, loDen uint64) (hiQuo uint64, loQuo uint64, hiRem uint64, loRem uint64) {
return 1, 2, 3, 4
}

func opDivw(cx *evalContext) {
loDen := len(cx.stack) - 1
hiDen := loDen - 1
loNum := hiDen - 1
hiNum := loDen - 1
hiQuo, loQuo, hiRem, loRem :=
opDivwImpl(cx.stack[hiNum].Uint, cx.stack[loNum].Uint, cx.stack[hiDen].Uint, cx.stack[loDen].Uint)
cx.stack[hiNum].Uint = hiQuo
cx.stack[loNum].Uint = loQuo
cx.stack[hiDen].Uint = hiRem
cx.stack[loDen].Uint = loRem
}

func opMinus(cx *evalContext) {
last := len(cx.stack) - 1
prev := last - 1
Expand Down
8 changes: 8 additions & 0 deletions data/transactions/logic/eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,10 @@ addr ` + testAddr + `
&&
`

const globalV4TestProgram = globalV3TestProgram + `
// No new globals in v4
`

func TestGlobal(t *testing.T) {
t.Parallel()
type desc struct {
Expand All @@ -1048,6 +1052,10 @@ func TestGlobal(t *testing.T) {
CreatorAddress, globalV3TestProgram,
EvalStateful, CheckStateful,
},
4: {
CreatorAddress, globalV4TestProgram,
EvalStateful, CheckStateful,
},
}
ledger := makeTestLedger(nil)
ledger.appID = 42
Expand Down
3 changes: 2 additions & 1 deletion data/transactions/logic/opcodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
)

// LogicVersion defines default assembler and max eval versions
const LogicVersion = 3
const LogicVersion = 4

// rekeyingEnabledVersion is the version of TEAL where RekeyTo functionality
// was enabled. This is important to remember so that old TEAL accounts cannot
Expand Down Expand Up @@ -151,6 +151,7 @@ var OpSpecs = []OpSpec{
{0x1c, "~", opBitNot, asmDefault, disDefault, oneInt, oneInt, 1, modeAny, opDefault},
{0x1d, "mulw", opMulw, asmDefault, disDefault, twoInts, twoInts, 1, modeAny, opDefault},
{0x1e, "addw", opAddw, asmDefault, disDefault, twoInts, twoInts, 2, modeAny, opDefault},
{0x1f, "divw", opDivw, asmDefault, disDefault, twoInts.plus(twoInts), twoInts.plus(twoInts), 4, modeAny, opDefault},

{0x20, "intcblock", opIntConstBlock, assembleIntCBlock, disIntcblock, nil, nil, 1, modeAny, varies(checkIntConstBlock, "uint ...", immInts)},
{0x21, "intc", opIntConstLoad, assembleIntC, disIntc, nil, oneInt, 1, modeAny, immediates("i")},
Expand Down