diff --git a/x/registry/keeper/msg_server.go b/x/registry/keeper/msg_server.go index b2e42cb0..9cd61378 100644 --- a/x/registry/keeper/msg_server.go +++ b/x/registry/keeper/msg_server.go @@ -115,7 +115,7 @@ func (ms msgServer) SetAuthorityBond(c context.Context, msg *registrytypes.MsgSe if err != nil { return nil, err } - err = ms.k.ProcessSetAuthorityBond(ctx, *msg) + err = ms.k.SetAuthorityBond(ctx, *msg) if err != nil { return nil, err } diff --git a/x/registry/keeper/naming_keeper.go b/x/registry/keeper/naming_keeper.go index b2766333..8c2eaba8 100644 --- a/x/registry/keeper/naming_keeper.go +++ b/x/registry/keeper/naming_keeper.go @@ -67,7 +67,7 @@ func (k Keeper) SaveNameAuthority(ctx sdk.Context, name string, authority *regis // updateBlockChangeSetForNameAuthority(ctx, codec, store, name) } -// ProcessReserveAuthority reserves a name authority. +// ReserveAuthority reserves a name authority. func (k Keeper) ReserveAuthority(ctx sdk.Context, msg registrytypes.MsgReserveAuthority) error { crn := fmt.Sprintf("crn://%s", msg.GetName()) parsedCrn, err := url.Parse(crn) @@ -180,8 +180,63 @@ func (k Keeper) createAuthority(ctx sdk.Context, name string, owner string, isRo return nil } -func (k Keeper) ProcessSetAuthorityBond(ctx sdk.Context, msg registrytypes.MsgSetAuthorityBond) error { - panic("unimplemented") +func (k Keeper) SetAuthorityBond(ctx sdk.Context, msg registrytypes.MsgSetAuthorityBond) error { + name := msg.GetName() + signer := msg.GetSigner() + + if has, err := k.HasNameAuthority(ctx, name); !has { + if err != nil { + return err + } + + return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Name authority not found.") + } + + authority, err := k.GetNameAuthority(ctx, name) + if err != nil { + return err + } + if authority.OwnerAddress != signer { + return errorsmod.Wrap(sdkerrors.ErrUnauthorized, "Access denied.") + } + + if has, err := k.bondKeeper.HasBond(ctx, msg.BondId); !has { + if err != nil { + return err + } + return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Bond not found.") + } + + bond, err := k.bondKeeper.GetBondById(ctx, msg.BondId) + if err != nil { + return err + } + if bond.Owner != signer { + return errorsmod.Wrap(sdkerrors.ErrUnauthorized, "Bond owner mismatch.") + } + + // No-op if bond hasn't changed. + if authority.BondId == msg.BondId { + 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 } // ProcessDeleteName removes a CRN -> Record ID mapping. diff --git a/x/registry/module/autocli.go b/x/registry/module/autocli.go index 72f7a66e..44fb09cf 100644 --- a/x/registry/module/autocli.go +++ b/x/registry/module/autocli.go @@ -71,6 +71,15 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { {ProtoField: "owner"}, }, }, + { + RpcMethod: "SetAuthorityBond", + Use: "authority-bond [name] [bond-id]", + Short: "Associate authority with bond", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "name"}, + {ProtoField: "bond_id"}, + }, + }, }, EnhanceCustomCommand: true, // Allow additional manual commands },