Skip to content

Commit 20c2dee

Browse files
committed
chore: complete poc for hyperlane app middleware
1 parent 76b0807 commit 20c2dee

7 files changed

Lines changed: 153 additions & 3 deletions

File tree

tests/simapp/app.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ func NewMiniAppWithCustomConfig(
198198

199199
app.App = appBuilder.Build(db, traceStore, baseAppOptions...)
200200

201+
app.RegisterWarpApps()
202+
201203
// register streaming services
202204
if err := app.RegisterStreamingServices(appOpts, app.kvStoreKeys()); err != nil {
203205
return nil, err

tests/simapp/warp.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package simapp
2+
3+
import (
4+
warp "github.com/bcp-innovations/hyperlane-cosmos/x/warp"
5+
warpTypes "github.com/bcp-innovations/hyperlane-cosmos/x/warp/types"
6+
)
7+
8+
func (app *App) RegisterWarpApps() {
9+
10+
warpApps := []warp.WarpApp{
11+
{TokenType: warpTypes.HYP_TOKEN_TYPE_COLLATERAL, App: &app.WarpKeeper},
12+
{TokenType: warpTypes.HYP_TOKEN_TYPE_SYNTHETIC, App: &app.WarpKeeper},
13+
}
14+
15+
warp.RegisterWarpApp(app.HyperlaneKeeper, warpApps...)
16+
}

x/core/keeper/keeper.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ func (k Keeper) AppRouter() *util.Router[util.HyperlaneApp] {
8787
return k.appRouter
8888
}
8989

90+
func (k Keeper) RegisterApp(moduleId uint8, module util.HyperlaneApp) {
91+
k.appRouter.RegisterModule(moduleId, module)
92+
}
93+
9094
func (k *Keeper) ReceiverIsmId(ctx context.Context, recipient util.HexAddress) (util.HexAddress, error) {
9195
handler, err := k.appRouter.GetModule(recipient)
9296
if err != nil {

x/warp/depinject.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"cosmossdk.io/core/store"
88
"cosmossdk.io/depinject"
99
modulev1 "github.com/bcp-innovations/hyperlane-cosmos/api/warp/module/v1"
10+
"github.com/bcp-innovations/hyperlane-cosmos/util"
1011
coreKeeper "github.com/bcp-innovations/hyperlane-cosmos/x/core/keeper"
1112
"github.com/bcp-innovations/hyperlane-cosmos/x/warp/keeper"
1213
"github.com/bcp-innovations/hyperlane-cosmos/x/warp/types"
@@ -61,6 +62,17 @@ func ProvideModule(in ModuleInputs) ModuleOutputs {
6162
return ModuleOutputs{Module: m, Keeper: k}
6263
}
6364

65+
type WarpApp struct {
66+
TokenType types.HypTokenType
67+
App util.HyperlaneApp
68+
}
69+
70+
func RegisterWarpApp(coreKeeper *coreKeeper.Keeper, warpApps ...WarpApp) {
71+
for _, warpApp := range warpApps {
72+
coreKeeper.RegisterApp(uint8(warpApp.TokenType), warpApp.App)
73+
}
74+
}
75+
6476
// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface.
6577
func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
6678
return &autocliv1.ModuleOptions{}

x/warp/keeper/keeper.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,6 @@ func NewKeeper(
7474
panic(err)
7575
}
7676

77-
coreKeeper.AppRouter().RegisterModule(uint8(types.HYP_TOKEN_TYPE_COLLATERAL), &k)
78-
coreKeeper.AppRouter().RegisterModule(uint8(types.HYP_TOKEN_TYPE_SYNTHETIC), &k)
79-
8077
k.Schema = schema
8178

8279
return k

x/warp/middleware/hook.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package middleware
2+
3+
import (
4+
"context"
5+
"github.com/bcp-innovations/hyperlane-cosmos/util"
6+
)
7+
8+
// HandleFn is the signature of the Handle function of an Hyperlane application.
9+
type HandleFn = func(ctx context.Context, mailboxId util.HexAddress, message util.HyperlaneMessage) error
10+
11+
type HandleHookI interface {
12+
PreHandleHook(ctx context.Context, mailboxID util.HexAddress, message util.HyperlaneMessage) error
13+
PostHandleHook(ctx context.Context, mailboxID util.HexAddress, message util.HyperlaneMessage) error
14+
}
15+
16+
type HandleHook struct {
17+
// preHandleHook is the behavior expected from a type that hook BEFORE executing
18+
// the Hyperlane application Handle method.
19+
preHandleFn HandleFn
20+
21+
// postHandleHook is the behavior expected from a type that hook AFTER executing
22+
// the Hyperlane application Handle method.
23+
postHandleFn HandleFn
24+
}
25+
26+
func (h *HandleHook) PreHandleHook(ctx context.Context, mailboxID util.HexAddress, message util.HyperlaneMessage) error {
27+
if h.preHandleFn != nil {
28+
return h.preHandleFn(ctx, mailboxID, message)
29+
}
30+
31+
return nil
32+
}
33+
34+
func (h *HandleHook) PostHandleHook(ctx context.Context, mailboxID util.HexAddress, message util.HyperlaneMessage) error {
35+
if h.postHandleFn != nil {
36+
return h.postHandleFn(ctx, mailboxID, message)
37+
}
38+
39+
return nil
40+
}
41+
42+
func NewHandleHook(opts ...HandleHookOpt) *HandleHook {
43+
h := &HandleHook{}
44+
45+
for _, opt := range opts {
46+
opt(h)
47+
}
48+
return h
49+
}
50+
51+
type HandleHookOpt func(*HandleHook)
52+
53+
func WithPreHandleHookFn(fn HandleFn) HandleHookOpt {
54+
return func(h *HandleHook) {
55+
h.preHandleFn = fn
56+
}
57+
}
58+
59+
func WithPostHandleFn(fn HandleFn) HandleHookOpt {
60+
return func(h *HandleHook) {
61+
h.postHandleFn = fn
62+
}
63+
}

x/warp/middleware/middleware.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package middleware
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/bcp-innovations/hyperlane-cosmos/util"
8+
)
9+
10+
// AppMiddleware defines the behavior an Hyperlane application middleware must implement.
11+
type AppMiddleware interface {
12+
util.HyperlaneApp
13+
}
14+
15+
var _ AppMiddleware = (*Middleware)(nil)
16+
17+
// Middleware is the default concrete type used to implement an Hyperlane
18+
// application middleware.
19+
type Middleware struct {
20+
util.HyperlaneApp
21+
hook HandleHookI
22+
}
23+
24+
func NewMiddleware(inner util.HyperlaneApp, hook HandleHookI) *Middleware {
25+
return &Middleware{
26+
HyperlaneApp: inner,
27+
hook: hook,
28+
}
29+
}
30+
31+
func (m *Middleware) Exists(ctx context.Context, recipient util.HexAddress) (bool, error) {
32+
return m.HyperlaneApp.Exists(ctx, recipient)
33+
}
34+
35+
func (m *Middleware) Handle(ctx context.Context, mailboxID util.HexAddress, message util.HyperlaneMessage) error {
36+
37+
err := m.hook.PreHandleHook(ctx, mailboxID, message)
38+
if err != nil {
39+
return fmt.Errorf("failed to execute pre handle hook: %w", err)
40+
}
41+
42+
err = m.HyperlaneApp.Handle(ctx, mailboxID, message)
43+
if err != nil {
44+
return err
45+
}
46+
47+
err = m.hook.PostHandleHook(ctx, mailboxID, message)
48+
if err != nil {
49+
return fmt.Errorf("failed to execute post handle hook: %w", err)
50+
}
51+
return nil
52+
}
53+
54+
func (m *Middleware) ReceiverIsmId(ctx context.Context, recipient util.HexAddress) (*util.HexAddress, error) {
55+
return m.HyperlaneApp.ReceiverIsmId(ctx, recipient)
56+
}

0 commit comments

Comments
 (0)