forked from cerc-io/laconicd
Setup hooks between laconic modules (#9)
- Implement auction and bond module hooks in registry module - Code cleanup Reviewed-on: deep-stack/laconic2d#9 Co-authored-by: Prathamesh Musale <prathamesh.musale0@gmail.com> Co-committed-by: Prathamesh Musale <prathamesh.musale0@gmail.com>
This commit is contained in:
@@ -43,12 +43,6 @@ func (k *Keeper) InitGenesis(ctx sdk.Context, data *registry.GenesisState) error
|
||||
if err := k.insertAuthorityExpiryQueue(ctx, authority.Name, authority.Entry.ExpiryTime); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO
|
||||
// Note: Bond genesis runs first, so bonds will already be present.
|
||||
// if authority.Entry.BondId != "" {
|
||||
// k.AddBondToAuthorityIndexEntry(ctx, authority.Entry.BondId, authority.Name)
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+28
-19
@@ -11,6 +11,7 @@ import (
|
||||
"cosmossdk.io/collections/indexes"
|
||||
storetypes "cosmossdk.io/core/store"
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
"cosmossdk.io/log"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@@ -28,8 +29,6 @@ import (
|
||||
"git.vdb.to/cerc-io/laconic2d/x/registry/helpers"
|
||||
)
|
||||
|
||||
// TODO: Add required methods
|
||||
|
||||
type RecordsIndexes struct {
|
||||
BondId *indexes.Multi[string, string, registrytypes.Record]
|
||||
}
|
||||
@@ -50,16 +49,24 @@ func newRecordIndexes(sb *collections.SchemaBuilder) RecordsIndexes {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
type AuthoritiesIndexes struct {
|
||||
AuctionId *indexes.Multi[string, string, registrytypes.NameAuthority]
|
||||
}
|
||||
|
||||
func (b AuthoritiesIndexes) IndexesList() []collections.Index[string, registrytypes.NameAuthority] {
|
||||
return []collections.Index[string, registrytypes.NameAuthority]{}
|
||||
func (a AuthoritiesIndexes) IndexesList() []collections.Index[string, registrytypes.NameAuthority] {
|
||||
return []collections.Index[string, registrytypes.NameAuthority]{a.AuctionId}
|
||||
}
|
||||
|
||||
func newAuthorityIndexes(sb *collections.SchemaBuilder) AuthoritiesIndexes {
|
||||
return AuthoritiesIndexes{}
|
||||
return AuthoritiesIndexes{
|
||||
AuctionId: indexes.NewMulti(
|
||||
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 {
|
||||
@@ -87,9 +94,8 @@ type Keeper struct {
|
||||
|
||||
accountKeeper auth.AccountKeeper
|
||||
bankKeeper bank.Keeper
|
||||
recordKeeper RecordKeeper
|
||||
bondKeeper bondkeeper.Keeper
|
||||
auctionKeeper auctionkeeper.Keeper
|
||||
bondKeeper *bondkeeper.Keeper
|
||||
auctionKeeper *auctionkeeper.Keeper
|
||||
|
||||
// state management
|
||||
Schema collections.Schema
|
||||
@@ -107,16 +113,14 @@ func NewKeeper(
|
||||
storeService storetypes.KVStoreService,
|
||||
accountKeeper auth.AccountKeeper,
|
||||
bankKeeper bank.Keeper,
|
||||
recordKeeper RecordKeeper,
|
||||
bondKeeper bondkeeper.Keeper,
|
||||
auctionKeeper auctionkeeper.Keeper,
|
||||
bondKeeper *bondkeeper.Keeper,
|
||||
auctionKeeper *auctionkeeper.Keeper,
|
||||
) Keeper {
|
||||
sb := collections.NewSchemaBuilder(storeService)
|
||||
k := Keeper{
|
||||
cdc: cdc,
|
||||
accountKeeper: accountKeeper,
|
||||
bankKeeper: bankKeeper,
|
||||
recordKeeper: recordKeeper,
|
||||
bondKeeper: bondKeeper,
|
||||
auctionKeeper: auctionKeeper,
|
||||
Params: collections.NewItem(sb, registrytypes.ParamsPrefix, "params", codec.CollValue[registrytypes.Params](cdc)),
|
||||
@@ -155,6 +159,15 @@ func NewKeeper(
|
||||
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.
|
||||
func (k Keeper) HasRecord(ctx sdk.Context, id string) (bool, error) {
|
||||
has, err := k.Records.Has(ctx, id)
|
||||
@@ -230,9 +243,6 @@ func (k Keeper) RecordsFromAttributes(ctx sdk.Context, attributes []*registrytyp
|
||||
// PutRecord - saves a record to the store.
|
||||
func (k Keeper) SaveRecord(ctx sdk.Context, record registrytypes.Record) error {
|
||||
return k.Records.Set(ctx, record.Id, record)
|
||||
|
||||
// TODO
|
||||
// k.updateBlockChangeSetForRecord(ctx, record.Id)
|
||||
}
|
||||
|
||||
// ProcessSetRecord creates a record.
|
||||
@@ -274,7 +284,7 @@ func (k Keeper) SetRecord(ctx sdk.Context, msg registrytypes.MsgSetRecord) (*reg
|
||||
|
||||
// Sort owners list.
|
||||
sort.Strings(record.Owners)
|
||||
sdkErr := k.processRecord(ctx, &record, false)
|
||||
sdkErr := k.processRecord(ctx, &record)
|
||||
if sdkErr != nil {
|
||||
return nil, sdkErr
|
||||
}
|
||||
@@ -282,7 +292,7 @@ func (k Keeper) SetRecord(ctx sdk.Context, msg registrytypes.MsgSetRecord) (*reg
|
||||
return &record, nil
|
||||
}
|
||||
|
||||
func (k Keeper) processRecord(ctx sdk.Context, record *registrytypes.ReadableRecord, isRenewal bool) error {
|
||||
func (k Keeper) processRecord(ctx sdk.Context, record *registrytypes.ReadableRecord) error {
|
||||
params, err := k.GetParams(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -420,7 +430,6 @@ func (k Keeper) GetModuleBalances(ctx sdk.Context) []*registrytypes.AccountBalan
|
||||
|
||||
// ProcessRecordExpiryQueue tries to renew expiring records (by collecting rent) else marks them as deleted.
|
||||
func (k Keeper) ProcessRecordExpiryQueue(ctx sdk.Context) error {
|
||||
// TODO: process expired records
|
||||
cids, err := k.getAllExpiredRecords(ctx, ctx.BlockHeader().Time)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -132,16 +132,7 @@ func (k Keeper) SaveNameRecord(ctx sdk.Context, crn string, id string) error {
|
||||
Height: uint64(ctx.BlockHeight()),
|
||||
}
|
||||
|
||||
// TODO: Check if index gets updated on entry updates
|
||||
if err := k.NameRecords.Set(ctx, crn, nameRecord); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO
|
||||
// Update changeSet for name.
|
||||
// k.updateBlockChangeSetForName(ctx, crn)
|
||||
|
||||
return nil
|
||||
return k.NameRecords.Set(ctx, crn, nameRecord)
|
||||
}
|
||||
|
||||
// SetName creates a CRN -> Record ID mapping.
|
||||
@@ -169,9 +160,6 @@ func (k Keeper) SetName(ctx sdk.Context, msg registrytypes.MsgSetName) error {
|
||||
// SaveNameAuthority creates the NameAuthority record.
|
||||
func (k Keeper) SaveNameAuthority(ctx sdk.Context, name string, authority *registrytypes.NameAuthority) error {
|
||||
return k.Authorities.Set(ctx, name, *authority)
|
||||
|
||||
// TODO
|
||||
// updateBlockChangeSetForNameAuthority(ctx, codec, store, name)
|
||||
}
|
||||
|
||||
// ReserveAuthority reserves a name authority.
|
||||
@@ -282,12 +270,9 @@ func (k Keeper) createAuthority(ctx sdk.Context, name string, owner string, isRo
|
||||
// If auctions are enabled, clear out owner fields. They will be set after a winner is picked.
|
||||
authority.OwnerAddress = ""
|
||||
authority.OwnerPublicKey = ""
|
||||
|
||||
// Reset bond ID if required.
|
||||
if authority.BondId != "" || len(authority.BondId) != 0 {
|
||||
// TODO
|
||||
// k.RemoveBondToAuthorityIndexEntry(ctx, authority.BondId, name)
|
||||
authority.BondId = ""
|
||||
}
|
||||
authority.BondId = ""
|
||||
|
||||
params := auctiontypes.Params{
|
||||
CommitsDuration: moduleParams.AuthorityAuctionCommitsDuration,
|
||||
@@ -305,10 +290,6 @@ func (k Keeper) createAuthority(ctx sdk.Context, name string, owner string, isRo
|
||||
return sdkErr
|
||||
}
|
||||
|
||||
// TODO
|
||||
// Create auction ID -> authority name index.
|
||||
// k.AddAuctionToAuthorityMapping(ctx, auction.Id, name)
|
||||
|
||||
authority.Status = registrytypes.AuthorityUnderAuction
|
||||
authority.AuctionId = auction.Id
|
||||
authority.ExpiryTime = auction.RevealsEndTime.Add(moduleParams.AuthorityGracePeriod)
|
||||
@@ -362,22 +343,12 @@ func (k Keeper) SetAuthorityBond(ctx sdk.Context, msg registrytypes.MsgSetAuthor
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO
|
||||
// Remove old bond ID mapping, if any.
|
||||
// if authority.BondId != "" {
|
||||
// k.RemoveBondToAuthorityIndexEntry(ctx, authority.BondId, name)
|
||||
// }
|
||||
|
||||
// Update bond id and save name authority in store.
|
||||
authority.BondId = bond.Id
|
||||
if err = k.SaveNameAuthority(ctx, name, &authority); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO
|
||||
// Add new bond ID mapping.
|
||||
// k.AddBondToAuthorityIndexEntry(ctx, authority.BondId, name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -546,8 +517,7 @@ func (k Keeper) ProcessAuthorityExpiryQueue(ctx sdk.Context) error {
|
||||
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
|
||||
}
|
||||
@@ -620,7 +590,7 @@ func (k Keeper) deleteAuthorityExpiryQueue(ctx sdk.Context, name string, authori
|
||||
|
||||
// tryTakeAuthorityRent tries to take rent from the authority bond.
|
||||
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)
|
||||
if err != nil {
|
||||
@@ -636,7 +606,8 @@ func (k Keeper) tryTakeAuthorityRent(ctx sdk.Context, name string, authority reg
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -653,7 +624,8 @@ func (k Keeper) tryTakeAuthorityRent(ctx sdk.Context, name string, authority reg
|
||||
// Save authority.
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,137 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"cosmossdk.io/collections"
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
|
||||
auctiontypes "git.vdb.to/cerc-io/laconic2d/x/auction"
|
||||
auctionkeeper "git.vdb.to/cerc-io/laconic2d/x/auction/keeper"
|
||||
bondtypes "git.vdb.to/cerc-io/laconic2d/x/bond"
|
||||
registrytypes "git.vdb.to/cerc-io/laconic2d/x/registry"
|
||||
)
|
||||
|
||||
// TODO: Add methods
|
||||
// Record keeper implements the bond usage keeper interface.
|
||||
var (
|
||||
_ auctiontypes.AuctionUsageKeeper = RecordKeeper{}
|
||||
_ bondtypes.BondUsageKeeper = RecordKeeper{}
|
||||
)
|
||||
|
||||
// RecordKeeper exposes the bare minimal read-only API for other modules.
|
||||
type RecordKeeper struct {
|
||||
cdc codec.BinaryCodec // The wire codec for binary encoding/decoding.
|
||||
auctionKeeper auctionkeeper.Keeper
|
||||
// storeKey storetypes.StoreKey // Unexposed key to access store from sdk.Context
|
||||
k *Keeper
|
||||
auctionKeeper *auctionkeeper.Keeper
|
||||
}
|
||||
|
||||
// NewRecordKeeper creates new instances of the registry RecordKeeper
|
||||
func NewRecordKeeper(cdc codec.BinaryCodec, k *Keeper, auctionKeeper *auctionkeeper.Keeper) RecordKeeper {
|
||||
return RecordKeeper{
|
||||
cdc: cdc,
|
||||
k: k,
|
||||
auctionKeeper: auctionKeeper,
|
||||
}
|
||||
}
|
||||
|
||||
// ModuleName returns the module name.
|
||||
func (rk RecordKeeper) ModuleName() string {
|
||||
return registrytypes.ModuleName
|
||||
}
|
||||
|
||||
func (rk RecordKeeper) UsesAuction(ctx sdk.Context, auctionId string) bool {
|
||||
iter, err := rk.k.Authorities.Indexes.AuctionId.MatchExact(ctx, auctionId)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return iter.Valid()
|
||||
}
|
||||
|
||||
func (rk RecordKeeper) OnAuctionWinnerSelected(ctx sdk.Context, auctionId string) {
|
||||
// Update authority status based on auction status/winner.
|
||||
iter, err := rk.k.Authorities.Indexes.AuctionId.MatchExact(ctx, auctionId)
|
||||
if err != nil && !errors.Is(err, collections.ErrNotFound) {
|
||||
panic(err)
|
||||
}
|
||||
names, err := iter.PrimaryKeys()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if len(names) == 0 {
|
||||
// We don't know about this auction, ignore.
|
||||
logger(ctx).Info(fmt.Sprintf("Ignoring auction notification, name mapping not found: %s", auctionId))
|
||||
return
|
||||
}
|
||||
|
||||
// Take the first one as an auction (non-empty) will map to only one name
|
||||
// MultiIndex being used as there can be multiple entries with empty auction id ("")
|
||||
name := names[0]
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
@@ -46,7 +159,7 @@ func (k Keeper) RenewRecord(ctx sdk.Context, msg registrytypes.MsgRenewRecord) e
|
||||
}
|
||||
|
||||
readableRecord := record.ToReadableRecord()
|
||||
return k.processRecord(ctx, &readableRecord, true)
|
||||
return k.processRecord(ctx, &readableRecord)
|
||||
}
|
||||
|
||||
// AssociateBond associates a record with a bond.
|
||||
|
||||
Reference in New Issue
Block a user