Skip to content

Commit

Permalink
fix(rollapp): add sequence id to Rollapp App (#1216)
Browse files Browse the repository at this point in the history
  • Loading branch information
zale144 authored Sep 12, 2024
1 parent 6de2c58 commit ae280ca
Show file tree
Hide file tree
Showing 15 changed files with 411 additions and 206 deletions.
14 changes: 8 additions & 6 deletions proto/dymensionxyz/dymension/rollapp/app.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ package dymensionxyz.dymension.rollapp;
option go_package = "github.com/dymensionxyz/dymension/v3/x/rollapp/types";

message App {
// id is the unique App's id in the Rollapp
uint64 id = 1;
// name is the unique App's name
string name = 1;
string name = 2;
// rollapp_id is the id of the Rollapp the App belongs to
string rollapp_id = 2;
string rollapp_id = 3;
// description is the description of the App
string description = 3;
string description = 4;
// image_url is the URL to the App's image
string image_url = 4;
string image_url = 5;
// url is the URL to the App's website
string url = 5;
string url = 6;
// order is the order of the App in the Rollapp
int32 order = 6;
int32 order = 7;
}
18 changes: 10 additions & 8 deletions proto/dymensionxyz/dymension/rollapp/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -133,18 +133,20 @@ message MsgUpdateApp {
option (cosmos.msg.v1.signer) = "creator";
// creator is the bech32-encoded address of the app owner
string creator = 1;
// id is the unique App's id in the Rollapp
uint64 id = 2;
// name is the unique App's name (immutable)
string name = 2;
string name = 3;
// rollapp_id is the id of the Rollapp the App belongs to
string rollapp_id = 3;
string rollapp_id = 4;
// description is the description of the App
string description = 4;
string description = 5;
// image is the url to the App image
string image = 5;
string image = 6;
// url is the URL to the App's website
string url = 6;
string url = 7;
// order is the order of the App in the Rollapp
int32 order = 7;
int32 order = 8;
}

message MsgUpdateAppResponse {
Expand All @@ -155,8 +157,8 @@ message MsgRemoveApp {
option (cosmos.msg.v1.signer) = "creator";
// creator is the bech32-encoded address of the app owner
string creator = 1;
// name is the unique App's name
string name = 2;
// id is the unique App's id in the Rollapp
uint64 id = 2;
// rollapp_id is the id of the Rollapp the App belongs to
string rollapp_id = 3;
}
Expand Down
11 changes: 8 additions & 3 deletions x/rollapp/client/cli/tx_remove_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,23 @@ var _ = strconv.Itoa(0)

func CmdRemoveApp() *cobra.Command {
cmd := &cobra.Command{
Use: "remove-app [name] [rollapp-id]",
Use: "remove-app [app-id] [rollapp-id]",
Short: "Remove an app",
Args: cobra.ExactArgs(6),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) (err error) {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

appID, err := strconv.ParseUint(args[0], 10, 64)
if err != nil {
return err
}

msg := types.NewMsgRemoveApp(
clientCtx.GetFromAddress().String(),
args[0],
appID,
args[1],
)

Expand Down
26 changes: 16 additions & 10 deletions x/rollapp/client/cli/tx_update_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,27 @@ import (

func CmdUpdateApp() *cobra.Command {
cmd := &cobra.Command{
Use: "update-app [name] [rollapp-id] [description] [logo] [url] [order]",
Use: "update-app [id] [name] [rollapp-id] [description] [logo] [url] [order]",
Short: "Update an app",
Example: "dymd tx app update-app 'app1' 'rollapp_1234-1' 1 'A description' '/logos/apps/app1.jpeg' 'https://app1.com/'",
Args: cobra.MinimumNArgs(1),
Example: "dymd tx rollapp update-app 1 'app1' 'rollapp_1234-1' 'A description' '/logos/apps/app1.jpeg' 'https://app1.com/' 3",
Args: cobra.MinimumNArgs(6),
RunE: func(cmd *cobra.Command, args []string) (err error) {
var (
name = args[0]
rollappId = args[1]
description = args[2]
logo = args[3]
url = args[4]
name = args[1]
rollappId = args[2]
description = args[3]
logo = args[4]
url = args[5]
order int64 = -1
)

if len(args) == 6 {
order, err = strconv.ParseInt(args[5], 10, 32)
id, err := strconv.ParseUint(args[0], 10, 64)
if err != nil {
return err
}

if len(args) == 7 {
order, err = strconv.ParseInt(args[6], 10, 32)
if err != nil {
return err
}
Expand All @@ -41,6 +46,7 @@ func CmdUpdateApp() *cobra.Command {

msg := types.NewMsgUpdateApp(
clientCtx.GetFromAddress().String(),
id,
name,
rollappId,
description,
Expand Down
23 changes: 21 additions & 2 deletions x/rollapp/keeper/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ func (k Keeper) DeleteApp(ctx sdk.Context, app types.App) {
store.Delete(key)
}

func (k Keeper) GetApp(ctx sdk.Context, name, rollappId string) (val types.App, found bool) {
func (k Keeper) GetApp(ctx sdk.Context, id uint64, rollappId string) (val types.App, found bool) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.AppKeyPrefix))
key := types.AppKey(types.App{Name: name, RollappId: rollappId})
key := types.AppKey(types.App{Id: id, RollappId: rollappId})
b := store.Get(key)
if b == nil {
return val, false
Expand Down Expand Up @@ -55,3 +55,22 @@ func (k Keeper) GetRollappApps(ctx sdk.Context, rollappId string) (list []*types

return list
}

// GenerateNextAppID increments and returns the next available App ID for a specific Rollapp.
func (k Keeper) GenerateNextAppID(ctx sdk.Context, rollappID string) uint64 {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.AppSequenceKeyPrefix))
sequenceKey := types.AppSequenceKey(rollappID)

bz := store.Get(sequenceKey)
var seq uint64
if bz == nil {
seq = 0
} else {
seq = sdk.BigEndianToUint64(bz)
}

seq++
store.Set(sequenceKey, sdk.Uint64ToBigEndian(seq))

return seq
}
44 changes: 32 additions & 12 deletions x/rollapp/keeper/msg_server_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ func (k msgServer) AddApp(goCtx context.Context, msg *types.MsgAddApp) (*types.M
}

app := msg.GetApp()
app.Id = k.GenerateNextAppID(ctx, app.RollappId)

k.SetApp(ctx, app)

if err := ctx.EventManager().EmitTypedEvent(app.GetAddedEvent()); err != nil {
Expand Down Expand Up @@ -83,36 +85,54 @@ func (k msgServer) RemoveApp(goCtx context.Context, msg *types.MsgRemoveApp) (*t
}

func (k msgServer) checkInputs(ctx sdk.Context, msg appMsg) error {
rollapp, foundRollapp := k.GetRollapp(ctx, msg.GetRollappId())
app := msg.GetApp()
rollapp, foundRollapp := k.GetRollapp(ctx, app.GetRollappId())
if !foundRollapp {
return gerrc.ErrNotFound.Wrapf("rollappId: %s", msg.GetRollappId())
return gerrc.ErrNotFound.Wrapf("rollappId: %s", app.GetRollappId())
}

// check if the sender is the owner of the app
if msg.GetCreator() != rollapp.Owner {
return gerrc.ErrPermissionDenied.Wrap("not the owner of the RollApp")
}

// check if the app already exists
_, foundApp := k.GetApp(ctx, msg.GetName(), msg.GetRollappId())
switch msg.(type) {
case *types.MsgAddApp:
if foundApp {
return gerrc.ErrAlreadyExists.Wrap("app already exists")
}
case *types.MsgUpdateApp, *types.MsgRemoveApp:
if !foundApp {
case *types.MsgRemoveApp, *types.MsgUpdateApp:
if idExists := k.appIDExists(ctx, app); !idExists {
return gerrc.ErrNotFound.Wrap("app not found")
}
}
switch msg.(type) {
case *types.MsgAddApp, *types.MsgUpdateApp:
apps := k.GetRollappApps(ctx, app.GetRollappId())
if nameExists := k.appNameExists(apps, app); nameExists {
return gerrc.ErrAlreadyExists.Wrap("app name already exists")
}
}

return nil
}

func (k msgServer) appNameExists(apps []*types.App, app types.App) bool {
for _, a := range apps {
// does name already exist:
// - id=0 means it is a new app
// - skip if the id is the same as the app being checked
if (app.GetId() == 0 || a.Id != app.GetId()) && a.Name == app.GetName() {
return true
}
}
return false
}

func (k msgServer) appIDExists(ctx sdk.Context, app types.App) bool {
_, foundApp := k.GetApp(ctx, app.GetId(), app.GetRollappId())
return foundApp
}

type appMsg interface {
GetName() string
GetRollappId() string
GetCreator() string
GetApp() types.App
}

var _ types.MsgServer = msgServer{}
Loading

0 comments on commit ae280ca

Please sign in to comment.