diff options
Diffstat (limited to 'data/transactions/logic/backwardCompat_test.go')
-rw-r--r-- | data/transactions/logic/backwardCompat_test.go | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/data/transactions/logic/backwardCompat_test.go b/data/transactions/logic/backwardCompat_test.go index d78275644..226c94840 100644 --- a/data/transactions/logic/backwardCompat_test.go +++ b/data/transactions/logic/backwardCompat_test.go @@ -22,8 +22,11 @@ import ( "strings" "testing" + "github.com/algorand/go-algorand/config" "github.com/algorand/go-algorand/crypto" "github.com/algorand/go-algorand/data/basics" + "github.com/algorand/go-algorand/data/transactions/logictest" + "github.com/algorand/go-algorand/protocol" "github.com/algorand/go-algorand/test/partitiontest" "github.com/stretchr/testify/require" ) @@ -371,6 +374,151 @@ func TestBackwardCompatTEALv1(t *testing.T) { } +// ensure v2 fields error on pre TEAL v2 logicsig version +// ensure v2 fields error in v1 program +func TestBackwardCompatGlobalFields(t *testing.T) { + partitiontest.PartitionTest(t) + + t.Parallel() + var fields []globalFieldSpec + for _, fs := range globalFieldSpecs { + if fs.version > 1 { + fields = append(fields, fs) + } + } + require.Greater(t, len(fields), 1) + + ledger := logictest.MakeLedger(nil) + for _, field := range fields { + text := fmt.Sprintf("global %s", field.field.String()) + // check assembler fails if version before introduction + testLine(t, text, assemblerNoVersion, "...available in version...") + for v := uint64(0); v < field.version; v++ { + testLine(t, text, v, "...available in version...") + } + + ops := testProg(t, text, AssemblerMaxVersion) + + proto := config.Consensus[protocol.ConsensusV23] + require.False(t, proto.Application) + ep := defaultEvalParams(nil, nil) + ep.Proto = &proto + ep.Ledger = ledger + + // check failure with version check + _, err := Eval(ops.Program, ep) + require.Error(t, err) + require.Contains(t, err.Error(), "greater than protocol supported version") + _, err = Eval(ops.Program, ep) + require.Error(t, err) + require.Contains(t, err.Error(), "greater than protocol supported version") + + // check opcodes failures + ops.Program[0] = 1 // set version to 1 + _, err = Eval(ops.Program, ep) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid global field") + _, err = Eval(ops.Program, ep) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid global field") + + // check opcodes failures + ops.Program[0] = 0 // set version to 0 + _, err = Eval(ops.Program, ep) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid global field") + _, err = Eval(ops.Program, ep) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid global field") + } +} + +// ensure v2 fields error in v1 program +func TestBackwardCompatTxnFields(t *testing.T) { + partitiontest.PartitionTest(t) + + t.Parallel() + var fields []txnFieldSpec + for _, fs := range txnFieldSpecs { + if fs.version > 1 { + fields = append(fields, fs) + } + } + require.Greater(t, len(fields), 1) + + tests := []string{ + "txn %s", + "gtxn 0 %s", + } + + ledger := logictest.MakeLedger(nil) + txn := makeSampleTxn() + // We'll reject too early if we have a nonzero RekeyTo, because that + // field must be zero for every txn in the group if this is an old + // TEAL version + txn.Txn.RekeyTo = basics.Address{} + txgroup := makeSampleTxnGroup(txn) + for _, fs := range fields { + field := fs.field.String() + for _, command := range tests { + text := fmt.Sprintf(command, field) + asmError := "...available in version ..." + if _, ok := txnaFieldSpecByField[fs.field]; ok { + parts := strings.Split(text, " ") + op := parts[0] + asmError = fmt.Sprintf("found array field %#v in %s op", field, op) + } + // check assembler fails if version before introduction + testLine(t, text, assemblerNoVersion, asmError) + for v := uint64(0); v < fs.version; v++ { + testLine(t, text, v, asmError) + } + + ops, err := AssembleStringWithVersion(text, AssemblerMaxVersion) + if _, ok := txnaFieldSpecByField[fs.field]; ok { + // "txn Accounts" is invalid, so skip evaluation + require.Error(t, err, asmError) + continue + } else { + require.NoError(t, err) + } + + proto := config.Consensus[protocol.ConsensusV23] + require.False(t, proto.Application) + ep := defaultEvalParams(nil, nil) + ep.Proto = &proto + ep.Ledger = ledger + ep.TxnGroup = txgroup + + // check failure with version check + _, err = Eval(ops.Program, ep) + require.Error(t, err) + require.Contains(t, err.Error(), "greater than protocol supported version") + _, err = Eval(ops.Program, ep) + require.Error(t, err) + require.Contains(t, err.Error(), "greater than protocol supported version") + + // check opcodes failures + ops.Program[0] = 1 // set version to 1 + _, err = Eval(ops.Program, ep) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid txn field") + _, err = Eval(ops.Program, ep) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid txn field") + + // check opcodes failures + ops.Program[0] = 0 // set version to 0 + _, err = Eval(ops.Program, ep) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid txn field") + _, err = Eval(ops.Program, ep) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid txn field") + } + } +} + func TestBackwardCompatAssemble(t *testing.T) { partitiontest.PartitionTest(t) @@ -404,3 +552,12 @@ done:` }) } } + +func TestExplicitConstants(t *testing.T) { + partitiontest.PartitionTest(t) + + require.Equal(t, 4096, MaxStringSize, "constant changed, move it to consensus params") + require.Equal(t, 64, MaxByteMathSize, "constant changed, move it to consensus params") + require.Equal(t, 1024, MaxLogSize, "constant changed, move it to consensus params") + require.Equal(t, 32, MaxLogCalls, "constant changed, move it to consensus params") +} |