summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrice Rising <brice@algorand.com>2021-08-07 12:55:05 -0400
committerBrice Rising <brice@algorand.com>2021-08-07 12:55:05 -0400
commit8ce1e6c69e5c4cf080fb170625e2551a387e9e63 (patch)
treebfc9315fa1361855e4746b86aeb5e12f56359af4
parent77e1aaf8939f4f35061711cf2f8520b047122431 (diff)
parent5d33a58fb12c92247d7fd2e8bb5dc484b95d406e (diff)
Merge branch 'hotfix/v2.9.1-travis' of github.com:algorand/go-algorand into hotfix/v2.9.1v2.9.1-beta
-rw-r--r--.travis.yml4
-rw-r--r--data/basics/units_test.go4
-rw-r--r--ledger/appcow.go25
-rw-r--r--ledger/appcow_test.go4
-rw-r--r--ledger/apply/application.go17
-rw-r--r--ledger/apply/application_test.go137
-rw-r--r--ledger/apply/apply.go17
-rw-r--r--ledger/apply/asset.go21
-rw-r--r--ledger/apply/keyreg_test.go16
-rw-r--r--ledger/apply/mockBalances_test.go14
-rw-r--r--ledger/assetcow.go48
-rw-r--r--ledger/cow.go20
-rw-r--r--ledger/cow_test.go2
-rw-r--r--ledger/eval.go15
-rwxr-xr-xscripts/travis/run_tests.sh4
-rw-r--r--test/e2e-go/features/transactions/app_pages_test.go3
16 files changed, 187 insertions, 164 deletions
diff --git a/.travis.yml b/.travis.yml
index c71c66279..c4212d488 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,11 +7,11 @@ if: tag IS blank
stages:
- name: build_commit
- if: NOT (branch =~ /^rel\//) AND type != pull_request
+ if: NOT (branch =~ /^hotfix\//) AND NOT (branch =~ /^rel\//) AND type != pull_request
- name: build_pr
if: type = pull_request
- name: build_release
- if: branch =~ /^rel\// AND type != pull_request
+ if: (branch =~ /^hotfix\// OR branch =~ /^rel\//) AND type != pull_request
- name: deploy
if: branch =~ /^rel\// AND type != pull_request
- name: post_deploy
diff --git a/data/basics/units_test.go b/data/basics/units_test.go
index d0a643966..b0b3a8885 100644
--- a/data/basics/units_test.go
+++ b/data/basics/units_test.go
@@ -32,8 +32,6 @@ func TestSubSaturate(t *testing.T) {
}
func TestSubSaturate32(t *testing.T) {
- partitiontest.PartitionTest(t)
-
require.Equal(t, uint32(0), SubSaturate32(0, 1))
require.Equal(t, uint32(0), SubSaturate32(1, 2))
require.Equal(t, uint32(0), SubSaturate32(1, 1))
@@ -43,8 +41,6 @@ func TestSubSaturate32(t *testing.T) {
}
func TestAddSaturate32(t *testing.T) {
- partitiontest.PartitionTest(t)
-
require.Equal(t, uint32(1), AddSaturate32(0, 1))
require.Equal(t, uint32(math.MaxUint32-1), AddSaturate32(math.MaxUint32-2, 1))
require.Equal(t, uint32(math.MaxUint32), AddSaturate32(math.MaxUint32, 0))
diff --git a/ledger/appcow.go b/ledger/appcow.go
index eafa0930f..4b41c92a5 100644
--- a/ledger/appcow.go
+++ b/ledger/appcow.go
@@ -222,7 +222,7 @@ func errAlreadyStorage(addr basics.Address, aidx basics.AppIndex, global bool) e
}
// Allocate creates kv storage for a given {addr, aidx, global}. It is called on app creation (global) or opting in (local)
-func (cb *roundCowState) Allocate(addr basics.Address, aidx basics.AppIndex, global bool, space basics.StateSchema) error {
+func (cb *roundCowState) AllocateApp(addr basics.Address, aidx basics.AppIndex, global bool, space basics.StateSchema) error {
// Check that account is not already opted in
allocated, err := cb.allocated(addr, aidx, global)
if err != nil {
@@ -241,11 +241,21 @@ func (cb *roundCowState) Allocate(addr basics.Address, aidx basics.AppIndex, glo
lsd.action = allocAction
lsd.maxCounts = &space
+ if global {
+ cb.mods.Creatables[basics.CreatableIndex(aidx)] = ledgercore.ModifiedCreatable{
+ Ctype: basics.AppCreatable,
+ Creator: addr,
+ Created: true,
+ }
+ }
+
+ cb.trackCreatable(basics.CreatableIndex(aidx))
+
return nil
}
// Deallocate clears storage for {addr, aidx, global}. It happens on app deletion (global) or closing out (local)
-func (cb *roundCowState) Deallocate(addr basics.Address, aidx basics.AppIndex, global bool) error {
+func (cb *roundCowState) DeallocateApp(addr basics.Address, aidx basics.AppIndex, global bool) error {
// Check that account has allocated storage
allocated, err := cb.allocated(addr, aidx, global)
if err != nil {
@@ -265,6 +275,15 @@ func (cb *roundCowState) Deallocate(addr basics.Address, aidx basics.AppIndex, g
lsd.counts = &basics.StateSchema{}
lsd.maxCounts = &basics.StateSchema{}
lsd.kvCow = make(stateDelta)
+
+ if global {
+ cb.mods.Creatables[basics.CreatableIndex(aidx)] = ledgercore.ModifiedCreatable{
+ Ctype: basics.AppCreatable,
+ Creator: addr,
+ Created: false,
+ }
+ }
+
return nil
}
@@ -619,7 +638,7 @@ func applyStorageDelta(data basics.AccountData, aapp storagePtr, store *storageD
delete(owned, aapp.aidx)
case allocAction, remainAllocAction:
// note: these should always exist because they were
- // at least preceded by a call to PutWithCreatable
+ // at least preceded by a call to Put()
params, ok := owned[aapp.aidx]
if !ok {
return basics.AccountData{}, fmt.Errorf("could not find existing params for %v", aapp.aidx)
diff --git a/ledger/appcow_test.go b/ledger/appcow_test.go
index 75dbfac91..0994ed2f6 100644
--- a/ledger/appcow_test.go
+++ b/ledger/appcow_test.go
@@ -239,7 +239,7 @@ func TestCowStorage(t *testing.T) {
NumUint: rand.Uint64(),
NumByteSlice: rand.Uint64(),
}
- err := cow.Allocate(addr, sptr.aidx, sptr.global, rschema)
+ err := cow.AllocateApp(addr, sptr.aidx, sptr.global, rschema)
if actuallyAllocated {
require.Error(t, err)
require.Contains(t, err.Error(), "cannot allocate")
@@ -253,7 +253,7 @@ func TestCowStorage(t *testing.T) {
// Deallocate
if rand.Float32() < 0.25 {
actuallyAllocated := st.allocated(aapp)
- err := cow.Deallocate(addr, sptr.aidx, sptr.global)
+ err := cow.DeallocateApp(addr, sptr.aidx, sptr.global)
if actuallyAllocated {
require.NoError(t, err)
err := st.dealloc(aapp)
diff --git a/ledger/apply/application.go b/ledger/apply/application.go
index 4771d42ad..644c8e396 100644
--- a/ledger/apply/application.go
+++ b/ledger/apply/application.go
@@ -121,21 +121,14 @@ func createApplication(ac *transactions.ApplicationCallTxnFields, balances Balan
totalExtraPages = basics.AddSaturate32(totalExtraPages, ac.ExtraProgramPages)
record.TotalExtraAppPages = totalExtraPages
- // Tell the cow what app we created
- created := &basics.CreatableLocator{
- Creator: creator,
- Type: basics.AppCreatable,
- Index: basics.CreatableIndex(appIdx),
- }
-
// Write back to the creator's balance record
- err = balances.PutWithCreatable(creator, record, created, nil)
+ err = balances.Put(creator, record)
if err != nil {
return 0, err
}
// Allocate global storage
- err = balances.Allocate(creator, appIdx, true, ac.GlobalStateSchema)
+ err = balances.AllocateApp(creator, appIdx, true, ac.GlobalStateSchema)
if err != nil {
return 0, err
}
@@ -179,7 +172,7 @@ func deleteApplication(balances Balances, creator basics.Address, appIdx basics.
}
// Deallocate global storage
- err = balances.Deallocate(creator, appIdx, true)
+ err = balances.DeallocateApp(creator, appIdx, true)
if err != nil {
return err
}
@@ -258,7 +251,7 @@ func optInApplication(balances Balances, sender basics.Address, appIdx basics.Ap
}
// Allocate local storage
- err = balances.Allocate(sender, appIdx, false, params.LocalStateSchema)
+ err = balances.AllocateApp(sender, appIdx, false, params.LocalStateSchema)
if err != nil {
return err
}
@@ -296,7 +289,7 @@ func closeOutApplication(balances Balances, sender basics.Address, appIdx basics
}
// Deallocate local storage
- err = balances.Deallocate(sender, appIdx, false)
+ err = balances.DeallocateApp(sender, appIdx, false)
if err != nil {
return err
}
diff --git a/ledger/apply/application_test.go b/ledger/apply/application_test.go
index 345e0de23..8b320b6e2 100644
--- a/ledger/apply/application_test.go
+++ b/ledger/apply/application_test.go
@@ -103,11 +103,9 @@ type testBalances struct {
proto config.ConsensusParams
put int // Put calls counter
- putWith int // PutWithCreatable calls counter
putBalances map[basics.Address]basics.AccountData
- putWithBalances map[basics.Address]basics.AccountData
- putWithNew []basics.CreatableLocator
- putWithDel []basics.CreatableLocator
+ createdCreatables []basics.CreatableLocator
+ deletedCreatables []basics.CreatableLocator
allocatedAppIdx basics.AppIndex
deAllocatedAppIdx basics.AppIndex
@@ -141,21 +139,6 @@ func (b *testBalances) Put(addr basics.Address, ad basics.AccountData) error {
return nil
}
-func (b *testBalances) PutWithCreatable(addr basics.Address, ad basics.AccountData, newCreatable *basics.CreatableLocator, deletedCreatable *basics.CreatableLocator) error {
- b.putWith++
- if b.putWithBalances == nil {
- b.putWithBalances = make(map[basics.Address]basics.AccountData)
- }
- b.putWithBalances[addr] = ad
- if newCreatable != nil {
- b.putWithNew = append(b.putWithNew, *newCreatable)
- }
- if deletedCreatable != nil {
- b.putWithDel = append(b.putWithDel, *deletedCreatable)
- }
- return nil
-}
-
func (b *testBalances) GetCreator(cidx basics.CreatableIndex, ctype basics.CreatableType) (basics.Address, bool, error) {
if ctype == basics.AppCreatable {
aidx := basics.AppIndex(cidx)
@@ -176,13 +159,60 @@ func (b *testBalances) Move(src, dst basics.Address, amount basics.MicroAlgos, s
func (b *testBalances) ConsensusParams() config.ConsensusParams {
return b.proto
}
-func (b *testBalances) Allocate(addr basics.Address, aidx basics.AppIndex, global bool, space basics.StateSchema) error {
+
+func (b *testBalances) AllocateApp(addr basics.Address, aidx basics.AppIndex, global bool, space basics.StateSchema) error {
b.allocatedAppIdx = aidx
+
+ if global {
+ locator := basics.CreatableLocator{
+ Type: basics.AppCreatable,
+ Creator: addr,
+ Index: basics.CreatableIndex(aidx),
+ }
+ b.createdCreatables = append(b.createdCreatables, locator)
+ }
+
return nil
}
-func (b *testBalances) Deallocate(addr basics.Address, aidx basics.AppIndex, global bool) error {
+func (b *testBalances) DeallocateApp(addr basics.Address, aidx basics.AppIndex, global bool) error {
b.deAllocatedAppIdx = aidx
+
+ if global {
+ locator := basics.CreatableLocator{
+ Type: basics.AppCreatable,
+ Creator: addr,
+ Index: basics.CreatableIndex(aidx),
+ }
+ b.deletedCreatables = append(b.deletedCreatables, locator)
+ }
+
+ return nil
+}
+
+func (b *testBalances) AllocateAsset(addr basics.Address, index basics.AssetIndex, global bool) error {
+ if global {
+ locator := basics.CreatableLocator{
+ Type: basics.AppCreatable,
+ Creator: addr,
+ Index: basics.CreatableIndex(index),
+ }
+ b.createdCreatables = append(b.createdCreatables, locator)
+ }
+
+ return nil
+}
+
+func (b *testBalances) DeallocateAsset(addr basics.Address, index basics.AssetIndex, global bool) error {
+ if global {
+ locator := basics.CreatableLocator{
+ Type: basics.AppCreatable,
+ Creator: addr,
+ Index: basics.CreatableIndex(index),
+ }
+ b.deletedCreatables = append(b.deletedCreatables, locator)
+ }
+
return nil
}
@@ -206,14 +236,6 @@ func (b *testBalancesPass) Put(addr basics.Address, ad basics.AccountData) error
return nil
}
-func (b *testBalancesPass) PutWithCreatable(addr basics.Address, ad basics.AccountData, newCreatable *basics.CreatableLocator, deletedCreatable *basics.CreatableLocator) error {
- if b.balances == nil {
- b.balances = make(map[basics.Address]basics.AccountData)
- }
- b.balances[addr] = ad
- return nil
-}
-
func (b *testBalancesPass) ConsensusParams() config.ConsensusParams {
return b.proto
}
@@ -230,14 +252,12 @@ func (b *testBalancesPass) StatefulEval(params logic.EvalParams, aidx basics.App
return true, b.delta, nil
}
-// ResetWrites clears side effects of Put/PutWithCreatable
+// ResetWrites clears side effects of Put.
func (b *testBalances) ResetWrites() {
b.put = 0
- b.putWith = 0
b.putBalances = nil
- b.putWithBalances = nil
- b.putWithNew = []basics.CreatableLocator{}
- b.putWithDel = []basics.CreatableLocator{}
+ b.createdCreatables = []basics.CreatableLocator{}
+ b.deletedCreatables = []basics.CreatableLocator{}
b.allocatedAppIdx = 0
}
@@ -415,11 +435,8 @@ func TestAppCallCreate(t *testing.T) {
appIdx, err = createApplication(&ac, &b, creator, txnCounter)
a.NoError(err)
a.Equal(txnCounter+1, uint64(appIdx))
- a.Equal(0, b.put)
- a.Equal(1, b.putWith)
+ a.Equal(1, b.put)
nbr, ok := b.putBalances[creator]
- a.False(ok)
- nbr, ok = b.putWithBalances[creator]
a.True(ok)
params, ok := nbr.AppParams[appIdx]
a.True(ok)
@@ -427,7 +444,7 @@ func TestAppCallCreate(t *testing.T) {
a.Equal(ac.ClearStateProgram, params.ClearStateProgram)
a.Equal(ac.LocalStateSchema, params.LocalStateSchema)
a.Equal(ac.GlobalStateSchema, params.GlobalStateSchema)
- a.True(len(b.putWithNew) > 0)
+ a.Equal(1, len(b.createdCreatables))
}
// TestAppCallApplyCreate carefully tracks and validates balance record updates
@@ -452,7 +469,6 @@ func TestAppCallApplyCreate(t *testing.T) {
a.Error(err)
a.Contains(err.Error(), "ApplicationCall cannot have nil ApplyData")
a.Equal(0, b.put)
- a.Equal(0, b.putWith)
b.balances = make(map[basics.Address]basics.AccountData)
b.balances[creator] = basics.AccountData{}
@@ -462,7 +478,6 @@ func TestAppCallApplyCreate(t *testing.T) {
a.Error(err)
a.Contains(err.Error(), "max created apps per acct is 0")
a.Equal(0, b.put)
- a.Equal(0, b.putWith)
b.SetProto(protocol.ConsensusFuture)
proto := b.ConsensusParams()
@@ -474,14 +489,13 @@ func TestAppCallApplyCreate(t *testing.T) {
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.Error(err)
a.Contains(err.Error(), "applications that do not exist")
- a.Equal(0, b.put)
- a.Equal(1, b.putWith)
+ a.Equal(1, b.put)
appIdx := basics.AppIndex(txnCounter + 1)
b.appCreators = map[basics.AppIndex]basics.Address{appIdx: creator}
// save the created app info to the side
- saved := b.putWithBalances[creator]
+ saved := b.putBalances[creator]
b.ResetWrites()
@@ -490,8 +504,7 @@ func TestAppCallApplyCreate(t *testing.T) {
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(0, b.put)
- a.Equal(1, b.putWith)
+ a.Equal(1, b.put)
b.ResetWrites()
@@ -504,15 +517,14 @@ func TestAppCallApplyCreate(t *testing.T) {
a.Error(err)
a.Contains(err.Error(), "transaction rejected by ApprovalProgram")
a.Equal(uint64(b.allocatedAppIdx), txnCounter+1)
- a.Equal(0, b.put)
- a.Equal(1, b.putWith)
+ a.Equal(1, b.put)
// ensure original balance record in the mock was not changed
// this ensure proper cloning and any in-intended in-memory modifications
//
// known artefact of cloning AppLocalState even with empty update, nil map vs empty map
saved.AppLocalStates = map[basics.AppIndex]basics.AppLocalState{}
a.Equal(saved, b.balances[creator])
- saved = b.putWithBalances[creator]
+ saved = b.putBalances[creator]
b.ResetWrites()
@@ -527,10 +539,9 @@ func TestAppCallApplyCreate(t *testing.T) {
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
a.Equal(appIdx, b.allocatedAppIdx)
- a.Equal(0, b.put)
- a.Equal(1, b.putWith)
+ a.Equal(1, b.put)
a.Equal(saved, b.balances[creator])
- br := b.putWithBalances[creator]
+ br := b.putBalances[creator]
a.Equal([]byte{1}, br.AppParams[appIdx].ApprovalProgram)
a.Equal([]byte{1}, br.AppParams[appIdx].ClearStateProgram)
a.Equal(basics.TealKeyValue(nil), br.AppParams[appIdx].GlobalState)
@@ -542,7 +553,7 @@ func TestAppCallApplyCreate(t *testing.T) {
ac.ExtraProgramPages = 1
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
- br = b.putWithBalances[creator]
+ br = b.putBalances[creator]
a.Equal(uint32(1), br.AppParams[appIdx].ExtraProgramPages)
a.Equal(uint32(1), br.TotalExtraAppPages)
}
@@ -610,13 +621,11 @@ func TestAppCallOptIn(t *testing.T) {
a.Error(err)
a.Contains(err.Error(), "cannot opt in app")
a.Equal(0, b.put)
- a.Equal(0, b.putWith)
b.SetProto(protocol.ConsensusFuture)
err = optInApplication(&b, sender, appIdx, params)
a.NoError(err)
a.Equal(1, b.put)
- a.Equal(0, b.putWith)
br := b.putBalances[sender]
a.Equal(basics.AccountData{AppLocalStates: map[basics.AppIndex]basics.AppLocalState{appIdx: {}}}, br)
@@ -629,7 +638,6 @@ func TestAppCallOptIn(t *testing.T) {
a.Error(err)
a.Contains(err.Error(), "has already opted in to app")
a.Equal(0, b.put)
- a.Equal(0, b.putWith)
b.ResetWrites()
@@ -639,7 +647,6 @@ func TestAppCallOptIn(t *testing.T) {
err = optInApplication(&b, sender, appIdx, params)
a.NoError(err)
a.Equal(1, b.put)
- a.Equal(0, b.putWith)
b.ResetWrites()
@@ -652,7 +659,6 @@ func TestAppCallOptIn(t *testing.T) {
err = optInApplication(&b, sender, appIdx, params)
a.NoError(err)
a.Equal(1, b.put)
- a.Equal(0, b.putWith)
br = b.putBalances[sender]
a.Equal(
basics.AccountData{
@@ -711,7 +717,6 @@ func TestAppCallClearState(t *testing.T) {
a.Error(err)
a.Contains(err.Error(), "is not currently opted in to app")
a.Equal(0, b.put)
- a.Equal(0, b.putWith)
// check non-existing app with empty opt-in
b.balances[sender] = basics.AccountData{
@@ -720,7 +725,6 @@ func TestAppCallClearState(t *testing.T) {
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
a.Equal(1, b.put)
- a.Equal(0, b.putWith)
br := b.putBalances[sender]
a.Equal(0, len(br.AppLocalStates))
a.Equal(basics.StateSchema{}, br.TotalAppSchema)
@@ -739,7 +743,6 @@ func TestAppCallClearState(t *testing.T) {
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
a.Equal(1, b.put)
- a.Equal(0, b.putWith)
br = b.putBalances[sender]
a.Equal(0, len(br.AppLocalStates))
a.Equal(basics.StateSchema{}, br.TotalAppSchema)
@@ -766,7 +769,6 @@ func TestAppCallClearState(t *testing.T) {
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
a.Equal(1, b.put)
- a.Equal(0, b.putWith)
br = b.putBalances[sender]
a.Equal(0, len(br.AppLocalStates))
a.Equal(basics.StateSchema{}, br.TotalAppSchema)
@@ -782,7 +784,6 @@ func TestAppCallClearState(t *testing.T) {
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
a.Equal(1, b.put)
- a.Equal(0, b.putWith)
br = b.putBalances[sender]
a.Equal(0, len(br.AppLocalStates))
a.Equal(basics.StateSchema{}, br.TotalAppSchema)
@@ -813,7 +814,6 @@ func TestAppCallClearState(t *testing.T) {
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
a.Equal(1, b.put)
- a.Equal(0, b.putWith)
a.Equal(appIdx, b.deAllocatedAppIdx)
a.Equal(0, len(br.AppLocalStates))
a.Equal(basics.StateSchema{}, br.TotalAppSchema)
@@ -864,7 +864,6 @@ func TestAppCallApplyCloseOut(t *testing.T) {
a.Error(err)
a.Contains(err.Error(), "transaction rejected by ApprovalProgram")
a.Equal(0, b.put)
- a.Equal(0, b.putWith)
br := b.balances[creator]
a.Equal(cbr, br)
a.Equal(basics.EvalDelta{}, ad.EvalDelta)
@@ -876,7 +875,6 @@ func TestAppCallApplyCloseOut(t *testing.T) {
a.Error(err)
a.Contains(err.Error(), "is not opted in to app")
a.Equal(0, b.put)
- a.Equal(0, b.putWith)
br = b.balances[creator]
a.Equal(cbr, br)
a.Equal(basics.EvalDelta{}, ad.EvalDelta)
@@ -892,7 +890,6 @@ func TestAppCallApplyCloseOut(t *testing.T) {
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
a.Equal(1, b.put)
- a.Equal(0, b.putWith)
br = b.putBalances[creator]
a.NotEqual(cbr, br)
a.Equal(basics.TealKeyValue(nil), br.AppParams[appIdx].GlobalState)
@@ -949,7 +946,6 @@ func TestAppCallApplyUpdate(t *testing.T) {
a.Error(err)
a.Contains(err.Error(), "transaction rejected by ApprovalProgram")
a.Equal(0, b.put)
- a.Equal(0, b.putWith)
br := b.balances[creator]
a.Equal(cbr, br)
a.Equal(basics.EvalDelta{}, ad.EvalDelta)
@@ -960,7 +956,6 @@ func TestAppCallApplyUpdate(t *testing.T) {
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
a.Equal(1, b.put)
- a.Equal(0, b.putWith)
br = b.balances[creator]
a.Equal(cbr, br)
br = b.putBalances[creator]
@@ -1096,7 +1091,6 @@ func TestAppCallApplyDelete(t *testing.T) {
a.Error(err)
a.Contains(err.Error(), "transaction rejected by ApprovalProgram")
a.Equal(0, b.put)
- a.Equal(0, b.putWith)
br := b.balances[creator]
a.Equal(cbr, br)
a.Equal(basics.EvalDelta{}, ad.EvalDelta)
@@ -1111,8 +1105,7 @@ func TestAppCallApplyDelete(t *testing.T) {
err = ApplicationCall(ac, h, &b, ad, &ep, txnCounter)
a.NoError(err)
a.Equal(appIdx, b.deAllocatedAppIdx)
- a.Equal(0, b.put)
- a.Equal(1, b.putWith)
+ a.Equal(1, b.put)
br = b.balances[creator]
a.Equal(cbr, br)
br = b.putBalances[creator]
diff --git a/ledger/apply/apply.go b/ledger/apply/apply.go
index e7a01c6cf..739d7803c 100644
--- a/ledger/apply/apply.go
+++ b/ledger/apply/apply.go
@@ -33,21 +33,22 @@ type Balances interface {
Put(basics.Address, basics.AccountData) error
- // PutWithCreatable is like Put, but should be used when creating or deleting an asset or application.
- PutWithCreatable(addr basics.Address, acct basics.AccountData, newCreatable *basics.CreatableLocator, deletedCreatable *basics.CreatableLocator) error
-
// GetCreator gets the address of the account that created a given creatable
GetCreator(cidx basics.CreatableIndex, ctype basics.CreatableType) (basics.Address, bool, error)
- // Allocate or Deallocate either global or address-local app storage.
+ // Allocate or deallocate either global or address-local app storage.
//
- // PutWithCreatable(...) and then {Allocate/Deallocate}(..., ..., global=true)
+ // Put(...) and then {AllocateApp/DeallocateApp}(..., ..., global=true)
// creates/destroys an application.
//
- // Put(...) and then {Allocate/Deallocate}(..., ..., global=false)
+ // Put(...) and then {AllocateApp/DeallocateApp}(..., ..., global=false)
// opts into/closes out of an application.
- Allocate(addr basics.Address, aidx basics.AppIndex, global bool, space basics.StateSchema) error
- Deallocate(addr basics.Address, aidx basics.AppIndex, global bool) error
+ AllocateApp(addr basics.Address, aidx basics.AppIndex, global bool, space basics.StateSchema) error
+ DeallocateApp(addr basics.Address, aidx basics.AppIndex, global bool) error
+
+ // Similar to above, notify COW that global/local asset state was created.
+ AllocateAsset(addr basics.Address, index basics.AssetIndex, global bool) error
+ DeallocateAsset(addr basics.Address, index basics.AssetIndex, global bool) error
// StatefulEval executes a TEAL program in stateful mode on the balances.
// It returns whether the program passed and its error. It alo returns
diff --git a/ledger/apply/asset.go b/ledger/apply/asset.go
index 26d50acf2..4c74649b7 100644
--- a/ledger/apply/asset.go
+++ b/ledger/apply/asset.go
@@ -95,14 +95,13 @@ func AssetConfig(cc transactions.AssetConfigTxnFields, header transactions.Heade
return fmt.Errorf("too many assets in account: %d > %d", len(record.Assets), balances.ConsensusParams().MaxAssetsPerAccount)
}
- // Tell the cow what asset we created
- created := &basics.CreatableLocator{
- Creator: header.Sender,
- Type: basics.AssetCreatable,
- Index: basics.CreatableIndex(newidx),
+ err = balances.Put(header.Sender, record)
+ if err != nil {
+ return err
}
- return balances.PutWithCreatable(header.Sender, record, created, nil)
+ // Tell the cow what asset we created
+ return balances.AllocateAsset(header.Sender, newidx, true)
}
// Re-configuration and destroying must be done by the manager key.
@@ -123,7 +122,6 @@ func AssetConfig(cc transactions.AssetConfigTxnFields, header transactions.Heade
record.Assets = cloneAssetHoldings(record.Assets)
record.AssetParams = cloneAssetParams(record.AssetParams)
- var deleted *basics.CreatableLocator
if cc.AssetParams == (basics.AssetParams{}) {
// Destroying an asset. The creator account must hold
// the entire outstanding asset amount.
@@ -132,10 +130,9 @@ func AssetConfig(cc transactions.AssetConfigTxnFields, header transactions.Heade
}
// Tell the cow what asset we deleted
- deleted = &basics.CreatableLocator{
- Creator: creator,
- Type: basics.AssetCreatable,
- Index: basics.CreatableIndex(cc.ConfigAsset),
+ err = balances.DeallocateAsset(creator, cc.ConfigAsset, true)
+ if err != nil {
+ return err
}
delete(record.Assets, cc.ConfigAsset)
@@ -158,7 +155,7 @@ func AssetConfig(cc transactions.AssetConfigTxnFields, header transactions.Heade
record.AssetParams[cc.ConfigAsset] = params
}
- return balances.PutWithCreatable(creator, record, nil, deleted)
+ return balances.Put(creator, record)
}
func takeOut(balances Balances, addr basics.Address, asset basics.AssetIndex, amount uint64, bypassFreeze bool) error {
diff --git a/ledger/apply/keyreg_test.go b/ledger/apply/keyreg_test.go
index ce9185300..58e4e8f68 100644
--- a/ledger/apply/keyreg_test.go
+++ b/ledger/apply/keyreg_test.go
@@ -49,10 +49,6 @@ func (balances keyregTestBalances) Put(addr basics.Address, ad basics.AccountDat
return nil
}
-func (balances keyregTestBalances) PutWithCreatable(basics.Address, basics.AccountData, *basics.CreatableLocator, *basics.CreatableLocator) error {
- return nil
-}
-
func (balances keyregTestBalances) Move(src, dst basics.Address, amount basics.MicroAlgos, srcRewards, dstRewards *basics.MicroAlgos) error {
return nil
}
@@ -65,11 +61,19 @@ func (balances keyregTestBalances) Round() basics.Round {
return basics.Round(4294967296)
}
-func (balances keyregTestBalances) Allocate(basics.Address, basics.AppIndex, bool, basics.StateSchema) error {
+func (balances keyregTestBalances) AllocateApp(basics.Address, basics.AppIndex, bool, basics.StateSchema) error {
+ return nil
+}
+
+func (balances keyregTestBalances) DeallocateApp(basics.Address, basics.AppIndex, bool) error {
+ return nil
+}
+
+func (balances keyregTestBalances) AllocateAsset(addr basics.Address, index basics.AssetIndex, global bool) error {
return nil
}
-func (balances keyregTestBalances) Deallocate(basics.Address, basics.AppIndex, bool) error {
+func (balances keyregTestBalances) DeallocateAsset(addr basics.Address, index basics.AssetIndex, global bool) error {
return nil
}
diff --git a/ledger/apply/mockBalances_test.go b/ledger/apply/mockBalances_test.go
index fadc97fe1..a1b64a2f2 100644
--- a/ledger/apply/mockBalances_test.go
+++ b/ledger/apply/mockBalances_test.go
@@ -49,22 +49,26 @@ func (balances mockBalances) Round() basics.Round {
return basics.Round(8675309)
}
-func (balances mockBalances) Allocate(basics.Address, basics.AppIndex, bool, basics.StateSchema) error {
+func (balances mockBalances) AllocateApp(basics.Address, basics.AppIndex, bool, basics.StateSchema) error {
return nil
}
-func (balances mockBalances) Deallocate(basics.Address, basics.AppIndex, bool) error {
+func (balances mockBalances) DeallocateApp(basics.Address, basics.AppIndex, bool) error {
return nil
}
-func (balances mockBalances) StatefulEval(logic.EvalParams, basics.AppIndex, []byte) (bool, basics.EvalDelta, error) {
- return false, basics.EvalDelta{}, nil
+func (balances mockBalances) AllocateAsset(addr basics.Address, index basics.AssetIndex, global bool) error {
+ return nil
}
-func (balances mockBalances) PutWithCreatable(basics.Address, basics.AccountData, *basics.CreatableLocator, *basics.CreatableLocator) error {
+func (balances mockBalances) DeallocateAsset(addr basics.Address, index basics.AssetIndex, global bool) error {
return nil
}
+func (balances mockBalances) StatefulEval(logic.EvalParams, basics.AppIndex, []byte) (bool, basics.EvalDelta, error) {
+ return false, basics.EvalDelta{}, nil
+}
+
func (balances mockBalances) Get(addr basics.Address, withPendingRewards bool) (basics.AccountData, error) {
return balances.b[addr], nil
}
diff --git a/ledger/assetcow.go b/ledger/assetcow.go
new file mode 100644
index 000000000..d84ae3221
--- /dev/null
+++ b/ledger/assetcow.go
@@ -0,0 +1,48 @@
+// Copyright (C) 2019-2021 Algorand, Inc.
+// This file is part of go-algorand
+//
+// go-algorand is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// go-algorand is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with go-algorand. If not, see <https://www.gnu.org/licenses/>.
+
+package ledger
+
+import (
+ "github.com/algorand/go-algorand/data/basics"
+ "github.com/algorand/go-algorand/ledger/ledgercore"
+)
+
+func (cs *roundCowState) AllocateAsset(addr basics.Address, index basics.AssetIndex, global bool) error {
+ if global {
+ cs.mods.Creatables[basics.CreatableIndex(index)] = ledgercore.ModifiedCreatable{
+ Ctype: basics.AssetCreatable,
+ Creator: addr,
+ Created: true,
+ }
+
+ cs.trackCreatable(basics.CreatableIndex(index))
+ }
+
+ return nil
+}
+
+func (cs *roundCowState) DeallocateAsset(addr basics.Address, index basics.AssetIndex, global bool) error {
+ if global {
+ cs.mods.Creatables[basics.CreatableIndex(index)] = ledgercore.ModifiedCreatable{
+ Ctype: basics.AssetCreatable,
+ Creator: addr,
+ Created: false,
+ }
+ }
+
+ return nil
+}
diff --git a/ledger/cow.go b/ledger/cow.go
index ba17dafc5..56ff9e33b 100644
--- a/ledger/cow.go
+++ b/ledger/cow.go
@@ -194,26 +194,6 @@ func (cb *roundCowState) blockHdr(r basics.Round) (bookkeeping.BlockHeader, erro
return cb.lookupParent.blockHdr(r)
}
-func (cb *roundCowState) put(addr basics.Address, new basics.AccountData, newCreatable *basics.CreatableLocator, deletedCreatable *basics.CreatableLocator) {
- cb.mods.Accts.Upsert(addr, new)
-
- if newCreatable != nil {
- cb.mods.Creatables[newCreatable.Index] = ledgercore.ModifiedCreatable{
- Ctype: newCreatable.Type,
- Creator: newCreatable.Creator,
- Created: true,
- }
- }
-
- if deletedCreatable != nil {
- cb.mods.Creatables[deletedCreatable.Index] = ledgercore.ModifiedCreatable{
- Ctype: deletedCreatable.Type,
- Creator: deletedCreatable.Creator,
- Created: false,
- }
- }
-}
-
func (cb *roundCowState) trackCreatable(creatableIndex basics.CreatableIndex) {
cb.trackedCreatables[cb.groupIdx] = creatableIndex
}
diff --git a/ledger/cow_test.go b/ledger/cow_test.go
index b09c479e8..71e12530b 100644
--- a/ledger/cow_test.go
+++ b/ledger/cow_test.go
@@ -101,7 +101,7 @@ func checkCow(t *testing.T, cow *roundCowState, accts map[basics.Address]basics.
func applyUpdates(cow *roundCowState, updates ledgercore.AccountDeltas) {
for i := 0; i < updates.Len(); i++ {
addr, delta := updates.GetByIdx(i)
- cow.put(addr, delta, nil, nil)
+ cow.Put(addr, delta)
}
}
diff --git a/ledger/eval.go b/ledger/eval.go
index 3b1968a74..f75d7a57e 100644
--- a/ledger/eval.go
+++ b/ledger/eval.go
@@ -247,16 +247,7 @@ func (cs *roundCowState) GetCreator(cidx basics.CreatableIndex, ctype basics.Cre
}
func (cs *roundCowState) Put(addr basics.Address, acct basics.AccountData) error {
- return cs.PutWithCreatable(addr, acct, nil, nil)
-}
-
-func (cs *roundCowState) PutWithCreatable(addr basics.Address, acct basics.AccountData, newCreatable *basics.CreatableLocator, deletedCreatable *basics.CreatableLocator) error {
- cs.put(addr, acct, newCreatable, deletedCreatable)
-
- // store the creatable locator
- if newCreatable != nil {
- cs.trackCreatable(newCreatable.Index)
- }
+ cs.mods.Accts.Upsert(addr, acct)
return nil
}
@@ -283,7 +274,7 @@ func (cs *roundCowState) Move(from basics.Address, to basics.Address, amt basics
if overflowed {
return fmt.Errorf("overspend (account %v, data %+v, tried to spend %v)", from, fromBal, amt)
}
- cs.put(from, fromBalNew, nil, nil)
+ cs.Put(from, fromBalNew)
toBal, err := cs.lookup(to)
if err != nil {
@@ -304,7 +295,7 @@ func (cs *roundCowState) Move(from basics.Address, to basics.Address, amt basics
if overflowed {
return fmt.Errorf("balance overflow (account %v, data %+v, was going to receive %v)", to, toBal, amt)
}
- cs.put(to, toBalNew, nil, nil)
+ cs.Put(to, toBalNew)
return nil
}
diff --git a/scripts/travis/run_tests.sh b/scripts/travis/run_tests.sh
index 0c6f278f4..cf47b0b97 100755
--- a/scripts/travis/run_tests.sh
+++ b/scripts/travis/run_tests.sh
@@ -4,14 +4,14 @@ set -e
if [ "${BUILD_TYPE}" = "integration" ]; then
# Run short tests when doing pull requests; leave the long testing for nightly runs.
- if [[ "${TRAVIS_BRANCH}" =~ ^rel/nightly ]]; then
+ if [[ "${TRAVIS_BRANCH}" =~ ^rel/nightly ]] || [[ "${TRAVIS_BRANCH}" =~ ^hotfix/ ]]; then
SHORTTEST=
else
SHORTTEST=-short
fi
export SHORTTEST
make integration
-elif [ "${TRAVIS_EVENT_TYPE}" = "cron" ] || [[ "${TRAVIS_BRANCH}" =~ ^rel/ ]]; then
+elif [ "${TRAVIS_EVENT_TYPE}" = "cron" ] || [[ "${TRAVIS_BRANCH}" =~ ^rel/ ]] || [[ "${TRAVIS_BRANCH}" =~ ^hotfix/ ]]; then
make fulltest -j2
else
make shorttest -j2
diff --git a/test/e2e-go/features/transactions/app_pages_test.go b/test/e2e-go/features/transactions/app_pages_test.go
index e76e88888..17983c1e2 100644
--- a/test/e2e-go/features/transactions/app_pages_test.go
+++ b/test/e2e-go/features/transactions/app_pages_test.go
@@ -28,12 +28,9 @@ import (
"github.com/algorand/go-algorand/data/transactions"
"github.com/algorand/go-algorand/data/transactions/logic"
"github.com/algorand/go-algorand/test/framework/fixtures"
- "github.com/algorand/go-algorand/test/partitiontest"
)
func TestExtraProgramPages(t *testing.T) {
- partitiontest.PartitionTest(t)
-
t.Parallel()
a := require.New(fixtures.SynchronizedTest(t))