Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add msg service router interface #2

Merged
merged 14 commits into from
Dec 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions baseapp/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ func (app *BaseApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
panic(fmt.Sprintf("unknown RequestCheckTx type: %s", req.Type))
}

gInfo, result, err := app.runTx(mode, req.Tx)
gInfo, result, _, err := app.runTx(mode, req.Tx)
if err != nil {
return sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace)
}
Expand Down Expand Up @@ -272,7 +272,7 @@ func (app *BaseApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx
telemetry.SetGauge(float32(gInfo.GasWanted), "tx", "gas", "wanted")
}()

gInfo, result, err := app.runTx(runTxModeDeliver, req.Tx)
gInfo, result, _, err := app.runTx(runTxModeDeliver, req.Tx)
if err != nil {
resultStr = "failed"
return sdkerrors.ResponseDeliverTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace)
Expand Down Expand Up @@ -744,7 +744,7 @@ func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) abci.Res
case "simulate":
txBytes := req.Data

gInfo, res, err := app.Simulate(txBytes)
gInfo, res, _, err := app.Simulate(txBytes)
if err != nil {
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to simulate tx"))
}
Expand Down
54 changes: 41 additions & 13 deletions baseapp/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ type BaseApp struct { // nolint: maligned
router sdk.Router // handle any kind of message
queryRouter sdk.QueryRouter // router for redirecting query calls
grpcQueryRouter *GRPCQueryRouter // router for redirecting gRPC query calls
msgServiceRouter *MsgServiceRouter // router for redirecting Msg service messages
msgServiceRouter IMsgServiceRouter // router for redirecting Msg service messages
interfaceRegistry types.InterfaceRegistry
txDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx

Expand Down Expand Up @@ -133,6 +133,9 @@ type BaseApp struct { // nolint: maligned
// indexEvents defines the set of events in the form {eventType}.{attributeKey},
// which informs Tendermint what to index. If empty, all events will be indexed.
indexEvents map[string]struct{}

// fee handler
feeHandler sdk.FeeHandler // ante handler for fee and auth
}

// NewBaseApp returns a reference to an initialized BaseApp. It accepts a
Expand Down Expand Up @@ -195,8 +198,13 @@ func (app *BaseApp) Trace() bool {
return app.trace
}

// sets MsgServiceRouter of the BaseApp.
func (app *BaseApp) SetMsgServiceRouter(msgServiceRouter IMsgServiceRouter) {
app.msgServiceRouter = msgServiceRouter
}

// MsgServiceRouter returns the MsgServiceRouter of a BaseApp.
func (app *BaseApp) MsgServiceRouter() *MsgServiceRouter { return app.msgServiceRouter }
func (app *BaseApp) MsgServiceRouter() IMsgServiceRouter { return app.msgServiceRouter }

// MountStores mounts all IAVL or DB stores to the provided keys in the BaseApp
// multistore.
Expand Down Expand Up @@ -572,7 +580,7 @@ func (app *BaseApp) cacheTxContext(ctx sdk.Context, txBytes []byte) (sdk.Context
// Note, gas execution info is always returned. A reference to a Result is
// returned if the tx does not run out of gas and if all the messages are valid
// and execute successfully. An error is returned otherwise.
func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, result *sdk.Result, err error) {
func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, result *sdk.Result, txCtx sdk.Context, err error) {
// NOTE: GasWanted should be returned by the AnteHandler. GasUsed is
// determined by the GasMeter. We need access to the context to get the gas
// meter so we initialize upfront.
Expand All @@ -584,7 +592,7 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re
// only run the tx if there is block gas remaining
if mode == runTxModeDeliver && ctx.BlockGasMeter().IsOutOfGas() {
gInfo = sdk.GasInfo{GasUsed: ctx.BlockGasMeter().GasConsumed()}
return gInfo, nil, sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "no block gas left to run tx")
return gInfo, nil, ctx, sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "no block gas left to run tx")
}

var startingGas uint64
Expand Down Expand Up @@ -620,12 +628,12 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re

tx, err := app.txDecoder(txBytes)
if err != nil {
return sdk.GasInfo{}, nil, err
return sdk.GasInfo{}, nil, ctx, err
}

msgs := tx.GetMsgs()
if err := validateBasicTxMsgs(msgs); err != nil {
return sdk.GasInfo{}, nil, err
return sdk.GasInfo{}, nil, ctx, err
}

var events sdk.Events
Expand Down Expand Up @@ -662,7 +670,7 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re
gasWanted = ctx.GasMeter().Limit()

if err != nil {
return gInfo, nil, err
return gInfo, nil, ctx, err
}

msCache.Write()
Expand All @@ -678,15 +686,35 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re
// Result if any single message fails or does not have a registered Handler.
result, err = app.runMsgs(runMsgCtx, msgs, mode)
if err == nil && mode == runTxModeDeliver {
msCache.Write()

if len(events) > 0 {
// append the events in the order of occurrence
result.Events = append(events.ToABCIEvents(), result.Events...)
// apply fee logic calls
events, err = FeeInvoke(mode, app, runMsgCtx, events)
// if err from FeeInvoke then don't write to cache
if err == nil {
msCache.Write()
if len(events) > 0 {
// append the events in the order of occurrence
result.Events = append(events.ToABCIEvents(), result.Events...)
}
}
}

return gInfo, result, err
return gInfo, result, ctx, err
}

// FeeInvoke apply fee logic and append events
func FeeInvoke(mode runTxMode, app *BaseApp, runMsgCtx sdk.Context, events sdk.Events) (sdk.Events, error) {
if app.feeHandler != nil {
// call the msgFee
_, eventsFromFeeHandler, err := app.feeHandler(runMsgCtx, mode == runTxModeSimulate)
if err != nil {
return nil, err
}
// append any events emitted by FeeHandler
if events != nil && len(events) > 0 {
events = events.AppendEvents(eventsFromFeeHandler)
}
}
return events, nil
}

// runMsgs iterates through a list of messages and executes them with the provided
Expand Down
4 changes: 2 additions & 2 deletions baseapp/baseapp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1131,13 +1131,13 @@ func TestSimulateTx(t *testing.T) {
require.Nil(t, err)

// simulate a message, check gas reported
gInfo, result, err := app.Simulate(txBytes)
gInfo, result, _, err := app.Simulate(txBytes)
require.NoError(t, err)
require.NotNil(t, result)
require.Equal(t, gasConsumed, gInfo.GasUsed)

// simulate again, same result
gInfo, result, err = app.Simulate(txBytes)
gInfo, result, _, err = app.Simulate(txBytes)
require.NoError(t, err)
require.NotNil(t, result)
require.Equal(t, gasConsumed, gInfo.GasUsed)
Expand Down
7 changes: 7 additions & 0 deletions baseapp/msg_service_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ func NewMsgServiceRouter() *MsgServiceRouter {
// MsgServiceHandler defines a function type which handles Msg service message.
type MsgServiceHandler = func(ctx sdk.Context, req sdk.Msg) (*sdk.Result, error)

type IMsgServiceRouter interface {
iramiller marked this conversation as resolved.
Show resolved Hide resolved
Handler(msg sdk.Msg) MsgServiceHandler
HandlerByTypeURL(typeURL string) MsgServiceHandler
RegisterService(sd *grpc.ServiceDesc, handler interface{})
SetInterfaceRegistry(interfaceRegistry codectypes.InterfaceRegistry)
}

// Handler returns the MsgServiceHandler for a given msg or nil if not found.
func (msr *MsgServiceRouter) Handler(msg sdk.Msg) MsgServiceHandler {
return msr.routes[sdk.MsgTypeURL(msg)]
Expand Down
9 changes: 9 additions & 0 deletions baseapp/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,12 @@ func (app *BaseApp) SetInterfaceRegistry(registry types.InterfaceRegistry) {
app.grpcQueryRouter.SetInterfaceRegistry(registry)
app.msgServiceRouter.SetInterfaceRegistry(registry)
}

// SetFeeHandler sets the FeeHandler which if set will change the behavior of fee handling
func (app *BaseApp) SetFeeHandler(feeHandler sdk.FeeHandler) {
if app.sealed {
panic("SetKeeperHandler() on sealed BaseApp")
}

app.feeHandler = feeHandler
}
8 changes: 5 additions & 3 deletions baseapp/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ func (app *BaseApp) Check(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *sdk
if err != nil {
return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err)
}
return app.runTx(runTxModeCheck, bz)
gasInfo, result, _, err := app.runTx(runTxModeCheck, bz)
return gasInfo, result, err
}

func (app *BaseApp) Simulate(txBytes []byte) (sdk.GasInfo, *sdk.Result, error) {
func (app *BaseApp) Simulate(txBytes []byte) (sdk.GasInfo, *sdk.Result, sdk.Context, error) {
return app.runTx(runTxModeSimulate, txBytes)
}

Expand All @@ -28,7 +29,8 @@ func (app *BaseApp) Deliver(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *s
if err != nil {
return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err)
}
return app.runTx(runTxModeDeliver, bz)
gasInfo, result, _, err := app.runTx(runTxModeDeliver, bz)
return gasInfo, result, err
}

// Context with current {check, deliver}State of the app used by tests.
Expand Down
2 changes: 1 addition & 1 deletion simapp/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ func SignCheckDeliver(
require.Nil(t, err)

// Must simulate now as CheckTx doesn't run Msgs anymore
_, res, err := app.Simulate(txBytes)
_, res, _, err := app.Simulate(txBytes)

if expSimPass {
require.NoError(t, err)
Expand Down
4 changes: 4 additions & 0 deletions types/fee_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package types

// FeeHandler optional custom fee handling implementations
type FeeHandler func(ctx Context, simulate bool) (coins Coins, events Events, err error)
4 changes: 2 additions & 2 deletions x/auth/tx/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
)

// baseAppSimulateFn is the signature of the Baseapp#Simulate function.
type baseAppSimulateFn func(txBytes []byte) (sdk.GasInfo, *sdk.Result, error)
type baseAppSimulateFn func(txBytes []byte) (sdk.GasInfo, *sdk.Result, sdk.Context, error)

// txServer is the server for the protobuf Tx service.
type txServer struct {
Expand Down Expand Up @@ -114,7 +114,7 @@ func (s txServer) Simulate(ctx context.Context, req *txtypes.SimulateRequest) (*
return nil, status.Errorf(codes.InvalidArgument, "empty txBytes is not allowed")
}

gasInfo, result, err := s.simulate(txBytes)
gasInfo, result, _, err := s.simulate(txBytes)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions x/authz/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ import (
type Keeper struct {
storeKey sdk.StoreKey
cdc codec.BinaryCodec
router *baseapp.MsgServiceRouter
router baseapp.IMsgServiceRouter
}

// NewKeeper constructs a message authorization Keeper
func NewKeeper(storeKey sdk.StoreKey, cdc codec.BinaryCodec, router *baseapp.MsgServiceRouter) Keeper {
func NewKeeper(storeKey sdk.StoreKey, cdc codec.BinaryCodec, router baseapp.IMsgServiceRouter) Keeper {
return Keeper{
storeKey: storeKey,
cdc: cdc,
Expand Down