From c3909ca39f425fdf942e2b52feb148afb0bc0353 Mon Sep 17 00:00:00 2001 From: marbar3778 Date: Sun, 18 Dec 2022 04:03:08 +0700 Subject: [PATCH 1/4] add way to add modules to message service router for errors and events --- baseapp/baseapp.go | 15 +++++++------- baseapp/msg_service_router.go | 37 +++++++++++++++++++++++++++++++++-- x/bank/module.go | 20 +++++++++---------- 3 files changed, 52 insertions(+), 20 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index de164579f3f3..4eb3c44c9af2 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -184,6 +184,8 @@ func NewBaseApp( app.cms.SetInterBlockCache(app.interBlockCache) } + // Set module names on the message server router + app.runTxRecoveryMiddleware = newDefaultRecoveryMiddleware() return app @@ -225,6 +227,8 @@ func (app *BaseApp) SetMsgServiceRouter(msgServiceRouter *MsgServiceRouter) { // MountStores mounts all IAVL or DB stores to the provided keys in the BaseApp // multistore. func (app *BaseApp) MountStores(keys ...storetypes.StoreKey) { + app.msgServiceRouter.SetModuleName(keys) + for _, key := range keys { switch key.(type) { case *storetypes.KVStoreKey: @@ -796,7 +800,7 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*s } // create message events - msgEvents := createEvents(msg).AppendEvents(msgResult.GetEvents()) + msgEvents := createEvents(msg, app.msgServiceRouter.moduleNames[msg.String()]).AppendEvents(msgResult.GetEvents()) // append message events, data and logs // @@ -838,7 +842,7 @@ func makeABCIData(msgResponses []*codectypes.Any) ([]byte, error) { return proto.Marshal(&sdk.TxMsgData{MsgResponses: msgResponses}) } -func createEvents(msg sdk.Msg) sdk.Events { +func createEvents(msg sdk.Msg, name string) sdk.Events { eventMsgName := sdk.MsgTypeURL(msg) msgEvent := sdk.NewEvent(sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyAction, eventMsgName)) @@ -847,12 +851,7 @@ func createEvents(msg sdk.Msg) sdk.Events { msgEvent = msgEvent.AppendAttributes(sdk.NewAttribute(sdk.AttributeKeySender, msg.GetSigners()[0].String())) } - // here we assume that routes module name is the second element of the route - // e.g. "cosmos.bank.v1beta1.MsgSend" => "bank" - moduleName := strings.Split(eventMsgName, ".") - if len(moduleName) > 1 { - msgEvent = msgEvent.AppendAttributes(sdk.NewAttribute(sdk.AttributeKeyModule, moduleName[1])) - } + msgEvent = msgEvent.AppendAttributes(sdk.NewAttribute(sdk.AttributeKeyModule, name)) return sdk.Events{msgEvent} } diff --git a/baseapp/msg_service_router.go b/baseapp/msg_service_router.go index 360bd8910512..8cd5601bc9f9 100644 --- a/baseapp/msg_service_router.go +++ b/baseapp/msg_service_router.go @@ -3,12 +3,14 @@ package baseapp import ( "context" "fmt" + "strings" gogogrpc "github.com/cosmos/gogoproto/grpc" "github.com/cosmos/gogoproto/proto" "google.golang.org/grpc" codectypes "github.com/cosmos/cosmos-sdk/codec/types" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -17,6 +19,8 @@ import ( type MsgServiceRouter struct { interfaceRegistry codectypes.InterfaceRegistry routes map[string]MsgServiceHandler + moduleNames map[string]string // map of module names associated with each Msg service msgURL/moduleName + mn map[string]struct{} } var _ gogogrpc.Server = &MsgServiceRouter{} @@ -24,13 +28,24 @@ var _ gogogrpc.Server = &MsgServiceRouter{} // NewMsgServiceRouter creates a new MsgServiceRouter. func NewMsgServiceRouter() *MsgServiceRouter { return &MsgServiceRouter{ - routes: map[string]MsgServiceHandler{}, + routes: map[string]MsgServiceHandler{}, + moduleNames: map[string]string{}, } } // MsgServiceHandler defines a function type which handles Msg service message. type MsgServiceHandler = func(ctx sdk.Context, req sdk.Msg) (*sdk.Result, error) +// SetModuleName sets a module name used +func (msr MsgServiceRouter) SetModuleName(names []storetypes.StoreKey) { + msr.mn = make(map[string]struct{}) + + for _, e := range names { + msr.mn[e.Name()] = struct{}{} + } + +} + // 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)] @@ -54,9 +69,27 @@ func (msr *MsgServiceRouter) RegisterService(sd *grpc.ServiceDesc, handler inter for _, method := range sd.Methods { fqMethod := fmt.Sprintf("/%s/%s", sd.ServiceName, method.MethodName) methodHandler := method.Handler - var requestTypeName string + // assign a module name to the message url + if _, ok := msr.moduleNames[sd.ServiceName]; !ok { + for k := range msr.mn { + fmt.Println(k, sd.ServiceName) + if strings.Contains(k, sd.ServiceName) { + fmt.Println("test") + if strings.Contains(k, ":") { + + } + msr.moduleNames[sd.ServiceName] = k // put the module name on the message url + } + } + } + + // check if the new map contains the service name, if not add it + // add the module name from the moduleNames map associated with the service name + + // fmt.Println(msr.moduleNames, "msr.moduleName", sd.ServiceName) + // NOTE: This is how we pull the concrete request type for each handler for registering in the InterfaceRegistry. // This approach is maybe a bit hacky, but less hacky than reflecting on the handler object itself. // We use a no-op interceptor to avoid actually calling into the handler itself. diff --git a/x/bank/module.go b/x/bank/module.go index 01b7df315c32..d89b73023558 100644 --- a/x/bank/module.go +++ b/x/bank/module.go @@ -107,6 +107,16 @@ type AppModule struct { var _ appmodule.AppModule = AppModule{} +// NewAppModule creates a new AppModule object +func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, accountKeeper types.AccountKeeper, ss exported.Subspace) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{cdc: cdc}, + keeper: keeper, + accountKeeper: accountKeeper, + legacySubspace: ss, + } +} + // IsOnePerModuleType implements the depinject.OnePerModuleType interface. func (am AppModule) IsOnePerModuleType() {} @@ -132,16 +142,6 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { } } -// NewAppModule creates a new AppModule object -func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, accountKeeper types.AccountKeeper, ss exported.Subspace) AppModule { - return AppModule{ - AppModuleBasic: AppModuleBasic{cdc: cdc}, - keeper: keeper, - accountKeeper: accountKeeper, - legacySubspace: ss, - } -} - // Name returns the bank module's name. func (AppModule) Name() string { return types.ModuleName } From 167251770963620193e76ad3a16f0d04298d18f3 Mon Sep 17 00:00:00 2001 From: marbar3778 Date: Sun, 18 Dec 2022 11:03:17 +0700 Subject: [PATCH 2/4] simple but ugly --- baseapp/msg_service_router.go | 42 ++++++++++++++++-------------- baseapp/msg_service_router_test.go | 13 +++++++++ 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/baseapp/msg_service_router.go b/baseapp/msg_service_router.go index 8cd5601bc9f9..2604d0826770 100644 --- a/baseapp/msg_service_router.go +++ b/baseapp/msg_service_router.go @@ -19,8 +19,10 @@ import ( type MsgServiceRouter struct { interfaceRegistry codectypes.InterfaceRegistry routes map[string]MsgServiceHandler - moduleNames map[string]string // map of module names associated with each Msg service msgURL/moduleName - mn map[string]struct{} + + // map of module names associated with each Msg service msgURL/moduleName, to be used for events and error wrapping + moduleNames map[string]string // map of module names associated with each Msg service msgURL/moduleName + names map[string]struct{} // map of module names set when keys are set in the store. Assumption is module name == storekey and the message url contains the module name } var _ gogogrpc.Server = &MsgServiceRouter{} @@ -37,13 +39,12 @@ func NewMsgServiceRouter() *MsgServiceRouter { type MsgServiceHandler = func(ctx sdk.Context, req sdk.Msg) (*sdk.Result, error) // SetModuleName sets a module name used -func (msr MsgServiceRouter) SetModuleName(names []storetypes.StoreKey) { - msr.mn = make(map[string]struct{}) +func (msr *MsgServiceRouter) SetModuleName(names []storetypes.StoreKey) { + msr.names = make(map[string]struct{}) for _, e := range names { - msr.mn[e.Name()] = struct{}{} + msr.names[e.Name()] = struct{}{} } - } // Handler returns the MsgServiceHandler for a given msg or nil if not found. @@ -71,20 +72,6 @@ func (msr *MsgServiceRouter) RegisterService(sd *grpc.ServiceDesc, handler inter methodHandler := method.Handler var requestTypeName string - // assign a module name to the message url - if _, ok := msr.moduleNames[sd.ServiceName]; !ok { - for k := range msr.mn { - fmt.Println(k, sd.ServiceName) - if strings.Contains(k, sd.ServiceName) { - fmt.Println("test") - if strings.Contains(k, ":") { - - } - msr.moduleNames[sd.ServiceName] = k // put the module name on the message url - } - } - } - // check if the new map contains the service name, if not add it // add the module name from the moduleNames map associated with the service name @@ -106,6 +93,7 @@ func (msr *MsgServiceRouter) RegisterService(sd *grpc.ServiceDesc, handler inter return nil }, noopInterceptor) + msr.RegisterModuleNames(requestTypeName) // Check that the service Msg fully-qualified method name has already // been registered (via RegisterInterfaces). If the user registers a // service without registering according service Msg type, there might be @@ -171,6 +159,20 @@ func (msr *MsgServiceRouter) SetInterfaceRegistry(interfaceRegistry codectypes.I msr.interfaceRegistry = interfaceRegistry } +// RegisterModuleNames adds the module name to the message url +func (msr *MsgServiceRouter) RegisterModuleNames(msgUrl string) { + // assign a module name to the message url + if _, ok := msr.moduleNames[msgUrl]; !ok { + for k := range msr.names { + if strings.Contains(msgUrl, k) { + if !strings.Contains(k, ":") { + msr.moduleNames[msgUrl] = k // put the module name on the message url + } + } + } + } +} + func noopDecoder(_ interface{}) error { return nil } func noopInterceptor(_ context.Context, _ interface{}, _ *grpc.UnaryServerInfo, _ grpc.UnaryHandler) (interface{}, error) { return nil, nil diff --git a/baseapp/msg_service_router_test.go b/baseapp/msg_service_router_test.go index 6c0c1adcf487..e695beaae5e7 100644 --- a/baseapp/msg_service_router_test.go +++ b/baseapp/msg_service_router_test.go @@ -11,10 +11,12 @@ import ( dbm "github.com/tendermint/tm-db" "cosmossdk.io/depinject" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/runtime" + storetypes "github.com/cosmos/cosmos-sdk/store/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" "github.com/cosmos/cosmos-sdk/types/tx/signing" authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" @@ -143,3 +145,14 @@ func TestMsgService(t *testing.T) { res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes}) require.Equal(t, abci.CodeTypeOK, res.Code, "res=%+v", res) } + +func TestSetModuleName(t *testing.T) { + modules := []storetypes.StoreKey{storetypes.NewKVStoreKey("staking"), storetypes.NewKVStoreKey("transient:staking")} + + msgServer := baseapp.NewMsgServiceRouter() + msgServer.SetModuleName(modules) + msgUrls := []string{"/cosmos.slashing.v1beta1.MsgUnjail", "/cosmos.slashing.v1beta1.MsgUpdateParams", "/cosmos.staking.v1beta1.MsgCreateValidator", "/cosmos.staking.v1beta1.MsgEditValidator", "/cosmos.staking.v1beta1.MsgDelegate", "/cosmos.staking.v1beta1.MsgBeginRedelegate", "/cosmos.staking.v1beta1.MsgUndelegate", "/cosmos.staking.v1beta1.MsgCancelUnbondingDelegation", "/cosmos.staking.v1beta1.MsgUpdateParams"} + for _, url := range msgUrls { + msgServer.RegisterModuleNames(url) + } +} From 510dc1c03431f0bf038fa9d64575f6498b6d2c24 Mon Sep 17 00:00:00 2001 From: marbar3778 Date: Sun, 18 Dec 2022 11:06:51 +0700 Subject: [PATCH 3/4] remove comment --- baseapp/baseapp.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 4eb3c44c9af2..9e45a1b5e261 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -184,8 +184,6 @@ func NewBaseApp( app.cms.SetInterBlockCache(app.interBlockCache) } - // Set module names on the message server router - app.runTxRecoveryMiddleware = newDefaultRecoveryMiddleware() return app From 16d1e04377f0f63c2c6ad2e1cb733cdd38b41f82 Mon Sep 17 00:00:00 2001 From: marbar3778 Date: Sun, 18 Dec 2022 11:08:35 +0700 Subject: [PATCH 4/4] add comment --- baseapp/msg_service_router.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/baseapp/msg_service_router.go b/baseapp/msg_service_router.go index 2604d0826770..c369edaa5860 100644 --- a/baseapp/msg_service_router.go +++ b/baseapp/msg_service_router.go @@ -165,7 +165,7 @@ func (msr *MsgServiceRouter) RegisterModuleNames(msgUrl string) { if _, ok := msr.moduleNames[msgUrl]; !ok { for k := range msr.names { if strings.Contains(msgUrl, k) { - if !strings.Contains(k, ":") { + if !strings.Contains(k, ":") { // avoid setting moduleurl to storekeys like transient:params msr.moduleNames[msgUrl] = k // put the module name on the message url } }