summaryrefslogtreecommitdiff
path: root/ledger/apply/application_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'ledger/apply/application_test.go')
-rw-r--r--ledger/apply/application_test.go138
1 files changed, 88 insertions, 50 deletions
diff --git a/ledger/apply/application_test.go b/ledger/apply/application_test.go
index 3251f0470..124a40936 100644
--- a/ledger/apply/application_test.go
+++ b/ledger/apply/application_test.go
@@ -114,7 +114,7 @@ type testBalances struct {
// logic evaluator control
pass bool
- delta basics.EvalDelta
+ delta transactions.EvalDelta
err error
}
@@ -126,6 +126,12 @@ const appIdxError basics.AppIndex = 0x11223344
const appIdxOk basics.AppIndex = 1
func (b *testBalances) Get(addr basics.Address, withPendingRewards bool) (basics.AccountData, error) {
+ if b.putBalances != nil {
+ ad, ok := b.putBalances[addr]
+ if ok {
+ return ad, nil
+ }
+ }
ad, ok := b.balances[addr]
if !ok {
return basics.AccountData{}, fmt.Errorf("mock balance not found")
@@ -219,7 +225,7 @@ func (b *testBalances) DeallocateAsset(addr basics.Address, index basics.AssetIn
return nil
}
-func (b *testBalances) StatefulEval(params logic.EvalParams, aidx basics.AppIndex, program []byte) (passed bool, evalDelta basics.EvalDelta, err error) {
+func (b *testBalances) StatefulEval(params logic.EvalParams, aidx basics.AppIndex, program []byte) (passed bool, evalDelta transactions.EvalDelta, err error) {
return b.pass, b.delta, b.err
}
@@ -252,7 +258,7 @@ func (b *testBalancesPass) Deallocate(addr basics.Address, aidx basics.AppIndex,
return nil
}
-func (b *testBalancesPass) StatefulEval(params logic.EvalParams, aidx basics.AppIndex, program []byte) (passed bool, evalDelta basics.EvalDelta, err error) {
+func (b *testBalancesPass) StatefulEval(params logic.EvalParams, aidx basics.AppIndex, program []byte) (passed bool, evalDelta transactions.EvalDelta, err error) {
return true, b.delta, nil
}
@@ -275,14 +281,14 @@ func (b *testBalances) SetParams(params config.ConsensusParams) {
type testEvaluator struct {
pass bool
- delta basics.EvalDelta
+ delta transactions.EvalDelta
appIdx basics.AppIndex
}
// Eval for tests that fail on program version > 10 and returns pass/delta from its own state rather than running the program
-func (e *testEvaluator) Eval(program []byte) (pass bool, stateDelta basics.EvalDelta, err error) {
+func (e *testEvaluator) Eval(program []byte) (pass bool, stateDelta transactions.EvalDelta, err error) {
if len(program) < 1 || program[0] > 10 {
- return false, basics.EvalDelta{}, fmt.Errorf("mock eval error")
+ return false, transactions.EvalDelta{}, fmt.Errorf("mock eval error")
}
return e.pass, e.delta, nil
}
@@ -515,15 +521,6 @@ func TestAppCallApplyCreate(t *testing.T) {
b.ResetWrites()
- // now looking up the creator will succeed, but we reset writes, so
- // they won't have the app params
- err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
- a.Error(err)
- a.Contains(err.Error(), fmt.Sprintf("app %d not found in account", appIdx))
- a.Equal(1, b.put)
-
- b.ResetWrites()
-
// now we give the creator the app params again
cp := basics.AccountData{}
cp.AppParams = cloneAppParams(saved.AppParams)
@@ -607,7 +604,7 @@ func TestAppCallApplyCreateOptIn(t *testing.T) {
b.appCreators = map[basics.AppIndex]basics.Address{appIdx: creator}
gd := map[string]basics.ValueDelta{"uint": {Action: basics.SetUintAction, Uint: 1}}
- b.delta = basics.EvalDelta{GlobalDelta: gd}
+ b.delta = transactions.EvalDelta{GlobalDelta: gd}
err := ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
@@ -690,6 +687,42 @@ func TestAppCallOptIn(t *testing.T) {
},
br,
)
+
+ // check max optins
+
+ var optInCountTest = []struct {
+ proto protocol.ConsensusVersion
+ }{
+ {protocol.ConsensusV29},
+ {protocol.ConsensusFuture},
+ }
+
+ prevMaxAppsOptedIn := 0
+ for _, test := range optInCountTest {
+ cparams, ok := config.Consensus[test.proto]
+ a.True(ok)
+ a.Less(prevMaxAppsOptedIn, cparams.MaxAppsOptedIn)
+ prevMaxAppsOptedIn = cparams.MaxAppsOptedIn
+
+ b.SetParams(cparams)
+ aparams := basics.AppParams{
+ StateSchemas: basics.StateSchemas{
+ LocalStateSchema: basics.StateSchema{NumUint: 1},
+ },
+ }
+ sender = getRandomAddress(a)
+ b.balances = map[basics.Address]basics.AccountData{sender: {}}
+ var appIdx basics.AppIndex = appIdx
+ for i := 0; i < cparams.MaxAppsOptedIn; i++ {
+ appIdx = appIdx + basics.AppIndex(i)
+ err = optInApplication(&b, sender, appIdx, aparams)
+ a.NoError(err)
+ }
+ appIdx++
+ err = optInApplication(&b, sender, appIdx, aparams)
+ a.Error(err)
+ a.Contains(err.Error(), "max opted-in apps per acct")
+ }
}
func TestAppCallClearState(t *testing.T) {
@@ -768,7 +801,7 @@ func TestAppCallClearState(t *testing.T) {
br = b.putBalances[sender]
a.Equal(0, len(br.AppLocalStates))
a.Equal(basics.StateSchema{}, br.TotalAppSchema)
- a.Equal(basics.EvalDelta{}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{}, ad.EvalDelta)
b.ResetWrites()
@@ -787,7 +820,7 @@ func TestAppCallClearState(t *testing.T) {
// one put: to opt out
b.pass = false
- b.delta = basics.EvalDelta{GlobalDelta: nil}
+ b.delta = transactions.EvalDelta{GlobalDelta: nil}
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
a.Equal(1, b.put)
@@ -801,7 +834,7 @@ func TestAppCallClearState(t *testing.T) {
// check existing application with logic err ClearStateProgram.
// one to opt out, one deallocate, no error from ApplicationCall
b.pass = true
- b.delta = basics.EvalDelta{GlobalDelta: nil}
+ b.delta = transactions.EvalDelta{GlobalDelta: nil}
b.err = ledgercore.LogicEvalError{Err: fmt.Errorf("test error")}
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
@@ -816,7 +849,7 @@ func TestAppCallClearState(t *testing.T) {
// check existing application with non-logic err ClearStateProgram.
// ApplicationCall must fail
b.pass = true
- b.delta = basics.EvalDelta{GlobalDelta: nil}
+ b.delta = transactions.EvalDelta{GlobalDelta: nil}
b.err = fmt.Errorf("test error")
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.Error(err)
@@ -832,23 +865,23 @@ func TestAppCallClearState(t *testing.T) {
b.pass = true
b.err = nil
gd := basics.StateDelta{"uint": {Action: basics.SetUintAction, Uint: 1}}
- b.delta = basics.EvalDelta{GlobalDelta: gd}
+ b.delta = transactions.EvalDelta{GlobalDelta: gd}
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
a.Equal(1, b.put)
a.Equal(appIdx, b.deAllocatedAppIdx)
a.Equal(0, len(br.AppLocalStates))
a.Equal(basics.StateSchema{}, br.TotalAppSchema)
- a.Equal(basics.EvalDelta{GlobalDelta: gd}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{GlobalDelta: gd}, ad.EvalDelta)
b.ResetWrites()
b.pass = true
b.err = nil
- logs := []basics.LogItem{{ID: 0, Message: "a"}}
- b.delta = basics.EvalDelta{Logs: []basics.LogItem{{ID: 0, Message: "a"}}}
+ logs := []string{"a"}
+ b.delta = transactions.EvalDelta{Logs: []string{"a"}}
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
- a.Equal(basics.EvalDelta{Logs: logs}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{Logs: logs}, ad.EvalDelta)
}
func TestAppCallApplyCloseOut(t *testing.T) {
@@ -899,7 +932,7 @@ func TestAppCallApplyCloseOut(t *testing.T) {
a.Equal(0, b.put)
br := b.balances[creator]
a.Equal(cbr, br)
- a.Equal(basics.EvalDelta{}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{}, ad.EvalDelta)
// check closing on empty sender's balance record
b.pass = true
@@ -910,13 +943,13 @@ func TestAppCallApplyCloseOut(t *testing.T) {
a.Equal(0, b.put)
br = b.balances[creator]
a.Equal(cbr, br)
- a.Equal(basics.EvalDelta{}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{}, ad.EvalDelta)
b.ResetWrites()
// check a happy case
gd := map[string]basics.ValueDelta{"uint": {Action: basics.SetUintAction, Uint: 1}}
- b.delta = basics.EvalDelta{GlobalDelta: gd}
+ b.delta = transactions.EvalDelta{GlobalDelta: gd}
b.balances[sender] = basics.AccountData{
AppLocalStates: map[basics.AppIndex]basics.AppLocalState{appIdx: {}},
}
@@ -928,14 +961,18 @@ func TestAppCallApplyCloseOut(t *testing.T) {
a.Equal(basics.TealKeyValue(nil), br.AppParams[appIdx].GlobalState)
br = b.putBalances[sender]
a.Equal(0, len(br.AppLocalStates))
- a.Equal(basics.EvalDelta{GlobalDelta: gd}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{GlobalDelta: gd}, ad.EvalDelta)
a.Equal(basics.StateSchema{NumUint: 0}, br.TotalAppSchema)
- logs := []basics.LogItem{{ID: 0, Message: "a"}}
- b.delta = basics.EvalDelta{Logs: []basics.LogItem{{ID: 0, Message: "a"}}}
+ b.ResetWrites()
+ logs := []string{"a"}
+ b.delta = transactions.EvalDelta{Logs: []string{"a"}}
+ b.balances[sender] = basics.AccountData{
+ AppLocalStates: map[basics.AppIndex]basics.AppLocalState{appIdx: {}},
+ }
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
- a.Equal(basics.EvalDelta{Logs: logs}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{Logs: logs}, ad.EvalDelta)
}
func TestAppCallApplyUpdate(t *testing.T) {
@@ -988,7 +1025,7 @@ func TestAppCallApplyUpdate(t *testing.T) {
a.Equal(0, b.put)
br := b.balances[creator]
a.Equal(cbr, br)
- a.Equal(basics.EvalDelta{}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{}, ad.EvalDelta)
// check updating on empty sender's balance record - happy case
b.pass = true
@@ -1001,7 +1038,7 @@ func TestAppCallApplyUpdate(t *testing.T) {
br = b.putBalances[creator]
a.Equal([]byte{2}, br.AppParams[appIdx].ApprovalProgram)
a.Equal([]byte{2}, br.AppParams[appIdx].ClearStateProgram)
- a.Equal(basics.EvalDelta{}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{}, ad.EvalDelta)
//check program len check happens in future consensus proto version
b.SetProto(protocol.ConsensusFuture)
@@ -1030,11 +1067,11 @@ func TestAppCallApplyUpdate(t *testing.T) {
b.balances[creator] = cp
b.appCreators = map[basics.AppIndex]basics.Address{appIdx: creator}
- logs := []basics.LogItem{{ID: 0, Message: "a"}}
- b.delta = basics.EvalDelta{Logs: []basics.LogItem{{ID: 0, Message: "a"}}}
+ logs := []string{"a"}
+ b.delta = transactions.EvalDelta{Logs: []string{"a"}}
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
- a.Equal(basics.EvalDelta{Logs: logs}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{Logs: logs}, ad.EvalDelta)
// check extraProgramPages is used
appr := make([]byte, 2*proto.MaxAppProgramLen+1)
@@ -1062,6 +1099,7 @@ func TestAppCallApplyUpdate(t *testing.T) {
a.Contains(err.Error(), fmt.Sprintf("updateApplication %s program too long", test.name))
}
+ b.ResetWrites()
// check extraProgramPages allows length of proto.MaxAppProgramLen + 1
appr = make([]byte, proto.MaxAppProgramLen+1)
appr[0] = 4
@@ -1142,7 +1180,7 @@ func TestAppCallApplyDelete(t *testing.T) {
a.Equal(0, b.put)
br := b.balances[creator]
a.Equal(cbr, br)
- a.Equal(basics.EvalDelta{}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{}, ad.EvalDelta)
// check calculation on ConsensusV28. TotalExtraAppPages does not change
b.SetProto(protocol.ConsensusV28)
@@ -1160,7 +1198,7 @@ func TestAppCallApplyDelete(t *testing.T) {
br = b.putBalances[creator]
a.Equal(basics.AppParams{}, br.AppParams[appIdx])
a.Equal(basics.StateSchema{}, br.TotalAppSchema)
- a.Equal(basics.EvalDelta{}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{}, ad.EvalDelta)
a.Equal(uint32(1), br.TotalExtraAppPages)
b.ResetWrites()
@@ -1190,7 +1228,7 @@ func TestAppCallApplyDelete(t *testing.T) {
br = b.putBalances[creator]
a.Equal(basics.AppParams{}, br.AppParams[appIdx])
a.Equal(basics.StateSchema{}, br.TotalAppSchema)
- a.Equal(basics.EvalDelta{}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{}, ad.EvalDelta)
if initTotalExtraPages <= params.ExtraProgramPages {
a.Equal(uint32(0), br.TotalExtraAppPages)
} else {
@@ -1198,11 +1236,11 @@ func TestAppCallApplyDelete(t *testing.T) {
}
b.ResetWrites()
}
- logs := []basics.LogItem{{ID: 0, Message: "a"}}
- b.delta = basics.EvalDelta{Logs: []basics.LogItem{{ID: 0, Message: "a"}}}
+ logs := []string{"a"}
+ b.delta = transactions.EvalDelta{Logs: []string{"a"}}
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
- a.Equal(basics.EvalDelta{Logs: logs}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{Logs: logs}, ad.EvalDelta)
}
func TestAppCallApplyCreateClearState(t *testing.T) {
@@ -1238,14 +1276,14 @@ func TestAppCallApplyCreateClearState(t *testing.T) {
b.pass = true
gd := map[string]basics.ValueDelta{"uint": {Action: basics.SetUintAction, Uint: 1}}
- b.delta = basics.EvalDelta{GlobalDelta: gd}
+ b.delta = transactions.EvalDelta{GlobalDelta: gd}
// check creation on empty balance record
err := ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.Error(err)
a.Contains(err.Error(), "not currently opted in")
a.Equal(appIdx, b.allocatedAppIdx)
- a.Equal(basics.EvalDelta{}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{}, ad.EvalDelta)
br := b.balances[creator]
a.Equal([]byte{1}, br.AppParams[appIdx].ApprovalProgram)
a.Equal([]byte{2}, br.AppParams[appIdx].ClearStateProgram)
@@ -1288,20 +1326,20 @@ func TestAppCallApplyCreateDelete(t *testing.T) {
b.pass = true
gd := map[string]basics.ValueDelta{"uint": {Action: basics.SetUintAction, Uint: 1}}
- b.delta = basics.EvalDelta{GlobalDelta: gd}
+ b.delta = transactions.EvalDelta{GlobalDelta: gd}
// check creation on empty balance record
err := ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
a.Equal(appIdx, b.allocatedAppIdx)
- a.Equal(basics.EvalDelta{GlobalDelta: gd}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{GlobalDelta: gd}, ad.EvalDelta)
br := b.balances[creator]
a.Equal(basics.AppParams{}, br.AppParams[appIdx])
- logs := []basics.LogItem{{ID: 0, Message: "a"}}
- b.delta = basics.EvalDelta{Logs: []basics.LogItem{{ID: 0, Message: "a"}}}
+ logs := []string{"a"}
+ b.delta = transactions.EvalDelta{Logs: []string{"a"}}
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
- a.Equal(basics.EvalDelta{Logs: logs}, ad.EvalDelta)
+ a.Equal(transactions.EvalDelta{Logs: logs}, ad.EvalDelta)
}