Implement auction hooks in registry module

This commit is contained in:
Prathamesh Musale 2024-02-27 14:59:24 +05:30
parent 56930ffa35
commit fe40617d9e
4 changed files with 108 additions and 24 deletions

View File

@ -11,6 +11,7 @@ import (
"cosmossdk.io/collections/indexes" "cosmossdk.io/collections/indexes"
storetypes "cosmossdk.io/core/store" storetypes "cosmossdk.io/core/store"
errorsmod "cosmossdk.io/errors" errorsmod "cosmossdk.io/errors"
"cosmossdk.io/log"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/legacy" "github.com/cosmos/cosmos-sdk/codec/legacy"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
@ -52,6 +53,7 @@ func newRecordIndexes(sb *collections.SchemaBuilder) RecordsIndexes {
// TODO // TODO
type AuthoritiesIndexes struct { type AuthoritiesIndexes struct {
AuctionId *indexes.Unique[string, string, registrytypes.NameAuthority]
} }
func (b AuthoritiesIndexes) IndexesList() []collections.Index[string, registrytypes.NameAuthority] { func (b AuthoritiesIndexes) IndexesList() []collections.Index[string, registrytypes.NameAuthority] {
@ -59,7 +61,15 @@ func (b AuthoritiesIndexes) IndexesList() []collections.Index[string, registryty
} }
func newAuthorityIndexes(sb *collections.SchemaBuilder) AuthoritiesIndexes { func newAuthorityIndexes(sb *collections.SchemaBuilder) AuthoritiesIndexes {
return AuthoritiesIndexes{} return AuthoritiesIndexes{
AuctionId: indexes.NewUnique(
sb, registrytypes.AuthoritiesByAuctionIdIndexPrefix, "authorities_by_auction_id",
collections.StringKey, collections.StringKey,
func(name string, v registrytypes.NameAuthority) (string, error) {
return v.AuctionId, nil
},
),
}
} }
type NameRecordsIndexes struct { type NameRecordsIndexes struct {
@ -87,7 +97,6 @@ type Keeper struct {
accountKeeper auth.AccountKeeper accountKeeper auth.AccountKeeper
bankKeeper bank.Keeper bankKeeper bank.Keeper
recordKeeper RecordKeeper
bondKeeper bondkeeper.Keeper bondKeeper bondkeeper.Keeper
auctionKeeper *auctionkeeper.Keeper auctionKeeper *auctionkeeper.Keeper
@ -107,7 +116,6 @@ func NewKeeper(
storeService storetypes.KVStoreService, storeService storetypes.KVStoreService,
accountKeeper auth.AccountKeeper, accountKeeper auth.AccountKeeper,
bankKeeper bank.Keeper, bankKeeper bank.Keeper,
recordKeeper RecordKeeper,
bondKeeper bondkeeper.Keeper, bondKeeper bondkeeper.Keeper,
auctionKeeper *auctionkeeper.Keeper, auctionKeeper *auctionkeeper.Keeper,
) Keeper { ) Keeper {
@ -116,7 +124,6 @@ func NewKeeper(
cdc: cdc, cdc: cdc,
accountKeeper: accountKeeper, accountKeeper: accountKeeper,
bankKeeper: bankKeeper, bankKeeper: bankKeeper,
recordKeeper: recordKeeper,
bondKeeper: bondKeeper, bondKeeper: bondKeeper,
auctionKeeper: auctionKeeper, auctionKeeper: auctionKeeper,
Params: collections.NewItem(sb, registrytypes.ParamsPrefix, "params", codec.CollValue[registrytypes.Params](cdc)), Params: collections.NewItem(sb, registrytypes.ParamsPrefix, "params", codec.CollValue[registrytypes.Params](cdc)),
@ -155,6 +162,15 @@ func NewKeeper(
return k return k
} }
// Logger returns a module-specific logger.
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return logger(ctx)
}
func logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", registrytypes.ModuleName)
}
// HasRecord - checks if a record by the given id exists. // HasRecord - checks if a record by the given id exists.
func (k Keeper) HasRecord(ctx sdk.Context, id string) (bool, error) { func (k Keeper) HasRecord(ctx sdk.Context, id string) (bool, error) {
has, err := k.Records.Has(ctx, id) has, err := k.Records.Has(ctx, id)

View File

@ -546,8 +546,7 @@ func (k Keeper) ProcessAuthorityExpiryQueue(ctx sdk.Context) error {
return err return err
} }
// TODO: Setup logger k.Logger(ctx).Info(fmt.Sprintf("Marking authority expired as no bond present: %s", name))
// k.Logger(ctx).Info(fmt.Sprintf("Marking authority expired as no bond present: %s", name))
return nil return nil
} }
@ -620,7 +619,7 @@ func (k Keeper) deleteAuthorityExpiryQueue(ctx sdk.Context, name string, authori
// tryTakeAuthorityRent tries to take rent from the authority bond. // tryTakeAuthorityRent tries to take rent from the authority bond.
func (k Keeper) tryTakeAuthorityRent(ctx sdk.Context, name string, authority registrytypes.NameAuthority) error { func (k Keeper) tryTakeAuthorityRent(ctx sdk.Context, name string, authority registrytypes.NameAuthority) error {
// k.Logger(ctx).Info(fmt.Sprintf("Trying to take rent for authority: %s", name)) k.Logger(ctx).Info(fmt.Sprintf("Trying to take rent for authority: %s", name))
params, err := k.GetParams(ctx) params, err := k.GetParams(ctx)
if err != nil { if err != nil {
@ -636,7 +635,8 @@ func (k Keeper) tryTakeAuthorityRent(ctx sdk.Context, name string, authority reg
return err return err
} }
// k.Logger(ctx).Info(fmt.Sprintf("Insufficient funds in owner account to pay authority rent, marking as expired: %s", name)) k.Logger(ctx).Info(fmt.Sprintf("Insufficient funds in owner account to pay authority rent, marking as expired: %s", name))
return k.deleteAuthorityExpiryQueue(ctx, name, authority) return k.deleteAuthorityExpiryQueue(ctx, name, authority)
} }
@ -653,7 +653,8 @@ func (k Keeper) tryTakeAuthorityRent(ctx sdk.Context, name string, authority reg
// Save authority. // Save authority.
authority.Status = registrytypes.AuthorityActive authority.Status = registrytypes.AuthorityActive
// k.Logger(ctx).Info(fmt.Sprintf("Authority rent paid successfully: %s", name)) k.Logger(ctx).Info(fmt.Sprintf("Authority rent paid successfully: %s", name))
return k.SaveNameAuthority(ctx, name, &authority) return k.SaveNameAuthority(ctx, name, &authority)
} }

View File

@ -1,8 +1,11 @@
package keeper package keeper
import ( import (
"errors"
"fmt"
"time" "time"
"cosmossdk.io/collections"
errorsmod "cosmossdk.io/errors" errorsmod "cosmossdk.io/errors"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
@ -24,37 +27,102 @@ var (
// RecordKeeper exposes the bare minimal read-only API for other modules. // RecordKeeper exposes the bare minimal read-only API for other modules.
type RecordKeeper struct { type RecordKeeper struct {
cdc codec.BinaryCodec // The wire codec for binary encoding/decoding. cdc codec.BinaryCodec // The wire codec for binary encoding/decoding.
k *Keeper
auctionKeeper *auctionkeeper.Keeper auctionKeeper *auctionkeeper.Keeper
// storeKey storetypes.StoreKey // Unexposed key to access store from sdk.Context
} }
// NewRecordKeeper creates new instances of the registry RecordKeeper // NewRecordKeeper creates new instances of the registry RecordKeeper
func NewRecordKeeper(cdc codec.BinaryCodec, auctionKeeper *auctionkeeper.Keeper) RecordKeeper { func NewRecordKeeper(cdc codec.BinaryCodec, k *Keeper, auctionKeeper *auctionkeeper.Keeper) RecordKeeper {
return RecordKeeper{ return RecordKeeper{
auctionKeeper: auctionKeeper,
cdc: cdc, cdc: cdc,
k: k,
auctionKeeper: auctionKeeper,
} }
} }
// ModuleName returns the module name. // ModuleName returns the module name.
func (k RecordKeeper) ModuleName() string { func (rk RecordKeeper) ModuleName() string {
return registrytypes.ModuleName return registrytypes.ModuleName
} }
func (k RecordKeeper) UsesAuction(ctx sdk.Context, auctionId string) bool { func (rk RecordKeeper) UsesAuction(ctx sdk.Context, auctionId string) bool {
panic("unimplemented") if _, err := rk.k.Authorities.Indexes.AuctionId.MatchExact(ctx, auctionId); err != nil {
// ErrNotFound
return false
}
return true
} }
func (k RecordKeeper) OnAuction(ctx sdk.Context, auctionId string) { func (rk RecordKeeper) OnAuction(ctx sdk.Context, auctionId string) {
panic("unimplemented") // no-op
} }
func (k RecordKeeper) OnAuctionBid(ctx sdk.Context, auctionId string, bidderAddress string) { func (rk RecordKeeper) OnAuctionBid(ctx sdk.Context, auctionId string, bidderAddress string) {
panic("unimplemented") // no-op
} }
func (k RecordKeeper) OnAuctionWinnerSelected(ctx sdk.Context, auctionId string) { func (rk RecordKeeper) OnAuctionWinnerSelected(ctx sdk.Context, auctionId string) {
panic("unimplemented") // Update authority status based on auction status/winner.
name, err := rk.k.Authorities.Indexes.AuctionId.MatchExact(ctx, auctionId)
if err != nil && !errors.Is(err, collections.ErrNotFound) {
panic(err)
}
if name == "" {
// We don't know about this auction, ignore.
logger(ctx).Info(fmt.Sprintf("Ignoring auction notification, name mapping not found: %s", auctionId))
return
}
if has, err := rk.k.HasNameAuthority(ctx, name); !has {
if err != nil {
panic(err)
}
// We don't know about this authority, ignore.
logger(ctx).Info(fmt.Sprintf("Ignoring auction notification, authority not found: %s", auctionId))
return
}
authority, err := rk.k.GetNameAuthority(ctx, name)
if err != nil {
panic(err)
}
auctionObj, err := rk.auctionKeeper.GetAuctionById(ctx, auctionId)
if err != nil {
panic(err)
}
if auctionObj.Status == auctiontypes.AuctionStatusCompleted {
if auctionObj.WinnerAddress != "" {
// Mark authority owner and change status to active.
authority.OwnerAddress = auctionObj.WinnerAddress
authority.Status = registrytypes.AuthorityActive
// Reset bond id if required, as owner has changed.
authority.BondId = ""
// Update height for updated/changed authority (owner).
// Can be used to check if names are older than the authority itself (stale names).
authority.Height = uint64(ctx.BlockHeight())
logger(ctx).Info(fmt.Sprintf("Winner selected, marking authority as active: %s", name))
} else {
// Mark as expired.
authority.Status = registrytypes.AuthorityExpired
logger(ctx).Info(fmt.Sprintf("No winner, marking authority as expired: %s", name))
}
// Forget about this auction now, we no longer need it.
authority.AuctionId = ""
if err = rk.k.SaveNameAuthority(ctx, name, &authority); err != nil {
panic(err)
}
} else {
logger(ctx).Info(fmt.Sprintf("Ignoring auction notification, status: %s", auctionObj.Status))
}
} }
// RenewRecord renews a record. // RenewRecord renews a record.

View File

@ -54,18 +54,17 @@ type ModuleOutputs struct {
} }
func ProvideModule(in ModuleInputs) ModuleOutputs { func ProvideModule(in ModuleInputs) ModuleOutputs {
recordKeeper := keeper.NewRecordKeeper(in.Cdc, in.AuctionKeeper)
k := keeper.NewKeeper( k := keeper.NewKeeper(
in.Cdc, in.Cdc,
in.StoreService, in.StoreService,
in.AccountKeeper, in.AccountKeeper,
in.BankKeeper, in.BankKeeper,
recordKeeper,
in.BondKeeper, in.BondKeeper,
in.AuctionKeeper, in.AuctionKeeper,
) )
m := NewAppModule(in.Cdc, k) m := NewAppModule(in.Cdc, k)
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}}
} }