Add commands to reserve and get name authority
This commit is contained in:
parent
91a8b56183
commit
764fb1f04a
@ -6,7 +6,23 @@ import (
|
|||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ sdk.Msg = &MsgCommitBid{}
|
var (
|
||||||
|
_ sdk.Msg = &MsgCreateAuction{}
|
||||||
|
_ sdk.Msg = &MsgCommitBid{}
|
||||||
|
_ sdk.Msg = &MsgRevealBid{}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewMsgCreateAuction is the constructor function for MsgCreateAuction.
|
||||||
|
func NewMsgCreateAuction(params Params, signer sdk.AccAddress) MsgCreateAuction {
|
||||||
|
return MsgCreateAuction{
|
||||||
|
CommitsDuration: params.CommitsDuration,
|
||||||
|
RevealsDuration: params.RevealsDuration,
|
||||||
|
CommitFee: params.CommitFee,
|
||||||
|
RevealFee: params.RevealFee,
|
||||||
|
MinimumBid: params.MinimumBid,
|
||||||
|
Signer: signer.String(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NewMsgCommitBid is the constructor function for MsgCommitBid.
|
// NewMsgCommitBid is the constructor function for MsgCommitBid.
|
||||||
func NewMsgCommitBid(auctionID string, commitHash string, signer sdk.AccAddress) MsgCommitBid {
|
func NewMsgCommitBid(auctionID string, commitHash string, signer sdk.AccAddress) MsgCommitBid {
|
||||||
|
@ -40,7 +40,7 @@ func (b RecordsIndexes) IndexesList() []collections.Index[string, registrytypes.
|
|||||||
func newRecordIndexes(sb *collections.SchemaBuilder) RecordsIndexes {
|
func newRecordIndexes(sb *collections.SchemaBuilder) RecordsIndexes {
|
||||||
return RecordsIndexes{
|
return RecordsIndexes{
|
||||||
BondId: indexes.NewMulti(
|
BondId: indexes.NewMulti(
|
||||||
sb, registrytypes.BondIdIndexPrefix, "records_by_bond_id",
|
sb, registrytypes.RecordsByBondIdIndexPrefix, "records_by_bond_id",
|
||||||
collections.StringKey, collections.StringKey,
|
collections.StringKey, collections.StringKey,
|
||||||
func(_ string, v registrytypes.Record) (string, error) {
|
func(_ string, v registrytypes.Record) (string, error) {
|
||||||
return v.BondId, nil
|
return v.BondId, nil
|
||||||
@ -49,6 +49,18 @@ func newRecordIndexes(sb *collections.SchemaBuilder) RecordsIndexes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
type AuthoritiesIndexes struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b AuthoritiesIndexes) IndexesList() []collections.Index[string, registrytypes.NameAuthority] {
|
||||||
|
return []collections.Index[string, registrytypes.NameAuthority]{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newAuthorityIndexes(sb *collections.SchemaBuilder) AuthoritiesIndexes {
|
||||||
|
return AuthoritiesIndexes{}
|
||||||
|
}
|
||||||
|
|
||||||
type Keeper struct {
|
type Keeper struct {
|
||||||
cdc codec.BinaryCodec
|
cdc codec.BinaryCodec
|
||||||
|
|
||||||
@ -59,9 +71,10 @@ type Keeper struct {
|
|||||||
auctionKeeper auctionkeeper.Keeper
|
auctionKeeper auctionkeeper.Keeper
|
||||||
|
|
||||||
// state management
|
// state management
|
||||||
Schema collections.Schema
|
Schema collections.Schema
|
||||||
Params collections.Item[registrytypes.Params]
|
Params collections.Item[registrytypes.Params]
|
||||||
Records *collections.IndexedMap[string, registrytypes.Record, RecordsIndexes]
|
Records *collections.IndexedMap[string, registrytypes.Record, RecordsIndexes]
|
||||||
|
Authorities *collections.IndexedMap[string, registrytypes.NameAuthority, AuthoritiesIndexes]
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewKeeper creates a new Keeper instance
|
// NewKeeper creates a new Keeper instance
|
||||||
@ -83,7 +96,16 @@ func NewKeeper(
|
|||||||
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)),
|
||||||
Records: collections.NewIndexedMap(sb, registrytypes.RecordsPrefix, "records", collections.StringKey, codec.CollValue[registrytypes.Record](cdc), newRecordIndexes(sb)),
|
Records: collections.NewIndexedMap(
|
||||||
|
sb, registrytypes.RecordsPrefix, "records",
|
||||||
|
collections.StringKey, codec.CollValue[registrytypes.Record](cdc),
|
||||||
|
newRecordIndexes(sb),
|
||||||
|
),
|
||||||
|
Authorities: collections.NewIndexedMap(
|
||||||
|
sb, registrytypes.AuthoritiesPrefix, "authorities",
|
||||||
|
collections.StringKey, codec.CollValue[registrytypes.NameAuthority](cdc),
|
||||||
|
newAuthorityIndexes(sb),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
schema, err := sb.Build()
|
schema, err := sb.Build()
|
||||||
|
@ -77,6 +77,7 @@ func (ms msgServer) SetName(c context.Context, msg *registrytypes.MsgSetName) (*
|
|||||||
|
|
||||||
func (ms msgServer) ReserveName(c context.Context, msg *registrytypes.MsgReserveAuthority) (*registrytypes.MsgReserveAuthorityResponse, error) {
|
func (ms msgServer) ReserveName(c context.Context, msg *registrytypes.MsgReserveAuthority) (*registrytypes.MsgReserveAuthorityResponse, error) {
|
||||||
ctx := sdk.UnwrapSDKContext(c)
|
ctx := sdk.UnwrapSDKContext(c)
|
||||||
|
|
||||||
_, err := sdk.AccAddressFromBech32(msg.Signer)
|
_, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -85,10 +86,12 @@ func (ms msgServer) ReserveName(c context.Context, msg *registrytypes.MsgReserve
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = ms.k.ProcessReserveAuthority(ctx, *msg)
|
|
||||||
|
err = ms.k.ReserveAuthority(ctx, *msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.EventManager().EmitEvents(sdk.Events{
|
ctx.EventManager().EmitEvents(sdk.Events{
|
||||||
sdk.NewEvent(
|
sdk.NewEvent(
|
||||||
registrytypes.EventTypeReserveNameAuthority,
|
registrytypes.EventTypeReserveNameAuthority,
|
||||||
|
@ -1,14 +1,42 @@
|
|||||||
package keeper
|
package keeper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"cosmossdk.io/collections"
|
||||||
|
errorsmod "cosmossdk.io/errors"
|
||||||
|
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
|
|
||||||
|
auctiontypes "git.vdb.to/cerc-io/laconic2d/x/auction"
|
||||||
registrytypes "git.vdb.to/cerc-io/laconic2d/x/registry"
|
registrytypes "git.vdb.to/cerc-io/laconic2d/x/registry"
|
||||||
|
"git.vdb.to/cerc-io/laconic2d/x/registry/helpers"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// HasNameAuthority - checks if a name/authority exists.
|
||||||
|
func (k Keeper) HasNameAuthority(ctx sdk.Context, name string) (bool, error) {
|
||||||
|
has, err := k.Authorities.Has(ctx, name)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return has, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetNameAuthority - gets a name authority from the store.
|
// GetNameAuthority - gets a name authority from the store.
|
||||||
func (k Keeper) GetNameAuthority(ctx sdk.Context, name string) registrytypes.NameAuthority {
|
func (k Keeper) GetNameAuthority(ctx sdk.Context, name string) (registrytypes.NameAuthority, error) {
|
||||||
panic("unimplemented")
|
authority, err := k.Authorities.Get(ctx, name)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, collections.ErrNotFound) {
|
||||||
|
return registrytypes.NameAuthority{}, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Name authority not found.")
|
||||||
|
}
|
||||||
|
return registrytypes.NameAuthority{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return authority, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasNameRecord - checks if a name record exists.
|
// HasNameRecord - checks if a name record exists.
|
||||||
@ -31,9 +59,125 @@ func (k Keeper) ProcessSetName(ctx sdk.Context, msg registrytypes.MsgSetName) er
|
|||||||
panic("unimplemented")
|
panic("unimplemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
// ProcessReserveAuthority reserves a name authority.
|
// ProcessReserveAuthority reserves a name authority.
|
||||||
func (k Keeper) ProcessReserveAuthority(ctx sdk.Context, msg registrytypes.MsgReserveAuthority) error {
|
func (k Keeper) ReserveAuthority(ctx sdk.Context, msg registrytypes.MsgReserveAuthority) error {
|
||||||
panic("unimplemented")
|
crn := fmt.Sprintf("crn://%s", msg.GetName())
|
||||||
|
parsedCrn, err := url.Parse(crn)
|
||||||
|
if err != nil {
|
||||||
|
return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Invalid name")
|
||||||
|
}
|
||||||
|
|
||||||
|
name := parsedCrn.Host
|
||||||
|
if fmt.Sprintf("crn://%s", name) != crn {
|
||||||
|
return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Invalid name")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// if strings.Contains(name, ".") {
|
||||||
|
// return k.ProcessReserveSubAuthority(ctx, name, msg)
|
||||||
|
// }
|
||||||
|
|
||||||
|
err = k.createAuthority(ctx, name, msg.GetSigner(), true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Keeper) createAuthority(ctx sdk.Context, name string, owner string, isRoot bool) error {
|
||||||
|
moduleParams, err := k.GetParams(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
has, err := k.HasNameAuthority(ctx, name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if has {
|
||||||
|
authority, err := k.GetNameAuthority(ctx, name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if authority.Status != registrytypes.AuthorityExpired {
|
||||||
|
return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Name already reserved.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ownerAddress, err := sdk.AccAddressFromBech32(owner)
|
||||||
|
if err != nil {
|
||||||
|
return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Invalid owner address.")
|
||||||
|
}
|
||||||
|
ownerAccount := k.accountKeeper.GetAccount(ctx, ownerAddress)
|
||||||
|
if ownerAccount == nil {
|
||||||
|
return errorsmod.Wrap(sdkerrors.ErrUnknownAddress, "Owner account not found.")
|
||||||
|
}
|
||||||
|
|
||||||
|
authority := registrytypes.NameAuthority{
|
||||||
|
OwnerPublicKey: getAuthorityPubKey(ownerAccount.GetPubKey()),
|
||||||
|
OwnerAddress: owner,
|
||||||
|
Height: uint64(ctx.BlockHeight()),
|
||||||
|
Status: registrytypes.AuthorityActive,
|
||||||
|
AuctionId: "",
|
||||||
|
BondId: "",
|
||||||
|
ExpiryTime: ctx.BlockTime().Add(moduleParams.AuthorityGracePeriod),
|
||||||
|
}
|
||||||
|
|
||||||
|
if isRoot && moduleParams.AuthorityAuctionEnabled {
|
||||||
|
// 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 = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
params := auctiontypes.Params{
|
||||||
|
CommitsDuration: moduleParams.AuthorityAuctionCommitsDuration,
|
||||||
|
RevealsDuration: moduleParams.AuthorityAuctionRevealsDuration,
|
||||||
|
CommitFee: moduleParams.AuthorityAuctionCommitFee,
|
||||||
|
RevealFee: moduleParams.AuthorityAuctionRevealFee,
|
||||||
|
MinimumBid: moduleParams.AuthorityAuctionMinimumBid,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an auction.
|
||||||
|
msg := auctiontypes.NewMsgCreateAuction(params, ownerAddress)
|
||||||
|
|
||||||
|
auction, sdkErr := k.auctionKeeper.CreateAuction(ctx, msg)
|
||||||
|
if sdkErr != nil {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save name authority in store.
|
||||||
|
if err = k.SaveNameAuthority(ctx, name, &authority); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// k.InsertAuthorityExpiryQueue(ctx, name, authority.ExpiryTime)
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k Keeper) ProcessSetAuthorityBond(ctx sdk.Context, msg registrytypes.MsgSetAuthorityBond) error {
|
func (k Keeper) ProcessSetAuthorityBond(ctx sdk.Context, msg registrytypes.MsgSetAuthorityBond) error {
|
||||||
@ -53,3 +197,11 @@ func (k Keeper) GetAuthorityExpiryQueue(ctx sdk.Context) []*registrytypes.Expiry
|
|||||||
func (k Keeper) ResolveCRN(ctx sdk.Context, crn string) *registrytypes.Record {
|
func (k Keeper) ResolveCRN(ctx sdk.Context, crn string) *registrytypes.Record {
|
||||||
panic("unimplemented")
|
panic("unimplemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getAuthorityPubKey(pubKey cryptotypes.PubKey) string {
|
||||||
|
if pubKey == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return helpers.BytesToBase64(pubKey.Bytes())
|
||||||
|
}
|
||||||
|
@ -104,7 +104,12 @@ func (qs queryServer) NameRecords(c context.Context, _ *registrytypes.QueryNameR
|
|||||||
|
|
||||||
func (qs queryServer) Whois(c context.Context, request *registrytypes.QueryWhoisRequest) (*registrytypes.QueryWhoisResponse, error) {
|
func (qs queryServer) Whois(c context.Context, request *registrytypes.QueryWhoisRequest) (*registrytypes.QueryWhoisResponse, error) {
|
||||||
ctx := sdk.UnwrapSDKContext(c)
|
ctx := sdk.UnwrapSDKContext(c)
|
||||||
nameAuthority := qs.k.GetNameAuthority(ctx, request.GetName())
|
|
||||||
|
nameAuthority, err := qs.k.GetNameAuthority(ctx, request.GetName())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return ®istrytypes.QueryWhoisResponse{NameAuthority: nameAuthority}, nil
|
return ®istrytypes.QueryWhoisResponse{NameAuthority: nameAuthority}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,10 @@ var (
|
|||||||
// ParamsKey is the prefix for params key
|
// ParamsKey is the prefix for params key
|
||||||
ParamsPrefix = collections.NewPrefix(0)
|
ParamsPrefix = collections.NewPrefix(0)
|
||||||
|
|
||||||
RecordsPrefix = collections.NewPrefix(1)
|
RecordsPrefix = collections.NewPrefix(1)
|
||||||
BondIdIndexPrefix = collections.NewPrefix(2)
|
RecordsByBondIdIndexPrefix = collections.NewPrefix(2)
|
||||||
|
|
||||||
|
AuthoritiesPrefix = collections.NewPrefix(3)
|
||||||
|
AuthoritiesByAuctionIdIndexPrefix = collections.NewPrefix(4)
|
||||||
|
AuthoritiesByBondIdIndexPrefix = collections.NewPrefix(5)
|
||||||
)
|
)
|
||||||
|
@ -43,11 +43,29 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
|
|||||||
{ProtoField: "id"},
|
{ProtoField: "id"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
RpcMethod: "Whois",
|
||||||
|
Use: "whois [name]",
|
||||||
|
Short: "Get name authority info",
|
||||||
|
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
|
||||||
|
{ProtoField: "name"},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Tx: &autocliv1.ServiceCommandDescriptor{
|
Tx: &autocliv1.ServiceCommandDescriptor{
|
||||||
Service: registryv1.Msg_ServiceDesc.ServiceName,
|
Service: registryv1.Msg_ServiceDesc.ServiceName,
|
||||||
RpcCommandOptions: []*autocliv1.RpcCommandOptions{},
|
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
|
||||||
|
{
|
||||||
|
RpcMethod: "ReserveName",
|
||||||
|
Use: "reserve-name [name] [owner]",
|
||||||
|
Short: "Reserve name",
|
||||||
|
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
|
||||||
|
{ProtoField: "name"},
|
||||||
|
{ProtoField: "owner"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
EnhanceCustomCommand: true, // Allow additional manual commands
|
EnhanceCustomCommand: true, // Allow additional manual commands
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user