cosmos-sdk/baseapp/baseapp_test.go

178 lines
4.4 KiB
Go
Raw Normal View History

package baseapp
2017-12-20 17:34:51 -08:00
import (
"bytes"
"encoding/json"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
abci "github.com/tendermint/abci/types"
"github.com/tendermint/go-crypto"
cmn "github.com/tendermint/tmlibs/common"
2017-12-26 17:04:48 -08:00
dbm "github.com/tendermint/tmlibs/db"
2018-01-15 17:38:56 -08:00
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
2017-12-20 17:34:51 -08:00
)
2018-01-06 12:53:31 -08:00
// A mock transaction to update a validator's voting power.
type testTx struct {
Addr []byte
NewPower int64
}
2017-12-20 17:34:51 -08:00
2018-01-15 17:38:56 -08:00
const txType = "testTx"
func (tx testTx) Type() string { return txType }
2018-01-06 12:53:31 -08:00
func (tx testTx) Get(key interface{}) (value interface{}) { return nil }
2018-01-15 17:38:56 -08:00
func (tx testTx) GetSignBytes() []byte { return nil }
2018-01-06 12:53:31 -08:00
func (tx testTx) ValidateBasic() error { return nil }
2018-01-15 17:38:56 -08:00
func (tx testTx) GetSigners() []crypto.Address { return nil }
func (tx testTx) GetFeePayer() crypto.Address { return nil }
func (tx testTx) GetSignatures() []sdk.StdSignature { return nil }
2018-01-06 12:53:31 -08:00
func TestBasic(t *testing.T) {
2018-01-15 17:38:56 -08:00
store, storeKeys := newCommitMultiStore()
2017-12-20 17:34:51 -08:00
// Create app.
app := NewBaseApp(t.Name(), store)
2018-01-15 17:38:56 -08:00
app.SetTxDecoder(func(txBytes []byte) (sdk.Tx, error) {
2017-12-26 17:04:48 -08:00
var ttx testTx
2018-01-06 12:53:31 -08:00
fromJSON(txBytes, &ttx)
return ttx, nil
})
2018-01-15 17:38:56 -08:00
app.SetDefaultAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) { return })
app.Router().AddRoute(txType, func(ctx sdk.Context, tx sdk.Tx) sdk.Result {
2018-01-06 12:53:31 -08:00
// TODO
2018-01-15 17:38:56 -08:00
return sdk.Result{}
2017-12-20 17:34:51 -08:00
})
// Load latest state, which should be empty.
2018-01-15 17:38:56 -08:00
err := app.LoadLatestVersion(storeKeys["main"])
2017-12-20 17:34:51 -08:00
assert.Nil(t, err)
2017-12-26 17:04:48 -08:00
assert.Equal(t, app.LastBlockHeight(), int64(0))
2017-12-20 17:34:51 -08:00
// Create the validators
var numVals = 3
2017-12-26 17:04:48 -08:00
var valSet = make([]abci.Validator, numVals)
2017-12-20 17:34:51 -08:00
for i := 0; i < numVals; i++ {
valSet[i] = makeVal(secret(i))
}
// Initialize the chain
app.InitChain(abci.RequestInitChain{
2017-12-26 17:04:48 -08:00
Validators: valSet,
2017-12-20 17:34:51 -08:00
})
// Simulate the start of a block.
app.BeginBlock(abci.RequestBeginBlock{})
// Add 1 to each validator's voting power.
for i, val := range valSet {
tx := testTx{
Addr: makePubKey(secret(i)).Address(),
NewPower: val.Power + 1,
}
txBytes := toJSON(tx)
res := app.DeliverTx(txBytes)
2017-12-26 17:04:48 -08:00
assert.True(t, res.IsOK(), "%#v", res)
2017-12-20 17:34:51 -08:00
}
// Simulate the end of a block.
// Get the summary of validator updates.
2017-12-26 17:04:48 -08:00
res := app.EndBlock(abci.RequestEndBlock{})
2017-12-20 17:34:51 -08:00
valUpdates := res.ValidatorUpdates
// Assert that validator updates are correct.
for _, val := range valSet {
2017-12-26 17:04:48 -08:00
// Sanity
assert.NotEqual(t, len(val.PubKey), 0)
2017-12-20 17:34:51 -08:00
// Find matching update and splice it out.
for j := 0; j < len(valUpdates); {
2017-12-26 17:04:48 -08:00
valUpdate := valUpdates[j]
2017-12-20 17:34:51 -08:00
// Matched.
if bytes.Equal(valUpdate.PubKey, val.PubKey) {
2017-12-26 17:04:48 -08:00
assert.Equal(t, valUpdate.Power, val.Power+1)
2017-12-20 17:34:51 -08:00
if j < len(valUpdates)-1 {
// Splice it out.
valUpdates = append(valUpdates[:j], valUpdates[j+1:]...)
}
break
}
// Not matched.
j += 1
}
}
assert.Equal(t, len(valUpdates), 0, "Some validator updates were unexpected")
}
//----------------------------------------
func randPower() int64 {
return cmn.RandInt64()
}
2017-12-26 17:04:48 -08:00
func makeVal(secret string) abci.Validator {
return abci.Validator{
PubKey: makePubKey(secret).Bytes(),
2017-12-20 17:34:51 -08:00
Power: randPower(),
}
}
func makePubKey(secret string) crypto.PubKey {
return makePrivKey(secret).PubKey()
}
func makePrivKey(secret string) crypto.PrivKey {
2017-12-26 17:04:48 -08:00
privKey := crypto.GenPrivKeyEd25519FromSecret([]byte(secret))
2018-01-15 17:38:56 -08:00
return privKey
2017-12-20 17:34:51 -08:00
}
2017-12-26 17:04:48 -08:00
func secret(index int) string {
return fmt.Sprintf("secret%d", index)
2017-12-20 17:34:51 -08:00
}
2017-12-26 17:04:48 -08:00
func copyVal(val abci.Validator) abci.Validator {
// val2 := *val
// return &val2
return val
2017-12-20 17:34:51 -08:00
}
func toJSON(o interface{}) []byte {
2017-12-26 17:04:48 -08:00
bz, err := json.Marshal(o)
2017-12-20 17:34:51 -08:00
if err != nil {
panic(err)
}
2017-12-26 17:04:48 -08:00
// fmt.Println(">> toJSON:", string(bz))
return bz
2017-12-20 17:34:51 -08:00
}
2017-12-26 17:04:48 -08:00
func fromJSON(bz []byte, ptr interface{}) {
// fmt.Println(">> fromJSON:", string(bz))
err := json.Unmarshal(bz, ptr)
2017-12-20 17:34:51 -08:00
if err != nil {
panic(err)
}
}
2017-12-26 17:04:48 -08:00
// Creates a sample CommitMultiStore
2018-01-15 17:38:56 -08:00
func newCommitMultiStore() (sdk.CommitMultiStore, map[string]sdk.SubstoreKey) {
2017-12-26 17:04:48 -08:00
dbMain := dbm.NewMemDB()
dbXtra := dbm.NewMemDB()
2018-01-15 17:38:56 -08:00
keyMain := sdk.NewKVStoreKey("main")
keyXtra := sdk.NewKVStoreKey("xtra")
2018-01-06 12:53:31 -08:00
ms := store.NewCommitMultiStore(dbMain) // Also store rootMultiStore metadata here (it shouldn't clash)
2018-01-15 17:38:56 -08:00
ms.SetSubstoreLoader(keyMain, store.NewIAVLStoreLoader(dbMain, 0, 0))
ms.SetSubstoreLoader(keyXtra, store.NewIAVLStoreLoader(dbXtra, 0, 0))
return ms, map[string]sdk.SubstoreKey{
"main": keyMain,
"xtra": keyXtra,
}
2017-12-26 17:04:48 -08:00
}