-
Notifications
You must be signed in to change notification settings - Fork 606
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: cleanup middleware stacks #1248
Conversation
// create IBC module from bottom to top of stack | ||
var transferStack porttypes.IBCModule | ||
transferStack = transfer.NewIBCModule(app.TransferKeeper) | ||
transferStack = ibcfee.NewIBCMiddleware(transferStack, app.IBCFeeKeeper) |
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.
This works fine and I like the UX.
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.
Maybe we should add the routing right after:
ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack)
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.
I love this UX as well ❤️
// Create static IBC router, add app routes, then set and seal it | ||
// pass in top-level (fully-wrapped) IBCModules to IBC Router | ||
ibcRouter := porttypes.NewRouter() | ||
ibcRouter.AddRoute(icacontrollertypes.SubModuleName, icaControllerIBCModule). |
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.
Wasn't sure if we needed this still. I'm guessing we do, but I'm not 100% sure why. We don't add the fee module middleware for example.
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.
For any observers, we need this because the controller module owns the port capability and the ica-auth module owns the channel capability. thanks @colin-axner for the reminder
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.
I think I'll add a comment explaining this
// create IBC module from bottom to top of stack | ||
var transferStack porttypes.IBCModule | ||
transferStack = transfer.NewIBCModule(app.TransferKeeper) | ||
transferStack = ibcfee.NewIBCMiddleware(transferStack, app.IBCFeeKeeper) |
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.
Maybe we should add the routing right after:
ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack)
Codecov Report
@@ Coverage Diff @@
## main #1248 +/- ##
==========================================
+ Coverage 80.05% 80.10% +0.04%
==========================================
Files 166 166
Lines 11910 11951 +41
==========================================
+ Hits 9535 9573 +38
- Misses 1914 1920 +6
+ Partials 461 458 -3
|
testing/simapp/app.go
Outdated
app.IBCFeeKeeper = ibcfeekeeper.NewKeeper(appCodec, keys[ibcfeetypes.StoreKey], app.GetSubspace(ibcfeetypes.ModuleName), | ||
app.IBCKeeper.ChannelKeeper, app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, app.AccountKeeper, app.BankKeeper, | ||
) | ||
|
||
// Create Transfer Stack |
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.
Should we add a comment similar to this?
I think even something simple like that makes the flow of control much clearer
awesome! feel free to use our BDD tests too ❤️ |
Nice, I'll check em out. Can you link? Great work btw, I really like the pattern you used. Thanks for the inspiration 🤝 |
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.
Highly recommend creating an IBCModule
struct and embed it to the IBCMiddleware
to simplify the diff:
https://github.com/tharsis/evmos/blob/main/ibc/module.go
https://github.com/tharsis/evmos/blob/main/x/claims/ibc_middleware.go#L14-L21
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.
Excellent!
testing/simapp/app.go
Outdated
) | ||
// Create Interchain Accounts Stack | ||
// SendPacket, since it is originating from the application to core IBC: | ||
// icaAuthModuleKeeper.SendPacket -> icaControllerKeeper.SendPacket -> channel.SendPacket |
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.
technically the icaAuthModuleKeeper calls SendTx, maybe we should reflect this approach?
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.
Are we not incentivizing ICA packets? I think it would be a good example to show how to stack more than 1 middleware in case of the controller
chanCap *capabilitytypes.Capability, | ||
packet exported.PacketI, | ||
) error { | ||
panic("SendPacket not supported for ICA controller module") |
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.
ICA auth SendPacket
should call this function and then this function will pass the call one layer up.
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.
Why would this occur? ICA auth calls SendTx
. ICA auth shouldn't send non ICA packets?
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.
ICA auth is being wrapped by ICA correct? In that case we will want the packet flow to be:
ICA-Auth -SendPacket-> ICA -SendPacket-> IBC
The ICA middleware in this case will do nothing but forward the packet one layer up. This is to keep consistency and to make sure ICA-auth packets are not missed by additional middleware that is wrapping the stack
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.
ICA auth is being wrapped by ICA correct?
Only partially (not all callbacks/interfaces should be implemented). SendPacket
usage is replaced by SendTx
ICA controller constructs the packet and thus calls SendPacket
. ICA Auth shouldn't call SendPacket
. It could bypass SendTx
by calling SendPacket
directly, if we panic, we disable this functionality. I don't understand the purpose of SendTx
if we do allow bypassing. The spec doesn't indicate the appropriate functionality
// ICA Controller keeper | ||
app.ICAControllerKeeper = icacontrollerkeeper.NewKeeper( | ||
appCodec, keys[icacontrollertypes.StoreKey], app.GetSubspace(icacontrollertypes.SubModuleName), | ||
app.IBCKeeper.ChannelKeeper, // may be replaced with middleware such as ics29 fee |
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.
Should we include this comment for every IBC keeper so that it is clearer to people looking at this file?
4254ea7
to
6624b73
Compare
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.
Left a couple of small nits, but more or less looks good to go from what I can see!
Would be good to get a couple of more acks before merging.
Nice work 👍
"github.com/cosmos/ibc-go/v3/modules/core/exported" | ||
ibcexported "github.com/cosmos/ibc-go/v3/modules/core/exported" |
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.
This is imported twice
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.
we should add a linter for this
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.
duplicate import is still there
func NewIBCModule(k keeper.Keeper, app porttypes.IBCModule) IBCModule { | ||
return IBCModule{ | ||
keeper: k, | ||
// NewIBCMiddlware creates a new IBCMiddlware given the keeper and underlying application |
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.
// NewIBCMiddlware creates a new IBCMiddlware given the keeper and underlying application | |
// NewIBCMiddleware creates a new IBCMiddleware given the keeper and underlying application |
testing/simapp/app.go
Outdated
|
||
icaModule := ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper) | ||
// OnAckPacket as this is where fee's are paid out |
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.
nit: may as well be explicit
// OnAckPacket as this is where fee's are paid out | |
// OnAcknowledgementPacket as this is where fee's are paid out |
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.
LGTM! Nice work!
testing/simapp/app.go
Outdated
|
||
// Create Interchain Accounts Stack | ||
// SendPacket, since it is originating from the application to core IBC: | ||
// icaAuthModuleKeeper.SendPacket -> fee.SendPacket -> icaControllerKeeper.SendPacket -> channel.SendPacket |
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.
Hmm, this doesn't make sense. If fee was in the stack, it should be above icaControllerKeeper
. Futhermore, icaAuthModuleKeeper
must call SendTx
not SendPacket
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.
I would say that the icaAuthModuleKeeper
is still calling SendPacket
it's just doing so via SendTx
but I agree we should change to SendTx
to be more explicit.
testing/simapp/app.go
Outdated
var icaControllerStack porttypes.IBCModule | ||
icaControllerStack = ibcmock.NewIBCModule(&mockModule, ibcmock.NewMockIBCApp("", scopedICAMockKeeper)) | ||
app.ICAAuthModule = icaControllerStack.(ibcmock.IBCModule) | ||
icaControllerStack = ibcfee.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper) | ||
icaControllerStack = icacontroller.NewIBCMiddleware(icaControllerStack, app.ICAControllerKeeper) |
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.
I would prefer this change to be made in a followup pr. Ideally it would come with tests. But if contained in this pr, the fee should be at the top of the stack. Generic middleware cannot be inserted between ICA auth and controller because the SendTx
API
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.
Yep, good point. I'll remove it and do it in a follow up PR.
feeMockModule := ibcmock.NewIBCModule(&mockModule, ibcmock.NewMockIBCApp(MockFeePort, scopedFeeMockKeeper)) | ||
app.FeeMockModule = feeMockModule | ||
feeWithMockModule := ibcfee.NewIBCMiddleware(feeMockModule, app.IBCFeeKeeper) |
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.
I think it is possible to combine mockIBCModule
and the fee mock stack. Ideally the fee version just wouldn't be set for the isolated mock module usage. I'd be in favor of a followup pr fixing this
testing/simapp/app.go
Outdated
|
||
mockIBCModule := ibcmock.NewIBCModule(&mockModule, ibcmock.NewMockIBCApp(ibcmock.ModuleName, scopedIBCMockKeeper)) | ||
// RecvPacket, message that originates from core IBC and goes down to app, the flow is the otherway |
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.
// RecvPacket, message that originates from core IBC and goes down to app, the flow is the otherway | |
// RecvPacket, message that originates from core IBC and goes bottom to app, the flow is the other way |
testing/simapp/app.go
Outdated
AddRoute(ibcmock.ModuleName+icacontrollertypes.SubModuleName, icaControllerStack) // ica with mock auth module stack route to ica (top level of middleware stack) | ||
|
||
// Create Mock IBC Fee module stack for testing | ||
// OnAckPacket as this is where fee's are paid out |
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.
Same nit as Damian's:
// OnAckPacket as this is where fee's are paid out | |
// OnAcknowledgementPacket as this is where fee's are paid out |
testing/simapp/app.go
Outdated
// OnAckPacket as this is where fee's are paid out | ||
// mockModule.OnAcknowledgementPacket -> fee.OnAcknowledgementPacket -> channel.OnAcknowledgementPacket | ||
|
||
// RecvPacket, message that originates from core IBC and goes down to app, the flow is the otherway |
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.
// RecvPacket, message that originates from core IBC and goes down to app, the flow is the otherway | |
// RecvPacket, message that originates from core IBC and goes bottom to app, the flow is the other way |
testing/simapp/app.go
Outdated
|
||
// SendPacket, since it is originating from the application to core IBC: |
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.
Wouldn't it be more clear if you revert the order? So the explanation for SendPacket
first, then RecvPacket
's, and finally OnAcknowledgementPacket
's
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.
Agree
@@ -163,3 +167,22 @@ func (im IBCModule) OnTimeoutPacket( | |||
|
|||
return im.app.OnTimeoutPacket(ctx, packet, relayer) | |||
} | |||
|
|||
// SendPacket implements the ICS4 Wrapper interface | |||
func (im IBCMiddleware) SendPacket( |
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.
Ok I understand now why you've done it this way.
I think it should be documented in this function's go-doc that the packet is going to get constructed directly by ICA controller and sent to IBC rather than being created by ICA-auth.
Reading this file, made me think SendPacket wasn't happening at all when really it is happening through the controller's SendTx function
modules/apps/27-interchain-accounts/controller/ibc_middleware.go
Outdated
Show resolved
Hide resolved
Co-authored-by: Aditya <adityasripal@gmail.com>
I think this is good to merge now? |
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.
Wahoo!! Great job 🚀
"github.com/cosmos/ibc-go/v3/modules/core/exported" | ||
ibcexported "github.com/cosmos/ibc-go/v3/modules/core/exported" |
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.
duplicate import is still there
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.
Nice work! Could you create a new issue to tackle wrapping ICA with fee?
feeMockModule := ibcmock.NewIBCModule(&mockModule, ibcmock.NewMockIBCApp(MockFeePort, scopedFeeMockKeeper)) | ||
app.FeeMockModule = feeMockModule | ||
feeWithMockModule := ibcfee.NewIBCMiddleware(feeMockModule, app.IBCFeeKeeper) |
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.
nit: why do you use different variables here, but with transfer you just reassign?
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.
I needed to satisfy the compiler. The mock module is of type ibcmock.MockModule
& the middleware is of type IBCMiddleware
.
I think we could do a follow-up to create a mock middleware if it's useful.
<!-- Please read and fill out this form before submitting your PR. Please make sure you have reviewed our contributors guide before submitting your first PR. --> ## Overview <!-- Please provide an explanation of the PR, including the appropriate context, background, goal, and rationale. If there is an issue with this information, please provide a tl;dr and link the issue. --> ## Checklist <!-- Please complete the checklist to ensure that the PR is ready to be reviewed. IMPORTANT: PRs should be left in Draft until the below checklist is completed. --> - [ ] New and updated code has appropriate documentation - [ ] New and updated code has new and/or updated testing - [ ] Required CI checks are passing - [ ] Visual proof for any user facing features like CLI or documentation updates - [ ] Linked issues closed with keywords --------- Co-authored-by: Manav Aggarwal <manavaggarwal1234@gmail.com>
Description
Cleaning up the middleware stacks using evmos as inspiration.
closes: #773
Before we can merge this PR, please make sure that all the following items have been
checked off. If any of the checklist items are not applicable, please leave them but
write a little note why.
docs/
) or specification (x/<module>/spec/
)godoc
comments.Unreleased
section inCHANGELOG.md
Files changed
in the Github PR explorerCodecov Report
in the comment section below once CI passes