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(core/handlers): improve handlers registration DevX #22007

Merged
merged 4 commits into from
Oct 1, 2024
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
50 changes: 34 additions & 16 deletions core/appmodule/v2/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ import (
type (
// PreMsgHandler is a handler that is executed before Handler. If it errors the execution reverts.
PreMsgHandler = func(ctx context.Context, msg transaction.Msg) error
// Handler handles the state transition of the provided message.
Handler = func(ctx context.Context, msg transaction.Msg) (msgResp transaction.Msg, err error)
// HandlerFunc handles the state transition of the provided message.
HandlerFunc = func(ctx context.Context, msg transaction.Msg) (msgResp transaction.Msg, err error)
Comment on lines +13 to +14
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Remaining references to Handler found

The renaming of Handler to HandlerFunc in core/appmodule/v2/handlers.go has introduced multiple remaining references to the old Handler type across the codebase. Please ensure that all instances are reviewed and updated accordingly to maintain consistency and prevent potential issues.

🔗 Analysis chain

Approve renaming of Handler to HandlerFunc

The renaming of Handler to HandlerFunc improves clarity and aligns with Go naming conventions for function types. This change enhances code readability.

To ensure this change doesn't introduce any issues, please run the following command to check for any remaining references to the old Handler type:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining references to the old Handler type
rg --type go 'type.*Handler.*=.*func\(ctx context\.Context, msg transaction\.Msg\).*\(transaction\.Msg, error\)'

Length of output: 138


Script:

#!/bin/bash
# Corrected script to search for any remaining references to the old Handler type
rg --type go "type\s+Handler\s*=\s*func\(ctx\s+context\.Context,\s+msg\s+transaction\.Msg\)\s+\(transaction\.Msg,\s+error\)"

Length of output: 126


Script:

#!/bin/bash
# Search for any remaining references to the old Handler type across the codebase
rg --type go '\bHandler\b'

Length of output: 56529

// PostMsgHandler runs after Handler, only if Handler does not error. If PostMsgHandler errors
// then the execution is reverted.
PostMsgHandler = func(ctx context.Context, msg, msgResp transaction.Msg) error
)

// 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
// RegisterPreMsgHandler will register a specific message handler hooking into the message with
// the provided name.
RegisterPreMsgHandler(msgName string, handler PreMsgHandler)
// RegisterGlobalPreHandler will register a global message handler hooking into any message
// RegisterGlobalPreMsgHandler will register a global message handler hooking into any message
// being executed.
RegisterGlobalPreMsgHandler(handler PreMsgHandler)
}
Expand Down Expand Up @@ -64,10 +64,10 @@ func RegisterMsgPreHandler[Req transaction.Msg](

// 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
// RegisterPostMsgHandler will register a specific message handler hooking after the execution of message with
// the provided name.
RegisterPostMsgHandler(msgName string, handler PostMsgHandler)
// RegisterGlobalPostHandler will register a global message handler hooking after the execution of any message.
// RegisterGlobalPostMsgHandler will register a global message handler hooking after the execution of any message.
RegisterGlobalPostMsgHandler(handler PostMsgHandler)
}

Expand All @@ -76,7 +76,7 @@ type HasPostMsgHandlers interface {
RegisterPostMsgHandlers(router PostMsgRouter)
}

// RegisterPostHandler is a helper function that modules can use to not lose type safety when registering handlers to the
// RegisterPostMsgHandler is a helper function that modules can use to not lose type safety when registering handlers to the
// PostMsgRouter. Example usage:
// ```go
//
Expand Down Expand Up @@ -110,9 +110,20 @@ func RegisterPostMsgHandler[Req, Resp transaction.Msg](
router.RegisterPostMsgHandler(msgName, untypedHandler)
}

// Handler defines a handler descriptor.
type Handler struct {
// Func defines the actual handler, the function that runs a request and returns a response.
// Can be query handler or msg handler.
Func HandlerFunc
// MakeMsg instantiates the type of the request, can be used in decoding contexts.
MakeMsg func() transaction.Msg
// MakeMsgResp instantiates a new response, can be used in decoding contexts.
MakeMsgResp func() transaction.Msg
}

// MsgRouter is a router that allows you to register Handlers for specific message types.
type MsgRouter = interface {
RegisterHandler(msgName string, handler Handler) error
RegisterHandler(handler Handler)
}

// HasMsgHandlers is an interface that modules must implement if they want to register Handlers.
Expand Down Expand Up @@ -142,27 +153,34 @@ type HasQueryHandlers interface {
//
// func (m Module) RegisterMsgHandlers(router appmodule.MsgRouter) {
// handlers := keeper.NewHandlers(m.keeper)
// err := appmodule.RegisterHandler(router, gogoproto.MessageName(types.MsgMint{}), handlers.MsgMint)
// err := appmodule.RegisterHandler(router, handlers.MsgMint)
// }
//
// func (m Module) RegisterQueryHandlers(router appmodule.QueryRouter) {
// handlers := keeper.NewHandlers(m.keeper)
// err := appmodule.RegisterHandler(router, gogoproto.MessageName(types.QueryBalanceRequest{}), handlers.QueryBalance)
// err := appmodule.RegisterHandler(router, handlers.QueryBalance)
// }
//
// ```
func RegisterHandler[Req, Resp transaction.Msg](
func RegisterMsgHandler[Req, Resp any, PReq transaction.GenericMsg[Req], PResp transaction.GenericMsg[Resp]](
router MsgRouter,
msgName string,
handler func(ctx context.Context, msg Req) (msgResp Resp, err error),
) error {
handler func(ctx context.Context, msg PReq) (msgResp PResp, err error),
) {
untypedHandler := func(ctx context.Context, m transaction.Msg) (transaction.Msg, error) {
typed, ok := m.(Req)
typed, ok := m.(PReq)
if !ok {
return nil, fmt.Errorf("unexpected type %T, wanted: %T", m, *new(Req))
}
return handler(ctx, typed)
}

return router.RegisterHandler(msgName, untypedHandler)
router.RegisterHandler(Handler{
Func: untypedHandler,
MakeMsg: func() transaction.Msg {
return PReq(new(Req))
},
MakeMsgResp: func() transaction.Msg {
return PResp(new(Resp))
},
})
}
8 changes: 8 additions & 0 deletions core/transaction/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ type (
Identity = []byte
)

// GenericMsg defines a generic version of a Msg.
// The GenericMsg refers to the non pointer version of Msg,
// and is required to allow its instantiations in generic contexts.
type GenericMsg[T any] interface {
*T
Msg
}

// Codec defines the TX codec, which converts a TX from bytes to its concrete representation.
type Codec[T Tx] interface {
// Decode decodes the tx bytes into a DecodedTx, containing
Expand Down
3 changes: 1 addition & 2 deletions simapp/v2/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.23.1
require (
cosmossdk.io/api v0.7.6
cosmossdk.io/client/v2 v2.0.0-00010101000000-000000000000
cosmossdk.io/core v1.0.0-alpha.3
cosmossdk.io/core v1.0.0-alpha.3.0.20241001182821-3f9c9a087760
cosmossdk.io/depinject v1.0.0
cosmossdk.io/log v1.4.1
cosmossdk.io/math v1.3.0
Expand Down Expand Up @@ -291,7 +291,6 @@ replace (
// server v2 integration
replace (
cosmossdk.io/api => ../../api
cosmossdk.io/core => ../../core
cosmossdk.io/runtime/v2 => ../../runtime/v2
cosmossdk.io/server/v2 => ../../server/v2
cosmossdk.io/server/v2/appmanager => ../../server/v2/appmanager
Expand Down
2 changes: 2 additions & 0 deletions simapp/v2/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX
cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg=
cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0=
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
cosmossdk.io/core v1.0.0-alpha.3.0.20241001182821-3f9c9a087760 h1:jyldjo99XdhT94cIyoSVBT2hxNoI4X/1pEUh4+659e0=
cosmossdk.io/core v1.0.0-alpha.3.0.20241001182821-3f9c9a087760/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY=
cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY=
cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs=
cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050=
Expand Down
Loading