Skip to content

Commit b3a330a

Browse files
committed
add CanInvoke
1 parent 1caec81 commit b3a330a

3 files changed

Lines changed: 52 additions & 25 deletions

File tree

core/appmodule/v2/environment.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ type Environment struct {
1818
EventService event.Service
1919
GasService gas.Service
2020
HeaderService header.Service
21-
RouterService router.Router
21+
RouterService router.Service
2222

2323
KVStoreService store.KVStoreService
2424
MemStoreService store.MemoryStoreService

core/router/service.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@ import (
66
"google.golang.org/protobuf/runtime/protoiface"
77
)
88

9-
// Router embeds a QueryRouterService and MessageRouterService.
10-
// Each service allows to invoke messages and queries via the corresponding router.
11-
type Router interface {
12-
QueryRouterService() Service
13-
MessageRouterService() Service
9+
// Service embeds a QueryRouterService and MessageRouterService.
10+
// Each router allows to invoke messages and queries via the corresponding router.
11+
type Service interface {
12+
QueryRouterService() Router
13+
MessageRouterService() Router
1414
}
1515

16-
// Service is the interface that wraps the basic methods for a router service.
17-
type Service interface {
16+
// Router is the interface that wraps the basic methods for a router.
17+
type Router interface {
18+
// CanInvoke returns an error if the given request cannot be invoked.
19+
CanInvoke(ctx context.Context, req protoiface.MessageV1) error
1820
// InvokeTyped execute a message or query. It should be used when the called knows the type of the response.
1921
InvokeTyped(ctx context.Context, req, res protoiface.MessageV1) error
2022
// InvokeUntyped execute a message or query. It should be used when the called doesn't know the type of the response.

runtime/router.go

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
)
1717

1818
// NewRouterService creates a router.Service which allows to invoke messages and queries using the msg router.
19-
func NewRouterService(storeService store.KVStoreService, queryRouter *baseapp.GRPCQueryRouter, msgRouter baseapp.MessageRouter) router.Router {
19+
func NewRouterService(storeService store.KVStoreService, queryRouter *baseapp.GRPCQueryRouter, msgRouter baseapp.MessageRouter) router.Service {
2020
return &routerService{
2121
queryRouterService: &queryRouterService{
2222
storeService: storeService, // TODO: this will be used later on as authenticating modules before routing
@@ -29,36 +29,46 @@ func NewRouterService(storeService store.KVStoreService, queryRouter *baseapp.GR
2929
}
3030
}
3131

32-
var _ router.Router = (*routerService)(nil)
32+
var _ router.Service = (*routerService)(nil)
3333

3434
type routerService struct {
35-
queryRouterService router.Service
36-
msgRouterService router.Service
35+
queryRouterService router.Router
36+
msgRouterService router.Router
3737
}
3838

39-
// MessageRouterService implements router.Router.
40-
func (r *routerService) MessageRouterService() router.Service {
39+
// MessageRouterService implements router.Service.
40+
func (r *routerService) MessageRouterService() router.Router {
4141
return r.msgRouterService
4242
}
4343

44-
// QueryRouterService implements router.Router.
45-
func (r *routerService) QueryRouterService() router.Service {
44+
// QueryRouterService implements router.Service.
45+
func (r *routerService) QueryRouterService() router.Router {
4646
return r.queryRouterService
4747
}
4848

49-
var _ router.Service = (*msgRouterService)(nil)
49+
var _ router.Router = (*msgRouterService)(nil)
5050

5151
type msgRouterService struct {
5252
storeService store.KVStoreService
5353
router baseapp.MessageRouter
5454
}
5555

56+
// CanInvoke returns an error if the given message cannot be invoked.
57+
func (m *msgRouterService) CanInvoke(ctx context.Context, msg protoiface.MessageV1) error {
58+
messageName := msgTypeURL(msg)
59+
handler := m.router.HybridHandlerByMsgName(messageName)
60+
if handler == nil {
61+
return fmt.Errorf("unknown message: %s", messageName)
62+
}
63+
64+
return nil
65+
}
66+
5667
// InvokeTyped execute a message and fill-in a response.
5768
// The response must be known and passed as a parameter.
5869
// Use InvokeUntyped if the response type is not known.
5970
func (m *msgRouterService) InvokeTyped(ctx context.Context, msg, resp protoiface.MessageV1) error {
6071
messageName := msgTypeURL(msg)
61-
6272
handler := m.router.HybridHandlerByMsgName(messageName)
6373
if handler == nil {
6474
return fmt.Errorf("unknown message: %s", messageName)
@@ -88,32 +98,47 @@ func (m *msgRouterService) InvokeUntyped(ctx context.Context, msg protoiface.Mes
8898
return msgResp, m.InvokeTyped(ctx, msg, msgResp)
8999
}
90100

91-
var _ router.Service = (*queryRouterService)(nil)
101+
var _ router.Router = (*queryRouterService)(nil)
92102

93103
type queryRouterService struct {
94104
storeService store.KVStoreService
95105
router *baseapp.GRPCQueryRouter
96106
}
97107

108+
// CanInvoke returns an error if the given request cannot be invoked.
109+
func (m *queryRouterService) CanInvoke(ctx context.Context, req protoiface.MessageV1) error {
110+
reqName := msgTypeURL(req)
111+
handlers := m.router.HybridHandlerByRequestName(reqName)
112+
if len(handlers) == 0 {
113+
return fmt.Errorf("unknown request: %s", reqName)
114+
} else if len(handlers) > 1 {
115+
return fmt.Errorf("ambiguous request, query have multiple handlers: %s", reqName)
116+
}
117+
118+
return nil
119+
}
120+
98121
// InvokeTyped execute a message and fill-in a response.
99122
// The response must be known and passed as a parameter.
100123
// Use InvokeUntyped if the response type is not known.
101124
func (m *queryRouterService) InvokeTyped(ctx context.Context, req, resp protoiface.MessageV1) error {
102-
messageName := msgTypeURL(req)
103-
handlers := m.router.HybridHandlerByRequestName(messageName)
125+
reqName := msgTypeURL(req)
126+
handlers := m.router.HybridHandlerByRequestName(reqName)
104127
if len(handlers) == 0 {
105-
return fmt.Errorf("unknown request: %s", messageName)
128+
return fmt.Errorf("unknown request: %s", reqName)
129+
} else if len(handlers) > 1 {
130+
return fmt.Errorf("ambiguous request, query have multiple handlers: %s", reqName)
106131
}
107132

108133
return handlers[0](ctx, req, resp)
109134
}
110135

111136
// InvokeUntyped execute a message and returns a response.
112137
func (m *queryRouterService) InvokeUntyped(ctx context.Context, req protoiface.MessageV1) (protoiface.MessageV1, error) {
113-
messageName := msgTypeURL(req)
114-
respName := m.router.ResponseNameByRequestName(messageName)
138+
reqName := msgTypeURL(req)
139+
respName := m.router.ResponseNameByRequestName(reqName)
115140
if respName == "" {
116-
return nil, fmt.Errorf("could not find response type for request %s (%T)", messageName, req)
141+
return nil, fmt.Errorf("could not find response type for request %s (%T)", reqName, req)
117142
}
118143

119144
// get response type

0 commit comments

Comments
 (0)