summaryrefslogtreecommitdiff
path: root/data/transactions/logic/fields_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'data/transactions/logic/fields_test.go')
-rw-r--r--data/transactions/logic/fields_test.go113
1 files changed, 65 insertions, 48 deletions
diff --git a/data/transactions/logic/fields_test.go b/data/transactions/logic/fields_test.go
index 7d65593b6..d40ddc263 100644
--- a/data/transactions/logic/fields_test.go
+++ b/data/transactions/logic/fields_test.go
@@ -23,16 +23,10 @@ import (
"github.com/stretchr/testify/require"
"github.com/algorand/go-algorand/data/basics"
- "github.com/algorand/go-algorand/data/transactions/logictest"
+ "github.com/algorand/go-algorand/data/transactions"
"github.com/algorand/go-algorand/test/partitiontest"
)
-func TestArrayFields(t *testing.T) {
- partitiontest.PartitionTest(t)
- require.Equal(t, len(TxnaFieldNames), len(TxnaFieldTypes))
- require.Equal(t, len(txnaFieldSpecByField), len(TxnaFieldTypes))
-}
-
// ensure v2+ fields fail in TEAL assembler and evaluator on a version before they introduced
// ensure v2+ fields error in v1 program
func TestGlobalFieldsVersions(t *testing.T) {
@@ -47,7 +41,7 @@ func TestGlobalFieldsVersions(t *testing.T) {
}
require.Greater(t, len(fields), 1)
- ledger := logictest.MakeLedger(nil)
+ ledger := MakeLedger(nil)
for _, field := range fields {
text := fmt.Sprintf("global %s", field.field.String())
// check assembler fails if version before introduction
@@ -61,30 +55,26 @@ func TestGlobalFieldsVersions(t *testing.T) {
// check on a version before the field version
preLogicVersion := field.version - 1
- proto := defaultEvalProtoWithVersion(preLogicVersion)
+ proto := makeTestProtoV(preLogicVersion)
if preLogicVersion < appsEnabledVersion {
require.False(t, proto.Application)
}
- ep := defaultEvalParams(nil, nil)
- ep.Proto = &proto
+ ep := defaultEvalParams(nil)
+ ep.Proto = proto
ep.Ledger = ledger
// check failure with version check
- _, err := Eval(ops.Program, ep)
+ _, err := EvalApp(ops.Program, 0, 0, ep)
require.Error(t, err)
require.Contains(t, err.Error(), "greater than protocol supported version")
// check opcodes failures
ops.Program[0] = byte(preLogicVersion) // set version
- _, err = Eval(ops.Program, ep)
- require.Error(t, err)
- require.Contains(t, err.Error(), "invalid global field")
+ testLogicBytes(t, ops.Program, ep, "invalid global field")
// check opcodes failures on 0 version
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")
+ testLogicBytes(t, ops.Program, ep, "invalid global field")
}
}
@@ -111,7 +101,7 @@ func TestTxnFieldVersions(t *testing.T) {
}
txnaVersion := uint64(appsEnabledVersion)
- ledger := logictest.MakeLedger(nil)
+ ledger := 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
@@ -125,7 +115,7 @@ func TestTxnFieldVersions(t *testing.T) {
text := fmt.Sprintf(command, field)
asmError := asmDefaultError
txnaMode := false
- if _, ok := txnaFieldSpecByField[fs.field]; ok {
+ if fs.array {
text = fmt.Sprintf(subs[command], field)
asmError = "...txna opcode was introduced in ..."
txnaMode = true
@@ -140,42 +130,75 @@ func TestTxnFieldVersions(t *testing.T) {
}
testLine(t, text, fs.version, "")
- ops, err := AssembleStringWithVersion(text, AssemblerMaxVersion)
- require.NoError(t, err)
+ ops := testProg(t, text, AssemblerMaxVersion)
preLogicVersion := fs.version - 1
- proto := defaultEvalProtoWithVersion(preLogicVersion)
+ proto := makeTestProtoV(preLogicVersion)
if preLogicVersion < appsEnabledVersion {
require.False(t, proto.Application)
}
- ep := defaultEvalParams(nil, nil)
- ep.Proto = &proto
+ ep := defaultEvalParams(nil)
+ ep.Proto = proto
ep.Ledger = ledger
- ep.TxnGroup = txgroup
+ ep.TxnGroup = transactions.WrapSignedTxnsWithAD(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")
+ testLogicBytes(t, ops.Program, ep,
+ "greater than protocol supported version", "greater than protocol supported version")
// check opcodes failures
ops.Program[0] = byte(preLogicVersion) // set version
- _, err = Eval(ops.Program, ep)
- require.Error(t, err)
+ checkErr := ""
+ evalErr := "invalid txn field"
if txnaMode && preLogicVersion < txnaVersion {
- require.Contains(t, err.Error(), "illegal opcode")
- } else {
- require.Contains(t, err.Error(), "invalid txn field")
+ checkErr = "illegal opcode"
+ evalErr = "illegal opcode"
}
+ testLogicBytes(t, ops.Program, ep, checkErr, evalErr)
// check opcodes failures on 0 version
ops.Program[0] = 0 // set version to 0
- _, err = Eval(ops.Program, ep)
- require.Error(t, err)
+ checkErr = ""
+ evalErr = "invalid txn field"
if txnaMode {
- require.Contains(t, err.Error(), "illegal opcode")
+ checkErr = "illegal opcode"
+ evalErr = "illegal opcode"
+ }
+ testLogicBytes(t, ops.Program, ep, checkErr, evalErr)
+ }
+ }
+}
+
+// TestTxnEffectsAvailable ensures that LogicSigs can not use "effects" fields
+// (ever). And apps can only use effects fields with `txn` after
+// txnEffectsVersion. (itxn could use them earlier)
+func TestTxnEffectsAvailable(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ t.Parallel()
+ for _, fs := range txnFieldSpecByField {
+ if !fs.effects {
+ continue
+ }
+ source := fmt.Sprintf("txn %s", fs.field.String())
+ if fs.array {
+ source = fmt.Sprintf("txna %s 0", fs.field.String())
+ }
+ for v := fs.version; v <= AssemblerMaxVersion; v++ {
+ ops := testProg(t, source, v)
+ ep := defaultEvalParams(nil)
+ ep.TxnGroup[0].Lsig.Logic = ops.Program
+ _, err := EvalSignature(0, ep)
+ require.Error(t, err)
+ ep.Ledger = MakeLedger(nil)
+ _, err = EvalApp(ops.Program, 0, 0, ep)
+ if v < txnEffectsVersion {
+ require.Error(t, err)
} else {
- require.Contains(t, err.Error(), "invalid txn field")
+ if fs.array {
+ continue // Array (Logs) will be 0 length, so will fail anyway
+ }
+ require.NoError(t, err)
}
}
}
@@ -199,19 +222,13 @@ func TestAssetParamsFieldsVersions(t *testing.T) {
text := fmt.Sprintf("intcblock 0 1; intc_0; asset_params_get %s; pop; pop; intc_1", field.field.String())
// check assembler fails if version before introduction
for v := uint64(2); v <= AssemblerMaxVersion; v++ {
- ep, _ := makeSampleEnv()
+ ep, _, _ := makeSampleEnv()
ep.Proto.LogicSigVersion = v
if field.version > v {
- testProg(t, text, v, expect{3, "...available in version..."})
+ testProg(t, text, v, Expect{3, "...available in version..."})
ops := testProg(t, text, field.version) // assemble in the future
- scratch := ops.Program
- scratch[0] = byte(v) // but we'll tweak the version byte back to v
- err := CheckStateful(scratch, ep)
- require.NoError(t, err)
- pass, err := EvalStateful(scratch, ep) // so eval fails on future field
- require.False(t, pass)
- require.Error(t, err)
- require.Contains(t, err.Error(), "invalid asset_params_get field")
+ ops.Program[0] = byte(v)
+ testAppBytes(t, ops.Program, ep, "invalid asset_params_get field")
} else {
testProg(t, text, v)
testApp(t, text, ep)