From 8574f923e8fd5e0b3d3eb39aabe3834f9ee20537 Mon Sep 17 00:00:00 2001 From: Adrian Brink Date: Wed, 28 Mar 2018 14:33:48 +0200 Subject: [PATCH 01/16] Mount every single store with its own DB --- baseapp/baseapp.go | 8 +++++--- examples/basecoin/app/app.go | 24 ++++++++++++++++++++++-- examples/kvstore/main.go | 2 +- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 3dad0483a3..dd0c35eaa8 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -54,6 +54,7 @@ type BaseApp struct { var _ abci.Application = (*BaseApp)(nil) // Create and name new BaseApp +// NOTE: The db is used to store the version number for now. func NewBaseApp(name string, logger log.Logger, db dbm.DB) *BaseApp { return &BaseApp{ Logger: logger, @@ -70,15 +71,16 @@ func (app *BaseApp) Name() string { } // Mount a store to the provided key in the BaseApp multistore +// Broken until #532 is implemented. func (app *BaseApp) MountStoresIAVL(keys ...*sdk.KVStoreKey) { for _, key := range keys { - app.MountStore(key, sdk.StoreTypeIAVL) + app.MountStore(key, sdk.StoreTypeIAVL, app.db) } } // Mount a store to the provided key in the BaseApp multistore -func (app *BaseApp) MountStore(key sdk.StoreKey, typ sdk.StoreType) { - app.cms.MountStoreWithDB(key, typ, app.db) +func (app *BaseApp) MountStore(key sdk.StoreKey, typ sdk.StoreType, db dbm.DB) { + app.cms.MountStoreWithDB(key, typ, db) } // nolint - Set functions diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index e5235bd667..4595d1bfb4 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -2,6 +2,8 @@ package app import ( "encoding/json" + "os" + "path/filepath" abci "github.com/tendermint/abci/types" oldwire "github.com/tendermint/go-wire" @@ -66,12 +68,30 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). AddRoute("staking", staking.NewHandler(stakeKeeper)) + rootDir := os.ExpandEnv("$HOME/.basecoind") + dbMain, err := dbm.NewGoLevelDB("basecoin-main", filepath.Join(rootDir, "data")) + if err != nil { + cmn.Exit(err.Error()) + } + dbIBC, err := dbm.NewGoLevelDB("basecoin-ibc", filepath.Join(rootDir, "data")) + if err != nil { + cmn.Exit(err.Error()) + } + dbStaking, err := dbm.NewGoLevelDB("basecoin-staking", filepath.Join(rootDir, "data")) + if err != nil { + cmn.Exit(err.Error()) + } + // initialize BaseApp app.SetTxDecoder(app.txDecoder) app.SetInitChainer(app.initChainer) - app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore, app.capKeyStakingStore) + app.MountStore(app.capKeyMainStore, sdk.StoreTypeIAVL, dbMain) + app.MountStore(app.capKeyIBCStore, sdk.StoreTypeIAVL, dbIBC) + app.MountStore(app.capKeyStakingStore, sdk.StoreTypeIAVL, dbStaking) + // NOTE: Broken until #532 lands + //app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore, app.capKeyStakingStore) app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) - err := app.LoadLatestVersion(app.capKeyMainStore) + err = app.LoadLatestVersion(app.capKeyMainStore) if err != nil { cmn.Exit(err.Error()) } diff --git a/examples/kvstore/main.go b/examples/kvstore/main.go index 5ffe590f1a..538235bf4d 100644 --- a/examples/kvstore/main.go +++ b/examples/kvstore/main.go @@ -30,7 +30,7 @@ func main() { var baseApp = bam.NewBaseApp("kvstore", logger, db) // Set mounts for BaseApp's MultiStore. - baseApp.MountStore(capKeyMainStore, sdk.StoreTypeIAVL) + baseApp.MountStoresIAVL(capKeyMainStore) // Set Tx decoder baseApp.SetTxDecoder(decodeTx) From 243564c2331725edfa7386d80a126b7fab8ccb75 Mon Sep 17 00:00:00 2001 From: Adrian Brink Date: Wed, 28 Mar 2018 15:08:59 +0200 Subject: [PATCH 02/16] Tests can never be proven to be non-deterministic Our tests are at best probabilistic deterministic. --- client/lcd/lcd_test.go | 2 +- examples/basecoin/app/app.go | 25 ++++++------------------- examples/basecoin/app/app_test.go | 11 ++++++----- examples/basecoin/cmd/basecoind/main.go | 16 ++++++++++++++-- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 285cf4d6d7..c21884d056 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -315,7 +315,7 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) { logger = log.NewFilter(logger, log.AllowError()) privValidatorFile := config.PrivValidatorFile() privVal := tmtypes.LoadOrGenPrivValidatorFS(privValidatorFile) - app := bapp.NewBasecoinApp(logger, dbm.NewMemDB()) + app := bapp.NewBasecoinApp(logger, dbm.NewMemDB(), dbm.NewMemDB(), dbm.NewMemDB(), dbm.NewMemDB()) genesisFile := config.GenesisFile() genDoc, err := tmtypes.GenesisDocFromFile(genesisFile) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index 4595d1bfb4..8bdab890ff 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -2,8 +2,6 @@ package app import ( "encoding/json" - "os" - "path/filepath" abci "github.com/tendermint/abci/types" oldwire "github.com/tendermint/go-wire" @@ -34,6 +32,7 @@ type BasecoinApp struct { // keys to access the substores capKeyMainStore *sdk.KVStoreKey + capKeyAccountStore *sdk.KVStoreKey capKeyIBCStore *sdk.KVStoreKey capKeyStakingStore *sdk.KVStoreKey @@ -41,12 +40,13 @@ type BasecoinApp struct { accountMapper sdk.AccountMapper } -func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { +func NewBasecoinApp(logger log.Logger, dbMain, dbAcc, dbIBC, dbStaking dbm.DB) *BasecoinApp { // create your application object var app = &BasecoinApp{ - BaseApp: bam.NewBaseApp(appName, logger, db), + BaseApp: bam.NewBaseApp(appName, logger, dbMain), cdc: MakeCodec(), capKeyMainStore: sdk.NewKVStoreKey("main"), + capKeyAccountStore: sdk.NewKVStoreKey("acc"), capKeyIBCStore: sdk.NewKVStoreKey("ibc"), capKeyStakingStore: sdk.NewKVStoreKey("staking"), } @@ -68,30 +68,17 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). AddRoute("staking", staking.NewHandler(stakeKeeper)) - rootDir := os.ExpandEnv("$HOME/.basecoind") - dbMain, err := dbm.NewGoLevelDB("basecoin-main", filepath.Join(rootDir, "data")) - if err != nil { - cmn.Exit(err.Error()) - } - dbIBC, err := dbm.NewGoLevelDB("basecoin-ibc", filepath.Join(rootDir, "data")) - if err != nil { - cmn.Exit(err.Error()) - } - dbStaking, err := dbm.NewGoLevelDB("basecoin-staking", filepath.Join(rootDir, "data")) - if err != nil { - cmn.Exit(err.Error()) - } - // initialize BaseApp app.SetTxDecoder(app.txDecoder) app.SetInitChainer(app.initChainer) app.MountStore(app.capKeyMainStore, sdk.StoreTypeIAVL, dbMain) + app.MountStore(app.capKeyAccountStore, sdk.StoreTypeIAVL, dbAcc) app.MountStore(app.capKeyIBCStore, sdk.StoreTypeIAVL, dbIBC) app.MountStore(app.capKeyStakingStore, sdk.StoreTypeIAVL, dbStaking) // NOTE: Broken until #532 lands //app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore, app.capKeyStakingStore) app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) - err = app.LoadLatestVersion(app.capKeyMainStore) + err := app.LoadLatestVersion(app.capKeyMainStore) if err != nil { cmn.Exit(err.Error()) } diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index b1a1c4cade..3767dcc392 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -68,8 +68,11 @@ var ( func newBasecoinApp() *BasecoinApp { logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") - db := dbm.NewMemDB() - return NewBasecoinApp(logger, db) + dbMain := dbm.NewMemDB() + dbAcc := dbm.NewMemDB() + dbIBC := dbm.NewMemDB() + dbStaking := dbm.NewMemDB() + return NewBasecoinApp(logger, dbMain, dbAcc, dbIBC, dbStaking) } //_______________________________________________________________________ @@ -112,9 +115,7 @@ func TestMsgs(t *testing.T) { } func TestGenesis(t *testing.T) { - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") - db := dbm.NewMemDB() - bapp := NewBasecoinApp(logger, db) + bapp := newBasecoinApp() // Construct some genesis bytes to reflect basecoin/types/AppAccount pk := crypto.GenPrivKeyEd25519().PubKey() diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index b25847358d..2c1fe851f0 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -51,11 +51,23 @@ func defaultOptions(args []string) (json.RawMessage, error) { } func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { - db, err := dbm.NewGoLevelDB("basecoin", filepath.Join(rootDir, "data")) + dbMain, err := dbm.NewGoLevelDB("basecoin", filepath.Join(rootDir, "data")) if err != nil { return nil, err } - bapp := app.NewBasecoinApp(logger, db) + dbAcc, err := dbm.NewGoLevelDB("basecoin-acc", filepath.Join(rootDir, "data")) + if err != nil { + return nil, err + } + dbIBC, err := dbm.NewGoLevelDB("basecoin-ibc", filepath.Join(rootDir, "data")) + if err != nil { + return nil, err + } + dbStaking, err := dbm.NewGoLevelDB("basecoin-staking", filepath.Join(rootDir, "data")) + if err != nil { + return nil, err + } + bapp := app.NewBasecoinApp(logger, dbMain, dbAcc, dbIBC, dbStaking) return bapp, nil } From 27d24610ab9a5ba3d08fd6c2b65d3997f30d3733 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 28 Mar 2018 17:03:17 +0200 Subject: [PATCH 03/16] basecoind init --testnet (closes #718) --- examples/basecoin/cmd/basecoind/main.go | 10 ++-- mock/app.go | 5 +- mock/app_test.go | 2 +- server/init.go | 67 ++++++++++++++++++++++--- 4 files changed, 69 insertions(+), 15 deletions(-) diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index 6a4f45956f..6ecf37c94f 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -10,6 +10,7 @@ import ( abci "github.com/tendermint/abci/types" "github.com/tendermint/tmlibs/cli" + cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -28,14 +29,11 @@ var ( // defaultOptions sets up the app_options for the // default genesis file -func defaultOptions(args []string) (json.RawMessage, error) { +func defaultOptions(args []string) (json.RawMessage, string, cmn.HexBytes, error) { addr, secret, err := server.GenerateCoinKey() if err != nil { - return nil, err + return nil, "", nil, err } - fmt.Println("Secret phrase to access coins:") - fmt.Println(secret) - opts := fmt.Sprintf(`{ "accounts": [{ "address": "%s", @@ -47,7 +45,7 @@ func defaultOptions(args []string) (json.RawMessage, error) { ] }] }`, addr) - return json.RawMessage(opts), nil + return json.RawMessage(opts), secret, addr, nil } func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { diff --git a/mock/app.go b/mock/app.go index c7c6432902..20863dd993 100644 --- a/mock/app.go +++ b/mock/app.go @@ -6,6 +6,7 @@ import ( "path/filepath" abci "github.com/tendermint/abci/types" + cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -106,7 +107,7 @@ func InitChainer(key sdk.StoreKey) func(sdk.Context, abci.RequestInitChain) abci // GenInitOptions can be passed into InitCmd, // returns a static string of a few key-values that can be parsed // by InitChainer -func GenInitOptions(args []string) (json.RawMessage, error) { +func GenInitOptions(args []string) (json.RawMessage, string, cmn.HexBytes, error) { opts := []byte(`{ "values": [ { @@ -119,5 +120,5 @@ func GenInitOptions(args []string) (json.RawMessage, error) { } ] }`) - return opts, nil + return opts, "", nil, nil } diff --git a/mock/app_test.go b/mock/app_test.go index 103530e501..47db93e1c5 100644 --- a/mock/app_test.go +++ b/mock/app_test.go @@ -21,7 +21,7 @@ func TestInitApp(t *testing.T) { require.NoError(t, err) // initialize it future-way - opts, err := GenInitOptions(nil) + opts, _, _, err := GenInitOptions(nil) require.NoError(t, err) req := abci.RequestInitChain{AppStateBytes: opts} app.InitChain(req) diff --git a/server/init.go b/server/init.go index 12e330dbc8..19eedda76a 100644 --- a/server/init.go +++ b/server/init.go @@ -2,18 +2,32 @@ package server import ( "encoding/json" + "fmt" "io/ioutil" "github.com/spf13/cobra" + "github.com/spf13/viper" cmn "github.com/tendermint/tmlibs/common" "github.com/tendermint/tmlibs/log" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" cfg "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/p2p" tmtypes "github.com/tendermint/tendermint/types" ) +const ( + flagTestnet = "testnet" +) + +type testnetInformation struct { + Secret string `json:"secret"` + Account string `json:"account"` + Validator tmtypes.GenesisValidator `json:"validator"` + NodeID p2p.ID `json:"node_id"` +} + // InitCmd will initialize all files for tendermint, // along with proper app_state. // The application can pass in a function to generate @@ -24,17 +38,20 @@ func InitCmd(gen GenAppState, logger log.Logger) *cobra.Command { genAppState: gen, logger: logger, } - return &cobra.Command{ + cobraCmd := cobra.Command{ Use: "init", Short: "Initialize genesis files", RunE: cmd.run, } + cobraCmd.Flags().Bool(flagTestnet, false, "Output testnet information in JSON") + return &cobraCmd } // GenAppState can parse command-line and flag to // generate default app_state for the genesis file. +// Also must return generated seed and address // This is application-specific -type GenAppState func(args []string) (json.RawMessage, error) +type GenAppState func(args []string) (json.RawMessage, string, cmn.HexBytes, error) type initCmd struct { genAppState GenAppState @@ -42,13 +59,20 @@ type initCmd struct { } func (c initCmd) run(cmd *cobra.Command, args []string) error { + // Store testnet information as we go + var testnetInfo testnetInformation + + if viper.GetBool(flagTestnet) { + c.logger = log.NewFilter(c.logger, log.AllowError()) + } + // Run the basic tendermint initialization, // set up a default genesis with no app_options config, err := tcmd.ParseConfig() if err != nil { return err } - err = c.initTendermintFiles(config) + err = c.initTendermintFiles(config, &testnetInfo) if err != nil { return err } @@ -59,19 +83,38 @@ func (c initCmd) run(cmd *cobra.Command, args []string) error { } // Now, we want to add the custom app_state - appState, err := c.genAppState(args) + appState, secret, address, err := c.genAppState(args) if err != nil { return err } + testnetInfo.Secret = secret + testnetInfo.Account = address.String() + // And add them to the genesis file genFile := config.GenesisFile() - return addGenesisState(genFile, appState) + if err := addGenesisState(genFile, appState); err != nil { + return err + } + + if viper.GetBool(flagTestnet) { + nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) + if err != nil { + return err + } + testnetInfo.NodeID = nodeKey.ID() + out, err := json.MarshalIndent(testnetInfo, "", " ") + if err != nil { + return err + } + fmt.Println(string(out)) + } + return nil } // This was copied from tendermint/cmd/tendermint/commands/init.go // so we could pass in the config and the logger. -func (c initCmd) initTendermintFiles(config *cfg.Config) error { +func (c initCmd) initTendermintFiles(config *cfg.Config, info *testnetInformation) error { // private validator privValFile := config.PrivValidatorFile() var privValidator *tmtypes.PrivValidatorFS @@ -102,6 +145,18 @@ func (c initCmd) initTendermintFiles(config *cfg.Config) error { } c.logger.Info("Generated genesis file", "path", genFile) } + + // reload the config file and find our validator info + loadedDoc, err := tmtypes.GenesisDocFromFile(genFile) + if err != nil { + return err + } + for _, validator := range loadedDoc.Validators { + if validator.PubKey == privValidator.GetPubKey() { + info.Validator = validator + } + } + return nil } From bb66b852ef4354377533e67f6b21af76afe0071f Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 28 Mar 2018 17:52:18 +0200 Subject: [PATCH 04/16] Move keybase DB to ~/.basecoind/data (closes #644) --- Makefile | 2 -- client/keys/utils.go | 5 +++-- client/lcd/lcd_test.go | 2 ++ examples/kvstore/main.go | 7 ++++++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 3a53f19446..e9565084d6 100644 --- a/Makefile +++ b/Makefile @@ -78,9 +78,7 @@ test_unit: test_cover: @rm -rf examples/basecoin/vendor/ - @rm -rf client/lcd/keys.db ~/.tendermint_test @bash tests/test_cover.sh - @rm -rf client/lcd/keys.db ~/.tendermint_test benchmark: @go test -bench=. $(PACKAGES) diff --git a/client/keys/utils.go b/client/keys/utils.go index c6239002ca..eed7abc6cc 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -2,6 +2,7 @@ package keys import ( "fmt" + "path/filepath" "github.com/spf13/viper" @@ -31,8 +32,8 @@ type KeyOutput struct { // GetKeyBase initializes a keybase based on the configuration func GetKeyBase() (keys.Keybase, error) { if keybase == nil { - rootDir := viper.GetString(cli.HomeFlag) - db, err := dbm.NewGoLevelDB(KeyDBName, rootDir) + rootDir := filepath.Join(viper.GetString(cli.HomeFlag), ".basecoind") + db, err := dbm.NewGoLevelDB(KeyDBName, filepath.Join(rootDir, "data")) if err != nil { return nil, err } diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 1e7104dae2..1e956d768c 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -25,6 +25,7 @@ import ( ctypes "github.com/tendermint/tendermint/rpc/core/types" tmrpc "github.com/tendermint/tendermint/rpc/lib/server" tmtypes "github.com/tendermint/tendermint/types" + "github.com/tendermint/tmlibs/cli" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -294,6 +295,7 @@ func TestTxs(t *testing.T) { // strt TM and the LCD in process, listening on their respective sockets func startTMAndLCD() (*nm.Node, net.Listener, error) { + viper.Set(cli.HomeFlag, os.ExpandEnv("$HOME")) kb, err := keys.GetKeyBase() // dbm.NewMemDB()) // :( if err != nil { return nil, nil, err diff --git a/examples/kvstore/main.go b/examples/kvstore/main.go index 9bcabb306a..31e4def8e3 100644 --- a/examples/kvstore/main.go +++ b/examples/kvstore/main.go @@ -3,8 +3,12 @@ package main import ( "fmt" "os" + "path/filepath" + + "github.com/spf13/viper" "github.com/tendermint/abci/server" + "github.com/tendermint/tmlibs/cli" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -17,7 +21,8 @@ func main() { logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "main") - db, err := dbm.NewGoLevelDB("basecoind", "data") + rootDir := viper.GetString(cli.HomeFlag) + db, err := dbm.NewGoLevelDB("basecoind", filepath.Join(rootDir, "data")) if err != nil { fmt.Println(err) os.Exit(1) From 44de18e8da3f674c7e4b547b360aba7ea9cb2811 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 28 Mar 2018 18:00:51 +0200 Subject: [PATCH 05/16] Use temporary dir for lcd keybase tests (closes #646) --- client/lcd/lcd_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 1e956d768c..c0245ba86c 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -295,7 +295,7 @@ func TestTxs(t *testing.T) { // strt TM and the LCD in process, listening on their respective sockets func startTMAndLCD() (*nm.Node, net.Listener, error) { - viper.Set(cli.HomeFlag, os.ExpandEnv("$HOME")) + viper.Set(cli.HomeFlag, os.ExpandEnv("/tmp/$HOME")) kb, err := keys.GetKeyBase() // dbm.NewMemDB()) // :( if err != nil { return nil, nil, err From 0f9bd93bb1335126f8f7987a1f6ef0b185244ea1 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 29 Mar 2018 12:10:13 +0200 Subject: [PATCH 06/16] Switch a few directories (#644 #646) --- client/keys/utils.go | 2 +- client/lcd/lcd_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/keys/utils.go b/client/keys/utils.go index eed7abc6cc..ebebf5d263 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -32,7 +32,7 @@ type KeyOutput struct { // GetKeyBase initializes a keybase based on the configuration func GetKeyBase() (keys.Keybase, error) { if keybase == nil { - rootDir := filepath.Join(viper.GetString(cli.HomeFlag), ".basecoind") + rootDir := filepath.Join(viper.GetString(cli.HomeFlag), ".tlc") db, err := dbm.NewGoLevelDB(KeyDBName, filepath.Join(rootDir, "data")) if err != nil { return nil, err diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index c0245ba86c..9bed2d3700 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -295,7 +295,7 @@ func TestTxs(t *testing.T) { // strt TM and the LCD in process, listening on their respective sockets func startTMAndLCD() (*nm.Node, net.Listener, error) { - viper.Set(cli.HomeFlag, os.ExpandEnv("/tmp/$HOME")) + viper.Set(cli.HomeFlag, os.TempDir()) kb, err := keys.GetKeyBase() // dbm.NewMemDB()) // :( if err != nil { return nil, nil, err From fd4e2c53edd4414685cf3d7db7e073ff980a25f9 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 29 Mar 2018 12:16:08 +0200 Subject: [PATCH 07/16] Update gaid for GenAppState change --- examples/gaia/gaiad/main.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/gaia/gaiad/main.go b/examples/gaia/gaiad/main.go index 0c4c49eec7..70a44d8cbc 100644 --- a/examples/gaia/gaiad/main.go +++ b/examples/gaia/gaiad/main.go @@ -9,6 +9,7 @@ import ( abci "github.com/tendermint/abci/types" "github.com/tendermint/tmlibs/cli" + cmn "github.com/tendermint/tmlibs/common" "github.com/tendermint/tmlibs/log" "github.com/cosmos/cosmos-sdk/baseapp" @@ -26,10 +27,10 @@ var ( // defaultOptions sets up the app_options for the // default genesis file -func defaultOptions(args []string) (json.RawMessage, error) { +func defaultOptions(args []string) (json.RawMessage, string, cmn.HexBytes, error) { addr, secret, err := server.GenerateCoinKey() if err != nil { - return nil, err + return nil, "", nil, err } fmt.Println("Secret phrase to access coins:") fmt.Println(secret) @@ -45,7 +46,7 @@ func defaultOptions(args []string) (json.RawMessage, error) { ] }] }`, addr) - return json.RawMessage(opts), nil + return json.RawMessage(opts), secret, addr, nil } func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { From e13b1f2ac9ade542527c1d46121648d9a44e2509 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 29 Mar 2018 18:23:11 +0200 Subject: [PATCH 08/16] Change key DB to ~/.basecli/keys/keys.db --- client/keys/utils.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/keys/utils.go b/client/keys/utils.go index ebebf5d263..d1b3d3f657 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -32,8 +32,8 @@ type KeyOutput struct { // GetKeyBase initializes a keybase based on the configuration func GetKeyBase() (keys.Keybase, error) { if keybase == nil { - rootDir := filepath.Join(viper.GetString(cli.HomeFlag), ".tlc") - db, err := dbm.NewGoLevelDB(KeyDBName, filepath.Join(rootDir, "data")) + rootDir := viper.GetString(cli.HomeFlag) + db, err := dbm.NewGoLevelDB(KeyDBName, filepath.Join(rootDir, "keys")) if err != nil { return nil, err } From fcc8a9a415907483bbe25cac3eb3c74b3ded37eb Mon Sep 17 00:00:00 2001 From: Adrian Brink Date: Thu, 29 Mar 2018 20:44:56 +0200 Subject: [PATCH 09/16] Address comments I hope this is correct. I'm feely pretty dizzy right now from the fish food. --- baseapp/baseapp.go | 9 +++++++-- baseapp/baseapp_test.go | 23 +++++++++++++---------- examples/basecoin/app/app.go | 8 ++++---- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index dd0c35eaa8..fefad88718 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -74,15 +74,20 @@ func (app *BaseApp) Name() string { // Broken until #532 is implemented. func (app *BaseApp) MountStoresIAVL(keys ...*sdk.KVStoreKey) { for _, key := range keys { - app.MountStore(key, sdk.StoreTypeIAVL, app.db) + app.MountStore(key, sdk.StoreTypeIAVL) } } // Mount a store to the provided key in the BaseApp multistore -func (app *BaseApp) MountStore(key sdk.StoreKey, typ sdk.StoreType, db dbm.DB) { +func (app *BaseApp) MountStoreWithDB(key sdk.StoreKey, typ sdk.StoreType, db dbm.DB) { app.cms.MountStoreWithDB(key, typ, db) } +// Mount a store to the provided key in the BaseApp multistore +func (app *BaseApp) MountStore(key sdk.StoreKey, typ sdk.StoreType) { + app.cms.MountStoreWithDB(key, typ, app.db) +} + // nolint - Set functions func (app *BaseApp) SetTxDecoder(txDecoder sdk.TxDecoder) { app.txDecoder = txDecoder diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index de9a0253c5..c04631b415 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -35,12 +35,15 @@ func TestMountStores(t *testing.T) { // make some cap keys capKey1 := sdk.NewKVStoreKey("key1") + db1 := dbm.NewMemDB() capKey2 := sdk.NewKVStoreKey("key2") + db2 := dbm.NewMemDB() // no stores are mounted assert.Panics(t, func() { app.LoadLatestVersion(capKey1) }) - app.MountStoresIAVL(capKey1, capKey2) + app.MountStoreWithDB(capKey1, sdk.StoreTypeIAVL, db1) + app.MountStoreWithDB(capKey2, sdk.StoreTypeIAVL, db2) // stores are mounted err := app.LoadLatestVersion(capKey1) @@ -126,7 +129,6 @@ func TestTxDecoder(t *testing.T) { // Test that Info returns the latest committed state. func TestInfo(t *testing.T) { - app := newBaseApp(t.Name()) // ----- test an empty response ------- @@ -145,17 +147,19 @@ func TestInfo(t *testing.T) { } func TestInitChainer(t *testing.T) { - logger := defaultLogger() - db := dbm.NewMemDB() name := t.Name() + db := dbm.NewMemDB() + logger := defaultLogger() app := NewBaseApp(name, logger, db) - // make cap keys and mount the stores // NOTE/TODO: mounting multiple stores is broken // see https://github.com/cosmos/cosmos-sdk/issues/532 capKey := sdk.NewKVStoreKey("main") - // capKey2 := sdk.NewKVStoreKey("key2") - app.MountStoresIAVL(capKey) // , capKey2) + db1 := dbm.NewMemDB() + capKey2 := sdk.NewKVStoreKey("key2") + db2 := dbm.NewMemDB() + app.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db1) + app.MountStoreWithDB(capKey2, sdk.StoreTypeIAVL, db2) err := app.LoadLatestVersion(capKey) // needed to make stores non-nil assert.Nil(t, err) @@ -187,9 +191,8 @@ func TestInitChainer(t *testing.T) { // reload app app = NewBaseApp(name, logger, db) - capKey = sdk.NewKVStoreKey("main") - // capKey2 = sdk.NewKVStoreKey("key2") // TODO - app.MountStoresIAVL(capKey) //, capKey2) + app.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db1) + app.MountStoreWithDB(capKey2, sdk.StoreTypeIAVL, db2) err = app.LoadLatestVersion(capKey) // needed to make stores non-nil assert.Nil(t, err) app.SetInitChainer(initChainer) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index 8bdab890ff..ca235fb70f 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -71,10 +71,10 @@ func NewBasecoinApp(logger log.Logger, dbMain, dbAcc, dbIBC, dbStaking dbm.DB) * // initialize BaseApp app.SetTxDecoder(app.txDecoder) app.SetInitChainer(app.initChainer) - app.MountStore(app.capKeyMainStore, sdk.StoreTypeIAVL, dbMain) - app.MountStore(app.capKeyAccountStore, sdk.StoreTypeIAVL, dbAcc) - app.MountStore(app.capKeyIBCStore, sdk.StoreTypeIAVL, dbIBC) - app.MountStore(app.capKeyStakingStore, sdk.StoreTypeIAVL, dbStaking) + app.MountStoreWithDB(app.capKeyMainStore, sdk.StoreTypeIAVL, dbMain) + app.MountStoreWithDB(app.capKeyAccountStore, sdk.StoreTypeIAVL, dbAcc) + app.MountStoreWithDB(app.capKeyIBCStore, sdk.StoreTypeIAVL, dbIBC) + app.MountStoreWithDB(app.capKeyStakingStore, sdk.StoreTypeIAVL, dbStaking) // NOTE: Broken until #532 lands //app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore, app.capKeyStakingStore) app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) From 0789a5eed071762dea6a8b9f18056cd8d48c1c03 Mon Sep 17 00:00:00 2001 From: Adrian Brink Date: Fri, 30 Mar 2018 12:18:12 +0200 Subject: [PATCH 10/16] NewBasecoinApp takes a map of databases NewBasecoinApp takes a map[string]dbm.DB . This stabilises the API, since it allows us to add more stores without a breaking change. The convention is that the keys of the dbs correspond to the names of the capKeys. --- client/lcd/lcd_test.go | 8 +++++++- examples/basecoin/app/app.go | 12 ++++++------ examples/basecoin/app/app_test.go | 12 +++++++----- examples/basecoin/cmd/basecoind/main.go | 8 +++++++- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index c21884d056..609a3b0641 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -315,7 +315,13 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) { logger = log.NewFilter(logger, log.AllowError()) privValidatorFile := config.PrivValidatorFile() privVal := tmtypes.LoadOrGenPrivValidatorFS(privValidatorFile) - app := bapp.NewBasecoinApp(logger, dbm.NewMemDB(), dbm.NewMemDB(), dbm.NewMemDB(), dbm.NewMemDB()) + dbs := map[string]dbm.DB{ + "main": dbm.NewMemDB(), + "acc": dbm.NewMemDB(), + "ibc": dbm.NewMemDB(), + "staking": dbm.NewMemDB(), + } + app := bapp.NewBasecoinApp(logger, dbs) genesisFile := config.GenesisFile() genDoc, err := tmtypes.GenesisDocFromFile(genesisFile) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index ca235fb70f..36d140e8a4 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -40,10 +40,10 @@ type BasecoinApp struct { accountMapper sdk.AccountMapper } -func NewBasecoinApp(logger log.Logger, dbMain, dbAcc, dbIBC, dbStaking dbm.DB) *BasecoinApp { +func NewBasecoinApp(logger log.Logger, dbs map[string]dbm.DB) *BasecoinApp { // create your application object var app = &BasecoinApp{ - BaseApp: bam.NewBaseApp(appName, logger, dbMain), + BaseApp: bam.NewBaseApp(appName, logger, dbs["main"]), cdc: MakeCodec(), capKeyMainStore: sdk.NewKVStoreKey("main"), capKeyAccountStore: sdk.NewKVStoreKey("acc"), @@ -71,10 +71,10 @@ func NewBasecoinApp(logger log.Logger, dbMain, dbAcc, dbIBC, dbStaking dbm.DB) * // initialize BaseApp app.SetTxDecoder(app.txDecoder) app.SetInitChainer(app.initChainer) - app.MountStoreWithDB(app.capKeyMainStore, sdk.StoreTypeIAVL, dbMain) - app.MountStoreWithDB(app.capKeyAccountStore, sdk.StoreTypeIAVL, dbAcc) - app.MountStoreWithDB(app.capKeyIBCStore, sdk.StoreTypeIAVL, dbIBC) - app.MountStoreWithDB(app.capKeyStakingStore, sdk.StoreTypeIAVL, dbStaking) + app.MountStoreWithDB(app.capKeyMainStore, sdk.StoreTypeIAVL, dbs["main"]) + app.MountStoreWithDB(app.capKeyAccountStore, sdk.StoreTypeIAVL, dbs["acc"]) + app.MountStoreWithDB(app.capKeyIBCStore, sdk.StoreTypeIAVL, dbs["ibc"]) + app.MountStoreWithDB(app.capKeyStakingStore, sdk.StoreTypeIAVL, dbs["staking"]) // NOTE: Broken until #532 lands //app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore, app.capKeyStakingStore) app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index 3767dcc392..f80836744e 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -68,11 +68,13 @@ var ( func newBasecoinApp() *BasecoinApp { logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") - dbMain := dbm.NewMemDB() - dbAcc := dbm.NewMemDB() - dbIBC := dbm.NewMemDB() - dbStaking := dbm.NewMemDB() - return NewBasecoinApp(logger, dbMain, dbAcc, dbIBC, dbStaking) + dbs := map[string]dbm.DB{ + "main": dbm.NewMemDB(), + "acc": dbm.NewMemDB(), + "ibc": dbm.NewMemDB(), + "staking": dbm.NewMemDB(), + } + return NewBasecoinApp(logger, dbs) } //_______________________________________________________________________ diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index 2c1fe851f0..8315456a35 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -67,7 +67,13 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { if err != nil { return nil, err } - bapp := app.NewBasecoinApp(logger, dbMain, dbAcc, dbIBC, dbStaking) + dbs := map[string]dbm.DB{ + "main": dbMain, + "acc": dbAcc, + "ibc": dbIBC, + "staking": dbStaking, + } + bapp := app.NewBasecoinApp(logger, dbs) return bapp, nil } From 55e72781ceb16e481565fed65f3b6e25023386a6 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 30 Mar 2018 13:40:04 +0300 Subject: [PATCH 11/16] basecoin: uncomment test --- examples/basecoin/app/app_test.go | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index f80836744e..58a0d1f411 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -66,7 +66,7 @@ var ( } ) -func newBasecoinApp() *BasecoinApp { +func loggerAndDBs() (log.Logger, map[string]dbm.DB) { logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") dbs := map[string]dbm.DB{ "main": dbm.NewMemDB(), @@ -74,6 +74,11 @@ func newBasecoinApp() *BasecoinApp { "ibc": dbm.NewMemDB(), "staking": dbm.NewMemDB(), } + return logger, dbs +} + +func newBasecoinApp() *BasecoinApp { + logger, dbs := loggerAndDBs() return NewBasecoinApp(logger, dbs) } @@ -117,7 +122,8 @@ func TestMsgs(t *testing.T) { } func TestGenesis(t *testing.T) { - bapp := newBasecoinApp() + logger, dbs := loggerAndDBs() + bapp := NewBasecoinApp(logger, dbs) // Construct some genesis bytes to reflect basecoin/types/AppAccount pk := crypto.GenPrivKeyEd25519().PubKey() @@ -145,13 +151,12 @@ func TestGenesis(t *testing.T) { ctx := bapp.BaseApp.NewContext(true, abci.Header{}) res1 := bapp.accountMapper.GetAccount(ctx, baseAcc.Address) assert.Equal(t, acc, res1) - /* - // reload app and ensure the account is still there - bapp = NewBasecoinApp(logger, db) - ctx = bapp.BaseApp.NewContext(true, abci.Header{}) - res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address) - assert.Equal(t, acc, res1) - */ + + // reload app and ensure the account is still there + bapp = NewBasecoinApp(logger, dbs) + ctx = bapp.BaseApp.NewContext(true, abci.Header{}) + res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address) + assert.Equal(t, acc, res1) } func TestSendMsgWithAccounts(t *testing.T) { From 10a22f20ba4b09e9297365ab68f42b4087fa02de Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 30 Mar 2018 16:27:26 +0200 Subject: [PATCH 12/16] Remove 'cool' and 'sketchy' modules from basecoind --- client/lcd/lcd_test.go | 3 -- examples/basecoin/app/app.go | 7 ---- examples/basecoin/app/app_test.go | 55 --------------------------- examples/basecoin/cmd/basecli/main.go | 9 ----- x/ibc/ibc_test.go | 4 -- 5 files changed, 78 deletions(-) diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index c9b1bb9bd8..9a3900759d 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -364,9 +364,6 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) { Coins: coins, }, }, - "cool": map[string]string{ - "trend": "ice-cold", - }, } stateBytes, err := json.Marshal(appState) if err != nil { diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index 18ac89131e..7c737566a7 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -18,8 +18,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/simplestake" "github.com/cosmos/cosmos-sdk/examples/basecoin/types" - "github.com/cosmos/cosmos-sdk/examples/basecoin/x/cool" - "github.com/cosmos/cosmos-sdk/examples/basecoin/x/sketchy" ) const ( @@ -60,13 +58,10 @@ func NewBasecoinApp(logger log.Logger, dbs map[string]dbm.DB) *BasecoinApp { // add handlers coinKeeper := bank.NewCoinKeeper(app.accountMapper) - coolKeeper := cool.NewKeeper(app.capKeyMainStore, coinKeeper) ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper) app.Router(). AddRoute("bank", bank.NewHandler(coinKeeper), nil). - AddRoute("cool", cool.NewHandler(coolKeeper), coolKeeper.InitGenesis). - AddRoute("sketchy", sketchy.NewHandler(), nil). AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper), nil). AddRoute("simplestake", simplestake.NewHandler(stakeKeeper), nil) @@ -103,8 +98,6 @@ func MakeCodec() *wire.Codec { struct{ sdk.Msg }{}, oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend}, oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue}, - oldwire.ConcreteType{cool.QuizMsg{}, msgTypeQuiz}, - oldwire.ConcreteType{cool.SetTrendMsg{}, msgTypeSetTrend}, oldwire.ConcreteType{ibc.IBCTransferMsg{}, msgTypeIBCTransferMsg}, oldwire.ConcreteType{ibc.IBCReceiveMsg{}, msgTypeIBCReceiveMsg}, oldwire.ConcreteType{simplestake.BondMsg{}, msgTypeBondMsg}, diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index c60092874f..144374f3f5 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -10,7 +10,6 @@ import ( "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/examples/basecoin/types" - "github.com/cosmos/cosmos-sdk/examples/basecoin/x/cool" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" @@ -39,31 +38,6 @@ var ( Inputs: []bank.Input{bank.NewInput(addr1, coins)}, Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, } - - quizMsg1 = cool.QuizMsg{ - Sender: addr1, - CoolAnswer: "icecold", - } - - quizMsg2 = cool.QuizMsg{ - Sender: addr1, - CoolAnswer: "badvibesonly", - } - - setTrendMsg1 = cool.SetTrendMsg{ - Sender: addr1, - Cool: "icecold", - } - - setTrendMsg2 = cool.SetTrendMsg{ - Sender: addr1, - Cool: "badvibesonly", - } - - setTrendMsg3 = cool.SetTrendMsg{ - Sender: addr1, - Cool: "warmandkind", - } ) func loggerAndDBs() (log.Logger, map[string]dbm.DB) { @@ -91,8 +65,6 @@ func TestMsgs(t *testing.T) { msg sdk.Msg }{ {sendMsg}, - {quizMsg1}, - {setTrendMsg1}, } sequences := []int64{0} @@ -140,9 +112,6 @@ func TestGenesis(t *testing.T) { "accounts": []*types.GenesisAccount{ types.NewGenesisAccount(acc), }, - "cool": map[string]string{ - "trend": "ice-cold", - }, } stateBytes, err := json.MarshalIndent(genesisState, "", "\t") @@ -180,9 +149,6 @@ func TestSendMsgWithAccounts(t *testing.T) { "accounts": []*types.GenesisAccount{ types.NewGenesisAccount(acc1), }, - "cool": map[string]string{ - "trend": "ice-cold", - }, } stateBytes, err := json.MarshalIndent(genesisState, "", "\t") require.Nil(t, err) @@ -255,9 +221,6 @@ func TestQuizMsg(t *testing.T) { "accounts": []*types.GenesisAccount{ types.NewGenesisAccount(acc1), }, - "cool": map[string]string{ - "trend": "ice-cold", - }, } stateBytes, err := json.MarshalIndent(genesisState, "", "\t") require.Nil(t, err) @@ -272,21 +235,6 @@ func TestQuizMsg(t *testing.T) { res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) assert.Equal(t, acc1, res1) - // Set the trend, submit a really cool quiz and check for reward - SignCheckDeliver(t, bapp, setTrendMsg1, 0, true) - SignCheckDeliver(t, bapp, quizMsg1, 1, true) - CheckBalance(t, bapp, "69icecold") - SignCheckDeliver(t, bapp, quizMsg2, 2, false) // result without reward - CheckBalance(t, bapp, "69icecold") - SignCheckDeliver(t, bapp, quizMsg1, 3, true) - CheckBalance(t, bapp, "138icecold") - SignCheckDeliver(t, bapp, setTrendMsg2, 4, true) // reset the trend - SignCheckDeliver(t, bapp, quizMsg1, 5, false) // the same answer will nolonger do! - CheckBalance(t, bapp, "138icecold") - SignCheckDeliver(t, bapp, quizMsg2, 6, true) // earlier answer now relavent again - CheckBalance(t, bapp, "69badvibesonly,138icecold") - SignCheckDeliver(t, bapp, setTrendMsg3, 7, false) // expect to fail to set the trend to something which is not cool - } func TestHandler(t *testing.T) { @@ -305,9 +253,6 @@ func TestHandler(t *testing.T) { "accounts": []*types.GenesisAccount{ types.NewGenesisAccount(acc1), }, - "cool": map[string]string{ - "trend": "ice-cold", - }, } stateBytes, err := json.MarshalIndent(genesisState, "", "\t") require.Nil(t, err) diff --git a/examples/basecoin/cmd/basecli/main.go b/examples/basecoin/cmd/basecli/main.go index 1c4b5833bf..a0152aee99 100644 --- a/examples/basecoin/cmd/basecli/main.go +++ b/examples/basecoin/cmd/basecli/main.go @@ -14,7 +14,6 @@ import ( "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/client/tx" - coolcmd "github.com/cosmos/cosmos-sdk/examples/basecoin/x/cool/commands" "github.com/cosmos/cosmos-sdk/version" authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" bankcmd "github.com/cosmos/cosmos-sdk/x/bank/commands" @@ -63,14 +62,6 @@ func main() { client.PostCommands( bankcmd.SendTxCmd(cdc), )...) - basecliCmd.AddCommand( - client.PostCommands( - coolcmd.QuizTxCmd(cdc), - )...) - basecliCmd.AddCommand( - client.PostCommands( - coolcmd.SetTrendTxCmd(cdc), - )...) basecliCmd.AddCommand( client.PostCommands( ibccmd.IBCTransferCmd(cdc), diff --git a/x/ibc/ibc_test.go b/x/ibc/ibc_test.go index bec08fb564..1e04311479 100644 --- a/x/ibc/ibc_test.go +++ b/x/ibc/ibc_test.go @@ -15,8 +15,6 @@ import ( "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" - - "github.com/cosmos/cosmos-sdk/examples/basecoin/x/cool" ) // AccountMapper(/CoinKeeper) and IBCMapper should use different StoreKey later @@ -53,8 +51,6 @@ func makeCodec() *wire.Codec { struct{ sdk.Msg }{}, oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend}, oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue}, - oldwire.ConcreteType{cool.QuizMsg{}, msgTypeQuiz}, - oldwire.ConcreteType{cool.SetTrendMsg{}, msgTypeSetTrend}, oldwire.ConcreteType{IBCTransferMsg{}, msgTypeIBCTransferMsg}, oldwire.ConcreteType{IBCReceiveMsg{}, msgTypeIBCReceiveMsg}, ) From f1af53fe300ecb140c525ebb6e5b219528a92763 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 30 Mar 2018 20:13:22 +0200 Subject: [PATCH 13/16] Move 'sketchy' and 'cool' modules to democoin, which is separate from basecoin --- Makefile | 7 + examples/democoin/LICENSE | 204 +++++++++++ examples/democoin/Makefile | 22 ++ examples/democoin/README.md | 70 ++++ examples/democoin/app/app.go | 158 +++++++++ examples/democoin/app/app_test.go | 327 ++++++++++++++++++ examples/democoin/cmd/democli/main.go | 91 +++++ examples/democoin/cmd/democoind/main.go | 98 ++++++ examples/democoin/types/account.go | 72 ++++ .../x/cool/commands/tx.go | 2 +- .../{basecoin => democoin}/x/cool/errors.go | 0 .../{basecoin => democoin}/x/cool/handler.go | 0 .../{basecoin => democoin}/x/cool/keeper.go | 0 .../{basecoin => democoin}/x/cool/types.go | 0 .../x/sketchy/handler.go | 0 15 files changed, 1050 insertions(+), 1 deletion(-) create mode 100644 examples/democoin/LICENSE create mode 100644 examples/democoin/Makefile create mode 100644 examples/democoin/README.md create mode 100644 examples/democoin/app/app.go create mode 100644 examples/democoin/app/app_test.go create mode 100644 examples/democoin/cmd/democli/main.go create mode 100644 examples/democoin/cmd/democoind/main.go create mode 100644 examples/democoin/types/account.go rename examples/{basecoin => democoin}/x/cool/commands/tx.go (97%) rename examples/{basecoin => democoin}/x/cool/errors.go (100%) rename examples/{basecoin => democoin}/x/cool/handler.go (100%) rename examples/{basecoin => democoin}/x/cool/keeper.go (100%) rename examples/{basecoin => democoin}/x/cool/types.go (100%) rename examples/{basecoin => democoin}/x/sketchy/handler.go (100%) diff --git a/Makefile b/Makefile index 3a53f19446..188a144b05 100644 --- a/Makefile +++ b/Makefile @@ -19,12 +19,17 @@ gaia: build: @rm -rf $(shell pwd)/examples/basecoin/vendor/ + @rm -rf $(shell pwd)/examples/democoin/vendor/ ifeq ($(OS),Windows_NT) go build $(BUILD_FLAGS) -o build/basecoind.exe ./examples/basecoin/cmd/basecoind go build $(BUILD_FLAGS) -o build/basecli.exe ./examples/basecoin/cmd/basecli + go build $(BUILD_FLAGS) -o build/democoind.exe ./examples/democoin/cmd/democoind + go build $(BUILD_FLAGS) -o build/democli.exe ./examples/democoin/cmd/democli else go build $(BUILD_FLAGS) -o build/basecoind ./examples/basecoin/cmd/basecoind go build $(BUILD_FLAGS) -o build/basecli ./examples/basecoin/cmd/basecli + go build $(BUILD_FLAGS) -o build/democoind ./examples/democoin/cmd/democoind + go build $(BUILD_FLAGS) -o build/democli ./examples/democoin/cmd/democli endif dist: @@ -74,10 +79,12 @@ test: test_unit # test_cli test_unit: @rm -rf examples/basecoin/vendor/ + @rm -rf examples/democoin/vendor/ @go test $(PACKAGES) test_cover: @rm -rf examples/basecoin/vendor/ + @rm -rf examples/democoin/vendor/ @rm -rf client/lcd/keys.db ~/.tendermint_test @bash tests/test_cover.sh @rm -rf client/lcd/keys.db ~/.tendermint_test diff --git a/examples/democoin/LICENSE b/examples/democoin/LICENSE new file mode 100644 index 0000000000..1697a74436 --- /dev/null +++ b/examples/democoin/LICENSE @@ -0,0 +1,204 @@ +Cosmos-SDK Democoin (template) +License: Apache2.0 + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018 All in Bits, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/examples/democoin/Makefile b/examples/democoin/Makefile new file mode 100644 index 0000000000..067d03e9bd --- /dev/null +++ b/examples/democoin/Makefile @@ -0,0 +1,22 @@ +PACKAGES=$(shell go list ./... | grep -v '/vendor/') +BUILD_FLAGS = -ldflags "-X github.com/cosmos/cosmos-sdk/examples/democoin/version.GitCommit=`git rev-parse --short HEAD`" + +all: get_tools get_vendor_deps build test + +get_tools: + go get github.com/golang/dep/cmd/dep + +build: + go build $(BUILD_FLAGS) -o build/democoin ./cmd/... + +get_vendor_deps: + @rm -rf vendor/ + @dep ensure + +test: + @go test $(PACKAGES) + +benchmark: + @go test -bench=. $(PACKAGES) + +.PHONY: all build test benchmark diff --git a/examples/democoin/README.md b/examples/democoin/README.md new file mode 100644 index 0000000000..fe65abda4b --- /dev/null +++ b/examples/democoin/README.md @@ -0,0 +1,70 @@ +# Democoin + +This is the "Democoin" example application built on the Cosmos-Sdk. This +"Democoin" is not affiliated with [Coinbase](http://www.getdemocoin.com/), nor +the [stable coin](http://www.getdemocoin.com/). + +Assuming you've run `make get_tools && make get_vendor_deps` from the root of +this repository, run `make build` here to build the `democoind` and `basecli` +binaries. + +If you want to create a new application, start by copying the Democoin app. + + +# Building your own Blockchain + +Democoin is the equivalent of an ERC20 token contract for blockchains. In order +to deploy your own application all you need to do is clone `examples/democoin` +and run it. Now you are already running your own blockchain. In the following +I will explain how to add functionality to your blockchain. This is akin to +defining your own vesting schedule within a contract or setting a specific +multisig. You are just extending the base layer with extra functionality here +and there. + +## Structure of Democoin + +Democoin is build with the cosmos-sdk. It is a sample application that works +with any engine that implements the ABCI protocol. Democoin defines multiple +unique modules as well as uses modules directly from the sdk. If you want +to modify Democoin, you either remove or add modules according to your wishes. + + +## Modules + +A module is a fundamental unit in the cosmos-sdk. A module defines its own +transaction, handles its own state as well as its own state transition logic. +Globally, in the `app/app.go` file you just have to define a key for that +module to access some parts of the state, as well as initialise the module +object and finally add it to the transaction router. The router ensures that +every module only gets its own messages. + + +## Transactions + +A user can send a transaction to the running blockchain application. This +transaction can be of any of the ones that are supported by any of the +registered modules. + +### CheckTx + +Once a user has submitted their transaction to the engine, +the engine will first run `checkTx` to confirm that it is a valid transaction. +The module has to define a handler that knows how to handle every transaction +type. The corresponding handler gets invoked with the checkTx flag set to true. +This means that the handler shouldn't do any expensive operations, but it can +and should write to the checkTx state. + +### DeliverTx + +The engine calls `deliverTx` when a new block has been agreed upon in +consensus. Again, the corresponding module will have its handler invoked +and the state and context is passed in. During deliverTx execution the +transaction needs to be processed fully and the results are written to the +application state. + + +## CLI + +The cosmos-sdk contains a number of helper libraries in `clients/` to build cli +and RPC interfaces for your specific application. + diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go new file mode 100644 index 0000000000..9c77c4735c --- /dev/null +++ b/examples/democoin/app/app.go @@ -0,0 +1,158 @@ +package app + +import ( + "encoding/json" + + abci "github.com/tendermint/abci/types" + oldwire "github.com/tendermint/go-wire" + cmn "github.com/tendermint/tmlibs/common" + dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" + + bam "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/ibc" + "github.com/cosmos/cosmos-sdk/x/simplestake" + + "github.com/cosmos/cosmos-sdk/examples/democoin/types" +) + +const ( + appName = "DemocoinApp" +) + +// Extended ABCI application +type DemocoinApp struct { + *bam.BaseApp + cdc *wire.Codec + + // keys to access the substores + capKeyMainStore *sdk.KVStoreKey + capKeyAccountStore *sdk.KVStoreKey + capKeyIBCStore *sdk.KVStoreKey + capKeyStakingStore *sdk.KVStoreKey + + // Manage getting and setting accounts + accountMapper sdk.AccountMapper +} + +func NewDemocoinApp(logger log.Logger, dbs map[string]dbm.DB) *DemocoinApp { + // create your application object + var app = &DemocoinApp{ + BaseApp: bam.NewBaseApp(appName, logger, dbs["main"]), + cdc: MakeCodec(), + capKeyMainStore: sdk.NewKVStoreKey("main"), + capKeyAccountStore: sdk.NewKVStoreKey("acc"), + capKeyIBCStore: sdk.NewKVStoreKey("ibc"), + capKeyStakingStore: sdk.NewKVStoreKey("stake"), + } + + // define the accountMapper + app.accountMapper = auth.NewAccountMapperSealed( + app.capKeyMainStore, // target store + &types.AppAccount{}, // prototype + ) + + // add handlers + coinKeeper := bank.NewCoinKeeper(app.accountMapper) + ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) + stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper) + app.Router(). + AddRoute("bank", bank.NewHandler(coinKeeper), nil). + AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper), nil). + AddRoute("simplestake", simplestake.NewHandler(stakeKeeper), nil) + + // initialize BaseApp + app.SetTxDecoder(app.txDecoder) + app.SetInitChainer(app.initChainer) + app.MountStoreWithDB(app.capKeyMainStore, sdk.StoreTypeIAVL, dbs["main"]) + app.MountStoreWithDB(app.capKeyAccountStore, sdk.StoreTypeIAVL, dbs["acc"]) + app.MountStoreWithDB(app.capKeyIBCStore, sdk.StoreTypeIAVL, dbs["ibc"]) + app.MountStoreWithDB(app.capKeyStakingStore, sdk.StoreTypeIAVL, dbs["staking"]) + // NOTE: Broken until #532 lands + //app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore, app.capKeyStakingStore) + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) + err := app.LoadLatestVersion(app.capKeyMainStore) + if err != nil { + cmn.Exit(err.Error()) + } + + return app +} + +// custom tx codec +// TODO: use new go-wire +func MakeCodec() *wire.Codec { + const msgTypeSend = 0x1 + const msgTypeIssue = 0x2 + const msgTypeQuiz = 0x3 + const msgTypeSetTrend = 0x4 + const msgTypeIBCTransferMsg = 0x5 + const msgTypeIBCReceiveMsg = 0x6 + const msgTypeBondMsg = 0x7 + const msgTypeUnbondMsg = 0x8 + var _ = oldwire.RegisterInterface( + struct{ sdk.Msg }{}, + oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend}, + oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue}, + oldwire.ConcreteType{ibc.IBCTransferMsg{}, msgTypeIBCTransferMsg}, + oldwire.ConcreteType{ibc.IBCReceiveMsg{}, msgTypeIBCReceiveMsg}, + oldwire.ConcreteType{simplestake.BondMsg{}, msgTypeBondMsg}, + oldwire.ConcreteType{simplestake.UnbondMsg{}, msgTypeUnbondMsg}, + ) + + const accTypeApp = 0x1 + var _ = oldwire.RegisterInterface( + struct{ sdk.Account }{}, + oldwire.ConcreteType{&types.AppAccount{}, accTypeApp}, + ) + cdc := wire.NewCodec() + + // cdc.RegisterInterface((*sdk.Msg)(nil), nil) + // bank.RegisterWire(cdc) // Register bank.[SendMsg,IssueMsg] types. + // crypto.RegisterWire(cdc) // Register crypto.[PubKey,PrivKey,Signature] types. + // ibc.RegisterWire(cdc) // Register ibc.[IBCTransferMsg, IBCReceiveMsg] types. + return cdc +} + +// custom logic for transaction decoding +func (app *DemocoinApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) { + var tx = sdk.StdTx{} + + if len(txBytes) == 0 { + return nil, sdk.ErrTxDecode("txBytes are empty") + } + + // StdTx.Msg is an interface. The concrete types + // are registered by MakeTxCodec in bank.RegisterWire. + err := app.cdc.UnmarshalBinary(txBytes, &tx) + if err != nil { + return nil, sdk.ErrTxDecode("").TraceCause(err, "") + } + return tx, nil +} + +// custom logic for democoin initialization +func (app *DemocoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { + stateJSON := req.AppStateBytes + + genesisState := new(types.GenesisState) + 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 _, gacc := range genesisState.Accounts { + acc, err := gacc.ToAppAccount() + if err != nil { + panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 + // return sdk.ErrGenesisParse("").TraceCause(err, "") + } + app.accountMapper.SetAccount(ctx, acc) + } + return abci.ResponseInitChain{} +} diff --git a/examples/democoin/app/app_test.go b/examples/democoin/app/app_test.go new file mode 100644 index 0000000000..d09b856aec --- /dev/null +++ b/examples/democoin/app/app_test.go @@ -0,0 +1,327 @@ +package app + +import ( + "encoding/json" + "fmt" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/examples/democoin/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/ibc" + + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" + dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" +) + +// Construct some global addrs and txs for tests. +var ( + chainID = "" // TODO + + priv1 = crypto.GenPrivKeyEd25519() + addr1 = priv1.PubKey().Address() + addr2 = crypto.GenPrivKeyEd25519().PubKey().Address() + coins = sdk.Coins{{"foocoin", 10}} + fee = sdk.StdFee{ + sdk.Coins{{"foocoin", 0}}, + 0, + } + + sendMsg = bank.SendMsg{ + Inputs: []bank.Input{bank.NewInput(addr1, coins)}, + Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, + } +) + +func loggerAndDBs() (log.Logger, map[string]dbm.DB) { + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") + dbs := map[string]dbm.DB{ + "main": dbm.NewMemDB(), + "acc": dbm.NewMemDB(), + "ibc": dbm.NewMemDB(), + "staking": dbm.NewMemDB(), + } + return logger, dbs +} + +func newDemocoinApp() *DemocoinApp { + logger, dbs := loggerAndDBs() + return NewDemocoinApp(logger, dbs) +} + +//_______________________________________________________________________ + +func TestMsgs(t *testing.T) { + bapp := newDemocoinApp() + + msgs := []struct { + msg sdk.Msg + }{ + {sendMsg}, + } + + sequences := []int64{0} + for i, m := range msgs { + sig := priv1.Sign(sdk.StdSignBytes(chainID, sequences, fee, m.msg)) + tx := sdk.NewStdTx(m.msg, fee, []sdk.StdSignature{{ + PubKey: priv1.PubKey(), + Signature: sig, + }}) + + // just marshal/unmarshal! + cdc := MakeCodec() + txBytes, err := cdc.MarshalBinary(tx) + require.NoError(t, err, "i: %v", i) + + // Run a Check + cres := bapp.CheckTx(txBytes) + assert.Equal(t, sdk.CodeUnknownAddress, + sdk.CodeType(cres.Code), "i: %v, log: %v", i, cres.Log) + + // Simulate a Block + bapp.BeginBlock(abci.RequestBeginBlock{}) + dres := bapp.DeliverTx(txBytes) + assert.Equal(t, sdk.CodeUnknownAddress, + sdk.CodeType(dres.Code), "i: %v, log: %v", i, dres.Log) + } +} + +func TestGenesis(t *testing.T) { + logger, dbs := loggerAndDBs() + bapp := NewDemocoinApp(logger, dbs) + + // Construct some genesis bytes to reflect democoin/types/AppAccount + pk := crypto.GenPrivKeyEd25519().PubKey() + addr := pk.Address() + coins, err := sdk.ParseCoins("77foocoin,99barcoin") + require.Nil(t, err) + baseAcc := auth.BaseAccount{ + Address: addr, + Coins: coins, + } + acc := &types.AppAccount{baseAcc, "foobart"} + + genesisState := map[string]interface{}{ + "accounts": []*types.GenesisAccount{ + types.NewGenesisAccount(acc), + }, + } + stateBytes, err := json.MarshalIndent(genesisState, "", "\t") + + vals := []abci.Validator{} + bapp.InitChain(abci.RequestInitChain{vals, stateBytes}) + bapp.Commit() + + // A checkTx context + ctx := bapp.BaseApp.NewContext(true, abci.Header{}) + res1 := bapp.accountMapper.GetAccount(ctx, baseAcc.Address) + assert.Equal(t, acc, res1) + + // reload app and ensure the account is still there + bapp = NewDemocoinApp(logger, dbs) + ctx = bapp.BaseApp.NewContext(true, abci.Header{}) + res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address) + assert.Equal(t, acc, res1) +} + +func TestSendMsgWithAccounts(t *testing.T) { + bapp := newDemocoinApp() + + // Construct some genesis bytes to reflect democoin/types/AppAccount + // Give 77 foocoin to the first key + coins, err := sdk.ParseCoins("77foocoin") + require.Nil(t, err) + baseAcc := auth.BaseAccount{ + Address: addr1, + Coins: coins, + } + acc1 := &types.AppAccount{baseAcc, "foobart"} + + // Construct genesis state + genesisState := map[string]interface{}{ + "accounts": []*types.GenesisAccount{ + types.NewGenesisAccount(acc1), + }, + } + stateBytes, err := json.MarshalIndent(genesisState, "", "\t") + require.Nil(t, err) + + // Initialize the chain + vals := []abci.Validator{} + bapp.InitChain(abci.RequestInitChain{vals, stateBytes}) + bapp.Commit() + + // A checkTx context (true) + ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) + res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, acc1, res1) + + // Sign the tx + sequences := []int64{0} + sig := priv1.Sign(sdk.StdSignBytes(chainID, sequences, fee, sendMsg)) + tx := sdk.NewStdTx(sendMsg, fee, []sdk.StdSignature{{ + PubKey: priv1.PubKey(), + Signature: sig, + }}) + + // Run a Check + res := bapp.Check(tx) + assert.Equal(t, sdk.CodeOK, res.Code, res.Log) + + // Simulate a Block + bapp.BeginBlock(abci.RequestBeginBlock{}) + res = bapp.Deliver(tx) + assert.Equal(t, sdk.CodeOK, res.Code, res.Log) + + // Check balances + ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) + res2 := bapp.accountMapper.GetAccount(ctxDeliver, addr1) + res3 := bapp.accountMapper.GetAccount(ctxDeliver, addr2) + assert.Equal(t, fmt.Sprintf("%v", res2.GetCoins()), "67foocoin") + assert.Equal(t, fmt.Sprintf("%v", res3.GetCoins()), "10foocoin") + + // Delivering again should cause replay error + res = bapp.Deliver(tx) + assert.Equal(t, sdk.CodeInvalidSequence, res.Code, res.Log) + + // bumping the txnonce number without resigning should be an auth error + tx.Signatures[0].Sequence = 1 + res = bapp.Deliver(tx) + assert.Equal(t, sdk.CodeUnauthorized, res.Code, res.Log) + + // resigning the tx with the bumped sequence should work + sequences = []int64{1} + sig = priv1.Sign(sdk.StdSignBytes(chainID, sequences, fee, tx.Msg)) + tx.Signatures[0].Signature = sig + res = bapp.Deliver(tx) + assert.Equal(t, sdk.CodeOK, res.Code, res.Log) +} + +func TestQuizMsg(t *testing.T) { + bapp := newDemocoinApp() + + // Construct genesis state + // Construct some genesis bytes to reflect democoin/types/AppAccount + coins := sdk.Coins{} + baseAcc := auth.BaseAccount{ + Address: addr1, + Coins: coins, + } + acc1 := &types.AppAccount{baseAcc, "foobart"} + + // Construct genesis state + genesisState := map[string]interface{}{ + "accounts": []*types.GenesisAccount{ + types.NewGenesisAccount(acc1), + }, + } + stateBytes, err := json.MarshalIndent(genesisState, "", "\t") + require.Nil(t, err) + + // Initialize the chain (nil) + vals := []abci.Validator{} + bapp.InitChain(abci.RequestInitChain{vals, stateBytes}) + bapp.Commit() + + // A checkTx context (true) + ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) + res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, acc1, res1) + +} + +func TestHandler(t *testing.T) { + bapp := newDemocoinApp() + + sourceChain := "source-chain" + destChain := "dest-chain" + + vals := []abci.Validator{} + baseAcc := auth.BaseAccount{ + Address: addr1, + Coins: coins, + } + acc1 := &types.AppAccount{baseAcc, "foobart"} + genesisState := map[string]interface{}{ + "accounts": []*types.GenesisAccount{ + types.NewGenesisAccount(acc1), + }, + } + stateBytes, err := json.MarshalIndent(genesisState, "", "\t") + require.Nil(t, err) + bapp.InitChain(abci.RequestInitChain{vals, stateBytes}) + bapp.Commit() + + // A checkTx context (true) + ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) + res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, acc1, res1) + + packet := ibc.IBCPacket{ + SrcAddr: addr1, + DestAddr: addr1, + Coins: coins, + SrcChain: sourceChain, + DestChain: destChain, + } + + transferMsg := ibc.IBCTransferMsg{ + IBCPacket: packet, + } + + receiveMsg := ibc.IBCReceiveMsg{ + IBCPacket: packet, + Relayer: addr1, + Sequence: 0, + } + + SignCheckDeliver(t, bapp, transferMsg, 0, true) + CheckBalance(t, bapp, "") + SignCheckDeliver(t, bapp, transferMsg, 1, false) + SignCheckDeliver(t, bapp, receiveMsg, 2, true) + CheckBalance(t, bapp, "10foocoin") + SignCheckDeliver(t, bapp, receiveMsg, 3, false) +} + +// TODO describe the use of this function +func SignCheckDeliver(t *testing.T, bapp *DemocoinApp, msg sdk.Msg, seq int64, expPass bool) { + + // Sign the tx + tx := sdk.NewStdTx(msg, fee, []sdk.StdSignature{{ + PubKey: priv1.PubKey(), + Signature: priv1.Sign(sdk.StdSignBytes(chainID, []int64{seq}, fee, msg)), + Sequence: seq, + }}) + + // Run a Check + res := bapp.Check(tx) + if expPass { + require.Equal(t, sdk.CodeOK, res.Code, res.Log) + } else { + require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + } + + // Simulate a Block + bapp.BeginBlock(abci.RequestBeginBlock{}) + res = bapp.Deliver(tx) + if expPass { + require.Equal(t, sdk.CodeOK, res.Code, res.Log) + } else { + require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + } + bapp.EndBlock(abci.RequestEndBlock{}) + //bapp.Commit() +} + +func CheckBalance(t *testing.T, bapp *DemocoinApp, balExpected string) { + ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) + res2 := bapp.accountMapper.GetAccount(ctxDeliver, addr1) + assert.Equal(t, balExpected, fmt.Sprintf("%v", res2.GetCoins())) +} diff --git a/examples/democoin/cmd/democli/main.go b/examples/democoin/cmd/democli/main.go new file mode 100644 index 0000000000..602e5478e9 --- /dev/null +++ b/examples/democoin/cmd/democli/main.go @@ -0,0 +1,91 @@ +package main + +import ( + "errors" + "os" + + "github.com/spf13/cobra" + + "github.com/tendermint/tmlibs/cli" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/keys" + "github.com/cosmos/cosmos-sdk/client/lcd" + "github.com/cosmos/cosmos-sdk/client/rpc" + "github.com/cosmos/cosmos-sdk/client/tx" + + "github.com/cosmos/cosmos-sdk/version" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" + bankcmd "github.com/cosmos/cosmos-sdk/x/bank/commands" + ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/commands" + simplestakingcmd "github.com/cosmos/cosmos-sdk/x/simplestake/commands" + + "github.com/cosmos/cosmos-sdk/examples/democoin/app" + "github.com/cosmos/cosmos-sdk/examples/democoin/types" +) + +// gaiacliCmd is the entry point for this binary +var ( + democliCmd = &cobra.Command{ + Use: "democli", + Short: "Democoin light-client", + } +) + +func todoNotImplemented(_ *cobra.Command, _ []string) error { + return errors.New("TODO: Command not yet implemented") +} + +func main() { + // disable sorting + cobra.EnableCommandSorting = false + + // get the codec + cdc := app.MakeCodec() + + // TODO: setup keybase, viper object, etc. to be passed into + // the below functions and eliminate global vars, like we do + // with the cdc + + // add standard rpc, and tx commands + rpc.AddCommands(democliCmd) + democliCmd.AddCommand(client.LineBreak) + tx.AddCommands(democliCmd, cdc) + democliCmd.AddCommand(client.LineBreak) + + // add query/post commands (custom to binary) + democliCmd.AddCommand( + client.GetCommands( + authcmd.GetAccountCmd("main", cdc, types.GetAccountDecoder(cdc)), + )...) + democliCmd.AddCommand( + client.PostCommands( + bankcmd.SendTxCmd(cdc), + )...) + democliCmd.AddCommand( + client.PostCommands( + ibccmd.IBCTransferCmd(cdc), + )...) + democliCmd.AddCommand( + client.PostCommands( + ibccmd.IBCRelayCmd(cdc), + simplestakingcmd.BondTxCmd(cdc), + )...) + democliCmd.AddCommand( + client.PostCommands( + simplestakingcmd.UnbondTxCmd(cdc), + )...) + + // add proxy, version and key info + democliCmd.AddCommand( + client.LineBreak, + lcd.ServeCommand(cdc), + keys.Commands(), + client.LineBreak, + version.VersionCmd, + ) + + // prepare and add flags + executor := cli.PrepareMainCmd(democliCmd, "BC", os.ExpandEnv("$HOME/.democli")) + executor.Execute() +} diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go new file mode 100644 index 0000000000..c2ee0a7c12 --- /dev/null +++ b/examples/democoin/cmd/democoind/main.go @@ -0,0 +1,98 @@ +package main + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + + "github.com/spf13/cobra" + + abci "github.com/tendermint/abci/types" + "github.com/tendermint/tmlibs/cli" + dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" + + "github.com/cosmos/cosmos-sdk/examples/democoin/app" + "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/version" +) + +// democoindCmd is the entry point for this binary +var ( + democoindCmd = &cobra.Command{ + Use: "democoind", + Short: "Gaia Daemon (server)", + } +) + +// defaultOptions sets up the app_options for the +// default genesis file +func defaultOptions(args []string) (json.RawMessage, error) { + addr, secret, err := server.GenerateCoinKey() + if err != nil { + return nil, err + } + fmt.Println("Secret phrase to access coins:") + fmt.Println(secret) + + opts := fmt.Sprintf(`{ + "accounts": [{ + "address": "%s", + "coins": [ + { + "denom": "mycoin", + "amount": 9007199254740992 + } + ] + }] + }`, addr) + return json.RawMessage(opts), nil +} + +func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { + dbMain, err := dbm.NewGoLevelDB("democoin", filepath.Join(rootDir, "data")) + if err != nil { + return nil, err + } + dbAcc, err := dbm.NewGoLevelDB("democoin-acc", filepath.Join(rootDir, "data")) + if err != nil { + return nil, err + } + dbIBC, err := dbm.NewGoLevelDB("democoin-ibc", filepath.Join(rootDir, "data")) + if err != nil { + return nil, err + } + dbStaking, err := dbm.NewGoLevelDB("democoin-staking", filepath.Join(rootDir, "data")) + if err != nil { + return nil, err + } + dbs := map[string]dbm.DB{ + "main": dbMain, + "acc": dbAcc, + "ibc": dbIBC, + "staking": dbStaking, + } + bapp := app.NewDemocoinApp(logger, dbs) + return bapp, nil +} + +func main() { + // TODO: set logger through CLI + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)). + With("module", "main") + + democoindCmd.AddCommand( + server.InitCmd(defaultOptions, logger), + server.StartCmd(generateApp, logger), + server.UnsafeResetAllCmd(logger), + server.ShowNodeIdCmd(logger), + server.ShowValidatorCmd(logger), + version.VersionCmd, + ) + + // prepare and add flags + rootDir := os.ExpandEnv("$HOME/.democoind") + executor := cli.PrepareBaseCmd(democoindCmd, "BC", rootDir) + executor.Execute() +} diff --git a/examples/democoin/types/account.go b/examples/democoin/types/account.go new file mode 100644 index 0000000000..f34113fc65 --- /dev/null +++ b/examples/democoin/types/account.go @@ -0,0 +1,72 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" +) + +var _ sdk.Account = (*AppAccount)(nil) + +// Custom extensions for this application. This is just an example of +// extending auth.BaseAccount with custom fields. +// +// This is compatible with the stock auth.AccountStore, since +// auth.AccountStore uses the flexible go-wire library. +type AppAccount struct { + auth.BaseAccount + Name string `json:"name"` +} + +// nolint +func (acc AppAccount) GetName() string { return acc.Name } +func (acc *AppAccount) SetName(name string) { acc.Name = name } + +// Get the AccountDecoder function for the custom AppAccount +func GetAccountDecoder(cdc *wire.Codec) sdk.AccountDecoder { + return func(accBytes []byte) (res sdk.Account, err error) { + if len(accBytes) == 0 { + return nil, sdk.ErrTxDecode("accBytes are empty") + } + acct := new(AppAccount) + err = cdc.UnmarshalBinary(accBytes, &acct) + if err != nil { + panic(err) + } + return acct, err + } +} + +//___________________________________________________________________________________ + +// State to Unmarshal +type GenesisState struct { + Accounts []*GenesisAccount `json:"accounts"` +} + +// GenesisAccount doesn't need pubkey or sequence +type GenesisAccount struct { + Name string `json:"name"` + Address sdk.Address `json:"address"` + Coins sdk.Coins `json:"coins"` +} + +func NewGenesisAccount(aa *AppAccount) *GenesisAccount { + return &GenesisAccount{ + Name: aa.Name, + Address: aa.Address, + Coins: aa.Coins, + } +} + +// convert GenesisAccount to AppAccount +func (ga *GenesisAccount) ToAppAccount() (acc *AppAccount, err error) { + baseAcc := auth.BaseAccount{ + Address: ga.Address, + Coins: ga.Coins, + } + return &AppAccount{ + BaseAccount: baseAcc, + Name: ga.Name, + }, nil +} diff --git a/examples/basecoin/x/cool/commands/tx.go b/examples/democoin/x/cool/commands/tx.go similarity index 97% rename from examples/basecoin/x/cool/commands/tx.go rename to examples/democoin/x/cool/commands/tx.go index c2d643a905..ab817309cf 100644 --- a/examples/basecoin/x/cool/commands/tx.go +++ b/examples/democoin/x/cool/commands/tx.go @@ -11,7 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/builder" "github.com/cosmos/cosmos-sdk/wire" - "github.com/cosmos/cosmos-sdk/examples/basecoin/x/cool" + "github.com/cosmos/cosmos-sdk/examples/democoin/x/cool" ) // take the coolness quiz transaction diff --git a/examples/basecoin/x/cool/errors.go b/examples/democoin/x/cool/errors.go similarity index 100% rename from examples/basecoin/x/cool/errors.go rename to examples/democoin/x/cool/errors.go diff --git a/examples/basecoin/x/cool/handler.go b/examples/democoin/x/cool/handler.go similarity index 100% rename from examples/basecoin/x/cool/handler.go rename to examples/democoin/x/cool/handler.go diff --git a/examples/basecoin/x/cool/keeper.go b/examples/democoin/x/cool/keeper.go similarity index 100% rename from examples/basecoin/x/cool/keeper.go rename to examples/democoin/x/cool/keeper.go diff --git a/examples/basecoin/x/cool/types.go b/examples/democoin/x/cool/types.go similarity index 100% rename from examples/basecoin/x/cool/types.go rename to examples/democoin/x/cool/types.go diff --git a/examples/basecoin/x/sketchy/handler.go b/examples/democoin/x/sketchy/handler.go similarity index 100% rename from examples/basecoin/x/sketchy/handler.go rename to examples/democoin/x/sketchy/handler.go From c8bba0545b69660b9195859615de44b9f8b106c9 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 30 Mar 2018 20:23:24 +0200 Subject: [PATCH 14/16] Add back cool module tests to democoin --- examples/democoin/app/app.go | 7 ++++ examples/democoin/app/app_test.go | 55 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 9c77c4735c..a15bea1dd2 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -18,6 +18,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/simplestake" "github.com/cosmos/cosmos-sdk/examples/democoin/types" + "github.com/cosmos/cosmos-sdk/examples/democoin/x/cool" + "github.com/cosmos/cosmos-sdk/examples/democoin/x/sketchy" ) const ( @@ -58,10 +60,13 @@ func NewDemocoinApp(logger log.Logger, dbs map[string]dbm.DB) *DemocoinApp { // add handlers coinKeeper := bank.NewCoinKeeper(app.accountMapper) + coolKeeper := cool.NewKeeper(app.capKeyMainStore, coinKeeper) ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper) app.Router(). AddRoute("bank", bank.NewHandler(coinKeeper), nil). + AddRoute("cool", cool.NewHandler(coolKeeper), coolKeeper.InitGenesis). + AddRoute("sketchy", sketchy.NewHandler(), nil). AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper), nil). AddRoute("simplestake", simplestake.NewHandler(stakeKeeper), nil) @@ -98,6 +103,8 @@ func MakeCodec() *wire.Codec { struct{ sdk.Msg }{}, oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend}, oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue}, + oldwire.ConcreteType{cool.QuizMsg{}, msgTypeQuiz}, + oldwire.ConcreteType{cool.SetTrendMsg{}, msgTypeSetTrend}, oldwire.ConcreteType{ibc.IBCTransferMsg{}, msgTypeIBCTransferMsg}, oldwire.ConcreteType{ibc.IBCReceiveMsg{}, msgTypeIBCReceiveMsg}, oldwire.ConcreteType{simplestake.BondMsg{}, msgTypeBondMsg}, diff --git a/examples/democoin/app/app_test.go b/examples/democoin/app/app_test.go index d09b856aec..bf2ddc232f 100644 --- a/examples/democoin/app/app_test.go +++ b/examples/democoin/app/app_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/examples/democoin/types" + "github.com/cosmos/cosmos-sdk/examples/democoin/x/cool" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" @@ -38,6 +39,31 @@ var ( Inputs: []bank.Input{bank.NewInput(addr1, coins)}, Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, } + + quizMsg1 = cool.QuizMsg{ + Sender: addr1, + CoolAnswer: "icecold", + } + + quizMsg2 = cool.QuizMsg{ + Sender: addr1, + CoolAnswer: "badvibesonly", + } + + setTrendMsg1 = cool.SetTrendMsg{ + Sender: addr1, + Cool: "icecold", + } + + setTrendMsg2 = cool.SetTrendMsg{ + Sender: addr1, + Cool: "badvibesonly", + } + + setTrendMsg3 = cool.SetTrendMsg{ + Sender: addr1, + Cool: "warmandkind", + } ) func loggerAndDBs() (log.Logger, map[string]dbm.DB) { @@ -65,6 +91,8 @@ func TestMsgs(t *testing.T) { msg sdk.Msg }{ {sendMsg}, + {quizMsg1}, + {setTrendMsg1}, } sequences := []int64{0} @@ -112,6 +140,9 @@ func TestGenesis(t *testing.T) { "accounts": []*types.GenesisAccount{ types.NewGenesisAccount(acc), }, + "cool": map[string]string{ + "trend": "ice-cold", + }, } stateBytes, err := json.MarshalIndent(genesisState, "", "\t") @@ -149,6 +180,9 @@ func TestSendMsgWithAccounts(t *testing.T) { "accounts": []*types.GenesisAccount{ types.NewGenesisAccount(acc1), }, + "cool": map[string]string{ + "trend": "ice-cold", + }, } stateBytes, err := json.MarshalIndent(genesisState, "", "\t") require.Nil(t, err) @@ -221,6 +255,9 @@ func TestQuizMsg(t *testing.T) { "accounts": []*types.GenesisAccount{ types.NewGenesisAccount(acc1), }, + "cool": map[string]string{ + "trend": "ice-cold", + }, } stateBytes, err := json.MarshalIndent(genesisState, "", "\t") require.Nil(t, err) @@ -235,6 +272,21 @@ func TestQuizMsg(t *testing.T) { res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) assert.Equal(t, acc1, res1) + // Set the trend, submit a really cool quiz and check for reward + SignCheckDeliver(t, bapp, setTrendMsg1, 0, true) + SignCheckDeliver(t, bapp, quizMsg1, 1, true) + CheckBalance(t, bapp, "69icecold") + SignCheckDeliver(t, bapp, quizMsg2, 2, false) // result without reward + CheckBalance(t, bapp, "69icecold") + SignCheckDeliver(t, bapp, quizMsg1, 3, true) + CheckBalance(t, bapp, "138icecold") + SignCheckDeliver(t, bapp, setTrendMsg2, 4, true) // reset the trend + SignCheckDeliver(t, bapp, quizMsg1, 5, false) // the same answer will nolonger do! + CheckBalance(t, bapp, "138icecold") + SignCheckDeliver(t, bapp, quizMsg2, 6, true) // earlier answer now relavent again + CheckBalance(t, bapp, "69badvibesonly,138icecold") + SignCheckDeliver(t, bapp, setTrendMsg3, 7, false) // expect to fail to set the trend to something which is not cool + } func TestHandler(t *testing.T) { @@ -253,6 +305,9 @@ func TestHandler(t *testing.T) { "accounts": []*types.GenesisAccount{ types.NewGenesisAccount(acc1), }, + "cool": map[string]string{ + "trend": "ice-cold", + }, } stateBytes, err := json.MarshalIndent(genesisState, "", "\t") require.Nil(t, err) From 20bb78399bf36f33fc24552820db34ac69190b09 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 31 Mar 2018 19:01:54 +0300 Subject: [PATCH 15/16] fix democoin --- examples/democoin/cmd/democoind/main.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index c2ee0a7c12..d9421954c9 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -10,6 +10,7 @@ import ( abci "github.com/tendermint/abci/types" "github.com/tendermint/tmlibs/cli" + cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -28,10 +29,10 @@ var ( // defaultOptions sets up the app_options for the // default genesis file -func defaultOptions(args []string) (json.RawMessage, error) { +func defaultOptions(args []string) (json.RawMessage, string, cmn.HexBytes, error) { addr, secret, err := server.GenerateCoinKey() if err != nil { - return nil, err + return nil, "", nil, err } fmt.Println("Secret phrase to access coins:") fmt.Println(secret) @@ -47,7 +48,7 @@ func defaultOptions(args []string) (json.RawMessage, error) { ] }] }`, addr) - return json.RawMessage(opts), nil + return json.RawMessage(opts), "", nil, nil } func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { From 24e1bb4f24d6fcfd29fed4fbb658d05fac699857 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 31 Mar 2018 19:13:34 +0300 Subject: [PATCH 16/16] make install --- Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Makefile b/Makefile index c99fb7b3f2..023e4f8c62 100644 --- a/Makefile +++ b/Makefile @@ -32,6 +32,12 @@ else go build $(BUILD_FLAGS) -o build/democli ./examples/democoin/cmd/democli endif +install: + go install $(BUILD_FLAGS) ./examples/basecoin/cmd/basecoind + go install $(BUILD_FLAGS) ./examples/basecoin/cmd/basecli + go install $(BUILD_FLAGS) ./examples/democoin/cmd/democoind + go install $(BUILD_FLAGS) ./examples/democoin/cmd/democli + dist: @bash publish/dist.sh @bash publish/publish.sh