Skip to content

Commit cfd426f

Browse files
authored
feat(runtime): message router service (#19571)
1 parent 83a7f0e commit cfd426f

22 files changed

Lines changed: 419 additions & 55 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i
4242

4343
### Features
4444

45+
* (runtime) [#19571](https://github.com/cosmos/cosmos-sdk/pull/19571) Implement `core/router.Service` it in runtime. This service is present in all modules (when using depinject).
4546
* (types) [#19164](https://github.com/cosmos/cosmos-sdk/pull/19164) Add a ValueCodec for the math.Uint type that can be used in collections maps.
4647
* (types) [#19281](https://github.com/cosmos/cosmos-sdk/pull/19281) Added a new method, `IsGT`, for `types.Coin`. This method is used to check if a `types.Coin` is greater than another `types.Coin`.
4748
* (client) [#18557](https://github.com/cosmos/cosmos-sdk/pull/18557) Add `--qrcode` flag to `keys show` command to support displaying keys address QR code.

baseapp/baseapp.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,10 +281,8 @@ func (app *BaseApp) Trace() bool {
281281
// MsgServiceRouter returns the MsgServiceRouter of a BaseApp.
282282
func (app *BaseApp) MsgServiceRouter() *MsgServiceRouter { return app.msgServiceRouter }
283283

284-
// SetMsgServiceRouter sets the MsgServiceRouter of a BaseApp.
285-
func (app *BaseApp) SetMsgServiceRouter(msgServiceRouter *MsgServiceRouter) {
286-
app.msgServiceRouter = msgServiceRouter
287-
}
284+
// GRPCQueryRouter returns the GRPCQueryRouter of a BaseApp.
285+
func (app *BaseApp) GRPCQueryRouter() *GRPCQueryRouter { return app.grpcQueryRouter }
288286

289287
// MountStores mounts all IAVL or DB stores to the provided keys in the BaseApp
290288
// multistore.

baseapp/grpcrouter.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ type GRPCQueryRouter struct {
2424
// hybridHandlers maps the request name to the handler. It is a hybrid handler which seamlessly
2525
// handles both gogo and protov2 messages.
2626
hybridHandlers map[string][]func(ctx context.Context, req, resp protoiface.MessageV1) error
27+
// responseByRequestName maps the request name to the response name.
28+
responseByRequestName map[string]string
2729
// binaryCodec is used to encode/decode binary protobuf messages.
2830
binaryCodec codec.BinaryCodec
2931
// cdc is the gRPC codec used by the router to correctly unmarshal messages.
@@ -43,8 +45,9 @@ var _ gogogrpc.Server = &GRPCQueryRouter{}
4345
// NewGRPCQueryRouter creates a new GRPCQueryRouter
4446
func NewGRPCQueryRouter() *GRPCQueryRouter {
4547
return &GRPCQueryRouter{
46-
routes: map[string]GRPCQueryHandler{},
47-
hybridHandlers: map[string][]func(ctx context.Context, req, resp protoiface.MessageV1) error{},
48+
routes: map[string]GRPCQueryHandler{},
49+
hybridHandlers: map[string][]func(ctx context.Context, req, resp protoiface.MessageV1) error{},
50+
responseByRequestName: map[string]string{},
4851
}
4952
}
5053

@@ -133,16 +136,26 @@ func (qrt *GRPCQueryRouter) HybridHandlerByRequestName(name string) []func(ctx c
133136
return qrt.hybridHandlers[name]
134137
}
135138

139+
func (qrt *GRPCQueryRouter) ResponseNameByRequestName(requestName string) string {
140+
return qrt.responseByRequestName[requestName]
141+
}
142+
136143
func (qrt *GRPCQueryRouter) registerHybridHandler(sd *grpc.ServiceDesc, method grpc.MethodDesc, handler interface{}) error {
137144
// extract message name from method descriptor
138145
inputName, err := protocompat.RequestFullNameFromMethodDesc(sd, method)
139146
if err != nil {
140147
return err
141148
}
149+
outputName, err := protocompat.ResponseFullNameFromMethodDesc(sd, method)
150+
if err != nil {
151+
return err
152+
}
142153
methodHandler, err := protocompat.MakeHybridHandler(qrt.binaryCodec, sd, method, handler)
143154
if err != nil {
144155
return err
145156
}
157+
// map input name to output name
158+
qrt.responseByRequestName[string(inputName)] = string(outputName)
146159
qrt.hybridHandlers[string(inputName)] = append(qrt.hybridHandlers[string(inputName)], methodHandler)
147160
return nil
148161
}

baseapp/grpcserver.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ import (
2020
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
2121
)
2222

23-
// GRPCQueryRouter returns the GRPCQueryRouter of a BaseApp.
24-
func (app *BaseApp) GRPCQueryRouter() *GRPCQueryRouter { return app.grpcQueryRouter }
25-
2623
// RegisterGRPCServer registers gRPC services directly with the gRPC server.
2724
func (app *BaseApp) RegisterGRPCServer(server gogogrpc.Server) {
2825
// Define an interceptor for all gRPC queries: this interceptor will create

baseapp/msg_service_router.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,17 @@ import (
2424
type MessageRouter interface {
2525
Handler(msg sdk.Msg) MsgServiceHandler
2626
HandlerByTypeURL(typeURL string) MsgServiceHandler
27+
28+
ResponseNameByMsgName(msgName string) string
29+
HybridHandlerByMsgName(msgName string) func(ctx context.Context, req, resp protoiface.MessageV1) error
2730
}
2831

2932
// MsgServiceRouter routes fully-qualified Msg service methods to their handler.
3033
type MsgServiceRouter struct {
3134
interfaceRegistry codectypes.InterfaceRegistry
3235
routes map[string]MsgServiceHandler
3336
hybridHandlers map[string]func(ctx context.Context, req, resp protoiface.MessageV1) error
34-
responseByRequest map[string]string
37+
responseByMsgName map[string]string
3538
circuitBreaker CircuitBreaker
3639
}
3740

@@ -42,7 +45,7 @@ func NewMsgServiceRouter() *MsgServiceRouter {
4245
return &MsgServiceRouter{
4346
routes: map[string]MsgServiceHandler{},
4447
hybridHandlers: map[string]func(ctx context.Context, req, resp protoiface.MessageV1) error{},
45-
responseByRequest: map[string]string{},
48+
responseByMsgName: map[string]string{},
4649
circuitBreaker: nil,
4750
}
4851
}
@@ -90,8 +93,8 @@ func (msr *MsgServiceRouter) HybridHandlerByMsgName(msgName string) func(ctx con
9093
return msr.hybridHandlers[msgName]
9194
}
9295

93-
func (msr *MsgServiceRouter) ResponseNameByRequestName(msgName string) string {
94-
return msr.responseByRequest[msgName]
96+
func (msr *MsgServiceRouter) ResponseNameByMsgName(msgName string) string {
97+
return msr.responseByMsgName[msgName]
9598
}
9699

97100
func (msr *MsgServiceRouter) registerHybridHandler(sd *grpc.ServiceDesc, method grpc.MethodDesc, handler interface{}) error {
@@ -109,7 +112,7 @@ func (msr *MsgServiceRouter) registerHybridHandler(sd *grpc.ServiceDesc, method
109112
return err
110113
}
111114
// map input name to output name
112-
msr.responseByRequest[string(inputName)] = string(outputName)
115+
msr.responseByMsgName[string(inputName)] = string(outputName)
113116
// if circuit breaker is not nil, then we decorate the hybrid handler with the circuit breaker
114117
if msr.circuitBreaker == nil {
115118
msr.hybridHandlers[string(inputName)] = hybridHandler

baseapp/options.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,3 +385,13 @@ func (app *BaseApp) SetStoreMetrics(gatherer metrics.StoreMetrics) {
385385
func (app *BaseApp) SetStreamingManager(manager storetypes.StreamingManager) {
386386
app.streamingManager = manager
387387
}
388+
389+
// SetMsgServiceRouter sets the MsgServiceRouter of a BaseApp.
390+
func (app *BaseApp) SetMsgServiceRouter(msgServiceRouter *MsgServiceRouter) {
391+
app.msgServiceRouter = msgServiceRouter
392+
}
393+
394+
// SetGRPCQueryRouter sets the GRPCQueryRouter of the BaseApp.
395+
func (app *BaseApp) SetGRPCQueryRouter(grpcQueryRouter *GRPCQueryRouter) {
396+
app.grpcQueryRouter = grpcQueryRouter
397+
}

client/grpc_query_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func (s *IntegrationTestSuite) SetupSuite() {
4747
s.testClient = testdata.NewQueryClient(queryHelper)
4848

4949
kvs := runtime.NewKVStoreService(keys[countertypes.StoreKey])
50-
counterKeeper := counterkeeper.NewKeeper(kvs, runtime.EventService{})
50+
counterKeeper := counterkeeper.NewKeeper(runtime.NewEnvironment(kvs, logger))
5151
countertypes.RegisterQueryServer(queryHelper, counterKeeper)
5252
s.counterClient = countertypes.NewQueryClient(queryHelper)
5353
}

core/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ Ref: https://keepachangelog.com/en/1.0.0/
4242
* [#18457](https://github.com/cosmos/cosmos-sdk/pull/18457) Add branch.ExecuteWithGasLimit.
4343
* [#19041](https://github.com/cosmos/cosmos-sdk/pull/19041) Add `appmodule.Environment` interface to fetch different services
4444
* [#19370](https://github.com/cosmos/cosmos-sdk/pull/19370) Add `appmodule.Migrations` interface to handle migrations
45-
* [#19617](https://github.com/cosmos/cosmos-sdk/pull/19617) Add DataBaseService to store non-consensus data in a database
45+
* [#19571](https://github.com/cosmos/cosmos-sdk/pull/19571) Add `router.Service` and add it in `appmodule.Environment`
46+
* [#19617](https://github.com/cosmos/cosmos-sdk/pull/19617) Server/v2 compatible interface:
47+
* Add DataBaseService to store non-consensus data in a database
4648
* Create V2 appmodule with v2 api for runtime/v2
4749
* Introduce `Transaction.Tx` for use in runtime/v2
4850
* Introduce `HasUpdateValidators` interface and `ValidatorUpdate` struct for validator updates

core/appmodule/v2/environment.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,21 @@ import (
55
"cosmossdk.io/core/event"
66
"cosmossdk.io/core/gas"
77
"cosmossdk.io/core/header"
8+
"cosmossdk.io/core/router"
89
"cosmossdk.io/core/store"
910
"cosmossdk.io/log"
1011
)
1112

1213
// Environment is used to get all services to their respective module
1314
type Environment struct {
14-
BranchService branch.Service
15-
EventService event.Service
16-
GasService gas.Service
17-
HeaderService header.Service
15+
Logger log.Logger
16+
17+
BranchService branch.Service
18+
EventService event.Service
19+
GasService gas.Service
20+
HeaderService header.Service
21+
RouterService router.Service
22+
1823
KVStoreService store.KVStoreService
1924
MemStoreService store.MemoryStoreService
20-
DataBaseService store.DatabaseService
21-
Logger log.Logger
2225
}
File renamed without changes.

0 commit comments

Comments
 (0)