diff --git a/app/app.go b/app/app.go index 75867f7915..39803d8df7 100644 --- a/app/app.go +++ b/app/app.go @@ -8,10 +8,9 @@ import ( "github.com/golang/protobuf/proto" "github.com/pkg/errors" abci "github.com/tendermint/abci/types" - cmn "github.com/tendermint/tmlibs/common" "github.com/tendermint/tmlibs/log" - sdk "github.com/cosmos/cosmos-sdk" + "github.com/cosmos/cosmos-sdk/types" ) const mainKeyHeader = "header" @@ -24,16 +23,16 @@ type App struct { name string // DeliverTx (main) state - store MultiStore + store types.MultiStore // CheckTx state - storeCheck CacheMultiStore + storeCheck types.CacheMultiStore // Current block header header *abci.Header // Handler for CheckTx and DeliverTx. - handler sdk.Handler + handler types.Handler // Cached validator changes from DeliverTx valUpdates []abci.Validator @@ -48,17 +47,17 @@ func NewApp(name string) *App { } } -func (app *App) SetStore(store MultiStore) { +func (app *App) SetStore(store types.MultiStore) { app.store = store } -func (app *App) SetHandler(handler Handler) { +func (app *App) SetHandler(handler types.Handler) { app.handler = handler } func (app *App) LoadLatestVersion() error { store := app.store - store.LoadLastVersion() + store.LoadLatestVersion() return app.initFromStore() } @@ -108,12 +107,67 @@ func (app *App) initFromStore() error { //---------------------------------------- -// DeliverTx - ABCI - dispatches to the handler +// Implements ABCI +func (app *App) Info(req abci.RequestInfo) abci.ResponseInfo { + + lastCommitID := app.store.LastCommitID() + + return abci.ResponseInfo{ + Data: app.Name, + LastBlockHeight: lastCommitID.Version, + LastBlockAppHash: lastCommitID.Hash, + } +} + +// Implements ABCI +func (app *App) SetOption(req abci.RequestSetOption) abci.ResponseSetOption { + return "Not Implemented" +} + +// Implements ABCI +func (app *App) InitChain(req abci.RequestInitChain) abci.ResponseInitChain { + // TODO: Use req.Validators +} + +// Implements ABCI +func (app *App) Query(req abci.RequestQuery) abci.ResponseQuery { + // TODO: See app/query.go +} + +// Implements ABCI +func (app *App) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock { + app.header = req.Header +} + +// Implements ABCI +func (app *App) CheckTx(txBytes []byte) abci.ResponseCheckTx { + + // Initialize arguments to Handler. + var isCheckTx = true + var ctx = types.NewContext(app.header, isCheckTx, txBytes) + var store = app.store + var tx Tx = nil // nil until a decorator parses one. + + // Run the handler. + var result = app.handler(ctx, app.store, tx) + + // Tell the blockchain engine (i.e. Tendermint). + return abci.ResponseDeliverTx{ + Code: result.Code, + Data: result.Data, + Log: result.Log, + Gas: result.Gas, + FeeDenom: result.FeeDenom, + FeeAmount: result.FeeAmount, + } +} + +// Implements ABCI func (app *App) DeliverTx(txBytes []byte) abci.ResponseDeliverTx { // Initialize arguments to Handler. var isCheckTx = false - var ctx = sdk.NewContext(app.header, isCheckTx, txBytes) + var ctx = types.NewContext(app.header, isCheckTx, txBytes) var store = app.store var tx Tx = nil // nil until a decorator parses one. @@ -137,104 +191,16 @@ func (app *App) DeliverTx(txBytes []byte) abci.ResponseDeliverTx { } } -// CheckTx - ABCI - dispatches to the handler -func (app *App) CheckTx(txBytes []byte) abci.ResponseCheckTx { - - // Initialize arguments to Handler. - var isCheckTx = true - var ctx = sdk.NewContext(app.header, isCheckTx, txBytes) - var store = app.store - var tx Tx = nil // nil until a decorator parses one. - - // Run the handler. - var result = app.handler(ctx, app.store, tx) - - // Tell the blockchain engine (i.e. Tendermint). - return abci.ResponseDeliverTx{ - Code: result.Code, - Data: result.Data, - Log: result.Log, - Gas: result.Gas, - FeeDenom: result.FeeDenom, - FeeAmount: result.FeeAmount, - } +// Implements ABCI +func (app *App) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBlock) { + // XXX Update to res.Updates. + res.ValidatorUpdates = app.valUpdates + app.valUpdates = nil + return } -// Info - ABCI -func (app *App) Info(req abci.RequestInfo) abci.ResponseInfo { - - lastCommitID := app.store.LastCommitID() - - return abci.ResponseInfo{ - Data: app.Name, - LastBlockHeight: lastCommitID.Version, - LastBlockAppHash: lastCommitID.Hash, - } -} - -// SetOption - ABCI -func (app *App) SetOption(key string, value string) string { - return "Not Implemented" -} - -// Query - ABCI -func (app *App) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) { - /* - XXX Make this work with MultiStore. - XXX It will require some interfaces updates in store/types.go. - - if len(reqQuery.Data) == 0 { - resQuery.Log = "Query cannot be zero length" - resQuery.Code = abci.CodeType_EncodingError - return - } - - // set the query response height to current - tree := app.state.Committed() - - height := reqQuery.Height - if height == 0 { - // TODO: once the rpc actually passes in non-zero - // heights we can use to query right after a tx - // we must retrun most recent, even if apphash - // is not yet in the blockchain - - withProof := app.CommittedHeight() - 1 - if tree.Tree.VersionExists(withProof) { - height = withProof - } else { - height = app.CommittedHeight() - } - } - resQuery.Height = height - - switch reqQuery.Path { - case "/store", "/key": // Get by key - key := reqQuery.Data // Data holds the key bytes - resQuery.Key = key - if reqQuery.Prove { - value, proof, err := tree.GetVersionedWithProof(key, height) - if err != nil { - resQuery.Log = err.Error() - break - } - resQuery.Value = value - resQuery.Proof = proof.Bytes() - } else { - value := tree.Get(key) - resQuery.Value = value - } - - default: - resQuery.Code = abci.CodeType_UnknownRequest - resQuery.Log = cmn.Fmt("Unexpected Query path: %v", reqQuery.Path) - } - return - */ -} - -// Commit implements abci.Application -func (app *App) Commit() (res abci.Result) { +// Implements ABCI +func (app *App) Commit() (res abci.ResponseCommit) { commitID := app.store.Commit() app.logger.Debug("Commit synced", "commit", commitID, @@ -242,22 +208,8 @@ func (app *App) Commit() (res abci.Result) { return abci.NewResultOK(hash, "") } -// InitChain - ABCI -func (app *App) InitChain(req abci.RequestInitChain) {} - -// BeginBlock - ABCI -func (app *App) BeginBlock(req abci.RequestBeginBlock) { - app.header = req.Header -} - -// EndBlock - ABCI -// Returns a list of all validator changes made in this block -func (app *App) EndBlock(height uint64) (res abci.ResponseEndBlock) { - // XXX Update to res.Updates. - res.Diffs = app.valUpdates - app.valUpdates = nil - return -} +//---------------------------------------- +// Misc. // Return index of list with validator of same PubKey, or -1 if no match func pubKeyIndex(val *abci.Validator, list []*abci.Validator) int { @@ -275,38 +227,3 @@ func pubKeyIndex(val *abci.Validator, list []*abci.Validator) int { func makeDefaultLogger() log.Logger { return log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") } - -// InitState - used to setup state (was SetOption) -// to be call from setting up the genesis file -func (app *InitApp) InitState(module, key, value string) error { - state := app.Append() - logger := app.Logger().With("module", module, "key", key) - - if module == sdk.ModuleNameBase { - if key == sdk.ChainKey { - app.info.SetChainID(state, value) - return nil - } - logger.Error("Invalid genesis option") - return fmt.Errorf("Unknown base option: %s", key) - } - - log, err := app.initState.InitState(logger, state, module, key, value) - if err != nil { - logger.Error("Invalid genesis option", "err", err) - } else { - logger.Info(log) - } - return err -} - -// InitChain - ABCI - sets the initial validators -func (app *InitApp) InitChain(req abci.RequestInitChain) { - // return early if no InitValidator registered - if app.initVals == nil { - return - } - - logger, store := app.Logger(), app.Append() - app.initVals.InitValidators(logger, store, req.Validators) -} diff --git a/app/query.go b/app/query.go new file mode 100644 index 0000000000..908a551ea5 --- /dev/null +++ b/app/query.go @@ -0,0 +1,54 @@ +package app + +/* + XXX Make this work with MultiStore. + XXX It will require some interfaces updates in store/types.go. + + if len(reqQuery.Data) == 0 { + resQuery.Log = "Query cannot be zero length" + resQuery.Code = abci.CodeType_EncodingError + return + } + + // set the query response height to current + tree := app.state.Committed() + + height := reqQuery.Height + if height == 0 { + // TODO: once the rpc actually passes in non-zero + // heights we can use to query right after a tx + // we must retrun most recent, even if apphash + // is not yet in the blockchain + + withProof := app.CommittedHeight() - 1 + if tree.Tree.VersionExists(withProof) { + height = withProof + } else { + height = app.CommittedHeight() + } + } + resQuery.Height = height + + switch reqQuery.Path { + case "/store", "/key": // Get by key + key := reqQuery.Data // Data holds the key bytes + resQuery.Key = key + if reqQuery.Prove { + value, proof, err := tree.GetVersionedWithProof(key, height) + if err != nil { + resQuery.Log = err.Error() + break + } + resQuery.Value = value + resQuery.Proof = proof.Bytes() + } else { + value := tree.Get(key) + resQuery.Value = value + } + + default: + resQuery.Code = abci.CodeType_UnknownRequest + resQuery.Log = cmn.Fmt("Unexpected Query path: %v", reqQuery.Path) + } + return +*/