Skip to content

Commit

Permalink
Merge pull request #314 from cosmos/sdk2-app
Browse files Browse the repository at this point in the history
New App structure
  • Loading branch information
ebuchman authored Jan 5, 2018
2 parents 1afab45 + 6578203 commit 8f14e4b
Show file tree
Hide file tree
Showing 27 changed files with 374 additions and 268 deletions.
310 changes: 127 additions & 183 deletions app/app.go

Large diffs are not rendered by default.

73 changes: 46 additions & 27 deletions app/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

sdk "github.com/cosmos/cosmos-sdk"
"github.com/cosmos/cosmos-sdk/store"
"github.com/cosmos/cosmos-sdk/types"
abci "github.com/tendermint/abci/types"
"github.com/tendermint/go-crypto"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
)

func TestBasic(t *testing.T) {
Expand All @@ -24,31 +25,33 @@ func TestBasic(t *testing.T) {
}

// Create app.
app := sdk.NewApp(t.Name())
app.SetStore(mockMultiStore())
app.SetHandler(func(ctx Context, store MultiStore, tx Tx) Result {
app := NewApp(t.Name())
app.SetCommitMultiStore(newCommitMultiStore())
app.SetHandler(func(ctx types.Context, store types.MultiStore, tx types.Tx) types.Result {

// This could be a decorator.
fromJSON(ctx.TxBytes(), &tx)
var ttx testTx
fromJSON(ctx.TxBytes(), &ttx)

fmt.Println(">>", tx)
// XXX
return types.Result{}
})

// Load latest state, which should be empty.
err := app.LoadLatestVersion()
assert.Nil(t, err)
assert.Equal(t, app.NextVersion(), 1)
assert.Equal(t, app.LastBlockHeight(), int64(0))

// Create the validators
var numVals = 3
var valSet = make([]*abci.Validator, numVals)
var valSet = make([]abci.Validator, numVals)
for i := 0; i < numVals; i++ {
valSet[i] = makeVal(secret(i))
}

// Initialize the chain
app.InitChain(abci.RequestInitChain{
Validators: valset,
Validators: valSet,
})

// Simulate the start of a block.
Expand All @@ -62,24 +65,26 @@ func TestBasic(t *testing.T) {
}
txBytes := toJSON(tx)
res := app.DeliverTx(txBytes)
require.True(res.IsOK(), "%#v", res)
assert.True(t, res.IsOK(), "%#v", res)
}

// Simulate the end of a block.
// Get the summary of validator updates.
res := app.EndBlock(app.height)
res := app.EndBlock(abci.RequestEndBlock{})
valUpdates := res.ValidatorUpdates

// Assert that validator updates are correct.
for _, val := range valSet {
// Sanity
assert.NotEqual(t, len(val.PubKey), 0)

// Find matching update and splice it out.
for j := 0; j < len(valUpdates); {
assert.NotEqual(len(valUpdates.PubKey), 0)
valUpdate := valUpdates[j]

// Matched.
if bytes.Equal(valUpdate.PubKey, val.PubKey) {
assert.Equal(valUpdate.NewPower, val.Power+1)
assert.Equal(t, valUpdate.Power, val.Power+1)
if j < len(valUpdates)-1 {
// Splice it out.
valUpdates = append(valUpdates[:j], valUpdates[j+1:]...)
Expand All @@ -100,9 +105,9 @@ func randPower() int64 {
return cmn.RandInt64()
}

func makeVal(secret string) *abci.Validator {
return &abci.Validator{
PubKey: makePubKey(string).Bytes(),
func makeVal(secret string) abci.Validator {
return abci.Validator{
PubKey: makePubKey(secret).Bytes(),
Power: randPower(),
}
}
Expand All @@ -112,29 +117,43 @@ func makePubKey(secret string) crypto.PubKey {
}

func makePrivKey(secret string) crypto.PrivKey {
return crypto.GenPrivKeyEd25519FromSecret([]byte(id))
privKey := crypto.GenPrivKeyEd25519FromSecret([]byte(secret))
return privKey.Wrap()
}

func secret(index int) []byte {
return []byte(fmt.Sprintf("secret%d", index))
func secret(index int) string {
return fmt.Sprintf("secret%d", index)
}

func copyVal(val *abci.Validator) *abci.Validator {
val2 := *val
return &val2
func copyVal(val abci.Validator) abci.Validator {
// val2 := *val
// return &val2
return val
}

func toJSON(o interface{}) []byte {
bytes, err := json.Marshal(o)
bz, err := json.Marshal(o)
if err != nil {
panic(err)
}
return bytes
// fmt.Println(">> toJSON:", string(bz))
return bz
}

func fromJSON(bytes []byte, ptr interface{}) {
err := json.Unmarshal(bytes, ptr)
func fromJSON(bz []byte, ptr interface{}) {
// fmt.Println(">> fromJSON:", string(bz))
err := json.Unmarshal(bz, ptr)
if err != nil {
panic(err)
}
}

// Creates a sample CommitMultiStore
func newCommitMultiStore() types.CommitMultiStore {
dbMain := dbm.NewMemDB()
dbXtra := dbm.NewMemDB()
ms := store.NewMultiStore(dbMain) // Also store rootMultiStore metadata here (it shouldn't clash)
ms.SetSubstoreLoader("main", store.NewIAVLStoreLoader(dbMain, 0, 0))
ms.SetSubstoreLoader("xtra", store.NewIAVLStoreLoader(dbXtra, 0, 0))
return ms
}
54 changes: 54 additions & 0 deletions app/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package app

/*
XXX Make this work with MultiStore.
XXX It will require some interfaces updates in store/types.go.
if len(reqQuery.Data) == 0 {
resQuery.Log = "Query cannot be zero length"
resQuery.Code = abci.CodeType_EncodingError
return
}
// set the query response height to current
tree := app.state.Committed()
height := reqQuery.Height
if height == 0 {
// TODO: once the rpc actually passes in non-zero
// heights we can use to query right after a tx
// we must retrun most recent, even if apphash
// is not yet in the blockchain
withProof := app.CommittedHeight() - 1
if tree.Tree.VersionExists(withProof) {
height = withProof
} else {
height = app.CommittedHeight()
}
}
resQuery.Height = height
switch reqQuery.Path {
case "/store", "/key": // Get by key
key := reqQuery.Data // Data holds the key bytes
resQuery.Key = key
if reqQuery.Prove {
value, proof, err := tree.GetVersionedWithProof(key, height)
if err != nil {
resQuery.Log = err.Error()
break
}
resQuery.Value = value
resQuery.Proof = proof.Bytes()
} else {
value := tree.Get(key)
resQuery.Value = value
}
default:
resQuery.Code = abci.CodeType_UnknownRequest
resQuery.Log = cmn.Fmt("Unexpected Query path: %v", reqQuery.Path)
}
return
*/
4 changes: 2 additions & 2 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion store/iavlstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type iavlStore struct {
tree *iavl.VersionedTree

// How many old versions we hold onto.
// A value of 0 means keep all history.
numHistory int64
}

Expand All @@ -71,7 +72,7 @@ func (st *iavlStore) Commit() CommitID {
}

// Release an old version of history
if st.numHistory < st.tree.Version64() {
if st.numHistory > 0 && (st.numHistory < st.tree.Version64()) {
toRelease := version - st.numHistory
st.tree.DeleteVersion(toRelease)
}
Expand Down
45 changes: 31 additions & 14 deletions store/rootmultistore.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ type rootMultiStore struct {
substores map[string]CommitStore
}

var _ CommitMultiStore = (*rootMultiStore)(nil)

func NewMultiStore(db dbm.DB) *rootMultiStore {
return &rootMultiStore{
db: db,
Expand All @@ -35,24 +37,26 @@ func NewMultiStore(db dbm.DB) *rootMultiStore {
}
}

// Implements CommitMultiStore.
func (rs *rootMultiStore) SetSubstoreLoader(name string, loader CommitStoreLoader) {
if _, ok := rs.storeLoaders[name]; ok {
panic(fmt.Sprintf("rootMultiStore duplicate substore name " + name))
}
rs.storeLoaders[name] = loader
}

// Call once after all calls to SetSubstoreLoader are complete.
// Implements CommitMultiStore.
func (rs *rootMultiStore) GetSubstore(name string) CommitStore {
return rs.substores[name]
}

// Implements CommitMultiStore.
func (rs *rootMultiStore) LoadLatestVersion() error {
ver := getLatestVersion(rs.db)
return rs.LoadVersion(ver)
}

// NOTE: Returns 0 unless LoadVersion() or LoadLatestVersion() is called.
func (rs *rootMultiStore) NextVersion() int64 {
return rs.nextVersion
}

// Implements CommitMultiStore.
func (rs *rootMultiStore) LoadVersion(ver int64) error {

// Special logic for version 0
Expand Down Expand Up @@ -106,10 +110,13 @@ func (rs *rootMultiStore) LoadVersion(ver int64) error {
return nil
}

// Implements CommitStore
//----------------------------------------
// +CommitStore

// Implements CommitStore.
func (rs *rootMultiStore) Commit() CommitID {

// Commit substores
// Commit substores.
version := rs.nextVersion
state := commitSubstores(version, rs.substores)

Expand All @@ -129,27 +136,36 @@ func (rs *rootMultiStore) Commit() CommitID {
return commitID
}

// Implements CommitStore
// Implements CommitStore.
func (rs *rootMultiStore) CacheWrap() CacheWrap {
return rs.CacheMultiStore().(CacheWrap)
}

// Get the last committed CommitID
//----------------------------------------
// +MultiStore

// Implements MultiStore.
func (rs *rootMultiStore) LastCommitID() CommitID {
return rs.lastCommitID
}

// Implements MultiStore
// Implements MultiStore.
// NOTE: Returns 0 unless LoadVersion() or LoadLatestVersion() is called.
func (rs *rootMultiStore) NextVersion() int64 {
return rs.nextVersion
}

// Implements MultiStore.
func (rs *rootMultiStore) CacheMultiStore() CacheMultiStore {
return newCacheMultiStoreFromRMS(rs)
}

// Implements MultiStore
func (rs *rootMultiStore) GetCommitStore(name string) CommitStore {
// Implements MultiStore.
func (rs *rootMultiStore) GetStore(name string) interface{} {
return rs.substores[name]
}

// Implements MultiStore
// Implements MultiStore.
func (rs *rootMultiStore) GetKVStore(name string) KVStore {
return rs.substores[name].(KVStore)
}
Expand Down Expand Up @@ -208,6 +224,7 @@ func (sc substoreCore) Hash() []byte {
}

//----------------------------------------
// Misc.

func getLatestVersion(db dbm.DB) int64 {
var latest int64
Expand Down
13 changes: 9 additions & 4 deletions x/coin/coin.go → types/coin.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package coin
package types

import (
"fmt"
"sort"
"strconv"
"strings"

"github.com/pkg/errors"
)

// Coin hold some amount of one currency
Expand Down Expand Up @@ -200,3 +197,11 @@ var _ sort.Interface = Coins{}

// Sort is a helper function to sort the set of coins inplace
func (coins Coins) Sort() { sort.Sort(coins) }

//----------------------------------------
// Misc

type Coinser interface {
GetCoins() Coins
SetCoins(Coins)
}
2 changes: 1 addition & 1 deletion x/coin/coin_test.go → types/coin_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package coin
package types

import (
"testing"
Expand Down
Loading

0 comments on commit 8f14e4b

Please sign in to comment.