-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
refactor(core): re-add handlers #21575
Changes from 6 commits
d1b339b
ee88f1d
1d29aa6
d86d287
ea34ede
3f04167
eb7803c
1d89400
14323ec
da06273
b3172a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ package appmodulev2 | |
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
transaction "cosmossdk.io/core/transaction" | ||
) | ||
|
@@ -16,47 +17,152 @@ type ( | |
PostMsgHandler = func(ctx context.Context, msg, msgResp transaction.Msg) error | ||
) | ||
|
||
// msg handler | ||
|
||
// PreMsgRouter is a router that allows you to register PreMsgHandlers for specific message types. | ||
type PreMsgRouter interface { | ||
// RegisterPreHandler will register a specific message handler hooking into the message with | ||
// the provided name. | ||
RegisterPreHandler(msgName string, handler PreMsgHandler) | ||
RegisterPreMsgHandler(msgName string, handler PreMsgHandler) | ||
// RegisterGlobalPreHandler will register a global message handler hooking into any message | ||
// being executed. | ||
RegisterGlobalPreHandler(handler PreMsgHandler) | ||
RegisterGlobalPreMsgHandler(handler PreMsgHandler) | ||
} | ||
|
||
// HasPreMsgHandlers is an interface that modules must implement if they want to register PreMsgHandlers. | ||
type HasPreMsgHandlers interface { | ||
RegisterPreMsgHandlers(router PreMsgRouter) | ||
} | ||
|
||
type MsgRouter interface { | ||
Register(msgName string, handler Handler) | ||
} | ||
// RegisterMsgPreHandler is a helper function that modules can use to not lose type safety when registering PreMsgHandler to the | ||
// PreMsgRouter. Example usage: | ||
// ```go | ||
// | ||
// func (h Handlers) BeforeSend(ctx context.Context, req *types.MsgSend) (*types.QueryBalanceResponse, error) { | ||
// ... before send logic ... | ||
// } | ||
// | ||
// func (m Module) RegisterPreMsgHandlers(router appmodule.PreMsgRouter) { | ||
// handlers := keeper.NewHandlers(m.keeper) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a way to use it. it's to simply define before send on the keeper and handle it via keeper, if we wanto to do it msg server style and have a wrapper like handlers then that is also fine. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like to think of the keeper as something only for state (basically, just holding public/private collections), and the business logic is somewhere else. |
||
// appmodule.RegisterMsgPreHandler(router, gogoproto.MessageName(types.MsgSend{}), handlers.BeforeSend) | ||
// } | ||
// | ||
// ``` | ||
func RegisterMsgPreHandler[Req transaction.Msg]( | ||
router PreMsgRouter, | ||
msgName string, | ||
handler func(ctx context.Context, msg Req) error, | ||
) { | ||
untypedHandler := func(ctx context.Context, m transaction.Msg) error { | ||
typed, ok := m.(Req) | ||
if !ok { | ||
return fmt.Errorf("unexpected type %T, wanted: %T", m, *new(Req)) | ||
} | ||
return handler(ctx, typed) | ||
} | ||
|
||
type HasMsgHandlers interface { | ||
RegisterMsgHandlers(router MsgRouter) | ||
router.RegisterPreMsgHandler(msgName, untypedHandler) | ||
} | ||
|
||
// PostMsgRouter is a router that allows you to register PostMsgHandlers for specific message types. | ||
type PostMsgRouter interface { | ||
// RegisterPostHandler will register a specific message handler hooking after the execution of message with | ||
// the provided name. | ||
RegisterPostHandler(msgName string, handler PostMsgHandler) | ||
RegisterPostMsgHandler(msgName string, handler PostMsgHandler) | ||
// RegisterGlobalPostHandler will register a global message handler hooking after the execution of any message. | ||
RegisterGlobalPostHandler(handler PostMsgHandler) | ||
RegisterGlobalPostMsgHandler(handler PostMsgHandler) | ||
} | ||
|
||
// HasPostMsgHandlers is an interface that modules must implement if they want to register PostMsgHandlers. | ||
type HasPostMsgHandlers interface { | ||
RegisterPostMsgHandlers(router PostMsgRouter) | ||
} | ||
|
||
// query handler | ||
// RegisterPostHandler is a helper function that modules can use to not lose type safety when registering handlers to the | ||
// PostMsgRouter. Example usage: | ||
// ```go | ||
// | ||
// func (h Handlers) AfterSend(ctx context.Context, req *types.MsgSend, resp *types.MsgSendResponse) error { | ||
// ... query logic ... | ||
// } | ||
// | ||
// func (m Module) RegisterPostMsgHandlers(router appmodule.PostMsgRouter) { | ||
// handlers := keeper.NewHandlers(m.keeper) | ||
// appmodule.RegisterPostMsgHandler(router, gogoproto.MessageName(types.MsgSend{}), handlers.AfterSend) | ||
// } | ||
// | ||
// ``` | ||
func RegisterPostMsgHandler[Req, Resp transaction.Msg]( | ||
router PostMsgRouter, | ||
msgName string, | ||
handler func(ctx context.Context, msg Req, msgResp Resp) error, | ||
) { | ||
untypedHandler := func(ctx context.Context, m, mResp transaction.Msg) error { | ||
typed, ok := m.(Req) | ||
if !ok { | ||
return fmt.Errorf("unexpected type %T, wanted: %T", m, *new(Req)) | ||
} | ||
typedResp, ok := mResp.(Resp) | ||
if !ok { | ||
return fmt.Errorf("unexpected type %T, wanted: %T", m, *new(Resp)) | ||
} | ||
return handler(ctx, typed, typedResp) | ||
} | ||
|
||
router.RegisterPostMsgHandler(msgName, untypedHandler) | ||
} | ||
|
||
// MsgRouter is a router that allows you to register Handlers for specific message types. | ||
type MsgRouter = interface { | ||
RegisterHandler(msgName string, handler Handler) error | ||
} | ||
|
||
type QueryRouter interface { | ||
Register(queryName string, handler Handler) | ||
// HasMsgHandlers is an interface that modules must implement if they want to register Handlers. | ||
type HasMsgHandlers interface { | ||
RegisterMsgHandlers(router MsgRouter) | ||
} | ||
|
||
// QueryRouter is a router that allows you to register QueryHandlers for specific query types. | ||
type QueryRouter = MsgRouter | ||
|
||
// HasQueryHandlers is an interface that modules must implement if they want to register QueryHandlers. | ||
type HasQueryHandlers interface { | ||
RegisterQueryHandlers(router QueryRouter) | ||
} | ||
|
||
// RegisterMsgHandler is a helper function that modules can use to not lose type safety when registering handlers to the MsgRouter and Query Router. | ||
// Example usage: | ||
// ```go | ||
// | ||
// func (h Handlers) Mint(ctx context.Context, req *types.MsgMint) (*types.MsgMintResponse, error) { | ||
// ... query logic ... | ||
julienrbrt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// } | ||
// | ||
// func (h Handlers) QueryBalance(ctx context.Context, req *types.QueryBalanceRequest) (*types.QueryBalanceResponse, error) { | ||
// ... query logic ... | ||
// } | ||
// | ||
// func (m Module) RegisterMsgHandlers(router appmodule.MsgRouter) { | ||
// handlers := keeper.NewHandlers(m.keeper) | ||
// err := appmodule.RegisterHandler(router, gogoproto.MessageName(types.MsgMint{}), handlers.MsgMint) | ||
// } | ||
// | ||
// func (m Module) RegisterQueryHandlers(router appmodule.QueryRouter) { | ||
// handlers := keeper.NewHandlers(m.keeper) | ||
// err := appmodule.RegisterHandler(router, gogoproto.MessageName(types.QueryBalanceRequest{}), handlers.QueryBalance) | ||
// } | ||
// | ||
// ``` | ||
func RegisterHandler[Req, Resp transaction.Msg]( | ||
router MsgRouter, | ||
msgName string, | ||
handler func(ctx context.Context, msg Req) (msgResp Resp, err error), | ||
) error { | ||
untypedHandler := func(ctx context.Context, m transaction.Msg) (transaction.Msg, error) { | ||
typed, ok := m.(Req) | ||
if !ok { | ||
return nil, fmt.Errorf("unexpected type %T, wanted: %T", m, *new(Req)) | ||
} | ||
return handler(ctx, typed) | ||
} | ||
|
||
return router.RegisterHandler(msgName, untypedHandler) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Response type here is invalid