Setup hooks between laconic modules #9
@ -77,7 +77,7 @@ type LaconicApp struct {
|
||||
|
||||
// laconic keepers
|
||||
AuctionKeeper *auctionkeeper.Keeper // (Use * as per ProvideModule implementation)
|
||||
BondKeeper bondkeeper.Keeper
|
||||
BondKeeper *bondkeeper.Keeper
|
||||
RegistryKeeper registrykeeper.Keeper
|
||||
// RegistryRecordKeeper registrykeeper.RecordKeeper
|
||||
|
||||
|
19
x/bond/expected_keeper.go
Normal file
19
x/bond/expected_keeper.go
Normal file
@ -0,0 +1,19 @@
|
||||
package bond
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// BondUsageKeeper keep track of bond usage in other modules.
|
||||
// Used to, for example, prevent deletion of a bond that's in use.
|
||||
type BondUsageKeeper interface {
|
||||
ModuleName() string
|
||||
UsesBond(ctx sdk.Context, bondId string) bool
|
||||
}
|
||||
|
||||
// BondHooksWrapper is a wrapper for modules to inject BondUsageKeeper using depinject.
|
||||
// Reference: https://github.com/cosmos/cosmos-sdk/tree/v0.50.3/core/appmodule#resolving-circular-dependencies
|
||||
type BondHooksWrapper struct{ BondUsageKeeper }
|
||||
|
||||
// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
|
||||
func (BondHooksWrapper) IsOnePerModuleType() {}
|
@ -49,7 +49,7 @@ type Keeper struct {
|
||||
bankKeeper bank.Keeper
|
||||
|
||||
// Track bond usage in other cosmos-sdk modules (more like a usage tracker).
|
||||
// usageKeepers []types.BondUsageKeeper
|
||||
usageKeepers []bondtypes.BondUsageKeeper
|
||||
|
||||
// State management
|
||||
Schema collections.Schema
|
||||
@ -63,8 +63,7 @@ func NewKeeper(
|
||||
storeService store.KVStoreService,
|
||||
accountKeeper auth.AccountKeeper,
|
||||
bankKeeper bank.Keeper,
|
||||
// usageKeepers []types.BondUsageKeeper,
|
||||
) Keeper {
|
||||
) *Keeper {
|
||||
sb := collections.NewSchemaBuilder(storeService)
|
||||
k := Keeper{
|
||||
cdc: cdc,
|
||||
@ -72,7 +71,7 @@ func NewKeeper(
|
||||
bankKeeper: bankKeeper,
|
||||
Params: collections.NewItem(sb, bondtypes.ParamsPrefix, "params", codec.CollValue[bondtypes.Params](cdc)),
|
||||
Bonds: collections.NewIndexedMap(sb, bondtypes.BondsPrefix, "bonds", collections.StringKey, codec.CollValue[bondtypes.Bond](cdc), newBondIndexes(sb)),
|
||||
// usageKeepers: usageKeepers,
|
||||
usageKeepers: nil,
|
||||
}
|
||||
|
||||
schema, err := sb.Build()
|
||||
@ -82,7 +81,15 @@ func NewKeeper(
|
||||
|
||||
k.Schema = schema
|
||||
|
||||
return k
|
||||
return &k
|
||||
}
|
||||
|
||||
func (k *Keeper) SetUsageKeepers(usageKeepers []bondtypes.BondUsageKeeper) {
|
||||
if k.usageKeepers != nil {
|
||||
panic("cannot set bond hooks twice")
|
||||
}
|
||||
|
||||
k.usageKeepers = usageKeepers
|
||||
}
|
||||
|
||||
// BondId simplifies generation of bond Ids.
|
||||
@ -318,13 +325,12 @@ func (k Keeper) CancelBond(ctx sdk.Context, id string, ownerAddress sdk.AccAddre
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrUnauthorized, "Bond owner mismatch.")
|
||||
}
|
||||
|
||||
// TODO
|
||||
// Check if bond is used in other modules.
|
||||
// for _, usageKeeper := range k.usageKeepers {
|
||||
// if usageKeeper.UsesBond(ctx, id) {
|
||||
// return nil, errorsmod.Wrap(sdkerrors.ErrUnauthorized, fmt.Sprintf("Bond in use by the '%s' module.", usageKeeper.ModuleName()))
|
||||
// }
|
||||
// }
|
||||
for _, usageKeeper := range k.usageKeepers {
|
||||
if usageKeeper.UsesBond(ctx, id) {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrUnauthorized, fmt.Sprintf("Bond in use by the '%s' module.", usageKeeper.ModuleName()))
|
||||
}
|
||||
}
|
||||
|
||||
// Move funds from the bond into the account.
|
||||
err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, bondtypes.ModuleName, ownerAddress, bond.Balance)
|
||||
|
@ -11,11 +11,11 @@ import (
|
||||
var _ bond.MsgServer = msgServer{}
|
||||
|
||||
type msgServer struct {
|
||||
k Keeper
|
||||
k *Keeper
|
||||
}
|
||||
|
||||
// NewMsgServerImpl returns an implementation of the module MsgServer interface.
|
||||
func NewMsgServerImpl(keeper Keeper) bond.MsgServer {
|
||||
func NewMsgServerImpl(keeper *Keeper) bond.MsgServer {
|
||||
return &msgServer{k: keeper}
|
||||
}
|
||||
|
||||
|
@ -13,11 +13,11 @@ import (
|
||||
var _ bondtypes.QueryServer = queryServer{}
|
||||
|
||||
type queryServer struct {
|
||||
k Keeper
|
||||
k *Keeper
|
||||
}
|
||||
|
||||
// NewQueryServerImpl returns an implementation of the module QueryServer.
|
||||
func NewQueryServerImpl(k Keeper) bondtypes.QueryServer {
|
||||
func NewQueryServerImpl(k *Keeper) bondtypes.QueryServer {
|
||||
return queryServer{k}
|
||||
}
|
||||
|
||||
|
@ -4,12 +4,14 @@ import (
|
||||
"cosmossdk.io/core/appmodule"
|
||||
"cosmossdk.io/core/store"
|
||||
"cosmossdk.io/depinject"
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
auth "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
bank "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
|
||||
modulev1 "git.vdb.to/cerc-io/laconic2d/api/cerc/bond/module/v1"
|
||||
"git.vdb.to/cerc-io/laconic2d/x/bond"
|
||||
"git.vdb.to/cerc-io/laconic2d/x/bond/keeper"
|
||||
)
|
||||
|
||||
@ -25,6 +27,7 @@ func init() {
|
||||
appmodule.Register(
|
||||
&modulev1.Module{},
|
||||
appmodule.Provide(ProvideModule),
|
||||
appmodule.Invoke(InvokeSetBondHooks),
|
||||
)
|
||||
}
|
||||
|
||||
@ -41,7 +44,7 @@ type ModuleInputs struct {
|
||||
type ModuleOutputs struct {
|
||||
depinject.Out
|
||||
|
||||
Keeper keeper.Keeper
|
||||
Keeper *keeper.Keeper
|
||||
Module appmodule.AppModule
|
||||
}
|
||||
|
||||
@ -51,3 +54,25 @@ func ProvideModule(in ModuleInputs) ModuleOutputs {
|
||||
|
||||
return ModuleOutputs{Module: m, Keeper: k}
|
||||
}
|
||||
|
||||
func InvokeSetBondHooks(
|
||||
config *modulev1.Module,
|
||||
keeper *keeper.Keeper,
|
||||
bondHooks map[string]bond.BondHooksWrapper,
|
||||
) error {
|
||||
// all arguments to invokers are optional
|
||||
if keeper == nil || config == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var usageKeepers []bond.BondUsageKeeper
|
||||
|
||||
for _, modName := range maps.Keys(bondHooks) {
|
||||
hook := bondHooks[modName]
|
||||
usageKeepers = append(usageKeepers, hook)
|
||||
}
|
||||
|
||||
keeper.SetUsageKeepers(usageKeepers)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -33,11 +33,11 @@ const ConsensusVersion = 1
|
||||
|
||||
type AppModule struct {
|
||||
cdc codec.Codec
|
||||
keeper keeper.Keeper
|
||||
keeper *keeper.Keeper
|
||||
}
|
||||
|
||||
// NewAppModule creates a new AppModule object
|
||||
func NewAppModule(cdc codec.Codec, keeper keeper.Keeper) AppModule {
|
||||
func NewAppModule(cdc codec.Codec, keeper *keeper.Keeper) AppModule {
|
||||
return AppModule{
|
||||
cdc: cdc,
|
||||
keeper: keeper,
|
||||
|
@ -97,7 +97,7 @@ type Keeper struct {
|
||||
|
||||
accountKeeper auth.AccountKeeper
|
||||
bankKeeper bank.Keeper
|
||||
bondKeeper bondkeeper.Keeper
|
||||
bondKeeper *bondkeeper.Keeper
|
||||
auctionKeeper *auctionkeeper.Keeper
|
||||
|
||||
// state management
|
||||
@ -116,7 +116,7 @@ func NewKeeper(
|
||||
storeService storetypes.KVStoreService,
|
||||
accountKeeper auth.AccountKeeper,
|
||||
bankKeeper bank.Keeper,
|
||||
bondKeeper bondkeeper.Keeper,
|
||||
bondKeeper *bondkeeper.Keeper,
|
||||
auctionKeeper *auctionkeeper.Keeper,
|
||||
) Keeper {
|
||||
sb := collections.NewSchemaBuilder(storeService)
|
||||
|
@ -46,12 +46,12 @@ func (rk RecordKeeper) ModuleName() string {
|
||||
}
|
||||
|
||||
func (rk RecordKeeper) UsesAuction(ctx sdk.Context, auctionId string) bool {
|
||||
if _, err := rk.k.Authorities.Indexes.AuctionId.MatchExact(ctx, auctionId); err != nil {
|
||||
// ErrNotFound
|
||||
return false
|
||||
iter, err := rk.k.Authorities.Indexes.AuctionId.MatchExact(ctx, auctionId)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return true
|
||||
return iter.Valid()
|
||||
}
|
||||
|
||||
func (rk RecordKeeper) OnAuction(ctx sdk.Context, auctionId string) {
|
||||
@ -133,6 +133,16 @@ func (rk RecordKeeper) OnAuctionWinnerSelected(ctx sdk.Context, auctionId string
|
||||
}
|
||||
}
|
||||
|
||||
// UsesBond returns true if the bond has associated records.
|
||||
func (rk RecordKeeper) UsesBond(ctx sdk.Context, bondId string) bool {
|
||||
iter, err := rk.k.Records.Indexes.BondId.MatchExact(ctx, bondId)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return iter.Valid()
|
||||
}
|
||||
|
||||
// RenewRecord renews a record.
|
||||
func (k Keeper) RenewRecord(ctx sdk.Context, msg registrytypes.MsgRenewRecord) error {
|
||||
if has, err := k.HasRecord(ctx, msg.RecordId); !has {
|
||||
|
@ -10,8 +10,9 @@ import (
|
||||
bank "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
|
||||
modulev1 "git.vdb.to/cerc-io/laconic2d/api/cerc/registry/module/v1"
|
||||
auction "git.vdb.to/cerc-io/laconic2d/x/auction"
|
||||
"git.vdb.to/cerc-io/laconic2d/x/auction"
|
||||
auctionkeeper "git.vdb.to/cerc-io/laconic2d/x/auction/keeper"
|
||||
"git.vdb.to/cerc-io/laconic2d/x/bond"
|
||||
bondkeeper "git.vdb.to/cerc-io/laconic2d/x/bond/keeper"
|
||||
"git.vdb.to/cerc-io/laconic2d/x/registry/keeper"
|
||||
)
|
||||
@ -40,7 +41,7 @@ type ModuleInputs struct {
|
||||
AccountKeeper auth.AccountKeeper
|
||||
BankKeeper bank.Keeper
|
||||
|
||||
BondKeeper bondkeeper.Keeper
|
||||
BondKeeper *bondkeeper.Keeper
|
||||
AuctionKeeper *auctionkeeper.Keeper
|
||||
}
|
||||
|
||||
@ -51,6 +52,7 @@ type ModuleOutputs struct {
|
||||
Module appmodule.AppModule
|
||||
|
||||
AuctionHooks auction.AuctionHooksWrapper
|
||||
BondHooks bond.BondHooksWrapper
|
||||
}
|
||||
|
||||
func ProvideModule(in ModuleInputs) ModuleOutputs {
|
||||
@ -66,5 +68,9 @@ func ProvideModule(in ModuleInputs) ModuleOutputs {
|
||||
|
||||
recordKeeper := keeper.NewRecordKeeper(in.Cdc, &k, in.AuctionKeeper)
|
||||
|
||||
return ModuleOutputs{Module: m, Keeper: k, AuctionHooks: auction.AuctionHooksWrapper{AuctionUsageKeeper: recordKeeper}}
|
||||
return ModuleOutputs{
|
||||
Module: m, Keeper: k,
|
||||
AuctionHooks: auction.AuctionHooksWrapper{AuctionUsageKeeper: recordKeeper},
|
||||
BondHooks: bond.BondHooksWrapper{BondUsageKeeper: recordKeeper},
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user