diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 5ac7be1b50..e92f58bdcc 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -19,7 +19,7 @@ import ( var mainHeaderKey = []byte("header") -// BaseApp - The ABCI application +// The ABCI application type BaseApp struct { logger log.Logger @@ -32,33 +32,38 @@ type BaseApp struct { // Main (uncached) state cms sdk.CommitMultiStore - // Unmarshal []byte into sdk.Tx + // unmarshal []byte into sdk.Tx txDecoder sdk.TxDecoder - // Ante handler for fee and auth. + // unmarshal rawjsonbytes to initialize the application + // TODO unexpose and call from InitChain + InitStater sdk.InitStater + + // ante handler for fee and auth defaultAnteHandler sdk.AnteHandler - // Handle any kind of message. + // handle any kind of message router Router //-------------------- // Volatile - // CheckTx state, a cache-wrap of `.cms`. + // CheckTx state, a cache-wrap of `.cms` msCheck sdk.CacheMultiStore - // DeliverTx state, a cache-wrap of `.cms`. + // DeliverTx state, a cache-wrap of `.cms` msDeliver sdk.CacheMultiStore - // Current block header + // current block header header *abci.Header - // Cached validator changes from DeliverTx. + // cached validator changes from DeliverTx valUpdates []abci.Validator } var _ abci.Application = &BaseApp{} +// Create and name new BaseApp func NewBaseApp(name string) *BaseApp { var baseapp = &BaseApp{ logger: makeDefaultLogger(), @@ -88,22 +93,26 @@ func (app *BaseApp) initMultiStore() { app.cms = cms } +// BaseApp Name func (app *BaseApp) Name() string { return app.name } +// 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 func (app *BaseApp) SetTxDecoder(txDecoder sdk.TxDecoder) { app.txDecoder = txDecoder } - +func (app *BaseApp) SetInitStater(initStater sdk.InitStater) { + app.InitStater = initStater +} func (app *BaseApp) SetDefaultAnteHandler(ah sdk.AnteHandler) { app.defaultAnteHandler = ah } - func (app *BaseApp) Router() Router { return app.router } @@ -111,14 +120,15 @@ func (app *BaseApp) Router() Router { /* TODO consider: func (app *BaseApp) SetBeginBlocker(...) {} func (app *BaseApp) SetEndBlocker(...) {} -func (app *BaseApp) SetInitStater(...) {} */ +// TODO add description func (app *BaseApp) LoadLatestVersion(mainKey sdk.StoreKey) error { app.cms.LoadLatestVersion() return app.initFromStore(mainKey) } +// Load application version func (app *BaseApp) LoadVersion(version int64, mainKey sdk.StoreKey) error { app.cms.LoadVersion(version) return app.initFromStore(mainKey) @@ -174,7 +184,7 @@ func (app *BaseApp) initFromStore(mainKey sdk.StoreKey) error { //---------------------------------------- -// Implements ABCI. +// Implements ABCI func (app *BaseApp) Info(req abci.RequestInfo) abci.ResponseInfo { lastCommitID := app.cms.LastCommitID() @@ -186,15 +196,16 @@ func (app *BaseApp) Info(req abci.RequestInfo) abci.ResponseInfo { } } -// Implements ABCI. +// Implements ABCI func (app *BaseApp) SetOption(req abci.RequestSetOption) (res abci.ResponseSetOption) { // TODO: Implement return } -// Implements ABCI. +// Implements ABCI func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitChain) { // TODO: Use req.Validators + // TODO: Use req.AppStateJSON (?) return } @@ -209,7 +220,7 @@ func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) { return queryable.Query(req) } -// Implements ABCI. +// Implements ABCI func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeginBlock) { // NOTE: For consistency we should unset these upon EndBlock. app.header = &req.Header @@ -219,7 +230,7 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg return } -// Implements ABCI. +// Implements ABCI func (app *BaseApp) CheckTx(txBytes []byte) (res abci.ResponseCheckTx) { // Decode the Tx. @@ -245,7 +256,7 @@ func (app *BaseApp) CheckTx(txBytes []byte) (res abci.ResponseCheckTx) { } -// Implements ABCI. +// Implements ABCI func (app *BaseApp) DeliverTx(txBytes []byte) (res abci.ResponseDeliverTx) { // Decode the Tx. @@ -333,7 +344,7 @@ func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk return result } -// Implements ABCI. +// Implements ABCI func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBlock) { res.ValidatorUpdates = app.valUpdates app.valUpdates = nil @@ -343,7 +354,7 @@ func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBloc return } -// Implements ABCI. +// Implements ABCI func (app *BaseApp) Commit() (res abci.ResponseCommit) { app.msDeliver.Write() commitID := app.cms.Commit() @@ -361,9 +372,8 @@ func (app *BaseApp) Commit() (res abci.ResponseCommit) { func (app *BaseApp) getMultiStore(isCheckTx bool) sdk.MultiStore { if isCheckTx { return app.msCheck - } else { - return app.msDeliver } + return app.msDeliver } // Return index of list with validator of same PubKey, or -1 if no match diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index 6e0f6c8e28..7ceaacd203 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -106,7 +106,7 @@ func TestBasic(t *testing.T) { } // Not matched. - j += 1 + j++ } } assert.Equal(t, len(valUpdates), 0, "Some validator updates were unexpected") diff --git a/baseapp/context.go b/baseapp/context.go index 281220665b..e5a60f9674 100644 --- a/baseapp/context.go +++ b/baseapp/context.go @@ -1,6 +1,8 @@ package baseapp -import sdk "github.com/cosmos/cosmos-sdk/types" +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) // NewContext returns a new Context suitable for AnteHandler (and indirectly Handler) processing. // NOTE: txBytes may be nil to support TestApp.RunCheckTx @@ -12,6 +14,7 @@ func (app *BaseApp) NewContext(isCheckTx bool, txBytes []byte) sdk.Context { } else { store = app.msDeliver } + if store == nil { panic("BaseApp.NewContext() requires BeginBlock(): missing store") } diff --git a/baseapp/genesis.go b/baseapp/genesis.go new file mode 100644 index 0000000000..b2dad3e334 --- /dev/null +++ b/baseapp/genesis.go @@ -0,0 +1,32 @@ +package baseapp + +import ( + "encoding/json" + "io/ioutil" +) + +// TODO: remove from here and pass the AppState +// through InitChain + +// GenesisDoc defines the initial conditions for a tendermint blockchain, in particular its validator set. +type GenesisDoc struct { + AppState json.RawMessage `json:"app_state,omitempty"` +} + +// GenesisDocFromFile reads JSON data from a file and unmarshalls it into a GenesisDoc. +func GenesisDocFromFile(genDocFile string) (*GenesisDoc, error) { + if genDocFile == "" { + var g GenesisDoc + return &g, nil + } + jsonBlob, err := ioutil.ReadFile(genDocFile) + if err != nil { + return nil, err + } + genDoc := GenesisDoc{} + err = json.Unmarshal(jsonBlob, &genDoc) + if err != nil { + return nil, err + } + return &genDoc, nil +} diff --git a/baseapp/router.go b/baseapp/router.go index a15be84515..2f27d7a544 100644 --- a/baseapp/router.go +++ b/baseapp/router.go @@ -6,6 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +// Router - TODO add description type Router interface { AddRoute(r string, h sdk.Handler) Route(path string) (h sdk.Handler) @@ -20,6 +21,9 @@ type router struct { routes []route } +// nolint +// NewRouter - create new router +// TODO either make Function unexported or make return type (router) Exported func NewRouter() *router { return &router{ routes: make([]route, 0), @@ -28,6 +32,7 @@ func NewRouter() *router { var isAlpha = regexp.MustCompile(`^[a-zA-Z]+$`).MatchString +// AddRoute - TODO add description func (rtr *router) AddRoute(r string, h sdk.Handler) { if !isAlpha(r) { panic("route expressions can only contain alphanumeric characters") @@ -35,6 +40,7 @@ func (rtr *router) AddRoute(r string, h sdk.Handler) { rtr.routes = append(rtr.routes, route{r, h}) } +// Route - TODO add description // TODO handle expressive matches. func (rtr *router) Route(path string) (h sdk.Handler) { for _, route := range rtr.routes { diff --git a/baseapp/testapp.go b/baseapp/testapp.go index c8708e222d..389593d65a 100644 --- a/baseapp/testapp.go +++ b/baseapp/testapp.go @@ -24,6 +24,7 @@ func NewTestApp(bapp *BaseApp) *TestApp { return app } +// execute BaseApp BeginBlock func (tapp *TestApp) RunBeginBlock() { if tapp.header != nil { panic("TestApp.header not nil, BeginBlock already run, or EndBlock not yet run.") @@ -56,36 +57,43 @@ func (tapp *TestApp) ensureBeginBlock() { } } +// run tx through CheckTx of TestApp func (tapp *TestApp) RunCheckTx(tx sdk.Tx) sdk.Result { tapp.ensureBeginBlock() return tapp.BaseApp.runTx(true, nil, tx) } +// run tx through DeliverTx of TestApp func (tapp *TestApp) RunDeliverTx(tx sdk.Tx) sdk.Result { tapp.ensureBeginBlock() return tapp.BaseApp.runTx(false, nil, tx) } +// run tx through CheckTx of TestApp // NOTE: Skips authentication by wrapping msg in testTx{}. func (tapp *TestApp) RunCheckMsg(msg sdk.Msg) sdk.Result { var tx = testTx{msg} return tapp.RunCheckTx(tx) } +// run tx through DeliverTx of TestApp // NOTE: Skips authentication by wrapping msg in testTx{}. func (tapp *TestApp) RunDeliverMsg(msg sdk.Msg) sdk.Result { var tx = testTx{msg} return tapp.RunDeliverTx(tx) } +// return the commited multistore func (tapp *TestApp) CommitMultiStore() sdk.CommitMultiStore { return tapp.BaseApp.cms } +// return a cache-wrap CheckTx state of multistore func (tapp *TestApp) MultiStoreCheck() sdk.MultiStore { return tapp.BaseApp.msCheck } +// return a cache-wrap DeliverTx state of multistore func (tapp *TestApp) MultiStoreDeliver() sdk.MultiStore { return tapp.BaseApp.msDeliver } @@ -97,11 +105,11 @@ type testTx struct { sdk.Msg } +// nolint func (tx testTx) GetMsg() sdk.Msg { return tx.Msg } func (tx testTx) GetSigners() []crypto.Address { return nil } func (tx testTx) GetFeePayer() crypto.Address { return nil } func (tx testTx) GetSignatures() []sdk.StdSignature { return nil } - func IsTestAppTx(tx sdk.Tx) bool { _, ok := tx.(testTx) return ok diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index e87a2d7965..4f26d49445 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -6,18 +6,21 @@ import ( bam "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/tendermint/abci/server" + abci "github.com/tendermint/abci/types" "github.com/tendermint/go-wire" cmn "github.com/tendermint/tmlibs/common" ) const appName = "BasecoinApp" +// BasecoinApp - extended ABCI application type BasecoinApp struct { *bam.BaseApp router bam.Router cdc *wire.Codec - multiStore sdk.CommitMultiStore + multiStore sdk.CommitMultiStore //TODO distinguish this store from *bam.BaseApp.cms <- is this one master?? confused // The key to access the substores. capKeyMainStore *sdk.KVStoreKey @@ -27,25 +30,44 @@ type BasecoinApp struct { accountMapper sdk.AccountMapper } +// NewBasecoinApp - create new BasecoinApp // TODO: This should take in more configuration options. -func NewBasecoinApp() *BasecoinApp { +// TODO: This should be moved into baseapp to isolate complexity +func NewBasecoinApp(genesisPath string) *BasecoinApp { // Create and configure app. var app = &BasecoinApp{} - app.initCapKeys() // ./init_capkeys.go - app.initBaseApp() // ./init_baseapp.go - app.initStores() // ./init_stores.go + + // TODO open up out of functions, or introduce clarity, + // interdependancies are a nightmare to debug + app.initCapKeys() // ./init_capkeys.go + app.initBaseApp() // ./init_baseapp.go + app.initStores() // ./init_stores.go + app.initBaseAppInitStater() app.initHandlers() // ./init_handlers.go - // TODO: Load genesis - // TODO: InitChain with validators - // TODO: Set the genesis accounts + genesisiDoc, err := bam.GenesisDocFromFile(genesisPath) + if err != nil { + panic(fmt.Errorf("error loading genesis state: %v", err)) + } + + // set up the cache store for ctx, get ctx + // TODO: can InitChain handle this too ? + app.BaseApp.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{}}) + ctx := app.BaseApp.NewContext(false, nil) // context for DeliverTx + + // TODO: combine with InitChain and let tendermint invoke it. + err = app.BaseApp.InitStater(ctx, genesisiDoc.AppState) + if err != nil { + panic(fmt.Errorf("error initializing application genesis state: %v", err)) + } app.loadStores() return app } +// RunForever - BasecoinApp execution and cleanup func (app *BasecoinApp) RunForever() { // Start the ABCI server @@ -64,7 +86,7 @@ func (app *BasecoinApp) RunForever() { } -// Load the stores. +// Load the stores func (app *BasecoinApp) loadStores() { if err := app.LoadLatestVersion(app.capKeyMainStore); err != nil { fmt.Println(err) diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index 206257d2cc..ce071eeeda 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -1,11 +1,17 @@ package app import ( + "encoding/json" "testing" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/bank" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/examples/basecoin/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/bank" + crypto "github.com/tendermint/go-crypto" ) @@ -37,4 +43,32 @@ func TestSendMsg(t *testing.T) { // Run a Deliver on SendMsg. res = tba.RunDeliverMsg(msg) assert.Equal(t, sdk.CodeUnrecognizedAddress, res.Code, res.Log) + + // TODO seperate this test, need a closer on db? keep getting resource unavailable + + // construct some genesis bytes to reflect basecoin/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 := GenesisState{ + Accounts: []*GenesisAccount{ + NewGenesisAccount(acc), + }, + } + bytes, err := json.MarshalIndent(genesisState, "", "\t") + + app := tba.BasecoinApp + ctx := app.BaseApp.NewContext(false, nil) // context for DeliverTx + err = app.BaseApp.InitStater(ctx, bytes) + require.Nil(t, err) + + res1 := app.accountMapper.GetAccount(ctx, baseAcc.Address) + assert.Equal(t, acc, res1) } diff --git a/examples/basecoin/app/init_baseapp.go b/examples/basecoin/app/init_baseapp.go index 35033aa99d..c1fcb94c6b 100644 --- a/examples/basecoin/app/init_baseapp.go +++ b/examples/basecoin/app/init_baseapp.go @@ -1,8 +1,13 @@ package app import ( + "encoding/json" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/examples/basecoin/types" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + crypto "github.com/tendermint/go-crypto" ) // initCapKeys, initBaseApp, initStores, initHandlers. @@ -11,6 +16,7 @@ func (app *BasecoinApp) initBaseApp() { app.BaseApp = bapp app.router = bapp.Router() app.initBaseAppTxDecoder() + app.initBaseAppInitStater() } func (app *BasecoinApp) initBaseAppTxDecoder() { @@ -26,3 +32,62 @@ func (app *BasecoinApp) initBaseAppTxDecoder() { return tx, nil }) } + +// define the custom logic for basecoin initialization +func (app *BasecoinApp) initBaseAppInitStater() { + accountMapper := app.accountMapper + + app.BaseApp.SetInitStater(func(ctx sdk.Context, state json.RawMessage) sdk.Error { + if state == nil { + return nil + } + + genesisState := new(GenesisState) + err := json.Unmarshal(state, genesisState) + if err != nil { + return sdk.ErrGenesisParse("").TraceCause(err, "") + } + + for _, gacc := range genesisState.Accounts { + acc, err := gacc.toAppAccount() + if err != nil { + return sdk.ErrGenesisParse("").TraceCause(err, "") + } + accountMapper.SetAccount(ctx, acc) + } + return nil + }) +} + +//----------------------------------------------------- + +type GenesisState struct { + Accounts []*GenesisAccount `accounts` +} + +// GenesisAccount doesn't need pubkey or sequence +type GenesisAccount struct { + Name string `json:"name"` + Address crypto.Address `json:"address"` + Coins sdk.Coins `json:"coins"` +} + +func NewGenesisAccount(aa *types.AppAccount) *GenesisAccount { + return &GenesisAccount{ + Name: aa.Name, + Address: aa.Address, + Coins: aa.Coins, + } +} + +// convert GenesisAccount to AppAccount +func (ga *GenesisAccount) toAppAccount() (acc *types.AppAccount, err error) { + baseAcc := auth.BaseAccount{ + Address: ga.Address, + Coins: ga.Coins, + } + return &types.AppAccount{ + BaseAccount: baseAcc, + Name: ga.Name, + }, nil +} diff --git a/examples/basecoin/app/testapp.go b/examples/basecoin/app/testapp.go index 544c48c0f7..8603911d51 100644 --- a/examples/basecoin/app/testapp.go +++ b/examples/basecoin/app/testapp.go @@ -10,7 +10,7 @@ type testBasecoinApp struct { } func newTestBasecoinApp() *testBasecoinApp { - app := NewBasecoinApp() + app := NewBasecoinApp("") tba := &testBasecoinApp{ BasecoinApp: app, } diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index cde9de191a..623bb35e45 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -1,9 +1,10 @@ package main -import ( - "fmt" -) +import "github.com/cosmos/cosmos-sdk/examples/basecoin/app" func main() { - fmt.Println("TODO: move examples/basecoin/main.go here and refactor") + // TODO CREATE CLI + + bapp := app.NewBasecoinApp("") + bapp.RunForever() } diff --git a/types/coin.go b/types/coin.go index 620c2f2891..ad541b99bd 100644 --- a/types/coin.go +++ b/types/coin.go @@ -184,6 +184,7 @@ func (coins Coins) IsNotNegative() bool { return true } +// Returns the amount of a denom from coins func (coins Coins) AmountOf(denom string) int64 { switch len(coins) { case 0: @@ -192,9 +193,8 @@ func (coins Coins) AmountOf(denom string) int64 { coin := coins[0] if coin.Denom == denom { return coin.Amount - } else { - return 0 } + return 0 default: midIdx := len(coins) / 2 // 2:1, 3:1, 4:2 coin := coins[midIdx] diff --git a/types/coin_test.go b/types/coin_test.go index 03890aa3fa..b58578a25f 100644 --- a/types/coin_test.go +++ b/types/coin_test.go @@ -192,7 +192,7 @@ func TestAmountOf(t *testing.T) { cases := []struct { coins Coins amountOf int64 - amountOf_ int64 + amountOfSpace int64 amountOfGAS int64 amountOfMINERAL int64 amountOfTREE int64 @@ -210,7 +210,7 @@ func TestAmountOf(t *testing.T) { for _, tc := range cases { assert.Equal(t, tc.amountOf, tc.coins.AmountOf("")) - assert.Equal(t, tc.amountOf_, tc.coins.AmountOf(" ")) + assert.Equal(t, tc.amountOfSpace, tc.coins.AmountOf(" ")) assert.Equal(t, tc.amountOfGAS, tc.coins.AmountOf("GAS")) assert.Equal(t, tc.amountOfMINERAL, tc.coins.AmountOf("MINERAL")) assert.Equal(t, tc.amountOfTREE, tc.coins.AmountOf("TREE")) diff --git a/types/context.go b/types/context.go index 4dbf64c3e2..3c90b016a2 100644 --- a/types/context.go +++ b/types/context.go @@ -30,6 +30,7 @@ type Context struct { // it's probably not what you want to do. } +// create a new context func NewContext(ms MultiStore, header abci.Header, isCheckTx bool, txBytes []byte) Context { c := Context{ Context: context.Background(), @@ -45,6 +46,7 @@ func NewContext(ms MultiStore, header abci.Header, isCheckTx bool, txBytes []byt return c } +// is context nil func (c Context) IsZero() bool { return c.Context == nil } @@ -52,6 +54,7 @@ func (c Context) IsZero() bool { //---------------------------------------- // Getting a value +// context value for the provided key func (c Context) Value(key interface{}) interface{} { value := c.Context.Value(key) if cloner, ok := value.(cloner); ok { @@ -71,34 +74,28 @@ func (c Context) KVStore(key StoreKey) KVStore { //---------------------------------------- // With* (setting a value) +// nolint func (c Context) WithValue(key interface{}, value interface{}) Context { return c.withValue(key, value) } - func (c Context) WithCloner(key interface{}, value cloner) Context { return c.withValue(key, value) } - func (c Context) WithCacheWrapper(key interface{}, value CacheWrapper) Context { return c.withValue(key, value) } - func (c Context) WithProtoMsg(key interface{}, value proto.Message) Context { return c.withValue(key, value) } - func (c Context) WithString(key interface{}, value string) Context { return c.withValue(key, value) } - func (c Context) WithInt32(key interface{}, value int32) Context { return c.withValue(key, value) } - func (c Context) WithUint32(key interface{}, value uint32) Context { return c.withValue(key, value) } - func (c Context) WithUint64(key interface{}, value uint64) Context { return c.withValue(key, value) } @@ -138,47 +135,38 @@ func (c Context) multiStore() MultiStore { return c.Value(contextKeyMultiStore).(MultiStore) } +// nolint func (c Context) BlockHeader() abci.Header { return c.Value(contextKeyBlockHeader).(abci.Header) } - func (c Context) BlockHeight() int64 { return c.Value(contextKeyBlockHeight).(int64) } - func (c Context) ChainID() string { return c.Value(contextKeyChainID).(string) } - func (c Context) IsCheckTx() bool { return c.Value(contextKeyIsCheckTx).(bool) } - func (c Context) TxBytes() []byte { return c.Value(contextKeyTxBytes).([]byte) } - func (c Context) WithMultiStore(ms MultiStore) Context { return c.withValue(contextKeyMultiStore, ms) } - func (c Context) WithBlockHeader(header abci.Header) Context { var _ proto.Message = &header // for cloning. return c.withValue(contextKeyBlockHeader, header) } - func (c Context) WithBlockHeight(height int64) Context { return c.withValue(contextKeyBlockHeight, height) } - func (c Context) WithChainID(chainID string) Context { return c.withValue(contextKeyChainID, chainID) } - func (c Context) WithIsCheckTx(isCheckTx bool) Context { return c.withValue(contextKeyIsCheckTx, isCheckTx) } - func (c Context) WithTxBytes(txBytes []byte) Context { return c.withValue(contextKeyTxBytes, txBytes) } @@ -199,6 +187,7 @@ type cloner interface { Clone() interface{} // deep copy } +// XXX add description type Op struct { // type is always 'with' gen int @@ -221,7 +210,7 @@ func newThePast() *thePast { func (pst *thePast) bump(op Op) { pst.mtx.Lock() - pst.ver += 1 + pst.ver++ pst.ops = append(pst.ops, op) pst.mtx.Unlock() } @@ -240,7 +229,6 @@ func (pst *thePast) getOp(ver int64) (Op, bool) { l := int64(len(pst.ops)) if l < ver || ver <= 0 { return Op{}, false - } else { - return pst.ops[ver-1], true } + return pst.ops[ver-1], true } diff --git a/types/errors.go b/types/errors.go index a878149313..77cea98ac7 100644 --- a/types/errors.go +++ b/types/errors.go @@ -7,19 +7,20 @@ import ( "github.com/tendermint/go-crypto" ) +// ABCI Response Code type CodeType uint32 +// is everything okay? func (code CodeType) IsOK() bool { if code == CodeOK { return true - } else { - return false } + return false } +// ABCI Response Codes +// Base SDK reserves 0 ~ 99. const ( - // ABCI Response Codes - // Base SDK reserves 0 ~ 99. CodeOK CodeType = 0 CodeInternal CodeType = 1 CodeTxParse CodeType = 2 @@ -29,6 +30,8 @@ const ( CodeUnknownRequest CodeType = 6 CodeUnrecognizedAddress CodeType = 7 CodeInvalidSequence CodeType = 8 + + CodeGenesisParse CodeType = 0xdead // TODO: remove ? ) // NOTE: Don't stringer this, we'll put better messages in later. @@ -38,6 +41,8 @@ func CodeToDefaultMsg(code CodeType) string { return "Internal error" case CodeTxParse: return "Tx parse error" + case CodeGenesisParse: + return "Genesis parse error" case CodeBadNonce: return "Bad nonce" case CodeUnauthorized: @@ -59,34 +64,31 @@ func CodeToDefaultMsg(code CodeType) string { // All errors are created via constructors so as to enable us to hijack them // and inject stack traces if we really want to. +// nolint func ErrInternal(msg string) Error { return newError(CodeInternal, msg) } - func ErrTxParse(msg string) Error { return newError(CodeTxParse, msg) } - +func ErrGenesisParse(msg string) Error { + return newError(CodeGenesisParse, msg) +} func ErrBadNonce(msg string) Error { return newError(CodeBadNonce, msg) } - func ErrUnauthorized(msg string) Error { return newError(CodeUnauthorized, msg) } - func ErrInsufficientFunds(msg string) Error { return newError(CodeInsufficientFunds, msg) } - func ErrUnknownRequest(msg string) Error { return newError(CodeUnknownRequest, msg) } - func ErrUnrecognizedAddress(addr crypto.Address) Error { return newError(CodeUnrecognizedAddress, addr.String()) } - func ErrInvalidSequence(msg string) Error { return newError(CodeInvalidSequence, msg) } @@ -94,6 +96,7 @@ func ErrInvalidSequence(msg string) Error { //---------------------------------------- // Error & sdkError +// sdk Error type type Error interface { Error() string ABCICode() CodeType diff --git a/types/genesis.go b/types/genesis.go new file mode 100644 index 0000000000..643235e3e9 --- /dev/null +++ b/types/genesis.go @@ -0,0 +1,6 @@ +package types + +import "encoding/json" + +// function variable used to initialize application state at genesis +type InitStater func(ctx Context, state json.RawMessage) Error diff --git a/types/handler.go b/types/handler.go index 6b45f54739..129f42647a 100644 --- a/types/handler.go +++ b/types/handler.go @@ -1,5 +1,6 @@ package types +// core function variable which application runs for transactions type Handler func(ctx Context, msg Msg) Result // If newCtx.IsZero(), ctx is used instead. diff --git a/types/signature.go b/types/signature.go index e22d0c78cb..7fecc5fe96 100644 --- a/types/signature.go +++ b/types/signature.go @@ -2,6 +2,7 @@ package types import crypto "github.com/tendermint/go-crypto" +// Standard Signature type StdSignature struct { crypto.PubKey // optional crypto.Signature diff --git a/types/store.go b/types/store.go index 6802a4bf10..872c380901 100644 --- a/types/store.go +++ b/types/store.go @@ -9,12 +9,12 @@ import ( // NOTE: These are implemented in cosmos-sdk/store. -type Store interface { +type Store interface { //nolint GetStoreType() StoreType CacheWrapper } -// Something that can persist to disk. +// something that can persist to disk type Committer interface { Commit() CommitID LastCommitID() CommitID @@ -37,7 +37,7 @@ type Queryable interface { //---------------------------------------- // MultiStore -type MultiStore interface { +type MultiStore interface { //nolint Store // Cache wrap MultiStore. @@ -139,10 +139,6 @@ type CacheKVStore interface { cache-wraps make no sense. It can return KVStore, HeapStore, SpaceStore, etc. */ -type CacheWrapper interface { - CacheWrap() CacheWrap -} - type CacheWrap interface { // Write syncs with the underlying store. @@ -152,6 +148,10 @@ type CacheWrap interface { CacheWrap() CacheWrap } +type CacheWrapper interface { //nolint + CacheWrap() CacheWrap +} + //---------------------------------------- // CommitID @@ -161,7 +161,7 @@ type CommitID struct { Hash []byte } -func (cid CommitID) IsZero() bool { +func (cid CommitID) IsZero() bool { //nolint return cid.Version == 0 && len(cid.Hash) == 0 } @@ -172,9 +172,11 @@ func (cid CommitID) String() string { //---------------------------------------- // Store types +// kind of store type StoreType int const ( + //nolint StoreTypeMulti StoreType = iota StoreTypeDB StoreTypeIAVL diff --git a/types/tx_msg.go b/types/tx_msg.go index 8e7a8e4281..ebed8a25a6 100644 --- a/types/tx_msg.go +++ b/types/tx_msg.go @@ -4,6 +4,7 @@ import ( crypto "github.com/tendermint/go-crypto" ) +// Transactions messages must fulfill the Msg type Msg interface { // Return the message type. @@ -26,6 +27,7 @@ type Msg interface { GetSigners() []crypto.Address } +// Transactions objects must fulfill the Tx type Tx interface { // Gets the Msg. @@ -47,13 +49,18 @@ type Tx interface { var _ Tx = (*StdTx)(nil) +// standard transaction form type StdTx struct { Msg Signatures []StdSignature } +//nolint func (tx StdTx) GetMsg() Msg { return tx.Msg } func (tx StdTx) GetFeePayer() crypto.Address { return tx.Signatures[0].PubKey.Address() } func (tx StdTx) GetSignatures() []StdSignature { return tx.Signatures } +//------------------------------------- + +// Application function variable used to unmarshal transaction bytes type TxDecoder func(txBytes []byte) (Tx, Error)