diff options
author | Brice Rising <brice@algorand.com> | 2021-08-07 12:55:05 -0400 |
---|---|---|
committer | Brice Rising <brice@algorand.com> | 2021-08-07 12:55:05 -0400 |
commit | 8ce1e6c69e5c4cf080fb170625e2551a387e9e63 (patch) | |
tree | bfc9315fa1361855e4746b86aeb5e12f56359af4 | |
parent | 77e1aaf8939f4f35061711cf2f8520b047122431 (diff) | |
parent | 5d33a58fb12c92247d7fd2e8bb5dc484b95d406e (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.yml | 4 | ||||
-rw-r--r-- | data/basics/units_test.go | 4 | ||||
-rw-r--r-- | ledger/appcow.go | 25 | ||||
-rw-r--r-- | ledger/appcow_test.go | 4 | ||||
-rw-r--r-- | ledger/apply/application.go | 17 | ||||
-rw-r--r-- | ledger/apply/application_test.go | 137 | ||||
-rw-r--r-- | ledger/apply/apply.go | 17 | ||||
-rw-r--r-- | ledger/apply/asset.go | 21 | ||||
-rw-r--r-- | ledger/apply/keyreg_test.go | 16 | ||||
-rw-r--r-- | ledger/apply/mockBalances_test.go | 14 | ||||
-rw-r--r-- | ledger/assetcow.go | 48 | ||||
-rw-r--r-- | ledger/cow.go | 20 | ||||
-rw-r--r-- | ledger/cow_test.go | 2 | ||||
-rw-r--r-- | ledger/eval.go | 15 | ||||
-rwxr-xr-x | scripts/travis/run_tests.sh | 4 | ||||
-rw-r--r-- | test/e2e-go/features/transactions/app_pages_test.go | 3 |
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)) |