cosmos-sdk/server/mock/app.go
Alessio Treglia 593921d04d Merge PR #2524: Replace GenTx with StdTx
Rework the process of loading a genesis.json file to load a starting app state and set of initial transactions to process.

* New function to create genesis account from MsgCreateValidator
* Add arg to PrintUnsignedStdTx() to actually operate in offline mode
* New func processStdTxs()
* Remove gen-tx command
* Cleanup, return validators as they need to be written into genesis.json
* Modify gaiad init to allow auto-create of stdTx
* Remove server/testnet.go
* Don't load node_key.json, which might not be available
* Get the txs through DeliverTx
* Add app.slashingKeeper.AddValidators at the end of genesis
* On InitChain(), Signature's account number must be 0
* Add (tentative?) command to generate {node_key,priv_validator}.json files
* Reintroduce gaiad testnet
* Prompt user for passwords
* Update gaia to work with auth.StdTx
* Remove test_utils, NewTestGaiaAppGenState is now deprecated
* Combine --genesis-format and --generate-only
* Improve sign command's --offline flag documentation
* Moniker must be set
* Call app.slashingKeeper.AddValidators() even if len(txs) == 0
* Refactoring, introduce gaiad init --skip-genesis, code cleanup
* Drop unnecessary workaround to make lcd_tests pass
* Reintroduce gentx
* Simple name changes, GenesisState.Txs -> .GenTxs; OWK -> OverwriteKey; OverwriteKeys -> OverwriteKey
2018-10-19 20:00:27 +02:00

126 lines
3.2 KiB
Go

package mock
import (
"encoding/json"
"fmt"
"path/filepath"
abci "github.com/tendermint/tendermint/abci/types"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
bam "github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// NewApp creates a simple mock kvstore app for testing. It should work
// similar to a real app. Make sure rootDir is empty before running the test,
// in order to guarantee consistent results
func NewApp(rootDir string, logger log.Logger) (abci.Application, error) {
db, err := dbm.NewGoLevelDB("mock", filepath.Join(rootDir, "data"))
if err != nil {
return nil, err
}
// Capabilities key to access the main KVStore.
capKeyMainStore := sdk.NewKVStoreKey("main")
// Create BaseApp.
baseApp := bam.NewBaseApp("kvstore", logger, db, decodeTx)
// Set mounts for BaseApp's MultiStore.
baseApp.MountStoresIAVL(capKeyMainStore)
baseApp.SetInitChainer(InitChainer(capKeyMainStore))
// Set a handler Route.
baseApp.Router().AddRoute("kvstore", KVStoreHandler(capKeyMainStore))
// Load latest version.
if err := baseApp.LoadLatestVersion(capKeyMainStore); err != nil {
return nil, err
}
return baseApp, nil
}
// KVStoreHandler is a simple handler that takes kvstoreTx and writes
// them to the db
func KVStoreHandler(storeKey sdk.StoreKey) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
dTx, ok := msg.(kvstoreTx)
if !ok {
panic("KVStoreHandler should only receive kvstoreTx")
}
// tx is already unmarshalled
key := dTx.key
value := dTx.value
store := ctx.KVStore(storeKey)
store.Set(key, value)
return sdk.Result{
Code: 0,
Log: fmt.Sprintf("set %s=%s", key, value),
}
}
}
// basic KV structure
type KV struct {
Key string `json:"key"`
Value string `json:"value"`
}
// What Genesis JSON is formatted as
type GenesisJSON struct {
Values []KV `json:"values"`
}
// InitChainer returns a function that can initialize the chain
// with key/value pairs
func InitChainer(key sdk.StoreKey) func(sdk.Context, abci.RequestInitChain) abci.ResponseInitChain {
return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
stateJSON := req.AppStateBytes
genesisState := new(GenesisJSON)
err := json.Unmarshal(stateJSON, genesisState)
if err != nil {
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468
// return sdk.ErrGenesisParse("").TraceCause(err, "")
}
for _, val := range genesisState.Values {
store := ctx.KVStore(key)
store.Set([]byte(val.Key), []byte(val.Value))
}
return abci.ResponseInitChain{}
}
}
// AppGenState can be passed into InitCmd, returns a static string of a few
// key-values that can be parsed by InitChainer
func AppGenState(_ *codec.Codec, _ []json.RawMessage) (appState json.RawMessage, err error) {
appState = json.RawMessage(`{
"values": [
{
"key": "hello",
"value": "goodbye"
},
{
"key": "foo",
"value": "bar"
}
]
}`)
return
}
// AppGenStateEmpty returns an empty transaction state for mocking.
func AppGenStateEmpty(_ *codec.Codec, _ []json.RawMessage) (appState json.RawMessage, err error) {
appState = json.RawMessage(``)
return
}