Skip to content

Commit

Permalink
looking better so far
Browse files Browse the repository at this point in the history
  • Loading branch information
sunnya97 committed May 9, 2018
1 parent 0a5722a commit 1859574
Show file tree
Hide file tree
Showing 46 changed files with 856 additions and 806 deletions.
2 changes: 1 addition & 1 deletion types/account.go → baseapp/account.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package types
package baseapp

import (
cmn "github.com/tendermint/tmlibs/common"
Expand Down
220 changes: 220 additions & 0 deletions baseapp/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
package baseapp

import (
"fmt"
"runtime/debug"

abci "github.com/tendermint/abci/types"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/log"

"github.com/cosmos/cosmos-sdk/store"
"github.com/cosmos/cosmos-sdk/wire"

sdk "github.com/cosmos/cosmos-sdk/types"
)

// Key to store the header in the DB itself.
// Use the db directly instead of a store to avoid
// conflicts with handlers writing to the store
// and to avoid affecting the Merkle root.
var dbHeaderKey = []byte("header")

// The ABCI application
type BaseApp struct {
// initialized on creation
*sdk.App

router Router // handle any kind of message

// must be set
txDecoder TxDecoder // unmarshal []byte into sdk.Tx
anteHandler AnteHandler // ante handler for fee and auth
}

var _ abci.Application = (*BaseApp)(nil)

// Create and name new BaseApp
// NOTE: The db is used to store the version number for now.
func NewApp(name string, cdc *wire.Codec, logger log.Logger, db dbm.DB) *BaseApp {

cms := store.NewCommitMultiStore(db)

baseapp := sdk.NewBaseApp(name, logger, db, cms)
app := &BaseApp{
BaseApp: baseapp,
router: NewRouter(),
txDecoder: defaultTxDecoder(cdc),
anteHandler: nil,
}

return app
}

// Implements ABCI
func (app *BaseApp) CheckTx(txBytes []byte) abci.ResponseCheckTx {
// Decode the Tx.
var result sdk.Result
var tx, err = app.txDecoder(txBytes)
if err != nil {
result = err.Result()
} else {
result = app.runTx(app.GetCheckContext(), true, txBytes, tx)
}

return abci.ResponseCheckTx{
Code: uint32(result.Code),
Data: result.Data,
Log: result.Log,
GasWanted: result.GasWanted,
Fee: cmn.KI64Pair{
[]byte(result.FeeDenom),
result.FeeAmount,
},
Tags: result.Tags,
}
}

// Implements ABCI
func (app *BaseApp) DeliverTx(txBytes []byte) abci.ResponseDeliverTx {

// Decode the Tx.
var result sdk.Result
var tx, err = app.txDecoder(txBytes)
if err != nil {
result = err.Result()
} else {
result = app.runTx(app.GetCheckContext(), false, txBytes, tx)
}

// After-handler hooks.
if result.IsOK() {
app.AppendValUpdates(result.ValidatorUpdates)
} else {
// Even though the Code is not OK, there will be some side
// effects, like those caused by fee deductions or sequence
// incrementations.
}

// Tell the blockchain engine (i.e. Tendermint).
return abci.ResponseDeliverTx{
Code: uint32(result.Code),
Data: result.Data,
Log: result.Log,
GasWanted: result.GasWanted,
GasUsed: result.GasUsed,
Tags: result.Tags,
}
}

// Implements ABCI
func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeginBlock) {
res = app.sdk.BeginBlock(req)
// TODO
return
}

// Implements ABCI
func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBlock) {
res = app.sdk.EndBlock(req)
// TODO
return
}

// txBytes may be nil in some cases, eg. in tests.
// Also, in the future we may support "internal" transactions.
func (app *BaseApp) runTx(ctx sdk.Context, isCheckTx bool, txBytes []byte, tx Tx) (result sdk.Result) {
// Handle any panics.
defer func() {
if r := recover(); r != nil {
log := fmt.Sprintf("Recovered: %v\nstack:\n%v", r, string(debug.Stack()))
result = ErrInternal(log).Result()
}
}()

// Get the Msg.
var msg = tx.GetMsg()
if msg == nil {
return ErrInternal("Tx.GetMsg() returned nil").Result()
}

// Validate the Msg.
err := msg.ValidateBasic()
if err != nil {
err = err.WithDefaultCodespace(sdk.CodespaceRoot)
return err.Result()
}

// Run the ante handler.
if app.anteHandler != nil {
newCtx, result, abort := app.anteHandler(ctx, tx)
if abort {
return result
}
if !newCtx.IsZero() {
ctx = newCtx
}
}

// Match route.
msgType := msg.Type()
handler := app.router.Route(msgType)
if handler == nil {
return sdk.ErrUnknownRequest("Unrecognized Msg type: " + msgType).Result()
}

// Get the correct cache
var msCache sdk.CacheMultiStore
if isCheckTx == true {
// CacheWrap app.checkState.ms in case it fails.
msCache = app.CacheCheckMultiStore()
ctx = ctx.WithMultiStore(msCache)
} else {
// CacheWrap app.deliverState.ms in case it fails.
msCache = app.CacheDeliverMultiStore()
ctx = ctx.WithMultiStore(msCache)

}

result = handler(ctx, msg)

// If result was successful, write to app.checkState.ms or app.deliverState.ms
if result.IsOK() {
msCache.Write()
}

return result
}

// Set the txDecoder function
func (app *BaseApp) SetTxDecoder(txDecoder TxDecoder) {
app.txDecoder = txDecoder
}

// Set the txDecoder function
func (app *BaseApp) SetAnteHandler(ah AnteHandler) {
app.anteHandler = ah
}

// Return the router
func (app *BaseApp) Router() Router { return app.router }

// default custom logic for transaction decoding
func defaultTxDecoder(cdc *wire.Codec) TxDecoder {
return func(txBytes []byte) (Tx, sdk.Error) {
var tx Tx

if len(txBytes) == 0 {
return nil, ErrTxDecode("txBytes are empty")
}

// StdTx.Msg is an interface. The concrete types
// are registered by MakeTxCodec
err := cdc.UnmarshalBinary(txBytes, &tx)
if err != nil {
return nil, ErrTxDecode("") // TODO: FIX WITH ERRORS: .Trace(err.Error())
}
return tx, nil
}
}
Loading

0 comments on commit 1859574

Please sign in to comment.