-
Notifications
You must be signed in to change notification settings - Fork 655
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: add app v2 scaffolding and app config #6216
base: feat/depinject
Are you sure you want to change the base?
Changes from 6 commits
d08c69c
2ed28d6
b923865
6033360
62c06d7
d4fe40a
b8b156b
5a72470
ed70ae2
fc30a95
fce3a30
2c3cb04
a8403f7
e7c2eae
1a232c0
54bc954
f8614c6
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 |
---|---|---|
|
@@ -13,7 +13,10 @@ import ( | |
modulev1 "github.com/cosmos/ibc-go/api/ibc/core/module/v1" | ||
capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper" | ||
clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" | ||
porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" | ||
"github.com/cosmos/ibc-go/v8/modules/core/exported" | ||
ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" | ||
ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" | ||
) | ||
|
||
var _ depinject.OnePerModuleType = AppModule{} | ||
|
@@ -25,6 +28,7 @@ func init() { | |
appmodule.Register( | ||
&modulev1.Module{}, | ||
appmodule.Provide(ProvideModule), | ||
appmodule.Invoke(InvokeAddAppRoutes, InvokeAddClientRoutes), | ||
) | ||
} | ||
|
||
|
@@ -36,9 +40,9 @@ type ModuleInputs struct { | |
Cdc codec.Codec | ||
Key *storetypes.KVStoreKey | ||
|
||
ConsensusHost clienttypes.ConsensusHost | ||
UpgradeKeeper clienttypes.UpgradeKeeper | ||
ScopedKeeper capabilitykeeper.ScopedKeeper | ||
CapabilityKeeper *capabilitykeeper.Keeper | ||
StakingKeeper clienttypes.StakingKeeper | ||
UpgradeKeeper clienttypes.UpgradeKeeper | ||
|
||
// LegacySubspace is used solely for migration of x/params managed parameters | ||
LegacySubspace paramtypes.Subspace `optional:"true"` | ||
|
@@ -48,27 +52,53 @@ type ModuleInputs struct { | |
type ModuleOutputs struct { | ||
depinject.Out | ||
|
||
IbcKeeper *ibckeeper.Keeper | ||
Module appmodule.AppModule | ||
Module appmodule.AppModule | ||
|
||
IBCKeeper *ibckeeper.Keeper | ||
ScopedKeeper capabilitykeeper.ScopedKeeper | ||
} | ||
|
||
// ProvideModule defines a depinject provider function to supply the module dependencies and return its outputs. | ||
func ProvideModule(in ModuleInputs) ModuleOutputs { | ||
// default to governance authority if not provided | ||
authority := authtypes.NewModuleAddress(govtypes.ModuleName) | ||
if in.Config.Authority != "" { | ||
authority = authtypes.NewModuleAddressOrBech32Address(in.Config.Authority) | ||
} | ||
|
||
scopedKeeper := in.CapabilityKeeper.ScopeToModule(exported.ModuleName) | ||
|
||
keeper := ibckeeper.NewKeeper( | ||
in.Cdc, | ||
in.Key, | ||
in.LegacySubspace, | ||
in.ConsensusHost, | ||
ibctm.NewConsensusHost(in.StakingKeeper), // NOTE: need to find a way to inject a ConsensusHost into DI container created outside context of app module. | ||
in.UpgradeKeeper, | ||
in.ScopedKeeper, | ||
scopedKeeper, | ||
authority.String(), | ||
) | ||
m := NewAppModule(keeper) | ||
|
||
return ModuleOutputs{IbcKeeper: keeper, Module: m} | ||
return ModuleOutputs{Module: m, IBCKeeper: keeper, ScopedKeeper: scopedKeeper} | ||
} | ||
|
||
// InvokeAddAppRoutes defines a depinject Invoker for registering ibc application modules on the core ibc application router. | ||
func InvokeAddAppRoutes(keeper *ibckeeper.Keeper, appRoutes []porttypes.IBCModuleRoute) { | ||
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. In contrast to https://github.com/cosmos/ibc-go/pull/6216/files#r1581785698, there is a bit of a gotcha when it comes to IBC apps. We cannot simply rely on the module name as the router key as some sdk modules may container more than one Here I added a wrapper type to 05-port called |
||
ibcRouter := porttypes.NewRouter() | ||
|
||
for _, route := range appRoutes { | ||
ibcRouter.AddRoute(route.Name, route.IBCModule) | ||
} | ||
|
||
ibcRouter.Seal() | ||
} | ||
|
||
// InvokeAddClientRoutes defines a depinject Invoker for registering ibc light client modules on the core ibc client router. | ||
// TODO: Maybe this should align with app router. i.e. create router here, add routes, and set on ibc keeper. | ||
// For app_v1 this would be the same approach, just create clientRouter in app.go instead of implicit creation inside of ibc.NewKeeper() | ||
func InvokeAddClientRoutes(keeper *ibckeeper.Keeper, clientRoutes map[string]exported.LightClientModule) { | ||
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. Lightclient modules implement This is my understanding. TBC when I get this all wired up together with tests! edit:
This doesn't seem to work with interface types(?). What does work is adding a wrapper struct for |
||
router := keeper.ClientKeeper.GetRouter() | ||
for modName, route := range clientRoutes { | ||
router.AddRoute(modName, route) | ||
} | ||
} |
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. Copied from sdk simapp. I don't think this is really needed, its just a mock vote extension handler. We can remove it if needs be |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package simapp | ||
|
||
import ( | ||
"bytes" | ||
"crypto/rand" | ||
"encoding/json" | ||
"fmt" | ||
|
||
"github.com/cosmos/cosmos-sdk/baseapp" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
|
||
abci "github.com/cometbft/cometbft/abci/types" | ||
) | ||
|
||
type ( | ||
// VoteExtensionHandler defines a dummy vote extension handler for SimApp. | ||
// | ||
// NOTE: This implementation is solely used for testing purposes. DO NOT use | ||
// in a production application! | ||
VoteExtensionHandler struct{} | ||
|
||
// VoteExtension defines the structure used to create a dummy vote extension. | ||
VoteExtension struct { | ||
Hash []byte | ||
Height int64 | ||
Data []byte | ||
} | ||
) | ||
|
||
func NewVoteExtensionHandler() *VoteExtensionHandler { | ||
return &VoteExtensionHandler{} | ||
} | ||
|
||
func (h *VoteExtensionHandler) SetHandlers(bApp *baseapp.BaseApp) { | ||
bApp.SetExtendVoteHandler(h.ExtendVote()) | ||
bApp.SetVerifyVoteExtensionHandler(h.VerifyVoteExtension()) | ||
} | ||
|
||
func (*VoteExtensionHandler) ExtendVote() sdk.ExtendVoteHandler { | ||
return func(_ sdk.Context, req *abci.RequestExtendVote) (*abci.ResponseExtendVote, error) { | ||
buf := make([]byte, 1024) | ||
|
||
_, err := rand.Read(buf) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to generate random vote extension data: %w", err) | ||
} | ||
|
||
ve := VoteExtension{ | ||
Hash: req.Hash, | ||
Height: req.Height, | ||
Data: buf, | ||
} | ||
|
||
bz, err := json.Marshal(ve) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to encode vote extension: %w", err) | ||
} | ||
|
||
return &abci.ResponseExtendVote{VoteExtension: bz}, nil | ||
} | ||
} | ||
|
||
func (*VoteExtensionHandler) VerifyVoteExtension() sdk.VerifyVoteExtensionHandler { | ||
return func(ctx sdk.Context, req *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) { | ||
var ve VoteExtension | ||
|
||
if err := json.Unmarshal(req.VoteExtension, &ve); err != nil { | ||
return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil | ||
} | ||
|
||
switch { | ||
case req.Height != ve.Height: | ||
return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil | ||
|
||
case !bytes.Equal(req.Hash, ve.Hash): | ||
return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil | ||
|
||
case len(ve.Data) != 1024: | ||
return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil | ||
} | ||
|
||
return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_ACCEPT}, nil | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
//go:build !app_v2 | ||
|
||
package simapp | ||
|
||
import ( | ||
|
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.
Unfortunately I haven't figured out a way to inject this interface type into the DI container yet. This is not a module output from another module and is instead created in
app.go
(v1). The concrete implementation type isibc tendermint
in almost all cases for cometbft chains. The constructor takes the staking keeper as an argument.app v1 snippet:
For now (while this PR is work-in-progress), we take the staking keeper as a module input and default to
ibctm.NewConsensusHost
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.
ConsensusHost will be deleted by the time this is picked back up